Skip to content

Commit cfa45c5

Browse files
hcahcaVasily Gorbik
authored andcommitted
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: Alexander Gordeev <agordeev@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
1 parent 0741ec1 commit cfa45c5

3 files changed

Lines changed: 20 additions & 18 deletions

File tree

arch/s390/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ static __always_inline void __noreturn disabled_wait(void)
313313
* Basic Program Check Handler.
314314
*/
315315
extern void s390_base_pgm_handler(void);
316-
extern void (*s390_base_pgm_handler_fn)(void);
316+
extern void (*s390_base_pgm_handler_fn)(struct pt_regs *regs);
317317

318318
#define ARCH_LOW_ADDRESS_LIMIT 0x7fffffffUL
319319

arch/s390/kernel/base.S

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,28 @@
1414
GEN_BR_THUNK %r9
1515
GEN_BR_THUNK %r14
1616

17+
__PT_R0 = __PT_GPRS
18+
__PT_R8 = __PT_GPRS + 64
19+
1720
ENTRY(s390_base_pgm_handler)
18-
stmg %r0,%r15,__LC_SAVE_AREA_SYNC
19-
basr %r13,0
20-
0: aghi %r15,-STACK_FRAME_OVERHEAD
21+
stmg %r8,%r15,__LC_SAVE_AREA_SYNC
22+
aghi %r15,-(STACK_FRAME_OVERHEAD+__PT_SIZE)
23+
la %r11,STACK_FRAME_OVERHEAD(%r15)
24+
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
25+
stmg %r0,%r7,__PT_R0(%r11)
26+
mvc __PT_PSW(16,%r11),__LC_PGM_OLD_PSW
27+
mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
28+
lgr %r2,%r11
2129
larl %r1,s390_base_pgm_handler_fn
2230
lg %r9,0(%r1)
2331
ltgr %r9,%r9
2432
jz 1f
2533
BASR_EX %r14,%r9
26-
lmg %r0,%r15,__LC_SAVE_AREA_SYNC
27-
lpswe __LC_PGM_OLD_PSW
28-
1: lpswe disabled_wait_psw-0b(%r13)
34+
mvc __LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
35+
lmg %r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
36+
lpswe __LC_RETURN_PSW
37+
1: larl %r13,disabled_wait_psw
38+
lpswe 0(%r13)
2939
ENDPROC(s390_base_pgm_handler)
3040

3141
.align 8

arch/s390/kernel/early.c

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -149,22 +149,14 @@ static __init void setup_topology(void)
149149
topology_max_mnest = max_mnest;
150150
}
151151

152-
static void early_pgm_check_handler(void)
152+
static void early_pgm_check_handler(struct pt_regs *regs)
153153
{
154154
const struct exception_table_entry *fixup;
155-
unsigned long cr0, cr0_new;
156-
unsigned long addr;
157155

158-
addr = S390_lowcore.program_old_psw.addr;
159-
fixup = s390_search_extables(addr);
156+
fixup = s390_search_extables(regs->psw.addr);
160157
if (!fixup)
161158
disabled_wait();
162-
/* Disable low address protection before storing into lowcore. */
163-
__ctl_store(cr0, 0, 0);
164-
cr0_new = cr0 & ~(1UL << 28);
165-
__ctl_load(cr0_new, 0, 0);
166-
S390_lowcore.program_old_psw.addr = extable_fixup(fixup);
167-
__ctl_load(cr0, 0, 0);
159+
regs->psw.addr = extable_fixup(fixup);
168160
}
169161

170162
static noinline __init void setup_lowcore_early(void)

0 commit comments

Comments
 (0)