Commit cfa45c5e authored by Heiko Carstens's avatar Heiko Carstens Committed by Vasily Gorbik
Browse files

s390/base: pass pt_regs to early program check handler



Pass pt_regs to early program check handler like it is done for every
other interrupt and exception handler.

Also the passed pt_regs can be changed by the called function and the
changes register contents and psw contents will be taken into account
when returning. In addition the return psw will not be copied to the
program check old psw in lowcore, but to the usual return psw
location, like it is also done by the regular program check handler.
This allows also to get rid of the code that disabled lowcore
protection when changing the return address.

Reviewed-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent 0741ec11
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -313,7 +313,7 @@ static __always_inline void __noreturn disabled_wait(void)
 * Basic Program Check Handler.
 */
extern void s390_base_pgm_handler(void);
extern void (*s390_base_pgm_handler_fn)(void);
extern void (*s390_base_pgm_handler_fn)(struct pt_regs *regs);

#define ARCH_LOW_ADDRESS_LIMIT	0x7fffffffUL

+16 −6
Original line number Diff line number Diff line
@@ -14,18 +14,28 @@
	GEN_BR_THUNK %r9
	GEN_BR_THUNK %r14

__PT_R0 = __PT_GPRS
__PT_R8 = __PT_GPRS + 64

ENTRY(s390_base_pgm_handler)
	stmg	%r0,%r15,__LC_SAVE_AREA_SYNC
	basr	%r13,0
0:	aghi	%r15,-STACK_FRAME_OVERHEAD
	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
	aghi	%r15,-(STACK_FRAME_OVERHEAD+__PT_SIZE)
	la	%r11,STACK_FRAME_OVERHEAD(%r15)
	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
	stmg	%r0,%r7,__PT_R0(%r11)
	mvc	__PT_PSW(16,%r11),__LC_PGM_OLD_PSW
	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
	lgr	%r2,%r11
	larl	%r1,s390_base_pgm_handler_fn
	lg	%r9,0(%r1)
	ltgr	%r9,%r9
	jz	1f
	BASR_EX	%r14,%r9
	lmg	%r0,%r15,__LC_SAVE_AREA_SYNC
	lpswe	__LC_PGM_OLD_PSW
1:	lpswe	disabled_wait_psw-0b(%r13)
	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
	lpswe	__LC_RETURN_PSW
1:	larl	%r13,disabled_wait_psw
	lpswe	0(%r13)
ENDPROC(s390_base_pgm_handler)

	.align	8
+3 −11
Original line number Diff line number Diff line
@@ -149,22 +149,14 @@ static __init void setup_topology(void)
	topology_max_mnest = max_mnest;
}

static void early_pgm_check_handler(void)
static void early_pgm_check_handler(struct pt_regs *regs)
{
	const struct exception_table_entry *fixup;
	unsigned long cr0, cr0_new;
	unsigned long addr;

	addr = S390_lowcore.program_old_psw.addr;
	fixup = s390_search_extables(addr);
	fixup = s390_search_extables(regs->psw.addr);
	if (!fixup)
		disabled_wait();
	/* Disable low address protection before storing into lowcore. */
	__ctl_store(cr0, 0, 0);
	cr0_new = cr0 & ~(1UL << 28);
	__ctl_load(cr0_new, 0, 0);
	S390_lowcore.program_old_psw.addr = extable_fixup(fixup);
	__ctl_load(cr0, 0, 0);
	regs->psw.addr = extable_fixup(fixup);
}

static noinline __init void setup_lowcore_early(void)