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

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
......@@ -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
......
......@@ -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
......
......@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment