diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2011-04-20 04:15:34 -0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2011-04-20 04:15:44 -0400 |
commit | e35c76cd47c244eaa7a74adaabde4d0a1cadb907 (patch) | |
tree | b43e89ca2e85753a5ca6d8c93ac7939a70c08279 /arch/s390/mm | |
parent | bffbbd2df4196a73ffdc16709866dd96eb66aad8 (diff) |
[S390] pfault: fix token handling
f6649a7e "[S390] cleanup lowcore access from external interrupts" changed
handling of external interrupts. Instead of letting the external interrupt
handlers accessing the per cpu lowcore the entry code of the kernel reads
already all fields that are necessary and passes them to the handlers.
The pfault interrupt handler was incorrectly converted. It tries to
dereference a value which used to be a pointer to a lowcore field. After
the conversion however it is not anymore the pointer to the field but its
content. So instead of a dereference only a cast is needed to get the
task pointer that caused the pfault.
Fixes a NULL pointer dereference and a subsequent kernel crash:
Unable to handle kernel pointer dereference at virtual kernel address (null)
Oops: 0004 [#1] SMP
Modules linked in: nfsd exportfs nfs lockd fscache nfs_acl auth_rpcgss sunrpc
loop qeth_l3 qeth vmur ccwgroup ext3 jbd mbcache dm_mod
dasd_eckd_mod dasd_diag_mod dasd_mod
CPU: 0 Not tainted 2.6.38-2-s390x #1
Process cron (pid: 1106, task: 000000001f962f78, ksp: 000000001fa0f9d0)
Krnl PSW : 0404200180000000 000000000002c03e (pfault_interrupt+0xa2/0x138)
R:0 T:1 IO:0 EX:0 Key:0 M:1 W:0 P:0 AS:0 CC:2 PM:0 EA:3
Krnl GPRS: 0000000000000000 0000000000000001 0000000000000000 0000000000000001
000000001f962f78 0000000000518968 0000000090000002 000000001ff03280
0000000000000000 000000000064f000 000000001f962f78 0000000000002603
0000000006002603 0000000000000000 000000001ff7fe68 000000001ff7fe48
Krnl Code: 000000000002c036: 5820d010 l %r2,16(%r13)
000000000002c03a: 1832 lr %r3,%r2
000000000002c03c: 1a31 ar %r3,%r1
>000000000002c03e: ba23d010 cs %r2,%r3,16(%r13)
000000000002c042: a744fffc brc 4,2c03a
000000000002c046: a7290002 lghi %r2,2
000000000002c04a: e320d0000024 stg %r2,0(%r13)
000000000002c050: 07f0 bcr 15,%r0
Call Trace:
([<000000001f962f78>] 0x1f962f78)
[<000000000001acda>] do_extint+0xf6/0x138
[<000000000039b6ca>] ext_no_vtime+0x30/0x34
[<000000007d706e04>] 0x7d706e04
Last Breaking-Event-Address:
[<0000000000000000>] 0x0
For stable maintainers:
the first kernel which contains this bug is 2.6.37.
Reported-by: Stephen Powell <zlinuxman@wowway.com>
Cc: Jonathan Nieder <jrnieder@gmail.com>
Cc: stable@kernel.org
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/mm')
-rw-r--r-- | arch/s390/mm/fault.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 9217e332b118..4cf85fef407c 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c | |||
@@ -558,9 +558,9 @@ static void pfault_interrupt(unsigned int ext_int_code, | |||
558 | * Get the token (= address of the task structure of the affected task). | 558 | * Get the token (= address of the task structure of the affected task). |
559 | */ | 559 | */ |
560 | #ifdef CONFIG_64BIT | 560 | #ifdef CONFIG_64BIT |
561 | tsk = *(struct task_struct **) param64; | 561 | tsk = (struct task_struct *) param64; |
562 | #else | 562 | #else |
563 | tsk = *(struct task_struct **) param32; | 563 | tsk = (struct task_struct *) param32; |
564 | #endif | 564 | #endif |
565 | 565 | ||
566 | if (subcode & 0x0080) { | 566 | if (subcode & 0x0080) { |