Skip to content

Commit c239c83

Browse files
svens-s390hcahca
authored andcommitted
s390/entry: add CIF_SIE flag and remove sie64a() address check
When a program check, interrupt or machine check is triggered, the PSW address is compared to a certain range of the sie64a() function to figure out whether SIE was interrupted and a cleanup of SIE is needed. This doesn't work with kprobes: If kprobes probes an instruction, it copies the instruction to the kprobes instruction page and overwrites the original instruction with an undefind instruction (Opcode 00). When this instruction is hit later, kprobes single-steps the instruction on the kprobes_instruction page. However, if this instruction is a relative branch instruction it will now point to a different location in memory due to being moved to the kprobes instruction page. If the new branch target points into sie64a() the kernel assumes it interrupted SIE when processing the breakpoint and will crash trying to access the SIE control block. Instead of comparing the address, introduce a new CIF_SIE flag which indicates whether SIE was interrupted. Signed-off-by: Sven Schnelle <svens@linux.ibm.com> Suggested-by: Heiko Carstens <hca@linux.ibm.com> Reviewed-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
1 parent 481ec3b commit c239c83

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

arch/s390/include/asm/processor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414

1515
#include <linux/bits.h>
1616

17+
#define CIF_SIE 0 /* CPU needs SIE exit cleanup */
1718
#define CIF_NOHZ_DELAY 2 /* delay HZ disable for a tick */
1819
#define CIF_ENABLED_WAIT 5 /* in enabled wait state */
1920
#define CIF_MCCK_GUEST 6 /* machine check happening in guest */
2021
#define CIF_DEDICATED_CPU 7 /* this CPU is dedicated */
2122

23+
#define _CIF_SIE BIT(CIF_SIE)
2224
#define _CIF_NOHZ_DELAY BIT(CIF_NOHZ_DELAY)
2325
#define _CIF_ENABLED_WAIT BIT(CIF_ENABLED_WAIT)
2426
#define _CIF_MCCK_GUEST BIT(CIF_MCCK_GUEST)

arch/s390/kernel/entry.S

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ _LPP_OFFSET = __LC_LPP
146146
lg %r9,__SF_SIE_CONTROL(%r15) # get control block pointer
147147
ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE
148148
lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce
149+
ni __LC_CPU_FLAGS+7,255-_CIF_SIE
149150
larl %r9,sie_exit # skip forward to sie_exit
150151
.endm
151152
#endif
@@ -214,6 +215,7 @@ SYM_FUNC_START(__sie64a)
214215
lg %r14,__LC_GMAP # get gmap pointer
215216
ltgr %r14,%r14
216217
jz .Lsie_gmap
218+
oi __LC_CPU_FLAGS+7,_CIF_SIE
217219
lctlg %c1,%c1,__GMAP_ASCE(%r14) # load primary asce
218220
.Lsie_gmap:
219221
lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer
@@ -235,6 +237,7 @@ SYM_FUNC_START(__sie64a)
235237
ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE
236238
lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce
237239
.Lsie_done:
240+
ni __LC_CPU_FLAGS+7,255-_CIF_SIE
238241
# some program checks are suppressing. C code (e.g. do_protection_exception)
239242
# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There
240243
# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable.
@@ -346,7 +349,8 @@ SYM_CODE_START(pgm_check_handler)
346349
.Lpgm_skip_asce:
347350
#if IS_ENABLED(CONFIG_KVM)
348351
# cleanup critical section for program checks in __sie64a
349-
OUTSIDE %r9,.Lsie_gmap,.Lsie_done,1f
352+
TSTMSK __LC_CPU_FLAGS,_CIF_SIE
353+
jz 1f
350354
BPENTER __SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
351355
SIEEXIT
352356
lghi %r10,_PIF_GUEST_FAULT
@@ -416,7 +420,8 @@ SYM_CODE_START(\name)
416420
tmhh %r8,0x0001 # interrupting from user ?
417421
jnz 1f
418422
#if IS_ENABLED(CONFIG_KVM)
419-
OUTSIDE %r9,.Lsie_gmap,.Lsie_done,0f
423+
TSTMSK __LC_CPU_FLAGS,_CIF_SIE
424+
jz 0f
420425
BPENTER __SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
421426
SIEEXIT
422427
#endif
@@ -513,7 +518,13 @@ SYM_CODE_START(mcck_int_handler)
513518
TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
514519
jno .Lmcck_panic
515520
#if IS_ENABLED(CONFIG_KVM)
516-
OUTSIDE %r9,.Lsie_gmap,.Lsie_done,.Lmcck_user
521+
TSTMSK __LC_CPU_FLAGS,_CIF_SIE
522+
jz .Lmcck_user
523+
# Need to compare the address instead of a CIF_SIE* flag.
524+
# Otherwise there would be a race between setting the flag
525+
# and entering SIE (or leaving and clearing the flag). This
526+
# would cause machine checks targeted at the guest to be
527+
# handled by the host.
517528
OUTSIDE %r9,.Lsie_entry,.Lsie_leave,4f
518529
oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
519530
4: BPENTER __SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST

0 commit comments

Comments
 (0)