Commit 742aed05 authored by Heiko Carstens's avatar Heiko Carstens Committed by Alexander Gordeev
Browse files

s390/nmi: move storage error checking back to C, enter with DAT on



Checking for storage errors in machine check entry code was done in order
to handle also storage errors on kernel page tables. However this is
extremely unlikely and some basic assumptions what works on machine check
entry are necessary anyway. In order to simplify machine check handling
delay checking for storage errors to C code.
With this also change the machine check new PSW to have DAT on, which
simplifies the entry code even further.

Reviewed-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
parent 506faa5b
Loading
Loading
Loading
Loading
+4 −30
Original line number Diff line number Diff line
@@ -122,24 +122,6 @@ _LPP_OFFSET = __LC_LPP
		    "jnz .+8; .insn rrf,0xb2e80000,0,0,13,0", 82
	.endm

	/*
	 * The CHKSTG macro jumps to the provided label in case the
	 * machine check interruption code reports one of unrecoverable
	 * storage errors:
	 * - Storage error uncorrected
	 * - Storage key error uncorrected
	 * - Storage degradation with Failing-storage-address validity
	 */
	.macro CHKSTG errlabel
	TSTMSK	__LC_MCCK_CODE,(MCCK_CODE_STG_ERROR|MCCK_CODE_STG_KEY_ERROR)
	jnz	\errlabel
	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_STG_DEGRAD
	jz	.Loklabel\@
	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_STG_FAIL_ADDR
	jnz	\errlabel
.Loklabel\@:
	.endm

#if IS_ENABLED(CONFIG_KVM)
	/*
	 * The OUTSIDE macro jumps to the provided label in case the value
@@ -546,26 +528,18 @@ ENTRY(mcck_int_handler)
3:	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID
	jno	.Lmcck_panic
	tmhh	%r8,0x0001		# interrupting from user ?
	jnz	6f
	jnz	.Lmcck_user
	TSTMSK	__LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
	jno	.Lmcck_panic
#if IS_ENABLED(CONFIG_KVM)
	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,6f
	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,.Lmcck_stack
	OUTSIDE	%r9,.Lsie_entry,.Lsie_leave,4f
	oi	__LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
	j	5f
4:	CHKSTG	.Lmcck_panic
5:	larl	%r14,.Lstosm_tmp
	stosm	0(%r14),0x04		# turn dat on, keep irqs off
	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
4:	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
	SIEEXIT
	j	.Lmcck_stack
#endif
6:	CHKSTG	.Lmcck_panic
	larl	%r14,.Lstosm_tmp
	stosm	0(%r14),0x04		# turn dat on, keep irqs off
	tmhh	%r8,0x0001		# interrupting from user ?
	jz	.Lmcck_stack
.Lmcck_user:
	BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
.Lmcck_stack:
	lg	%r15,__LC_MCCK_STACK
+15 −1
Original line number Diff line number Diff line
@@ -487,7 +487,21 @@ int notrace s390_do_machine_check(struct pt_regs *regs)
			mcck->stp_queue |= stp_island_check();
		mcck_pending = 1;
	}

	/*
	 * Reinject storage related machine checks into the guest if they
	 * happen when the guest is running.
	 */
	if (!test_cpu_flag(CIF_MCCK_GUEST)) {
		/* Storage error uncorrected */
		if (mci.se)
			s390_handle_damage();
		/* Storage key-error uncorrected */
		if (mci.ke)
			s390_handle_damage();
		/* Storage degradation */
		if (mci.ds && mci.fa)
			s390_handle_damage();
	}
	if (mci.cp) {
		/* Channel report word pending */
		mcck->channel_report = 1;
+2 −1
Original line number Diff line number Diff line
@@ -437,7 +437,7 @@ static void __init setup_lowcore_dat_off(void)
	lc->svc_new_psw.addr = (unsigned long) system_call;
	lc->program_new_psw.mask = int_psw_mask | PSW_MASK_MCHECK;
	lc->program_new_psw.addr = (unsigned long) pgm_check_handler;
	lc->mcck_new_psw.mask = PSW_KERNEL_BITS;
	lc->mcck_new_psw.mask = int_psw_mask;
	lc->mcck_new_psw.addr = (unsigned long) mcck_int_handler;
	lc->io_new_psw.mask = int_psw_mask | PSW_MASK_MCHECK;
	lc->io_new_psw.addr = (unsigned long) io_int_handler;
@@ -512,6 +512,7 @@ static void __init setup_lowcore_dat_on(void)
	S390_lowcore.external_new_psw.mask |= PSW_MASK_DAT;
	S390_lowcore.svc_new_psw.mask |= PSW_MASK_DAT;
	S390_lowcore.program_new_psw.mask |= PSW_MASK_DAT;
	S390_lowcore.mcck_new_psw.mask |= PSW_MASK_DAT;
	S390_lowcore.io_new_psw.mask |= PSW_MASK_DAT;
	__ctl_set_bit(0, 28);
	__ctl_store(S390_lowcore.cregs_save_area, 0, 15);