summaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2017-01-25 12:54:17 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2017-01-31 10:46:53 +0100
commit34525e1f7e8dc47834b52d19b02c94b250df6f1f (patch)
tree744812c35d9c5d98acbd48fac1237a2ce2dfadd9 /arch/s390/kernel
parent3b1bea012710c1a299573c7a6a0584d623e6cbcf (diff)
downloadlinux-34525e1f7e8dc47834b52d19b02c94b250df6f1f.tar.gz
linux-34525e1f7e8dc47834b52d19b02c94b250df6f1f.tar.xz
s390: store breaking event address only for program checks
The principles of operations specifies that the breaking event address is stored to the address 0x110 in the prefix page only for program checks. The last branch in user space is lost as soon as a branch in kernel space is executed after e.g. an svc. This makes it impossible to accurately maintain the breaking event address for a user space process. Simplify the code, just copy the current breaking event address from 0x110 to the task structure for program checks from user space. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/entry.S50
1 files changed, 12 insertions, 38 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 97298c58b2be..f687f168c94d 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -103,8 +103,7 @@ _PIF_WORK = (_PIF_PER_TRAP)
CHECK_STACK 1<<STACK_SHIFT,\savearea
aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
j 3f
-1: LAST_BREAK %r14
- UPDATE_VTIME %r14,%r15,\timer
+1: UPDATE_VTIME %r14,%r15,\timer
2: lg %r15,__LC_ASYNC_STACK # load async stack
3: la %r11,STACK_FRAME_OVERHEAD(%r15)
.endm
@@ -121,18 +120,6 @@ _PIF_WORK = (_PIF_PER_TRAP)
mvc __LC_LAST_UPDATE_TIMER(8),\enter_timer
.endm
- .macro LAST_BREAK scratch
- srag \scratch,%r10,23
-#ifdef CONFIG_HAVE_MARCH_Z990_FEATURES
- jz .+10
- stg %r10,__TASK_thread+__THREAD_last_break(%r12)
-#else
- jz .+14
- lghi \scratch,__TASK_thread
- stg %r10,__THREAD_last_break(\scratch,%r12)
-#endif
- .endm
-
.macro REENABLE_IRQS
stg %r8,__LC_RETURN_PSW
ni __LC_RETURN_PSW,0xbf
@@ -278,15 +265,14 @@ ENTRY(system_call)
stpt __LC_SYNC_ENTER_TIMER
.Lsysc_stmg:
stmg %r8,%r15,__LC_SAVE_AREA_SYNC
- lg %r10,__LC_LAST_BREAK
lg %r12,__LC_CURRENT
+ lghi %r13,__TASK_thread
lghi %r14,_PIF_SYSCALL
.Lsysc_per:
lg %r15,__LC_KERNEL_STACK
la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
- LAST_BREAK %r13
.Lsysc_vtime:
- UPDATE_VTIME %r10,%r13,__LC_SYNC_ENTER_TIMER
+ UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER
stmg %r0,%r7,__PT_R0(%r11)
mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
mvc __PT_PSW(16,%r11),__LC_SVC_OLD_PSW
@@ -294,12 +280,7 @@ ENTRY(system_call)
stg %r14,__PT_FLAGS(%r11)
.Lsysc_do_svc:
# load address of system call table
-#ifdef CONFIG_HAVE_MARCH_Z990_FEATURES
- lg %r10,__TASK_thread+__THREAD_sysc_table(%r12)
-#else
- lghi %r13,__TASK_thread
lg %r10,__THREAD_sysc_table(%r13,%r12)
-#endif
llgh %r8,__PT_INT_CODE+2(%r11)
slag %r8,%r8,2 # shift and test for svc 0
jnz .Lsysc_nr_ok
@@ -508,8 +489,7 @@ ENTRY(pgm_check_handler)
1: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
j 3f
-2: LAST_BREAK %r14
- UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
+2: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
lg %r15,__LC_KERNEL_STACK
lgr %r14,%r12
aghi %r14,__TASK_thread # pointer to thread_struct
@@ -518,6 +498,7 @@ ENTRY(pgm_check_handler)
jz 3f
mvc __THREAD_trap_tdb(256,%r14),0(%r13)
3: la %r11,STACK_FRAME_OVERHEAD(%r15)
+ stg %r10,__THREAD_last_break(%r14)
stmg %r0,%r7,__PT_R0(%r11)
mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
stmg %r8,%r9,__PT_PSW(%r11)
@@ -576,7 +557,6 @@ ENTRY(io_int_handler)
STCK __LC_INT_CLOCK
stpt __LC_ASYNC_ENTER_TIMER
stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
- lg %r10,__LC_LAST_BREAK
lg %r12,__LC_CURRENT
larl %r13,cleanup_critical
lmg %r8,%r9,__LC_IO_OLD_PSW
@@ -750,7 +730,6 @@ ENTRY(ext_int_handler)
STCK __LC_INT_CLOCK
stpt __LC_ASYNC_ENTER_TIMER
stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
- lg %r10,__LC_LAST_BREAK
lg %r12,__LC_CURRENT
larl %r13,cleanup_critical
lmg %r8,%r9,__LC_EXT_OLD_PSW
@@ -893,7 +872,6 @@ ENTRY(mcck_int_handler)
la %r1,4095 # revalidate r1
spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer
lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
- lg %r10,__LC_LAST_BREAK
lg %r12,__LC_CURRENT
larl %r13,cleanup_critical
lmg %r8,%r9,__LC_MCK_OLD_PSW
@@ -1088,9 +1066,10 @@ cleanup_critical:
0: # check if base register setup + TIF bit load has been done
clg %r9,BASED(.Lcleanup_system_call_insn+16)
jhe 0f
- # set up saved registers r10 and r12
- stg %r10,16(%r11) # r10 last break
- stg %r12,32(%r11) # r12 task struct pointer
+ # set up saved register r12 task struct pointer
+ stg %r12,32(%r11)
+ # set up saved register r13 __TASK_thread offset
+ mvc 40(8,%r11),BASED(.Lcleanup_system_call_const)
0: # check if the user time update has been done
clg %r9,BASED(.Lcleanup_system_call_insn+24)
jh 0f
@@ -1107,14 +1086,7 @@ cleanup_critical:
stg %r15,__LC_SYSTEM_TIMER
0: # update accounting time stamp
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
- # do LAST_BREAK
- lg %r9,16(%r11)
- srag %r9,%r9,23
- jz 0f
- lgr %r9,%r12
- aghi %r9,__TASK_thread
- mvc __THREAD_last_break(8,%r9),16(%r11)
-0: # set up saved register r11
+ # set up saved register r11
lg %r15,__LC_KERNEL_STACK
la %r9,STACK_FRAME_OVERHEAD(%r15)
stg %r9,24(%r11) # r11 pt_regs pointer
@@ -1136,6 +1108,8 @@ cleanup_critical:
.quad .Lsysc_per
.quad .Lsysc_vtime+36
.quad .Lsysc_vtime+42
+.Lcleanup_system_call_const:
+ .quad __TASK_thread
.Lcleanup_sysc_tif:
larl %r9,.Lsysc_tif