11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2923c1f34SJens Wiklander /*-
3923c1f34SJens Wiklander * Copyright (c) 2015 Linaro Limited
4923c1f34SJens Wiklander * Copyright (c) 2015 The FreeBSD Foundation
5923c1f34SJens Wiklander * All rights reserved.
6923c1f34SJens Wiklander *
7923c1f34SJens Wiklander * This software was developed by Semihalf under
8923c1f34SJens Wiklander * the sponsorship of the FreeBSD Foundation.
9923c1f34SJens Wiklander *
10923c1f34SJens Wiklander * Redistribution and use in source and binary forms, with or without
11923c1f34SJens Wiklander * modification, are permitted provided that the following conditions
12923c1f34SJens Wiklander * are met:
13923c1f34SJens Wiklander * 1. Redistributions of source code must retain the above copyright
14923c1f34SJens Wiklander * notice, this list of conditions and the following disclaimer.
15923c1f34SJens Wiklander * 2. Redistributions in binary form must reproduce the above copyright
16923c1f34SJens Wiklander * notice, this list of conditions and the following disclaimer in the
17923c1f34SJens Wiklander * documentation and/or other materials provided with the distribution.
18923c1f34SJens Wiklander *
19923c1f34SJens Wiklander * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20923c1f34SJens Wiklander * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21923c1f34SJens Wiklander * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22923c1f34SJens Wiklander * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23923c1f34SJens Wiklander * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24923c1f34SJens Wiklander * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25923c1f34SJens Wiklander * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26923c1f34SJens Wiklander * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27923c1f34SJens Wiklander * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28923c1f34SJens Wiklander * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29923c1f34SJens Wiklander * SUCH DAMAGE.
30923c1f34SJens Wiklander */
31923c1f34SJens Wiklander
32a681fabaSJerome Forissier #include <arm.h>
33170e9084SJens Wiklander #include <kernel/linker.h>
34170e9084SJens Wiklander #include <kernel/thread.h>
35170e9084SJens Wiklander #include <kernel/unwind.h>
3602d307b7SJerome Forissier #include <unw/unwind.h>
37a367dcbbSJerome Forissier
38a367dcbbSJerome Forissier #include "unwind_private.h"
39923c1f34SJens Wiklander
40*93dc6b29SJens Wiklander #if defined(CFG_CORE_PAUTH)
pauth_strip_pac(uint64_t * lr)41*93dc6b29SJens Wiklander void pauth_strip_pac(uint64_t *lr)
42*93dc6b29SJens Wiklander {
43*93dc6b29SJens Wiklander const uint64_t va_mask = GENMASK_64(CFG_LPAE_ADDR_SPACE_BITS - 1, 0);
44*93dc6b29SJens Wiklander
45*93dc6b29SJens Wiklander *lr = *lr & va_mask;
46*93dc6b29SJens Wiklander }
47*93dc6b29SJens Wiklander #endif
48*93dc6b29SJens Wiklander
unw_get_kernel_stack(void)49a367dcbbSJerome Forissier vaddr_t *unw_get_kernel_stack(void)
50a367dcbbSJerome Forissier {
51a367dcbbSJerome Forissier size_t n = 0;
52a367dcbbSJerome Forissier size_t size = 0;
53a367dcbbSJerome Forissier vaddr_t *tmp = NULL;
54a367dcbbSJerome Forissier vaddr_t *addr = NULL;
55a367dcbbSJerome Forissier uaddr_t stack = thread_stack_start();
56a367dcbbSJerome Forissier size_t stack_size = thread_stack_size();
5702d307b7SJerome Forissier struct unwind_state_arm64 state = {
5802d307b7SJerome Forissier .pc = read_pc(),
5902d307b7SJerome Forissier .fp = read_fp()
6002d307b7SJerome Forissier };
61a367dcbbSJerome Forissier
62c9826bf5SJens Wiklander while (unwind_stack_arm64(&state, stack, stack_size)) {
63a367dcbbSJerome Forissier tmp = unw_grow(addr, &size, (n + 1) * sizeof(vaddr_t));
64a367dcbbSJerome Forissier if (!tmp)
65a367dcbbSJerome Forissier goto err;
66a367dcbbSJerome Forissier addr = tmp;
67a367dcbbSJerome Forissier addr[n] = state.pc;
68a367dcbbSJerome Forissier n++;
69a367dcbbSJerome Forissier }
70a367dcbbSJerome Forissier
71a367dcbbSJerome Forissier if (addr) {
72a367dcbbSJerome Forissier tmp = unw_grow(addr, &size, (n + 1) * sizeof(vaddr_t));
73a367dcbbSJerome Forissier if (!tmp)
74a367dcbbSJerome Forissier goto err;
75a367dcbbSJerome Forissier addr = tmp;
76a367dcbbSJerome Forissier addr[n] = 0;
77a367dcbbSJerome Forissier }
78a367dcbbSJerome Forissier
79a367dcbbSJerome Forissier return addr;
80a367dcbbSJerome Forissier err:
81a367dcbbSJerome Forissier EMSG("Out of memory");
82a367dcbbSJerome Forissier free(addr);
83a367dcbbSJerome Forissier return NULL;
84a367dcbbSJerome Forissier }
8502d307b7SJerome Forissier
86adb7766eSMoritz Lummerzheim #if defined(CFG_UNWIND) && (TRACE_LEVEL > 0)
print_kernel_stack(void)8702d307b7SJerome Forissier void print_kernel_stack(void)
8802d307b7SJerome Forissier {
8902d307b7SJerome Forissier struct unwind_state_arm64 state = { };
9002d307b7SJerome Forissier vaddr_t stack_start = 0;
9102d307b7SJerome Forissier vaddr_t stack_end = 0;
9202d307b7SJerome Forissier
9302d307b7SJerome Forissier state.pc = read_pc();
9402d307b7SJerome Forissier state.fp = read_fp();
9502d307b7SJerome Forissier
9602d307b7SJerome Forissier trace_printf_helper_raw(TRACE_ERROR, true,
9702d307b7SJerome Forissier "TEE load address @ %#"PRIxVA, VCORE_START_VA);
9802d307b7SJerome Forissier get_stack_hard_limits(&stack_start, &stack_end);
9902d307b7SJerome Forissier print_stack_arm64(&state, stack_start, stack_end - stack_start);
10002d307b7SJerome Forissier }
101adb7766eSMoritz Lummerzheim #endif
102