aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2017-10-05 02:29:47 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2017-10-25 01:59:30 -0400
commit0a5e2ec2647737907d267c09dc9a25fab1468865 (patch)
treeb6788e55a1560e921419acaea0ed48772b9ed1e6
parentf34157878d3b17641ad2366988600c23c89d98b2 (diff)
s390/kvm: fix detection of guest machine checks
The new detection code for guest machine checks added a check based on %r11 to .Lcleanup_sie to distinguish between normal asynchronous interrupts and machine checks. But the funtion is called from the program check handler as well with an undefined value in %r11. The effect is that all program exceptions pointing to the SIE instruction will set the CIF_MCCK_GUEST bit. The bit stays set for the CPU until the next machine check comes in which will incorrectly be interpreted as a guest machine check. The simplest fix is to stop using .Lcleanup_sie in the program check handler and duplicate a few instructions. Fixes: c929500d7a5a ("s390/nmi: s390: New low level handling for machine check happening in guest") Cc: <stable@vger.kernel.org> # v4.13+ Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/kernel/entry.S7
1 files changed, 5 insertions, 2 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 21900e1cee9c..d185aa3965bf 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -521,12 +521,15 @@ ENTRY(pgm_check_handler)
521 tmhh %r8,0x0001 # test problem state bit 521 tmhh %r8,0x0001 # test problem state bit
522 jnz 2f # -> fault in user space 522 jnz 2f # -> fault in user space
523#if IS_ENABLED(CONFIG_KVM) 523#if IS_ENABLED(CONFIG_KVM)
524 # cleanup critical section for sie64a 524 # cleanup critical section for program checks in sie64a
525 lgr %r14,%r9 525 lgr %r14,%r9
526 slg %r14,BASED(.Lsie_critical_start) 526 slg %r14,BASED(.Lsie_critical_start)
527 clg %r14,BASED(.Lsie_critical_length) 527 clg %r14,BASED(.Lsie_critical_length)
528 jhe 0f 528 jhe 0f
529 brasl %r14,.Lcleanup_sie 529 lg %r14,__SF_EMPTY(%r15) # get control block pointer
530 ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE
531 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
532 larl %r9,sie_exit # skip forward to sie_exit
530#endif 533#endif
5310: tmhh %r8,0x4000 # PER bit set in old PSW ? 5340: tmhh %r8,0x4000 # PER bit set in old PSW ?
532 jnz 1f # -> enabled, can't be a double fault 535 jnz 1f # -> enabled, can't be a double fault