Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34525e1f authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

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: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 3b1bea01
Loading
Loading
Loading
Loading
+12 −38
Original line number Original line Diff line number Diff line
@@ -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