Re: [PATCH v2 3/9] KVM: s390: Fix get_all_floating_irqs()

From: Christoph Schlameuss

Date: Wed Aug 12 2026 - 10:12:16 EST


On Wed Aug 12, 2026 at 12:44 PM CEST, Claudio Imbrenda wrote:
> When attempting to report all pending floating interrupt to userspace,
> the GISA IPM bits are atomically tested and cleared, and the
> corresponding interrupt description is written in the output buffer. If
> the output buffer is too small, an error is returned to userspace, but
> the GISA IPM bits are now lost.
>
> Moreover, the contract of KVM_DEV_FLIC_GET_ALL_IRQS, which is the only
> path to get_all_floating_irqs(), states that:
>
>> All interrupts remain pending, i.e. are not deleted from the list of
>> currently pending interrupts.
>
> Fix by non-destructively testing for the GISA IPM bits.
>
> Fixes: 24160af6cb28 ("KVM: s390: add GISA interrupts to FLIC ioctl interface")
> Signed-off-by: Claudio Imbrenda <imbrenda@xxxxxxxxxxxxx>

Reviewed-by: Christoph Schlameuss <schlameuss@xxxxxxxxxxxxx>

> ---
> arch/s390/kvm/interrupt.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
> index 6b3f97a7513b..61e75d10110e 100644
> --- a/arch/s390/kvm/interrupt.c
> +++ b/arch/s390/kvm/interrupt.c
> @@ -273,6 +273,11 @@ static inline int gisa_tac_ipm_gisc(struct kvm_s390_gisa *gisa, u32 gisc)
> return test_and_clear_bit_inv(IPM_BIT_OFFSET + gisc, (unsigned long *) gisa);
> }
>
> +static inline int gisa_test_ipm_gisc(struct kvm_s390_gisa *gisa, u32 gisc)
> +{
> + return test_bit_inv(IPM_BIT_OFFSET + gisc, (unsigned long *)gisa);
> +}
> +
> static inline unsigned long pending_irqs_no_gisa(struct kvm_vcpu *vcpu)
> {
> unsigned long pending = vcpu->kvm->arch.float_int.pending_irqs |
> @@ -2242,7 +2247,7 @@ static int get_all_floating_irqs(struct kvm *kvm, u8 __user *usrbuf, u64 len)
> ret = -ENOMEM;
> goto out_nolock;
> }
> - if (gisa_tac_ipm_gisc(gi->origin, i)) {
> + if (gisa_test_ipm_gisc(gi->origin, i)) {
> irq = (struct kvm_s390_irq *) &buf[n];
> irq->type = KVM_S390_INT_IO(1, 0, 0, 0);
> irq->u.io.io_int_word = isc_to_int_word(i);