* kernel 4.6-rc unbootable due to module changes @ 2016-04-05 17:31 Mikulas Patocka 2016-04-05 17:36 ` Mikulas Patocka 0 siblings, 1 reply; 11+ messages in thread From: Mikulas Patocka @ 2016-04-05 17:31 UTC (permalink / raw) To: Helge Deller; +Cc: linux-parisc Hi The patch "parisc: Use generic extable search and sort routines" makes the kernel unable to load any modules. It fails with: module unix: Unknown relocation: 9 modprobe: FATAL: Error inserting unix (/lib/modules/4.6.0-rc2/kernel/net/unix/unix.ko): Invalid module format When I revert the patch, the kernel 4.6-rc2 boots fine. Apparently, the function apply_relocate_add in arch/parisc/kernel/module.c doesn't handle the new relocation type. Mikulas ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: kernel 4.6-rc unbootable due to module changes 2016-04-05 17:31 kernel 4.6-rc unbootable due to module changes Mikulas Patocka @ 2016-04-05 17:36 ` Mikulas Patocka 2016-04-05 18:54 ` Helge Deller 0 siblings, 1 reply; 11+ messages in thread From: Mikulas Patocka @ 2016-04-05 17:36 UTC (permalink / raw) To: Helge Deller; +Cc: linux-parisc On Tue, 5 Apr 2016, Mikulas Patocka wrote: > Hi > > The patch "parisc: Use generic extable search and sort routines" makes the > kernel unable to load any modules. It fails with: > > module unix: Unknown relocation: 9 > modprobe: FATAL: Error inserting unix (/lib/modules/4.6.0-rc2/kernel/net/unix/unix.ko): Invalid module format > > When I revert the patch, the kernel 4.6-rc2 boots fine. > > Apparently, the function apply_relocate_add in arch/parisc/kernel/module.c > doesn't handle the new relocation type. > > Mikulas BTW. I'm using hppa64 binutils 2.21 to build the kernel. It generates the R_PARISC_PCREL32 relocation that the kernel module loader doesn't handle: RELOCATION RECORDS FOR [__ex_table]: OFFSET TYPE VALUE 0000000000000000 R_PARISC_PCREL32 .text.unix_ioctl+0x0000000000000064 0000000000000004 R_PARISC_PCREL32 fixup_put_user_skip_1+0x0000000000000008 0000000000000008 R_PARISC_PCREL32 .text.unix_ioctl+0x00000000000000a8 000000000000000c R_PARISC_PCREL32 fixup_put_user_skip_1+0x0000000000000008 0000000000000010 R_PARISC_PCREL32 .text.unix_ioctl+0x00000000000000b4 0000000000000014 R_PARISC_PCREL32 fixup_put_user_skip_1+0x0000000000000008 0000000000000018 R_PARISC_PCREL32 .text.unix_ioctl+0x00000000000000c0 000000000000001c R_PARISC_PCREL32 fixup_put_user_skip_1+0x0000000000000008 Mikulas ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: kernel 4.6-rc unbootable due to module changes 2016-04-05 17:36 ` Mikulas Patocka @ 2016-04-05 18:54 ` Helge Deller 2016-04-05 20:15 ` Mikulas Patocka 2016-04-05 20:18 ` John David Anglin 0 siblings, 2 replies; 11+ messages in thread From: Helge Deller @ 2016-04-05 18:54 UTC (permalink / raw) To: Mikulas Patocka; +Cc: linux-parisc [-- Attachment #1: Type: text/plain, Size: 1483 bytes --] On 05.04.2016 19:36, Mikulas Patocka wrote: > On Tue, 5 Apr 2016, Mikulas Patocka wrote: > >> Hi >> >> The patch "parisc: Use generic extable search and sort routines" makes the >> kernel unable to load any modules. It fails with: >> >> module unix: Unknown relocation: 9 >> modprobe: FATAL: Error inserting unix (/lib/modules/4.6.0-rc2/kernel/net/unix/unix.ko): Invalid module format >> >> When I revert the patch, the kernel 4.6-rc2 boots fine. >> >> Apparently, the function apply_relocate_add in arch/parisc/kernel/module.c >> doesn't handle the new relocation type. >> >> Mikulas > > BTW. I'm using hppa64 binutils 2.21 to build the kernel. It generates the > R_PARISC_PCREL32 relocation that the kernel module loader doesn't handle: Can you try attached patch (untested) ? Helge > RELOCATION RECORDS FOR [__ex_table]: > OFFSET TYPE VALUE > 0000000000000000 R_PARISC_PCREL32 .text.unix_ioctl+0x0000000000000064 > 0000000000000004 R_PARISC_PCREL32 fixup_put_user_skip_1+0x0000000000000008 > 0000000000000008 R_PARISC_PCREL32 .text.unix_ioctl+0x00000000000000a8 > 000000000000000c R_PARISC_PCREL32 fixup_put_user_skip_1+0x0000000000000008 > 0000000000000010 R_PARISC_PCREL32 .text.unix_ioctl+0x00000000000000b4 > 0000000000000014 R_PARISC_PCREL32 fixup_put_user_skip_1+0x0000000000000008 > 0000000000000018 R_PARISC_PCREL32 .text.unix_ioctl+0x00000000000000c0 > 000000000000001c R_PARISC_PCREL32 fixup_put_user_skip_1+0x0000000000000008 [-- Attachment #2: module.patch --] [-- Type: text/x-diff, Size: 455 bytes --] diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index b9d75d9..f3bfd6a 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -660,6 +660,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, } *loc = (*loc & ~0x3ff1ffd) | reassemble_22(val); break; + case R_PARISC_PCREL32: + val -= (uint32_t) loc; + *loc = val; + break; default: printk(KERN_ERR "module %s: Unknown relocation: %u\n", ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: kernel 4.6-rc unbootable due to module changes 2016-04-05 18:54 ` Helge Deller @ 2016-04-05 20:15 ` Mikulas Patocka 2016-04-06 14:30 ` Mikulas Patocka 2016-04-05 20:18 ` John David Anglin 1 sibling, 1 reply; 11+ messages in thread From: Mikulas Patocka @ 2016-04-05 20:15 UTC (permalink / raw) To: Helge Deller; +Cc: linux-parisc On Tue, 5 Apr 2016, Helge Deller wrote: > On 05.04.2016 19:36, Mikulas Patocka wrote: > > On Tue, 5 Apr 2016, Mikulas Patocka wrote: > > > >> Hi > >> > >> The patch "parisc: Use generic extable search and sort routines" makes the > >> kernel unable to load any modules. It fails with: > >> > >> module unix: Unknown relocation: 9 > >> modprobe: FATAL: Error inserting unix (/lib/modules/4.6.0-rc2/kernel/net/unix/unix.ko): Invalid module format > >> > >> When I revert the patch, the kernel 4.6-rc2 boots fine. > >> > >> Apparently, the function apply_relocate_add in arch/parisc/kernel/module.c > >> doesn't handle the new relocation type. > >> > >> Mikulas > > > > BTW. I'm using hppa64 binutils 2.21 to build the kernel. It generates the > > R_PARISC_PCREL32 relocation that the kernel module loader doesn't handle: > > > Can you try attached patch (untested) ? > > Helge I tried a similar patch, the system booted fine ... but then I discovered that the system boots fine no matter what value is written to *loc. Apparently, none of the modules trigger any exceptions in my configuration. I'll have to create a test module that triggers some exception. Mikulas ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: kernel 4.6-rc unbootable due to module changes 2016-04-05 20:15 ` Mikulas Patocka @ 2016-04-06 14:30 ` Mikulas Patocka 2016-04-06 21:44 ` Helge Deller 0 siblings, 1 reply; 11+ messages in thread From: Mikulas Patocka @ 2016-04-06 14:30 UTC (permalink / raw) To: Helge Deller, John David Anglin; +Cc: linux-parisc [-- Attachment #1: Type: TEXT/PLAIN, Size: 2398 bytes --] On Tue, 5 Apr 2016, Mikulas Patocka wrote: > > > On Tue, 5 Apr 2016, Helge Deller wrote: > > > On 05.04.2016 19:36, Mikulas Patocka wrote: > > > On Tue, 5 Apr 2016, Mikulas Patocka wrote: > > > > > >> Hi > > >> > > >> The patch "parisc: Use generic extable search and sort routines" makes the > > >> kernel unable to load any modules. It fails with: > > >> > > >> module unix: Unknown relocation: 9 > > >> modprobe: FATAL: Error inserting unix (/lib/modules/4.6.0-rc2/kernel/net/unix/unix.ko): Invalid module format > > >> > > >> When I revert the patch, the kernel 4.6-rc2 boots fine. > > >> > > >> Apparently, the function apply_relocate_add in arch/parisc/kernel/module.c > > >> doesn't handle the new relocation type. > > >> > > >> Mikulas > > > > > > BTW. I'm using hppa64 binutils 2.21 to build the kernel. It generates the > > > R_PARISC_PCREL32 relocation that the kernel module loader doesn't handle: > > > > > > Can you try attached patch (untested) ? > > > > Helge > > I tried a similar patch, the system booted fine ... but then I discovered > that the system boots fine no matter what value is written to *loc. > > Apparently, none of the modules trigger any exceptions in my > configuration. > > I'll have to create a test module that triggers some exception. > > Mikulas Hmm - it's even more strange. I created a test kernel module that triggers an exception by using get_user with an invalid address (see the attached file exception.tar) On x86-64 the module loads fine, but on pa-risc it always crashes, even with older kernel version (I tried versions 2.6.39, 4.5 and 4.6-rc2 and I always get a crash). When I write a userspace code that triggers a fault in module unix.ko, by passing an invalid address to the ioctl syscall, the kernel also crashes. 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. Mikulas /* this will crash pa-risc kernel if it is compiled with CONFIG_UNIX=m */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> int main(void) { int s, r; s = socket(PF_UNIX, SOCK_STREAM, 0); if (s == -1) perror("socket"), exit(1); r = ioctl(s, SIOCOUTQ, 0x124); if (r == -1) perror("ioctl"), exit(1); return 0; } [-- Attachment #2: exception module --] [-- Type: APPLICATION/X-TAR, Size: 10240 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: kernel 4.6-rc unbootable due to module changes 2016-04-06 14:30 ` Mikulas Patocka @ 2016-04-06 21:44 ` Helge Deller 2016-04-07 22:48 ` Helge Deller 0 siblings, 1 reply; 11+ messages in thread From: Helge Deller @ 2016-04-06 21:44 UTC (permalink / raw) To: Mikulas Patocka, John David Anglin; +Cc: linux-parisc On 06.04.2016 16:30, Mikulas Patocka wrote: >>>>> The patch "parisc: Use generic extable search and sort routines" makes the >>>>> kernel unable to load any modules. It fails with: >>>>> >>>>> module unix: Unknown relocation: 9 >>>>> modprobe: FATAL: Error inserting unix (/lib/modules/4.6.0-rc2/kernel/net/unix/unix.ko): Invalid module format >>>>> >>>>> When I revert the patch, the kernel 4.6-rc2 boots fine. >>>>> >>>>> Apparently, the function apply_relocate_add in arch/parisc/kernel/module.c >>>>> doesn't handle the new relocation type. >>>>> >>>>> Mikulas >>>> >>>> BTW. I'm using hppa64 binutils 2.21 to build the kernel. It generates the >>>> R_PARISC_PCREL32 relocation that the kernel module loader doesn't handle: >>> >>> Can you try attached patch (untested) ? >>> >>> Helge >> >> I tried a similar patch, the system booted fine ... but then I discovered >> that the system boots fine no matter what value is written to *loc. >> >> Apparently, none of the modules trigger any exceptions in my >> configuration. >> >> I'll have to create a test module that triggers some exception. >> >> Mikulas > > Hmm - it's even more strange. > > I created a test kernel module that triggers an exception by using > get_user with an invalid address (see the attached file exception.tar) I see there is a kernel module <sourcetree>/lib/test_user_copy.c as well. It seems to crash too. > On x86-64 the module loads fine, but on pa-risc it always crashes, even > with older kernel version (I tried versions 2.6.39, 4.5 and 4.6-rc2 and I > always get a crash). I don't fully trust the 4.5 kernel yet. I was working the last few days on trying to fix the FTRACE functions, but am seeing strange crashes too. Any chance that you can try 4.4-stable, just to make sure ? > When I write a userspace code that triggers a fault in module unix.ko, by > passing an invalid address to the ioctl syscall, the kernel also crashes. > > 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. I'll try to dig deeper as soon as I find time. Helge ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: kernel 4.6-rc unbootable due to module changes 2016-04-06 21:44 ` Helge Deller @ 2016-04-07 22:48 ` Helge Deller 2016-04-08 12:06 ` Aw: " Helge Deller 0 siblings, 1 reply; 11+ messages in thread From: Helge Deller @ 2016-04-07 22:48 UTC (permalink / raw) To: Mikulas Patocka, John David Anglin; +Cc: linux-parisc [-- Attachment #1: Type: text/plain, Size: 7879 bytes --] On 06.04.2016 23:44, Helge Deller wrote: > On 06.04.2016 16:30, Mikulas Patocka wrote: >>>>>> The patch "parisc: Use generic extable search and sort routines" makes the >>>>>> kernel unable to load any modules. It fails with: >>>>>> >>>>>> module unix: Unknown relocation: 9 >>>>>> modprobe: FATAL: Error inserting unix (/lib/modules/4.6.0-rc2/kernel/net/unix/unix.ko): Invalid module format >>>>>> >>>>>> When I revert the patch, the kernel 4.6-rc2 boots fine. >>>>>> >>>>>> Apparently, the function apply_relocate_add in arch/parisc/kernel/module.c >>>>>> doesn't handle the new relocation type. >> Hmm - it's even more strange. >> >> I created a test kernel module that triggers an exception by using >> get_user with an invalid address (see the attached file exception.tar) > > I see there is a kernel module <sourcetree>/lib/test_user_copy.c as well. > It seems to crash too. >> 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 most of the issues: 1. Kernel doesn't crash any longer on the "illegal reversed copy_to_user" testcase. 2. It fixes the R_PARISC_DIR64 ex_table entries to create absolute addresses for the exceptions in the module instead of trying to refer to function pointers. BUT: It then crashes afterwards. What happens is that the exception fixup handler now jumps from the module directly to fixup_get_user_skip_1() in the kernel code. In arch/parisc/lib/fixup.S we have: ENTRY(fixup_get_user_skip_1) get_fault_ip %r1,%r8 .... which expands to: 0000000040a5aab0 <fixup_get_user_skip_1>: 40a5aab0: 2b 76 50 00 addil L%6c800,dp,r1 40a5aab4: 50 21 02 f0 ldd 178(r1),r1 40a5aab8: 03 c0 08 a8 mfctl tr6,r8 40a5aabc: 49 08 00 28 ldw 14(r8),r8 and the kernel then crashes at 40a5aab4 because dp still has the value of the module and not of the kernel. I wonder how we should avoid that. Maybe the easiest way is to not inline the get_user()/put_user() code in modules, but instead jumping into the kernel and call functions like - get_user_1(), get_user_2(), get_user_4()... and so on. What shall we do? - Skip the exception handling in modules (as mentioned above by get_user_1()) with the drawback of less performance due to additional calls, - rewrite the exception table code to use function pointers, or - rewrite get_fault_ip() macro to temporary set dp to %r0 (if possible at all?), - other ideas / opinions ? Helge FYI, here is my current log while loading the test_copy_user module: [ 289.900000] Non local DIR64 Symbol fixup_get_user_skip_1 loc 00000000020b16a0 val 40a5aab0 points to 0x40a5aab0 [ 290.020000] --- local DIR64 Symbol loc 00000000020b16a8 val 20b32c0 points to 0x20b34e4 [ 290.120000] Non local DIR64 Symbol fixup_get_user_skip_1 loc 00000000020b16b0 val 40a5aab0 points to 0x40a5aab0 [ 290.240000] --- local DIR64 Symbol loc 00000000020b16b8 val 20b32c0 points to 0x20b3558 [ 290.336000] Non local DIR64 Symbol fixup_put_user_skip_1 loc 00000000020b16c0 val 40a5ab20 points to 0x40a5ab20 [ 290.456000] --- local DIR64 Symbol loc 00000000020b16c8 val 20b32c0 points to 0x20b3564 [ 290.552000] Non local DIR64 Symbol fixup_put_user_skip_1 loc 00000000020b16d0 val 40a5ab20 points to 0x40a5ab20 [ 290.676000] --- local DIR64 Symbol loc 00000000020b16d8 val 20b32c0 points to 0x20b3808 [ 290.772000] Non local DIR64 Symbol fixup_get_user_skip_1 loc 00000000020b16e0 val 40a5aab0 points to 0x40a5aab0 [ 290.892000] --- local DIR64 Symbol loc 00000000020b16e8 val 20b32c0 points to 0x20b3814 [ 290.988000] Non local DIR64 Symbol fixup_get_user_skip_1 loc 00000000020b16f0 val 40a5aab0 points to 0x40a5aab0 [ 291.112000] --- local DIR64 Symbol loc 00000000020b16f8 val 20b32c0 points to 0x20b3898 [ 291.208000] Non local DIR64 Symbol fixup_put_user_skip_1 loc 00000000020b1700 val 40a5ab20 points to 0x40a5ab20 [ 291.328000] --- local DIR64 Symbol loc 00000000020b1708 val 20b32c0 points to 0x20b38a4 [ 291.424000] Non local DIR64 Symbol fixup_put_user_skip_1 loc 00000000020b1710 val 40a5ab20 points to 0x40a5ab20 [ 291.548000] test_user_copy: Testing: legitimate copy_from_user failed [ 291.624000] test_user_copy: FINISHED: result = 0 [ 291.680000] test_user_copy: Testing: legitimate copy_to_user failed [ 291.756000] test_user_copy: FINISHED: result = 0 [ 291.808000] test_user_copy: Testing: legitimate get_user failed [ 291.880000] test_user_copy: FINISHED: result = 0 [ 291.936000] test_user_copy: Testing: legitimate put_user failed [ 292.008000] test_user_copy: FINISHED: result = 0 [ 292.064000] test_user_copy: Testing: illegal all-kernel copy_from_user passed [ 292.148000] fault at 0x406d671c ... found ! fixup = 0x406d6844 [ 292.220000] test_user_copy: FINISHED: result = 0 [ 292.272000] test_user_copy: Testing: illegal reversed copy_from_user passed [ 292.356000] fault at 0x406d671c ... found ! fixup = 0x406d6844 [ 292.428000] test_user_copy: FINISHED: result = 0 [ 292.484000] test_user_copy: Testing: illegal all-kernel copy_to_user passed [ 292.568000] fault at 0x406d672c ... found ! fixup = 0x406d684c [ 292.640000] test_user_copy: FINISHED: result = 0 [ 292.692000] test_user_copy: Testing: illegal reversed copy_to_user passed [ 292.776000] fault at 0x406d671c ... found ! fixup = 0x406d6844 [ 292.844000] test_user_copy: FINISHED: result = 0 [ 292.900000] test_user_copy: Testing: illegal get_user passed [ 292.968000] fault at 0x020b3814 ... found ! fixup = 0x40a5aab0 [ 293.040000] fault at 0x40a5aab4 ... not found ! [ 293.096000] Backtrace: [ 293.096000] fault at 0x40223eac ... found ! fixup = 0x40a5aab0 [ 293.096000] [ 293.096000] [ 293.096000] Kernel Fault: Code=15 regs=00000000b12946a0 (Addr=000000000211d978) [ 293.096000] CPU: 0 PID: 1320 Comm: modprobe Not tainted 4.5.0-64bit+ #290 [ 293.096000] task: 00000000b290a700 ti: 00000000b1294000 task.ti: 00000000b1294000 [ 293.096000] [ 293.096000] YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI [ 293.096000] PSW: 00001000000001001111110000001111 Not tainted [ 293.096000] r00-03 000000ff0804fc0f 000000000211d800 00000000020b37f4 00000000b12945b0 [ 293.096000] r04-07 00000000020b1000 00000000b2b3a000 00000000fa6fa000 00000000020b1478 [ 293.096000] r08-11 0000000000000000 00000000020b15d0 00000000020b1430 0000000000000000 [ 293.096000] r12-15 0000000000000000 0000000000000000 0000000000000000 0000000000000000 [ 293.096000] r16-19 0000000000000000 0000000000000000 00000000020b15d0 0000000000000000 [ 293.096000] r20-23 0000000000000000 00000000000002f5 0000000000000000 00000000000002ee [ 293.096000] r24-27 0000000000000000 000000000800000f 0000000040d62080 00000000020b1000 [ 293.096000] r28-31 0000000000000001 00000000b12949c0 00000000b12946a0 0000000040dce928 [ 293.096000] sr00-03 00000000003eb800 0000000000000000 0000000000000000 00000000003eb800 [ 293.096000] sr04-07 0000000000000000 0000000000000000 0000000000000000 0000000000000000 [ 293.096000] [ 293.096000] IASQ: 0000000000000000 0000000000000000 IAOQ: 0000000040a5aab4 0000000040a5aab8 [ 293.096000] IIR: 502102f0 ISR: 0000000000000000 IOR: 000000000211d978 [ 293.096000] CPU: 0 CR30: 00000000b1294000 CR31: 00000000fffff5ff [ 293.096000] ORIG_R28: 0000000040e24df0 [ 293.096000] IAOQ[0]: fixup_get_user_skip_1+0x4/0x38 [ 293.096000] IAOQ[1]: fixup_get_user_skip_1+0x8/0x38 [ 293.096000] RP(r2): test_user_copy_init+0x534/0x6e8 [test_user_copy] [ 293.096000] Backtrace: [ 293.096000] fault at 0x40223eac ... found ! fixup = 0x40a5aab0 [ 293.096000] [ 293.096000] Kernel panic - not syncing: Kernel Fault [-- Attachment #2: fixup.patch --] [-- Type: text/x-diff, Size: 1432 bytes --] diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index 568b2c6..4b18a04 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c @@ -48,10 +48,14 @@ 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); +//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); +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 553b098..bb7f191 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -798,6 +798,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); } ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Aw: Re: kernel 4.6-rc unbootable due to module changes 2016-04-07 22:48 ` Helge Deller @ 2016-04-08 12:06 ` Helge Deller 2016-04-08 14:59 ` Helge Deller 0 siblings, 1 reply; 11+ messages in thread From: Helge Deller @ 2016-04-08 12:06 UTC (permalink / raw) To: Helge Deller; +Cc: Mikulas Patocka, John David Anglin, linux-parisc [-- Attachment #1: Type: text/plain, Size: 641 bytes --] > >> 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 ? Helge [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: fixup2.patch --] [-- Type: text/x-patch, Size: 3616 bytes --] diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h index 0abdd4c..1b05163 100644 --- a/arch/parisc/include/asm/uaccess.h +++ b/arch/parisc/include/asm/uaccess.h @@ -78,6 +78,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/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 553b098..77e2262 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -798,6 +798,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 a762864..245784e 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -153,6 +153,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] = ((fix->fixup) & ~3); /* ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Aw: Re: kernel 4.6-rc unbootable due to module changes 2016-04-08 12:06 ` Aw: " Helge Deller @ 2016-04-08 14:59 ` Helge Deller 2016-04-08 19:43 ` Helge Deller 0 siblings, 1 reply; 11+ messages in thread From: Helge Deller @ 2016-04-08 14:59 UTC (permalink / raw) To: Helge Deller; +Cc: Mikulas Patocka, John David Anglin, linux-parisc [-- Attachment #1: Type: text/plain, Size: 884 bytes --] > > >> 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 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: fixup3.patch --] [-- Type: text/x-patch, Size: 4171 bytes --] 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; ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: Aw: Re: kernel 4.6-rc unbootable due to module changes 2016-04-08 14:59 ` Helge Deller @ 2016-04-08 19:43 ` Helge Deller 0 siblings, 0 replies; 11+ messages in thread From: Helge Deller @ 2016-04-08 19:43 UTC (permalink / raw) Cc: Mikulas Patocka, John David Anglin, linux-parisc On 08.04.2016 16:59, Helge Deller wrote: >>>>> 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 ? I've pushed all relevant changes into my for-next tree which can be pulled: http://git.kernel.org/cgit/linux/kernel/git/deller/parisc-linux.git/log/?h=for-next Helge ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: kernel 4.6-rc unbootable due to module changes 2016-04-05 18:54 ` Helge Deller 2016-04-05 20:15 ` Mikulas Patocka @ 2016-04-05 20:18 ` John David Anglin 1 sibling, 0 replies; 11+ messages in thread From: John David Anglin @ 2016-04-05 20:18 UTC (permalink / raw) To: Helge Deller, Mikulas Patocka; +Cc: linux-parisc On 2016-04-05 2:54 PM, Helge Deller wrote: > + case R_PARISC_PCREL32: > + val -= (uint32_t) loc; > + *loc = val; > + break; PCREL32 for a 64-bit application is "symbol - PC - 8 + addend". Dave -- John David Anglin dave.anglin@bell.net ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2016-04-08 19:43 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-04-05 17:31 kernel 4.6-rc unbootable due to module changes Mikulas Patocka 2016-04-05 17:36 ` Mikulas Patocka 2016-04-05 18:54 ` Helge Deller 2016-04-05 20:15 ` Mikulas Patocka 2016-04-06 14:30 ` Mikulas Patocka 2016-04-06 21:44 ` Helge Deller 2016-04-07 22:48 ` Helge Deller 2016-04-08 12:06 ` Aw: " Helge Deller 2016-04-08 14:59 ` Helge Deller 2016-04-08 19:43 ` Helge Deller 2016-04-05 20:18 ` John David Anglin
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.