From patchwork Tue Aug 21 12:31:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Helge Deller X-Patchwork-Id: 10571483 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2D276112E for ; Tue, 21 Aug 2018 12:31:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 200B22A0ED for ; Tue, 21 Aug 2018 12:31:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 13D342A110; Tue, 21 Aug 2018 12:31:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,FREEMAIL_FROM, MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 606662A0F4 for ; Tue, 21 Aug 2018 12:31:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727018AbeHUPvk (ORCPT ); Tue, 21 Aug 2018 11:51:40 -0400 Received: from mout.gmx.net ([212.227.15.15]:42791 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727015AbeHUPvj (ORCPT ); Tue, 21 Aug 2018 11:51:39 -0400 Received: from ls3530.fritz.box ([92.116.144.167]) by mail.gmx.com (mrgmx003 [212.227.17.190]) with ESMTPSA (Nemesis) id 0MMjgF-1flEro1pt9-008XTu; Tue, 21 Aug 2018 14:31:35 +0200 Date: Tue, 21 Aug 2018 14:31:32 +0200 From: Helge Deller To: linux-parisc@vger.kernel.org, James Bottomley , John David Anglin Subject: [PATCH] parisc: Fix boot failure of 64-bit kernel Message-ID: <20180821123132.GA4250@ls3530.fritz.box> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.9.1 (2017-09-22) X-Provags-ID: V03:K1:AC2gZmQVR4Fx0nYC/rs6IGdeColhDG0XemlqjNGRgY3S62Kn0S5 wrisDKRXHlBM/m8SA+7ODrtCFidtUrUOdlSVHuBjBOzuWsinI+bxkfbfd0mkPk0PoqXamwR pfAO8fcHEfDlAbaUW8pWeYz0yzmdxpIeGfMoAZpaEDn6WlTUCWIdsYUHrxCq4HDHHwl0/w9 COWB4boyR18sV3J5X4aLQ== X-UI-Out-Filterresults: notjunk:1;V01:K0:TK/trOBeB68=:yZ5V4qzFPdJaJ53KTk37Bj +kFJ+DiGp6kf0PBWlkPaX+P0ypuYYwjQe1FIAXIQuoPb4DogIyzoopf8A0SyRNWku6t1KYFlO 3JKFkuTf7nqG9VCSwS8GnIRIDquJDLGOkjls7mIAKTuohIEEYcGw4C8A3pFZdvVlxDfCyjGpE mK8HaIiDUGvcViKbIjsa+7WqlOx7MD5mnBu+hb4i6Lo7QfnP4VOfGIpcOqfWWzz5TbDAkzsli XOkHnZpezVbrGzsJyAlWojnuqtQ44ON9gVoFMs24xGc9Uzh5D2splrI1w+4csujVijDEhmolF c/ArL4TUBOCMJjLn4Yn+25ZBc10eMypebYggBP/26nfM13nqjrriFZiVTnz63vyh05D/lFikU jeJk4Ybl5RaKkLUptuKXPvdBNt81h4BfAqHYeHgNjURCfyfJ5ppUOkCkySHCTYFRXilosaph2 hjbYsivR6xSbPqbadi9eEMi++Uf0pl3Q9oWxbnBdmafW+PrhYcZxxLFcAsFyotlLE1eUoKd1n 2pilX4rN5BIUBeBqh6DT69oYgMNVV/1Ik/uCcolvjJjekZnORkOyG7ubIh+YmAHSKRdsRVJMn 2Ko1MR0zdVg0SwUn5IlwZxMp6IPUm+t6mYw87yaVGIk4dQ27/K36bLhIH5xDEFm8xtSc/c0Yf mIviJoVzXwj3N8dir9y0byXHiuRO7rllyOK9ulPdwjByi/LVOaVmez9XqSzohz3xucN9Y+dAd oB/Is93a1qldqi2VtNCPSXtUV/BO6QZx2uoB1g4TCVmUsnYynEo2uupCYOI= Sender: linux-parisc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-parisc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 Fixes: c8921d72e390 ("parisc: Fix and improve kernel stack unwinding") diff --git a/arch/parisc/include/asm/linkage.h b/arch/parisc/include/asm/linkage.h index 49f6f3d772cc..cd6fe4febead 100644 --- a/arch/parisc/include/asm/linkage.h +++ b/arch/parisc/include/asm/linkage.h @@ -22,15 +22,6 @@ name: ASM_NL\ .export name -#ifdef CONFIG_64BIT -#define ENDPROC(name) \ - END(name) -#else -#define ENDPROC(name) \ - .type name, @function !\ - END(name) -#endif - #define ENTRY_CFI(name, ...) \ ENTRY(name) ASM_NL\ .proc ASM_NL\ diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index e170365941f8..242c5ab65611 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -777,7 +777,7 @@ END(fault_vector_11) * copy_thread moved args into task save area. */ -ENTRY_CFI(ret_from_kernel_thread) +ENTRY(ret_from_kernel_thread) /* Call schedule_tail first though */ BL schedule_tail, %r2 nop @@ -792,7 +792,7 @@ ENTRY_CFI(ret_from_kernel_thread) copy %r31, %r2 b finish_child_return nop -ENDPROC_CFI(ret_from_kernel_thread) +END(ret_from_kernel_thread) /* @@ -816,9 +816,8 @@ ENTRY_CFI(_switch_to) LDREG TASK_THREAD_INFO(%r25), %r25 bv %r0(%r2) mtctl %r25,%cr30 -ENDPROC_CFI(_switch_to) -ENTRY_CFI(_switch_to_ret) +ENTRY(_switch_to_ret) mtctl %r0, %cr0 /* Needed for single stepping */ callee_rest callee_rest_float @@ -826,7 +825,7 @@ ENTRY_CFI(_switch_to_ret) LDREG -RP_OFFSET(%r30), %r2 bv %r0(%r2) copy %r26, %r28 -ENDPROC_CFI(_switch_to_ret) +ENDPROC_CFI(_switch_to) /* * Common rfi return path for interruptions, kernel execve, and @@ -887,14 +886,12 @@ ENTRY_CFI(syscall_exit_rfi) STREG %r19,PT_SR5(%r16) STREG %r19,PT_SR6(%r16) STREG %r19,PT_SR7(%r16) -ENDPROC_CFI(syscall_exit_rfi) -ENTRY_CFI(intr_return) +ENTRY(intr_return) /* check for reschedule */ mfctl %cr30,%r1 LDREG TI_FLAGS(%r1),%r19 /* sched.h: TIF_NEED_RESCHED */ bb,<,n %r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */ -ENDPROC_CFI(intr_return) .import do_notify_resume,code intr_check_sig: @@ -1050,6 +1047,7 @@ intr_extint: b do_cpu_irq_mask ldo R%intr_return(%r2), %r2 /* return to intr_return, not here */ +ENDPROC_CFI(syscall_exit_rfi) /* Generic interruptions (illegal insn, unaligned, page fault, etc) */ @@ -1751,7 +1749,7 @@ fork_like fork fork_like vfork /* Set the return value for the child */ -ENTRY_CFI(child_return) +ENTRY(child_return) BL schedule_tail, %r2 nop finish_child_return: @@ -1763,7 +1761,7 @@ finish_child_return: reg_restore %r1 b syscall_exit copy %r0,%r28 -ENDPROC_CFI(child_return) +END(child_return) ENTRY_CFI(sys_rt_sigreturn_wrapper) LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 @@ -1795,7 +1793,7 @@ ENTRY_CFI(sys_rt_sigreturn_wrapper) LDREG PT_GR28(%r1),%r28 /* reload original r28 for syscall_exit */ ENDPROC_CFI(sys_rt_sigreturn_wrapper) -ENTRY_CFI(syscall_exit) +ENTRY(syscall_exit) /* NOTE: Not all syscalls exit this way. rt_sigreturn will exit * via syscall_exit_rfi if the signal was received while the process * was running. @@ -1994,15 +1992,13 @@ syscall_do_resched: #else nop #endif -ENDPROC_CFI(syscall_exit) +END(syscall_exit) #ifdef CONFIG_FUNCTION_TRACER .import ftrace_function_trampoline,code .align L1_CACHE_BYTES - .globl mcount - .type mcount, @function ENTRY_CFI(mcount, caller) _mcount: .export _mcount,data @@ -2031,8 +2027,6 @@ ENDPROC_CFI(mcount) #ifdef CONFIG_FUNCTION_GRAPH_TRACER .align 8 - .globl return_to_handler - .type return_to_handler, @function ENTRY_CFI(return_to_handler, caller,frame=FRAME_SIZE) .export parisc_return_to_handler,data parisc_return_to_handler: @@ -2082,6 +2076,7 @@ ENDPROC_CFI(return_to_handler) /* void call_on_stack(unsigned long param1, void *func, unsigned long new_stack) */ ENTRY_CFI(call_on_stack, FRAME=2*FRAME_SIZE,CALLS,SAVE_RP,SAVE_SP) +ENTRY(_call_on_stack) copy %sp, %r1 /* Regarding the HPPA calling conventions for function pointers, 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;