summaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/binfmt_elf32.c5
-rw-r--r--arch/s390/kernel/entry.S80
-rw-r--r--arch/s390/kernel/entry64.S80
-rw-r--r--arch/s390/kernel/head.S22
-rw-r--r--arch/s390/kernel/head31.S77
-rw-r--r--arch/s390/kernel/head64.S79
-rw-r--r--arch/s390/kernel/s390_ksyms.c2
-rw-r--r--arch/s390/kernel/setup.c55
-rw-r--r--arch/s390/kernel/traps.c8
9 files changed, 259 insertions, 149 deletions
diff --git a/arch/s390/kernel/binfmt_elf32.c b/arch/s390/kernel/binfmt_elf32.c
index 1f451c2cb07..12a6311e983 100644
--- a/arch/s390/kernel/binfmt_elf32.c
+++ b/arch/s390/kernel/binfmt_elf32.c
@@ -177,11 +177,6 @@ struct elf_prpsinfo32
#include <linux/highuid.h>
-#undef NEW_TO_OLD_UID
-#undef NEW_TO_OLD_GID
-#define NEW_TO_OLD_UID(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
-#define NEW_TO_OLD_GID(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
-
#define elf_addr_t u32
/*
#define init_elf_binfmt init_elf32_binfmt
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index b2448487854..aa8b52c2140 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -93,13 +93,22 @@ STACK_SIZE = 1 << STACK_SHIFT
l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
.endm
- .macro SAVE_ALL psworg,savearea,sync
+ .macro SAVE_ALL_SYNC psworg,savearea
la %r12,\psworg
- .if \sync
tm \psworg+1,0x01 # test problem state bit
bz BASED(2f) # skip stack setup save
l %r15,__LC_KERNEL_STACK # problem state -> load ksp
- .else
+#ifdef CONFIG_CHECK_STACK
+ b BASED(3f)
+2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
+ bz BASED(stack_overflow)
+3:
+#endif
+2:
+ .endm
+
+ .macro SAVE_ALL_ASYNC psworg,savearea
+ la %r12,\psworg
tm \psworg+1,0x01 # test problem state bit
bnz BASED(1f) # from user -> load async stack
clc \psworg+4(4),BASED(.Lcritical_end)
@@ -115,7 +124,6 @@ STACK_SIZE = 1 << STACK_SHIFT
sra %r14,STACK_SHIFT
be BASED(2f)
1: l %r15,__LC_ASYNC_STACK
- .endif
#ifdef CONFIG_CHECK_STACK
b BASED(3f)
2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
@@ -196,7 +204,7 @@ system_call:
STORE_TIMER __LC_SYNC_ENTER_TIMER
sysc_saveall:
SAVE_ALL_BASE __LC_SAVE_AREA
- SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+ SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
lh %r7,0x8a # get svc number from lowcore
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
@@ -425,7 +433,7 @@ pgm_check_handler:
SAVE_ALL_BASE __LC_SAVE_AREA
tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
bnz BASED(pgm_per) # got per exception -> special case
- SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+ SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -464,7 +472,7 @@ pgm_per:
# Normal per exception
#
pgm_per_std:
- SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+ SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -490,7 +498,7 @@ pgm_no_vtime2:
# it was a single stepped SVC that is causing all the trouble
#
pgm_svcper:
- SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+ SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -519,7 +527,7 @@ io_int_handler:
STORE_TIMER __LC_ASYNC_ENTER_TIMER
stck __LC_INT_CLOCK
SAVE_ALL_BASE __LC_SAVE_AREA+16
- SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0
+ SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16
CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -631,7 +639,7 @@ ext_int_handler:
STORE_TIMER __LC_ASYNC_ENTER_TIMER
stck __LC_INT_CLOCK
SAVE_ALL_BASE __LC_SAVE_AREA+16
- SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0
+ SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16
CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -657,21 +665,31 @@ __critical_end:
.globl mcck_int_handler
mcck_int_handler:
spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer
- mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA
lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs
SAVE_ALL_BASE __LC_SAVE_AREA+32
la %r12,__LC_MCK_OLD_PSW
tm __LC_MCCK_CODE,0x80 # system damage?
bo BASED(mcck_int_main) # yes -> rest of mcck code invalid
- tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
- bo BASED(0f)
- spt __LC_LAST_UPDATE_TIMER # revalidate cpu timer
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER
- mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER
- mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER
+ mvc __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER
+ mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA
+ tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
+ bo BASED(1f)
+ la %r14,__LC_SYNC_ENTER_TIMER
+ clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
+ bl BASED(0f)
+ la %r14,__LC_ASYNC_ENTER_TIMER
+0: clc 0(8,%r14),__LC_EXIT_TIMER
+ bl BASED(0f)
+ la %r14,__LC_EXIT_TIMER
+0: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
+ bl BASED(0f)
+ la %r14,__LC_LAST_UPDATE_TIMER
+0: spt 0(%r14)
+ mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14)
+1:
#endif
-0: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
+ tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
bno BASED(mcck_int_main) # no -> skip cleanup critical
tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
bnz BASED(mcck_int_main) # from user -> load async stack
@@ -691,7 +709,7 @@ mcck_int_main:
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
bno BASED(mcck_no_vtime) # no -> skip cleanup critical
- tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ?
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
bz BASED(mcck_no_vtime)
UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
@@ -715,6 +733,20 @@ mcck_no_vtime:
l %r1,BASED(.Ls390_handle_mcck)
basr %r14,%r1 # call machine check handler
mcck_return:
+ mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW
+ ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+52
+ tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
+ bno BASED(0f)
+ lm %r0,%r15,SP_R0(%r15) # load gprs 0-15
+ stpt __LC_EXIT_TIMER
+ lpsw __LC_RETURN_MCCK_PSW # back to caller
+0:
+#endif
+ lm %r0,%r15,SP_R0(%r15) # load gprs 0-15
+ lpsw __LC_RETURN_MCCK_PSW # back to caller
+
RESTORE_ALL __LC_RETURN_MCCK_PSW,0
#ifdef CONFIG_SMP
@@ -781,6 +813,8 @@ cleanup_table_sysc_leave:
.long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000
cleanup_table_sysc_work_loop:
.long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000
+cleanup_table_io_return:
+ .long io_return + 0x80000000, io_leave + 0x80000000
cleanup_table_io_leave:
.long io_leave + 0x80000000, io_done + 0x80000000
cleanup_table_io_work_loop:
@@ -807,6 +841,11 @@ cleanup_critical:
clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4)
bl BASED(cleanup_sysc_return)
0:
+ clc 4(4,%r12),BASED(cleanup_table_io_return)
+ bl BASED(0f)
+ clc 4(4,%r12),BASED(cleanup_table_io_return+4)
+ bl BASED(cleanup_io_return)
+0:
clc 4(4,%r12),BASED(cleanup_table_io_leave)
bl BASED(0f)
clc 4(4,%r12),BASED(cleanup_table_io_leave+4)
@@ -839,7 +878,7 @@ cleanup_system_call:
mvc __LC_SAVE_AREA(16),0(%r12)
0: st %r13,4(%r12)
st %r12,__LC_SAVE_AREA+48 # argh
- SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+ SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
l %r12,__LC_SAVE_AREA+48 # argh
st %r15,12(%r12)
@@ -980,7 +1019,6 @@ cleanup_io_leave_insn:
.long cleanup_critical
#define SYSCALL(esa,esame,emu) .long esa
- .globl sys_call_table
sys_call_table:
#include "syscalls.S"
#undef SYSCALL
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 2ac095bc0e2..f3222a1b286 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -87,13 +87,22 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
larl %r13,system_call
.endm
- .macro SAVE_ALL psworg,savearea,sync
+ .macro SAVE_ALL_SYNC psworg,savearea
la %r12,\psworg
- .if \sync
tm \psworg+1,0x01 # test problem state bit
jz 2f # skip stack setup save
lg %r15,__LC_KERNEL_STACK # problem state -> load ksp
- .else
+#ifdef CONFIG_CHECK_STACK
+ j 3f
+2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
+ jz stack_overflow
+3:
+#endif
+2:
+ .endm
+
+ .macro SAVE_ALL_ASYNC psworg,savearea
+ la %r12,\psworg
tm \psworg+1,0x01 # test problem state bit
jnz 1f # from user -> load kernel stack
clc \psworg+8(8),BASED(.Lcritical_end)
@@ -108,7 +117,6 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
srag %r14,%r14,STACK_SHIFT
jz 2f
1: lg %r15,__LC_ASYNC_STACK # load async stack
- .endif
#ifdef CONFIG_CHECK_STACK
j 3f
2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
@@ -187,7 +195,7 @@ system_call:
STORE_TIMER __LC_SYNC_ENTER_TIMER
sysc_saveall:
SAVE_ALL_BASE __LC_SAVE_AREA
- SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+ SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
@@ -446,7 +454,7 @@ pgm_check_handler:
SAVE_ALL_BASE __LC_SAVE_AREA
tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
jnz pgm_per # got per exception -> special case
- SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+ SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -485,7 +493,7 @@ pgm_per:
# Normal per exception
#
pgm_per_std:
- SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+ SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -511,7 +519,7 @@ pgm_no_vtime2:
# it was a single stepped SVC that is causing all the trouble
#
pgm_svcper:
- SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+ SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -539,7 +547,7 @@ io_int_handler:
STORE_TIMER __LC_ASYNC_ENTER_TIMER
stck __LC_INT_CLOCK
SAVE_ALL_BASE __LC_SAVE_AREA+32
- SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0
+ SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+32
CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -647,7 +655,7 @@ ext_int_handler:
STORE_TIMER __LC_ASYNC_ENTER_TIMER
stck __LC_INT_CLOCK
SAVE_ALL_BASE __LC_SAVE_AREA+32
- SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0
+ SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32
CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -672,21 +680,32 @@ __critical_end:
mcck_int_handler:
la %r1,4095 # revalidate r1
spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer
- mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r1)
lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
SAVE_ALL_BASE __LC_SAVE_AREA+64
la %r12,__LC_MCK_OLD_PSW
tm __LC_MCCK_CODE,0x80 # system damage?
jo mcck_int_main # yes -> rest of mcck code invalid
- tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
- jo 0f
- spt __LC_LAST_UPDATE_TIMER
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER
- mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER
- mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER
+ la %r14,4095
+ mvc __LC_SAVE_AREA+104(8),__LC_ASYNC_ENTER_TIMER
+ mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r14)
+ tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
+ jo 1f
+ la %r14,__LC_SYNC_ENTER_TIMER
+ clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
+ jl 0f
+ la %r14,__LC_ASYNC_ENTER_TIMER
+0: clc 0(8,%r14),__LC_EXIT_TIMER
+ jl 0f
+ la %r14,__LC_EXIT_TIMER
+0: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
+ jl 0f
+ la %r14,__LC_LAST_UPDATE_TIMER
+0: spt 0(%r14)
+ mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14)
+1:
#endif
-0: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
+ tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
jno mcck_int_main # no -> skip cleanup critical
tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
jnz mcck_int_main # from user -> load kernel stack
@@ -705,7 +724,7 @@ mcck_int_main:
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
jno mcck_no_vtime # no -> no timer update
- tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ?
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
jz mcck_no_vtime
UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
@@ -727,7 +746,17 @@ mcck_no_vtime:
jno mcck_return
brasl %r14,s390_handle_mcck
mcck_return:
- RESTORE_ALL __LC_RETURN_MCCK_PSW,0
+ mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW
+ ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
+ lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+104
+ tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
+ jno 0f
+ stpt __LC_EXIT_TIMER
+0:
+#endif
+ lpswe __LC_RETURN_MCCK_PSW # back to caller
#ifdef CONFIG_SMP
/*
@@ -789,6 +818,8 @@ cleanup_table_sysc_leave:
.quad sysc_leave, sysc_work_loop
cleanup_table_sysc_work_loop:
.quad sysc_work_loop, sysc_reschedule
+cleanup_table_io_return:
+ .quad io_return, io_leave
cleanup_table_io_leave:
.quad io_leave, io_done
cleanup_table_io_work_loop:
@@ -815,6 +846,11 @@ cleanup_critical:
clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8)
jl cleanup_sysc_return
0:
+ clc 8(8,%r12),BASED(cleanup_table_io_return)
+ jl 0f
+ clc 8(8,%r12),BASED(cleanup_table_io_return+8)
+ jl cleanup_io_return
+0:
clc 8(8,%r12),BASED(cleanup_table_io_leave)
jl 0f
clc 8(8,%r12),BASED(cleanup_table_io_leave+8)
@@ -847,7 +883,7 @@ cleanup_system_call:
mvc __LC_SAVE_AREA(32),0(%r12)
0: stg %r13,8(%r12)
stg %r12,__LC_SAVE_AREA+96 # argh
- SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+ SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
lg %r12,__LC_SAVE_AREA+96 # argh
stg %r15,24(%r12)
@@ -957,7 +993,6 @@ cleanup_io_leave_insn:
.quad __critical_end
#define SYSCALL(esa,esame,emu) .long esame
- .globl sys_call_table
sys_call_table:
#include "syscalls.S"
#undef SYSCALL
@@ -965,7 +1000,6 @@ sys_call_table:
#ifdef CONFIG_COMPAT
#define SYSCALL(esa,esame,emu) .long emu
- .globl sys_call_table_emu
sys_call_table_emu:
#include "syscalls.S"
#undef SYSCALL
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index ea88d066bf0..538c82da49b 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -1,7 +1,7 @@
/*
* arch/s390/kernel/head.S
*
- * (C) Copyright IBM Corp. 1999, 2005
+ * Copyright (C) IBM Corp. 1999,2006
*
* Author(s): Hartmut Penner <hp@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -482,24 +482,23 @@ start:
.macro GET_IPL_DEVICE
.Lget_ipl_device:
- basr %r12,0
-.LGID: l %r1,0xb8 # get sid
+ l %r1,0xb8 # get sid
sll %r1,15 # test if subchannel is enabled
srl %r1,31
ltr %r1,%r1
- bz 0(%r14) # subchannel disabled
+ bz 2f-.LPG1(%r13) # subchannel disabled
l %r1,0xb8
- la %r5,.Lipl_schib-.LGID(%r12)
+ la %r5,.Lipl_schib-.LPG1(%r13)
stsch 0(%r5) # get schib of subchannel
- bnz 0(%r14) # schib not available
+ bnz 2f-.LPG1(%r13) # schib not available
tm 5(%r5),0x01 # devno valid?
- bno 0(%r14)
- la %r6,ipl_parameter_flags-.LGID(%r12)
+ bno 2f-.LPG1(%r13)
+ la %r6,ipl_parameter_flags-.LPG1(%r13)
oi 3(%r6),0x01 # set flag
- la %r2,ipl_devno-.LGID(%r12)
+ la %r2,ipl_devno-.LPG1(%r13)
mvc 0(2,%r2),6(%r5) # store devno
tm 4(%r5),0x80 # qdio capable device?
- bno 0(%r14)
+ bno 2f-.LPG1(%r13)
oi 3(%r6),0x02 # set flag
# copy ipl parameters
@@ -523,7 +522,7 @@ start:
ar %r2,%r1
sr %r0,%r4
jne 1b
- b 0(%r14)
+ b 2f-.LPG1(%r13)
.align 4
.Lipl_schib:
@@ -537,6 +536,7 @@ ipl_parameter_flags:
.globl ipl_devno
ipl_devno:
.word 0
+2:
.endm
#ifdef CONFIG_64BIT
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
index 2d3b089bfb8..d00de17b377 100644
--- a/arch/s390/kernel/head31.S
+++ b/arch/s390/kernel/head31.S
@@ -1,7 +1,7 @@
/*
* arch/s390/kernel/head31.S
*
- * (C) Copyright IBM Corp. 2005
+ * Copyright (C) IBM Corp. 2005,2006
*
* Author(s): Hartmut Penner <hp@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -16,12 +16,31 @@
# or linload or SALIPL
#
.org 0x10000
-startup:basr %r13,0 # get base
-.LPG1: l %r1, .Lget_ipl_device_addr-.LPG1(%r13)
- basr %r14, %r1
+startup:basr %r13,0 # get base
+.LPG0: l %r13,0f-.LPG0(%r13)
+ b 0(%r13)
+0: .long startup_continue
+
+#
+# params at 10400 (setup.h)
+#
+ .org PARMAREA
+ .long 0,0 # IPL_DEVICE
+ .long 0,RAMDISK_ORIGIN # INITRD_START
+ .long 0,RAMDISK_SIZE # INITRD_SIZE
+
+ .org COMMAND_LINE
+ .byte "root=/dev/ram0 ro"
+ .byte 0
+
+ .org 0x11000
+
+startup_continue:
+ basr %r13,0 # get base
+.LPG1: GET_IPL_DEVICE
lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
- la %r12,_pstart-.LPG1(%r13) # pointer to parameter area
- # move IPL device to lowcore
+ l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
+ # move IPL device to lowcore
mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
#
@@ -51,8 +70,8 @@ startup:basr %r13,0 # get base
a %r1,__LC_EXT_NEW_PSW+4 # set handler
st %r1,__LC_EXT_NEW_PSW+4
- la %r4,_pstart-.LPG1(%r13) # %r4 is our index for sccb stuff
- la %r1, .Lsccb-PARMAREA(%r4) # our sccb
+ l %r4,.Lsccbaddr-.LPG1(%r13) # %r4 is our index for sccb stuff
+ lr %r1,%r4 # our sccb
.insn rre,0xb2200000,%r2,%r1 # service call
ipm %r1
srl %r1,28 # get cc code
@@ -63,7 +82,7 @@ startup:basr %r13,0 # get base
be .Lservicecall-.LPG1(%r13)
lpsw .Lwaitsclp-.LPG1(%r13)
.Lsclph:
- lh %r1,.Lsccbr-PARMAREA(%r4)
+ lh %r1,.Lsccbr-.Lsccb(%r4)
chi %r1,0x10 # 0x0010 is the sucess code
je .Lprocsccb # let's process the sccb
chi %r1,0x1f0
@@ -74,7 +93,7 @@ startup:basr %r13,0 # get base
b .Lservicecall-.LPG1(%r13)
.Lprocsccb:
lhi %r1,0
- icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
+ icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0
jnz .Lscnd
lhi %r1,0x800 # otherwise report 2GB
.Lscnd:
@@ -84,10 +103,10 @@ startup:basr %r13,0 # get base
lr %r1,%r3
.Lno2gb:
xr %r3,%r3 # same logic
- ic %r3,.Lscpa1-PARMAREA(%r4)
+ ic %r3,.Lscpa1-.Lsccb(%r4)
chi %r3,0x00
jne .Lcompmem
- l %r3,.Lscpa2-PARMAREA(%r13)
+ l %r3,.Lscpa2-.Lsccb(%r4)
.Lcompmem:
mr %r2,%r1 # mem in MB on 128-bit
l %r1,.Lonemb-.LPG1(%r13)
@@ -95,8 +114,6 @@ startup:basr %r13,0 # get base
b .Lfchunk-.LPG1(%r13)
.align 4
-.Lget_ipl_device_addr:
- .long .Lget_ipl_device
.Lpmask:
.byte 0
.align 8
@@ -242,6 +259,8 @@ startup:basr %r13,0 # get base
.long 0 # cr13: home space segment table
.long 0xc0000000 # cr14: machine check handling off
.long 0 # cr15: linkage stack operations
+.Lduct: .long 0,0,0,0,0,0,0,0
+ .long 0,0,0,0,0,0,0,0
.Lpcmem:.long 0x00080000,0x80000000 + .Lchkmem
.Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu
.Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp
@@ -252,25 +271,9 @@ startup:basr %r13,0 # get base
.Lmflags:.long machine_flags
.Lbss_bgn: .long __bss_start
.Lbss_end: .long _end
-
- .org PARMAREA-64
-.Lduct: .long 0,0,0,0,0,0,0,0
- .long 0,0,0,0,0,0,0,0
-
-#
-# params at 10400 (setup.h)
-#
- .org PARMAREA
- .global _pstart
-_pstart:
- .long 0,0 # IPL_DEVICE
- .long 0,RAMDISK_ORIGIN # INITRD_START
- .long 0,RAMDISK_SIZE # INITRD_SIZE
-
- .org COMMAND_LINE
- .byte "root=/dev/ram0 ro"
- .byte 0
- .org 0x11000
+.Lparmaddr: .long PARMAREA
+.Lsccbaddr: .long .Lsccb
+ .align 4096
.Lsccb:
.hword 0x1000 # length, one page
.byte 0x00,0x00,0x00
@@ -287,18 +290,14 @@ _pstart:
.Lscpincr2:
.quad 0x00
.fill 3984,1,0
- .org 0x12000
- .global _pend
-_pend:
-
- GET_IPL_DEVICE
+ .align 4096
#ifdef CONFIG_SHARED_KERNEL
.org 0x100000
#endif
#
-# startup-code, running in virtual mode
+# startup-code, running in absolute addressing mode
#
.globl _stext
_stext: basr %r13,0 # get base
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index f08c06f45d5..47744fcca93 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -1,7 +1,7 @@
/*
* arch/s390/kernel/head64.S
*
- * (C) Copyright IBM Corp. 1999,2005
+ * Copyright (C) IBM Corp. 1999,2006
*
* Author(s): Hartmut Penner <hp@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -15,18 +15,37 @@
# this is called either by the ipl loader or directly by PSW restart
# or linload or SALIPL
#
- .org 0x10000
-startup:basr %r13,0 # get base
+ .org 0x10000
+startup:basr %r13,0 # get base
+.LPG0: l %r13,0f-.LPG0(%r13)
+ b 0(%r13)
+0: .long startup_continue
+
+#
+# params at 10400 (setup.h)
+#
+ .org PARMAREA
+ .quad 0 # IPL_DEVICE
+ .quad RAMDISK_ORIGIN # INITRD_START
+ .quad RAMDISK_SIZE # INITRD_SIZE
+
+ .org COMMAND_LINE
+ .byte "root=/dev/ram0 ro"
+ .byte 0
+
+ .org 0x11000
+
+startup_continue:
+ basr %r13,0 # get base
.LPG1: sll %r13,1 # remove high order bit
srl %r13,1
- l %r1,.Lget_ipl_device_addr-.LPG1(%r13)
- basr %r14,%r1
+ GET_IPL_DEVICE
lhi %r1,1 # mode 1 = esame
slr %r0,%r0 # set cpuid to zero
sigp %r1,%r0,0x12 # switch to esame mode
sam64 # switch to 64 bit mode
lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
- larl %r12,_pstart # pointer to parameter area
+ lg %r12,.Lparmaddr-.LPG1(%r13)# pointer to parameter area
# move IPL device to lowcore
mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12)
@@ -55,8 +74,8 @@ startup:basr %r13,0 # get base
larl %r1,.Lsclph
stg %r1,__LC_EXT_NEW_PSW+8 # set handler
- larl %r4,_pstart # %r4 is our index for sccb stuff
- la %r1,.Lsccb-PARMAREA(%r4) # our sccb
+ larl %r4,.Lsccb # %r4 is our index for sccb stuff
+ lgr %r1,%r4 # our sccb
.insn rre,0xb2200000,%r2,%r1 # service call
ipm %r1
srl %r1,28 # get cc code
@@ -67,7 +86,7 @@ startup:basr %r13,0 # get base
be .Lservicecall-.LPG1(%r13)
lpswe .Lwaitsclp-.LPG1(%r13)
.Lsclph:
- lh %r1,.Lsccbr-PARMAREA(%r4)
+ lh %r1,.Lsccbr-.Lsccb(%r4)
chi %r1,0x10 # 0x0010 is the sucess code
je .Lprocsccb # let's process the sccb
chi %r1,0x1f0
@@ -78,15 +97,15 @@ startup:basr %r13,0 # get base
b .Lservicecall-.LPG1(%r13)
.Lprocsccb:
lghi %r1,0
- icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
+ icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0
jnz .Lscnd
- lg %r1,.Lscpincr2-PARMAREA(%r4) # otherwise use this one
+ lg %r1,.Lscpincr2-.Lsccb(%r4) # otherwise use this one
.Lscnd:
xr %r3,%r3 # same logic
- ic %r3,.Lscpa1-PARMAREA(%r4)
+ ic %r3,.Lscpa1-.Lsccb(%r4)
chi %r3,0x00
jne .Lcompmem
- l %r3,.Lscpa2-PARMAREA(%r13)
+ l %r3,.Lscpa2-.Lsccb(%r4)
.Lcompmem:
mlgr %r2,%r1 # mem in MB on 128-bit
l %r1,.Lonemb-.LPG1(%r13)
@@ -94,8 +113,6 @@ startup:basr %r13,0 # get base
b .Lfchunk-.LPG1(%r13)
.align 4
-.Lget_ipl_device_addr:
- .long .Lget_ipl_device
.Lpmask:
.byte 0
.align 8
@@ -242,29 +259,16 @@ startup:basr %r13,0 # get base
.quad 0 # cr13: home space segment table
.quad 0xc0000000 # cr14: machine check handling off
.quad 0 # cr15: linkage stack operations
+.Lduct: .long 0,0,0,0,0,0,0,0
+ .long 0,0,0,0,0,0,0,0
.Lpcmsk:.quad 0x0000000180000000
.L4malign:.quad 0xffffffffffc00000
.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8
.Lnop: .long 0x07000700
+.Lparmaddr:
+ .quad PARMAREA
- .org PARMAREA-64
-.Lduct: .long 0,0,0,0,0,0,0,0
- .long 0,0,0,0,0,0,0,0
-
-#
-# params at 10400 (setup.h)
-#
- .org PARMAREA
- .global _pstart
-_pstart:
- .quad 0 # IPL_DEVICE
- .quad RAMDISK_ORIGIN # INITRD_START
- .quad RAMDISK_SIZE # INITRD_SIZE
-
- .org COMMAND_LINE
- .byte "root=/dev/ram0 ro"
- .byte 0
- .org 0x11000
+ .align 4096
.Lsccb:
.hword 0x1000 # length, one page
.byte 0x00,0x00,0x00
@@ -281,18 +285,14 @@ _pstart:
.Lscpincr2:
.quad 0x00
.fill 3984,1,0
- .org 0x12000
- .global _pend
-_pend:
-
- GET_IPL_DEVICE
+ .align 4096
#ifdef CONFIG_SHARED_KERNEL
.org 0x100000
#endif
#
-# startup-code, running in virtual mode
+# startup-code, running in absolute addressing mode
#
.globl _stext
_stext: basr %r13,0 # get base
@@ -326,4 +326,3 @@ _stext: basr %r13,0 # get base
.align 8
.Ldw: .quad 0x0002000180000000,0x0000000000000000
.Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c
index 4176c77670c..0886e739d12 100644
--- a/arch/s390/kernel/s390_ksyms.c
+++ b/arch/s390/kernel/s390_ksyms.c
@@ -46,8 +46,6 @@ EXPORT_SYMBOL(__down_interruptible);
*/
extern int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs);
EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(overflowuid);
-EXPORT_SYMBOL(overflowgid);
EXPORT_SYMBOL(empty_zero_page);
/*
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index b282034452a..2b2551e3510 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -37,6 +37,7 @@
#include <linux/seq_file.h>
#include <linux/kernel_stat.h>
#include <linux/device.h>
+#include <linux/notifier.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -115,6 +116,7 @@ void __devinit cpu_init (void)
*/
char vmhalt_cmd[128] = "";
char vmpoff_cmd[128] = "";
+char vmpanic_cmd[128] = "";
static inline void strncpy_skip_quote(char *dst, char *src, int n)
{
@@ -146,6 +148,38 @@ static int __init vmpoff_setup(char *str)
__setup("vmpoff=", vmpoff_setup);
+static int vmpanic_notify(struct notifier_block *self, unsigned long event,
+ void *data)
+{
+ if (MACHINE_IS_VM && strlen(vmpanic_cmd) > 0)
+ cpcmd(vmpanic_cmd, NULL, 0, NULL);
+
+ return NOTIFY_OK;
+}
+
+#define PANIC_PRI_VMPANIC 0
+
+static struct notifier_block vmpanic_nb = {
+ .notifier_call = vmpanic_notify,
+ .priority = PANIC_PRI_VMPANIC
+};
+
+static int __init vmpanic_setup(char *str)
+{
+ static int register_done __initdata = 0;
+
+ strncpy_skip_quote(vmpanic_cmd, str, 127);
+ vmpanic_cmd[127] = 0;
+ if (!register_done) {
+ register_done = 1;
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &vmpanic_nb);
+ }
+ return 1;
+}
+
+__setup("vmpanic=", vmpanic_setup);
+
/*
* condev= and conmode= setup parameter.
*/
@@ -289,19 +323,34 @@ void (*_machine_power_off)(void) = do_machine_power_off_nonsmp;
void machine_restart(char *command)
{
- console_unblank();
+ if (!in_interrupt() || oops_in_progress)
+ /*
+ * Only unblank the console if we are called in enabled
+ * context or a bust_spinlocks cleared the way for us.
+ */
+ console_unblank();
_machine_restart(command);
}
void machine_halt(void)
{
- console_unblank();
+ if (!in_interrupt() || oops_in_progress)
+ /*
+ * Only unblank the console if we are called in enabled
+ * context or a bust_spinlocks cleared the way for us.
+ */
+ console_unblank();
_machine_halt();
}
void machine_power_off(void)
{
- console_unblank();
+ if (!in_interrupt() || oops_in_progress)
+ /*
+ * Only unblank the console if we are called in enabled
+ * context or a bust_spinlocks cleared the way for us.
+ */
+ console_unblank();
_machine_power_off();
}
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index a46793beedd..b7630436f69 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -150,13 +150,11 @@ void show_stack(struct task_struct *task, unsigned long *sp)
unsigned long *stack;
int i;
- // debugging aid: "show_stack(NULL);" prints the
- // back trace for this cpu.
-
if (!sp)
- sp = task ? (unsigned long *) task->thread.ksp : __r15;
+ stack = task ? (unsigned long *) task->thread.ksp : __r15;
+ else
+ stack = sp;
- stack = sp;
for (i = 0; i < kstack_depth_to_print; i++) {
if (((addr_t) stack & (THREAD_SIZE-1)) == 0)
break;