diff options
author | Helge Deller <deller@gmx.de> | 2018-08-21 14:31:32 +0200 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2018-08-21 14:32:44 +0200 |
commit | 8801ccb9fa524c195322c26b6d44e99827772bde (patch) | |
tree | 6168bab9019068b9dfe86fb38c72b5f011e905ff /arch/parisc/kernel/unwind.c | |
parent | 9e0d5c451f9e559dd06af3fff49a0d2068c634c4 (diff) |
parisc: Fix boot failure of 64-bit kernel
Commit c8921d72e390 ("parisc: Fix and improve kernel stack unwinding")
broke booting of 64-bit kernels. On 64-bit kernels function pointers are
actually function descriptors which require dereferencing. In this patch
we instead declare functions in assembly code which are referenced from
C-code as external data pointers with the ENTRY() macro and thus can use
a simple external reference to the functions.
Signed-off-by: Helge Deller <deller@gmx.de>
Fixes: c8921d72e390 ("parisc: Fix and improve kernel stack unwinding")
Diffstat (limited to 'arch/parisc/kernel/unwind.c')
-rw-r--r-- | arch/parisc/kernel/unwind.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c index 5578a325a730..f329b466e68f 100644 --- a/arch/parisc/kernel/unwind.c +++ b/arch/parisc/kernel/unwind.c @@ -209,6 +209,8 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int * We have to use void * instead of a function pointer, because * function pointers aren't a pointer to the function on 64-bit. * Make them const so the compiler knows they live in .text + * Note: We could use dereference_kernel_function_descriptor() + * instead but we want to keep it simple here. */ extern void * const handle_interruption; extern void * const ret_from_kernel_thread; @@ -216,7 +218,7 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int extern void * const intr_return; extern void * const _switch_to_ret; #ifdef CONFIG_IRQSTACKS - extern void * const call_on_stack; + extern void * const _call_on_stack; #endif /* CONFIG_IRQSTACKS */ if (pc == (unsigned long) &handle_interruption) { @@ -251,7 +253,7 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int } #ifdef CONFIG_IRQSTACKS - if (pc == (unsigned long) &call_on_stack) { + if (pc == (unsigned long) &_call_on_stack) { info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ); info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET); return 1; |