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>
This commit is contained in:
Martin Schwidefsky 2017-01-25 12:54:17 +01:00
parent 3b1bea0127
commit 34525e1f7e

View File

@ -103,8 +103,7 @@ _PIF_WORK = (_PIF_PER_TRAP)
CHECK_STACK 1<<STACK_SHIFT,\savearea CHECK_STACK 1<<STACK_SHIFT,\savearea
aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
j 3f j 3f
1: LAST_BREAK %r14 1: UPDATE_VTIME %r14,%r15,\timer
UPDATE_VTIME %r14,%r15,\timer
2: lg %r15,__LC_ASYNC_STACK # load async stack 2: lg %r15,__LC_ASYNC_STACK # load async stack
3: la %r11,STACK_FRAME_OVERHEAD(%r15) 3: la %r11,STACK_FRAME_OVERHEAD(%r15)
.endm .endm
@ -121,18 +120,6 @@ _PIF_WORK = (_PIF_PER_TRAP)
mvc __LC_LAST_UPDATE_TIMER(8),\enter_timer mvc __LC_LAST_UPDATE_TIMER(8),\enter_timer
.endm .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 .macro REENABLE_IRQS
stg %r8,__LC_RETURN_PSW stg %r8,__LC_RETURN_PSW
ni __LC_RETURN_PSW,0xbf ni __LC_RETURN_PSW,0xbf
@ -278,15 +265,14 @@ ENTRY(system_call)
stpt __LC_SYNC_ENTER_TIMER stpt __LC_SYNC_ENTER_TIMER
.Lsysc_stmg: .Lsysc_stmg:
stmg %r8,%r15,__LC_SAVE_AREA_SYNC stmg %r8,%r15,__LC_SAVE_AREA_SYNC
lg %r10,__LC_LAST_BREAK
lg %r12,__LC_CURRENT lg %r12,__LC_CURRENT
lghi %r13,__TASK_thread
lghi %r14,_PIF_SYSCALL lghi %r14,_PIF_SYSCALL
.Lsysc_per: .Lsysc_per:
lg %r15,__LC_KERNEL_STACK lg %r15,__LC_KERNEL_STACK
la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
LAST_BREAK %r13
.Lsysc_vtime: .Lsysc_vtime:
UPDATE_VTIME %r10,%r13,__LC_SYNC_ENTER_TIMER UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER
stmg %r0,%r7,__PT_R0(%r11) stmg %r0,%r7,__PT_R0(%r11)
mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
mvc __PT_PSW(16,%r11),__LC_SVC_OLD_PSW mvc __PT_PSW(16,%r11),__LC_SVC_OLD_PSW
@ -294,12 +280,7 @@ ENTRY(system_call)
stg %r14,__PT_FLAGS(%r11) stg %r14,__PT_FLAGS(%r11)
.Lsysc_do_svc: .Lsysc_do_svc:
# load address of system call table # 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) lg %r10,__THREAD_sysc_table(%r13,%r12)
#endif
llgh %r8,__PT_INT_CODE+2(%r11) llgh %r8,__PT_INT_CODE+2(%r11)
slag %r8,%r8,2 # shift and test for svc 0 slag %r8,%r8,2 # shift and test for svc 0
jnz .Lsysc_nr_ok jnz .Lsysc_nr_ok
@ -508,8 +489,7 @@ ENTRY(pgm_check_handler)
1: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC 1: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
j 3f j 3f
2: LAST_BREAK %r14 2: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
lg %r15,__LC_KERNEL_STACK lg %r15,__LC_KERNEL_STACK
lgr %r14,%r12 lgr %r14,%r12
aghi %r14,__TASK_thread # pointer to thread_struct aghi %r14,__TASK_thread # pointer to thread_struct
@ -518,6 +498,7 @@ ENTRY(pgm_check_handler)
jz 3f jz 3f
mvc __THREAD_trap_tdb(256,%r14),0(%r13) mvc __THREAD_trap_tdb(256,%r14),0(%r13)
3: la %r11,STACK_FRAME_OVERHEAD(%r15) 3: la %r11,STACK_FRAME_OVERHEAD(%r15)
stg %r10,__THREAD_last_break(%r14)
stmg %r0,%r7,__PT_R0(%r11) stmg %r0,%r7,__PT_R0(%r11)
mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
stmg %r8,%r9,__PT_PSW(%r11) stmg %r8,%r9,__PT_PSW(%r11)
@ -576,7 +557,6 @@ ENTRY(io_int_handler)
STCK __LC_INT_CLOCK STCK __LC_INT_CLOCK
stpt __LC_ASYNC_ENTER_TIMER stpt __LC_ASYNC_ENTER_TIMER
stmg %r8,%r15,__LC_SAVE_AREA_ASYNC stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
lg %r10,__LC_LAST_BREAK
lg %r12,__LC_CURRENT lg %r12,__LC_CURRENT
larl %r13,cleanup_critical larl %r13,cleanup_critical
lmg %r8,%r9,__LC_IO_OLD_PSW lmg %r8,%r9,__LC_IO_OLD_PSW
@ -750,7 +730,6 @@ ENTRY(ext_int_handler)
STCK __LC_INT_CLOCK STCK __LC_INT_CLOCK
stpt __LC_ASYNC_ENTER_TIMER stpt __LC_ASYNC_ENTER_TIMER
stmg %r8,%r15,__LC_SAVE_AREA_ASYNC stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
lg %r10,__LC_LAST_BREAK
lg %r12,__LC_CURRENT lg %r12,__LC_CURRENT
larl %r13,cleanup_critical larl %r13,cleanup_critical
lmg %r8,%r9,__LC_EXT_OLD_PSW lmg %r8,%r9,__LC_EXT_OLD_PSW
@ -893,7 +872,6 @@ ENTRY(mcck_int_handler)
la %r1,4095 # revalidate r1 la %r1,4095 # revalidate r1
spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer
lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
lg %r10,__LC_LAST_BREAK
lg %r12,__LC_CURRENT lg %r12,__LC_CURRENT
larl %r13,cleanup_critical larl %r13,cleanup_critical
lmg %r8,%r9,__LC_MCK_OLD_PSW 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 0: # check if base register setup + TIF bit load has been done
clg %r9,BASED(.Lcleanup_system_call_insn+16) clg %r9,BASED(.Lcleanup_system_call_insn+16)
jhe 0f jhe 0f
# set up saved registers r10 and r12 # set up saved register r12 task struct pointer
stg %r10,16(%r11) # r10 last break stg %r12,32(%r11)
stg %r12,32(%r11) # r12 task struct pointer # 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 0: # check if the user time update has been done
clg %r9,BASED(.Lcleanup_system_call_insn+24) clg %r9,BASED(.Lcleanup_system_call_insn+24)
jh 0f jh 0f
@ -1107,14 +1086,7 @@ cleanup_critical:
stg %r15,__LC_SYSTEM_TIMER stg %r15,__LC_SYSTEM_TIMER
0: # update accounting time stamp 0: # update accounting time stamp
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
# do LAST_BREAK # set up saved register r11
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
lg %r15,__LC_KERNEL_STACK lg %r15,__LC_KERNEL_STACK
la %r9,STACK_FRAME_OVERHEAD(%r15) la %r9,STACK_FRAME_OVERHEAD(%r15)
stg %r9,24(%r11) # r11 pt_regs pointer stg %r9,24(%r11) # r11 pt_regs pointer
@ -1136,6 +1108,8 @@ cleanup_critical:
.quad .Lsysc_per .quad .Lsysc_per
.quad .Lsysc_vtime+36 .quad .Lsysc_vtime+36
.quad .Lsysc_vtime+42 .quad .Lsysc_vtime+42
.Lcleanup_system_call_const:
.quad __TASK_thread
.Lcleanup_sysc_tif: .Lcleanup_sysc_tif:
larl %r9,.Lsysc_tif larl %r9,.Lsysc_tif