Skip to content

Commit

Permalink
core: dump call stack of user TAs on abort
Browse files Browse the repository at this point in the history
Update the abort handling code in the TEE core to support unwinding
the user mode stack in addition to the kernel stack. unwind_arm32.c is
modified slightly so that it can be built for AArch64. This allows a
64-bit TEE core to dump both 32- and 64-bit TAs.

Paged TAs (CFG_PAGED_USER_TA=y) cannot currently be unwound, because
the code is not ready to handle the page faults that might occur as
the unwinding tables are accessed.

CFG_CORE_UNWIND is renamed to CFG_UNWIND since it enables both the
kernel and user TA stack dumps. It is still set automatically when
CFG_TEE_CORE_DEBUG=y.

32-bit user TAs have to be compiled with `-funwind-tables`, otherwise
the call stack can't be unwound and the abort reports will not show a
call stack .The TA dev kit takes care of adding this flag automatically
when CFG_UNWIND=y.

Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (HiKey)
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
  • Loading branch information
jforissier committed May 24, 2017
1 parent 1191e65 commit 31a2964
Show file tree
Hide file tree
Showing 20 changed files with 347 additions and 149 deletions.
5 changes: 4 additions & 1 deletion core/arch/arm/arm.mk
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ arch-bits-core := 32
core-platform-cppflags += $(arm32-platform-cppflags)
core-platform-cflags += $(arm32-platform-cflags)
core-platform-cflags += $(arm32-platform-cflags-no-hard-float)
ifeq ($(CFG_CORE_UNWIND),y)
ifeq ($(CFG_UNWIND),y)
core-platform-cflags += -funwind-tables
endif
core-platform-cflags += $(arm32-platform-cflags-generic)
Expand All @@ -120,6 +120,9 @@ ta_arm32-platform-cflags += $(arm32-platform-cflags-hard-float)
else
ta_arm32-platform-cflags += $(arm32-platform-cflags-no-hard-float)
endif
ifeq ($(CFG_UNWIND),y)
ta_arm32-platform-cflags += -funwind-tables
endif
ta_arm32-platform-aflags += $(platform-aflags-debug-info)
ta_arm32-platform-aflags += $(arm32-platform-aflags)

Expand Down
2 changes: 2 additions & 0 deletions core/arch/arm/include/kernel/abort.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ struct abort_info {
struct thread_abort_regs *regs;
};

/* Print abort info to the console */
void abort_print(struct abort_info *ai);
/* Print abort info + stack dump to the console */
void abort_print_error(struct abort_info *ai);

void abort_handler(uint32_t abort_type, struct thread_abort_regs *regs);
Expand Down
10 changes: 9 additions & 1 deletion core/arch/arm/include/kernel/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,15 @@ void thread_unwind_user_mode(uint32_t ret, uint32_t exit_status0,
vaddr_t thread_get_saved_thread_sp(void);
#endif /*ARM64*/

bool thread_addr_is_in_stack(vaddr_t va);
/*
* Returns the start address (bottom) of the stack for the current thread,
* zero if there is no current thread.
*/
vaddr_t thread_stack_start(void);


/* Returns the stack size for the current thread */
size_t thread_stack_size(void);

/*
* Adds a mutex to the list of held mutexes for current thread
Expand Down
34 changes: 23 additions & 11 deletions core/arch/arm/include/kernel/unwind.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,39 +37,51 @@
#include <compiler.h>
#include <types_ext.h>

#ifdef ARM32
/* The state of the unwind process */
struct unwind_state {
/* The state of the unwind process (32-bit mode) */
struct unwind_state_arm32 {
uint32_t registers[16];
uint32_t start_pc;
uint32_t *insn;
unsigned entries;
unsigned byte;
uint16_t update_mask;
};
#endif /*ARM32*/

/*
* Unwind a 32-bit user or kernel stack.
* @exidx, @exidx_sz: address and size of the binary search index table
* (.ARM.exidx section).
*/
bool unwind_stack_arm32(struct unwind_state_arm32 *state, uaddr_t exidx,
size_t exidx_sz);

#ifdef ARM64
struct unwind_state {
/* The state of the unwind process (64-bit mode) */
struct unwind_state_arm64 {
uint64_t fp;
uint64_t sp;
uint64_t pc;
};
#endif /*ARM64*/

bool unwind_stack(struct unwind_state *state);
/*
* Unwind a 64-bit user or kernel stack.
* @stack, @stack_size: the bottom of the stack and its size, respectively.
*/
bool unwind_stack_arm64(struct unwind_state_arm64 *state, uaddr_t stack,
size_t stack_size);
#endif /*ARM64*/

#if defined(CFG_CORE_UNWIND) && (TRACE_LEVEL > 0)
void print_stack(int level);
#if defined(CFG_UNWIND) && (TRACE_LEVEL > 0)
void print_kernel_stack(int level);
#else
static inline void print_stack(int level __unused)
static inline void print_kernel_stack(int level __unused)
{
}
#endif

#endif /*ASM*/

#ifdef CFG_CORE_UNWIND
#ifdef CFG_UNWIND
#define UNWIND(...) __VA_ARGS__
#else
#define UNWIND(...)
Expand Down
2 changes: 2 additions & 0 deletions core/arch/arm/include/kernel/user_ta.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ TAILQ_HEAD(tee_storage_enum_head, tee_storage_enum);

struct user_ta_ctx {
uaddr_t entry_func;
uaddr_t exidx_start; /* 32-bit TA: exception handling index table */
size_t exidx_size;
bool is_32bit; /* true if 32-bit ta, false if 64-bit ta */
/* list of sessions opened by this TA */
struct tee_ta_session_head open_sessions;
Expand Down
Loading

0 comments on commit 31a2964

Please sign in to comment.