aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel/unwind.c
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2018-08-21 14:31:32 +0200
committerHelge Deller <deller@gmx.de>2018-08-21 14:32:44 +0200
commit8801ccb9fa524c195322c26b6d44e99827772bde (patch)
tree6168bab9019068b9dfe86fb38c72b5f011e905ff /arch/parisc/kernel/unwind.c
parentparisc: Consolidate unwind initialization calls (diff)
downloadlinux-dev-8801ccb9fa524c195322c26b6d44e99827772bde.tar.xz
linux-dev-8801ccb9fa524c195322c26b6d44e99827772bde.zip
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 '')
-rw-r--r--arch/parisc/kernel/unwind.c6
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;