]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: s390: Fix lpsw/e breaking event handling
authorJanosch Frank <frankja@linux.ibm.com>
Mon, 23 Mar 2026 15:35:22 +0000 (15:35 +0000)
committerJanosch Frank <frankja@linux.ibm.com>
Tue, 31 Mar 2026 08:37:06 +0000 (08:37 +0000)
LPSW and LPSWE need to set the gbea on completion but currently don't.
Time to fix this up.

LPSWEY was designed to not set the bear.

Fixes: 48a3e950f4cee ("KVM: s390: Add support for machine checks.")
Reported-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
arch/s390/kvm/priv.c

index a3250ad83a8e869b28f83faf7b0ddd7d158ee7b1..cc0553da14cbbb8a9d0df17d994f441e10df5cf1 100644 (file)
@@ -714,12 +714,13 @@ int kvm_s390_handle_lpsw(struct kvm_vcpu *vcpu)
 {
        psw_t *gpsw = &vcpu->arch.sie_block->gpsw;
        psw32_t new_psw;
-       u64 addr;
+       u64 addr, iaddr;
        int rc;
        u8 ar;
 
        vcpu->stat.instruction_lpsw++;
 
+       iaddr = gpsw->addr - kvm_s390_get_ilen(vcpu);
        if (gpsw->mask & PSW_MASK_PSTATE)
                return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
 
@@ -737,18 +738,20 @@ int kvm_s390_handle_lpsw(struct kvm_vcpu *vcpu)
        gpsw->addr = new_psw.addr & ~PSW32_ADDR_AMODE;
        if (!is_valid_psw(gpsw))
                return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+       vcpu->arch.sie_block->gbea = iaddr;
        return 0;
 }
 
 static int handle_lpswe(struct kvm_vcpu *vcpu)
 {
        psw_t new_psw;
-       u64 addr;
+       u64 addr, iaddr;
        int rc;
        u8 ar;
 
        vcpu->stat.instruction_lpswe++;
 
+       iaddr = vcpu->arch.sie_block->gpsw.addr - kvm_s390_get_ilen(vcpu);
        if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
                return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
 
@@ -761,6 +764,7 @@ static int handle_lpswe(struct kvm_vcpu *vcpu)
        vcpu->arch.sie_block->gpsw = new_psw;
        if (!is_valid_psw(&vcpu->arch.sie_block->gpsw))
                return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+       vcpu->arch.sie_block->gbea = iaddr;
        return 0;
 }