Commit 68c76088 authored by Alexei Fedorov's avatar Alexei Fedorov
Browse files

Make PAC demangling more generic



At the moment, address demangling is only used by the backtrace
functionality. However, at some point, other parts of the TF-A
codebase may want to use it.
The 'demangle_address' function is replaced with a single XPACI
instruction which is also added in 'do_crash_reporting()'.
Signed-off-by: default avatarAlexei Fedorov <Alexei.Fedorov@arm.com>
Change-Id: I4424dcd54d5bf0a5f9b2a0a84c4e565eec7329ec
parent 235c8174
/* /*
* Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -244,6 +244,11 @@ func do_crash_reporting ...@@ -244,6 +244,11 @@ func do_crash_reporting
mrs x0, tpidr_el3 mrs x0, tpidr_el3
/* report x30 first from the crash buf */ /* report x30 first from the crash buf */
ldr x4, [x0, #REGSZ * 7] ldr x4, [x0, #REGSZ * 7]
#if ENABLE_PAUTH
/* Demangle address */
xpaci x4
#endif
bl asm_print_hex bl asm_print_hex
bl asm_print_newline bl asm_print_newline
/* Load the crash buf address */ /* Load the crash buf address */
......
/* /*
* Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -37,47 +37,6 @@ struct frame_record { ...@@ -37,47 +37,6 @@ struct frame_record {
uintptr_t return_addr; uintptr_t return_addr;
}; };
/*
* Strip the Pointer Authentication Code (PAC) from the address to retrieve the
* original one.
*
* The PAC field is stored on the high bits of the address and defined as:
* - PAC field = Xn[54:bottom_PAC_bit], when address tagging is used.
* - PAC field = Xn[63:56, 54:bottom_PAC_bit], without address tagging.
*
* With bottom_PAC_bit = 64 - TCR_ELx.TnSZ
*/
#if ENABLE_PAUTH
static uintptr_t demangle_address(uintptr_t addr)
{
unsigned int el, t0sz, bottom_pac_bit;
uint64_t tcr, pac_mask;
/*
* Different virtual address space size can be defined for each EL.
* Ensure that we use the proper one by reading the corresponding
* TCR_ELx register.
*/
el = get_current_el();
if (el == 3U) {
tcr = read_tcr_el3();
} else if (el == 2U) {
tcr = read_tcr_el2();
} else {
tcr = read_tcr_el1();
}
/* T0SZ = TCR_ELx[5:0] */
t0sz = tcr & 0x1f;
bottom_pac_bit = 64 - t0sz;
pac_mask = (1ULL << bottom_pac_bit) - 1;
/* demangle the address with the computed mask */
return (addr & pac_mask);
}
#endif /* ENABLE_PAUTH */
static const char *get_el_str(unsigned int el) static const char *get_el_str(unsigned int el)
{ {
if (el == 3U) { if (el == 3U) {
...@@ -104,9 +63,8 @@ static bool is_address_readable(uintptr_t addr) ...@@ -104,9 +63,8 @@ static bool is_address_readable(uintptr_t addr)
* stack contains a PAC. It must be stripped to retrieve the return * stack contains a PAC. It must be stripped to retrieve the return
* address. * address.
*/ */
addr = demangle_address(addr); xpaci(addr);
#endif #endif
if (el == 3U) { if (el == 3U) {
ats1e3r(addr); ats1e3r(addr);
} else if (el == 2U) { } else if (el == 2U) {
...@@ -257,9 +215,8 @@ static void unwind_stack(struct frame_record *fr, uintptr_t current_pc, ...@@ -257,9 +215,8 @@ static void unwind_stack(struct frame_record *fr, uintptr_t current_pc,
* the stack contains a PAC. It must be stripped to retrieve the * the stack contains a PAC. It must be stripped to retrieve the
* return address. * return address.
*/ */
call_site = demangle_address(call_site); xpaci(call_site);
#endif #endif
/* /*
* If the address is invalid it means that the frame record is * If the address is invalid it means that the frame record is
* probably corrupted. * probably corrupted.
......
...@@ -189,7 +189,7 @@ Common build options ...@@ -189,7 +189,7 @@ Common build options
that is only required for the assertion and does not fit in the assertion that is only required for the assertion and does not fit in the assertion
itself. itself.
- ``ENABLE_BACKTRACE``: This option controls whether to enables backtrace - ``ENABLE_BACKTRACE``: This option controls whether to enable backtrace
dumps or not. It is supported in both AArch64 and AArch32. However, in dumps or not. It is supported in both AArch64 and AArch32. However, in
AArch32 the format of the frame records are not defined in the AAPCS and they AArch32 the format of the frame records are not defined in the AAPCS and they
are defined by the implementation. This implementation of backtrace only are defined by the implementation. This implementation of backtrace only
......
/* /*
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -69,6 +69,13 @@ static inline void _op(void) \ ...@@ -69,6 +69,13 @@ static inline void _op(void) \
__asm__ (#_op); \ __asm__ (#_op); \
} }
/* Define function for system instruction with register parameter */
#define DEFINE_SYSOP_PARAM_FUNC(_op) \
static inline void _op(uint64_t v) \
{ \
__asm__ (#_op " %0" : : "r" (v)); \
}
/* Define function for system instruction with type specifier */ /* Define function for system instruction with type specifier */
#define DEFINE_SYSOP_TYPE_FUNC(_op, _type) \ #define DEFINE_SYSOP_TYPE_FUNC(_op, _type) \
static inline void _op ## _type(void) \ static inline void _op ## _type(void) \
...@@ -211,6 +218,11 @@ DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e1r) ...@@ -211,6 +218,11 @@ DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e1r)
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e2r) DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e2r)
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e3r) DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e3r)
/*******************************************************************************
* Strip Pointer Authentication Code
******************************************************************************/
DEFINE_SYSOP_PARAM_FUNC(xpaci)
void flush_dcache_range(uintptr_t addr, size_t size); void flush_dcache_range(uintptr_t addr, size_t size);
void clean_dcache_range(uintptr_t addr, size_t size); void clean_dcache_range(uintptr_t addr, size_t size);
void inv_dcache_range(uintptr_t addr, size_t size); void inv_dcache_range(uintptr_t addr, size_t size);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment