* 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 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
* 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
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.