All of lore.kernel.org
 help / color / mirror / Atom feed
* 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.