From patchwork Fri Apr 8 14:59:01 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Helge Deller X-Patchwork-Id: 8783991 Return-Path: X-Original-To: patchwork-linux-parisc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id A3D13C0553 for ; Fri, 8 Apr 2016 14:59:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D2CA7200D0 for ; Fri, 8 Apr 2016 14:59:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C6935202EC for ; Fri, 8 Apr 2016 14:59:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758577AbcDHO71 (ORCPT ); Fri, 8 Apr 2016 10:59:27 -0400 Received: from mout.gmx.net ([212.227.15.15]:55381 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758327AbcDHO7Q (ORCPT ); Fri, 8 Apr 2016 10:59:16 -0400 Received: from [155.56.68.219] by 3capp-gmx-bs27.server.lan (via HTTP); Fri, 8 Apr 2016 16:59:01 +0200 MIME-Version: 1.0 Message-ID: From: "Helge Deller" To: "Helge Deller" Cc: "Mikulas Patocka" , "John David Anglin" , linux-parisc@vger.kernel.org Subject: Aw: Re: kernel 4.6-rc unbootable due to module changes Date: Fri, 8 Apr 2016 16:59:01 +0200 Importance: normal Sensitivity: Normal In-Reply-To: References: <570409DA.1060508@gmx.de> <57058332.8050204@gmx.de>, <5706E3A0.2020902@gmx.de>, X-UI-Message-Type: mail X-Priority: 3 X-Provags-ID: V03:K0:EAlo41A1XV225MzfYDF3jOBboRcOar4gpOS4gkmeiJ/ lEMnP9RInylDqGyt7ZCTBbe/3swH0gxfT9Ay+tjHjlojNyLqcC JNP7OfCeqYLjIM00EZtglOW0dglPeGUD58LJ+V4ZzjALL4DLBw MMCjo7o9Z/ucwCRDth2B/5eiUUQgwn76AgYfLHP0K5cwReJAiG ijV7CzifT/uYoYa9l90O7U9mKkdwVEtKSTDog42/SFTVudlbvh K3rw6S6HEOGGLYhX1MDeyE8QT39Qi9ANQRYiSN44bYHfglE5hl eC+cuM= X-UI-Out-Filterresults: notjunk:1; V01:K0:4M3+pY1QYAo=:KwzSt0vP8EkgKlh62AVFNU OqLQ++azMQ2nyQL38uIbGGgS8+WV1BHA56tkol0AC/sWEmHdrAyjrnUxGNOT6D26mOFDA3Hi0 +LIg1vimYxIb/3XJmzZ+Ho0TY0b9C4o6oG8BuyM4OTIT6gdGTBd9Sowj0NGkQ4z5afJF5gFCu 8dw21Ys2Ve+Ro5v8tatPE5QKQZALiU5id6VmVMr76lIcq3Mpr/+xRcKHZN7ooCQB9bIXxByrQ RnOVHZgNCyVHfX7duedST+HsVnALDqpL2gqmopp5y0jdGQk4Ex0Sd8rT4JomJ0p6yIowz3+2l f7SsvDYxLxrLKvMREEVdvArEVxM3OZ1RUPf1040CKyYbL0YHaxrix0mumdmwtKXlpuhwVmDdY HG1hZyoBFQ7Wn6b9z+3kMsQ15bPGgFMzvfK4bhWaiGwdLhjtxzuu0uPXkWtxzaN+xjzvkfB2J syW4pPVNMA== Sender: linux-parisc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-parisc@vger.kernel.org X-Spam-Status: No, score=-7.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_TVD_MIME_EPI,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP > > >> So, it seems that handling exceptions from modules never worked on > > >> pa-risc, it was just masked by the fact that exceptions from modules don't > > >> happen during normal use. > > > > Sadly you seem to be right :-( > > I did more testing with the test_user_copy module (with vanilla kernel 4.5 and without the relative extable support). > > The attached patch fixes the exception handling for modules for me. > This is realized by saving the %r27 register in the fault handler and restoring it in the exception path. > With this patch the "test_user_copy" kernel module succeeds when loaded. > Mikulas, can you try it with your testcases ? Attached patch additionally adds support for resolving R_PARISC_PCREL32 relocations, which fixes the 32bit extable change which was introduced with kernel 4.6-rc1. With that I think we have all module issues resolved ? Helge diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h index d4dd6e5..b370d61 100644 --- a/arch/parisc/include/asm/uaccess.h +++ b/arch/parisc/include/asm/uaccess.h @@ -79,6 +79,7 @@ struct exception_data { unsigned long fault_ip; unsigned long fault_space; unsigned long fault_addr; + unsigned long fault_gp; }; #define __get_user(x, ptr) \ diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c index d2f6257..137c91e 100644 --- a/arch/parisc/kernel/asm-offsets.c +++ b/arch/parisc/kernel/asm-offsets.c @@ -301,6 +301,7 @@ int main(void) DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip)); DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space)); DEFINE(EXCDATA_ADDR, offsetof(struct exception_data, fault_addr)); + DEFINE(EXCDATA_GP, offsetof(struct exception_data, fault_gp)); BLANK(); DEFINE(ASM_PDC_RESULT_SIZE, NUM_PDC_RESULT * sizeof(unsigned long)); BLANK(); diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index b9d75d9..c54cf39 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -788,6 +788,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, CHECK_RELOC(val, 22); *loc = (*loc & ~0x3ff1ffd) | reassemble_22(val); break; + case R_PARISC_PCREL32: + /* 32-bit PC relative address */ + *loc = val - dot - 8 + addend; + break; case R_PARISC_DIR64: /* 64-bit effective address */ *loc64 = val + addend; diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index 568b2c6..3cad8aa 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c @@ -47,11 +47,11 @@ EXPORT_SYMBOL(__cmpxchg_u64); EXPORT_SYMBOL(lclear_user); EXPORT_SYMBOL(lstrnlen_user); -/* Global fixups */ -extern void fixup_get_user_skip_1(void); -extern void fixup_get_user_skip_2(void); -extern void fixup_put_user_skip_1(void); -extern void fixup_put_user_skip_2(void); +/* Global fixups - defined as int to avoid creation of function pointers */ +extern int fixup_get_user_skip_1; +extern int fixup_get_user_skip_2; +extern int fixup_put_user_skip_1; +extern int fixup_put_user_skip_2; EXPORT_SYMBOL(fixup_get_user_skip_1); EXPORT_SYMBOL(fixup_get_user_skip_2); EXPORT_SYMBOL(fixup_put_user_skip_1); diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 16e0735..97d6b20 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -795,6 +795,9 @@ void notrace handle_interruption(int code, struct pt_regs *regs) if (fault_space == 0 && !faulthandler_disabled()) { + /* Clean up and return if in exception table. */ + if (fixup_exception(regs)) + return; pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC); parisc_terminate("Kernel Fault", regs, code, fault_address); } diff --git a/arch/parisc/lib/fixup.S b/arch/parisc/lib/fixup.S index 536ef66..1052b74 100644 --- a/arch/parisc/lib/fixup.S +++ b/arch/parisc/lib/fixup.S @@ -26,6 +26,7 @@ #ifdef CONFIG_SMP .macro get_fault_ip t1 t2 + loadgp addil LT%__per_cpu_offset,%r27 LDREG RT%__per_cpu_offset(%r1),\t1 /* t2 = smp_processor_id() */ @@ -40,14 +41,19 @@ LDREG RT%exception_data(%r1),\t1 /* t1 = this_cpu_ptr(&exception_data) */ add,l \t1,\t2,\t1 + /* %r27 = t1->fault_gp - restore gp */ + LDREG EXCDATA_GP(\t1), %r27 /* t1 = t1->fault_ip */ LDREG EXCDATA_IP(\t1), \t1 .endm #else .macro get_fault_ip t1 t2 + loadgp /* t1 = this_cpu_ptr(&exception_data) */ addil LT%exception_data,%r27 LDREG RT%exception_data(%r1),\t2 + /* %r27 = t2->fault_gp - restore gp */ + LDREG EXCDATA_GP(\t2), %r27 /* t1 = t2->fault_ip */ LDREG EXCDATA_IP(\t2), \t1 .endm diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 26fac9c..7a6ecaa 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -147,6 +147,7 @@ int fixup_exception(struct pt_regs *regs) d->fault_ip = regs->iaoq[0]; d->fault_space = regs->isr; d->fault_addr = regs->ior; + d->fault_gp = regs->gr[27]; regs->iaoq[0] = (unsigned long)&fix->fixup + fix->fixup; regs->iaoq[0] &= ~3;