Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: s390: only deliver the set service event bits

The SCLP driver code masks off the last two bits of the parameter [1]
to determine if a read is required, but doesn't care about the
contents of those bits. Meanwhile, the KVM code that delivers
event interrupts masks off those two bits but sends both to the
guest, even if only one was specified by userspace [2].

This works for the driver code, but it means any nuances of those
bits gets lost. Use the event pending mask as an actual mask, and
only send the bit(s) that were specified in the pending interrupt.

[1] Linux: sclp_interrupt_handler() (drivers/s390/char/sclp.c:658)
[2] QEMU: service_interrupt() (hw/s390x/sclp.c:360..363)

Fixes: 0890ddea1a90 ("KVM: s390: protvirt: Add SCLP interrupt handling")
Signed-off-by: Eric Farman <farman@linux.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Link: https://lore.kernel.org/r/20240205214300.1018522-1-farman@linux.ibm.com
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Message-Id: <20240205214300.1018522-1-farman@linux.ibm.com>

authored by

Eric Farman and committed by
Janosch Frank
85a19b30 7b2411e7

+2 -2
+2 -2
arch/s390/kvm/interrupt.c
··· 1031 1031 return 0; 1032 1032 } 1033 1033 ext = fi->srv_signal; 1034 - /* only clear the event bit */ 1034 + /* only clear the event bits */ 1035 1035 fi->srv_signal.ext_params &= ~SCCB_EVENT_PENDING; 1036 1036 clear_bit(IRQ_PEND_EXT_SERVICE_EV, &fi->pending_irqs); 1037 1037 spin_unlock(&fi->lock); ··· 1041 1041 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_SERVICE, 1042 1042 ext.ext_params, 0); 1043 1043 1044 - return write_sclp(vcpu, SCCB_EVENT_PENDING); 1044 + return write_sclp(vcpu, ext.ext_params & SCCB_EVENT_PENDING); 1045 1045 } 1046 1046 1047 1047 static int __must_check __deliver_pfault_done(struct kvm_vcpu *vcpu)