Re: [PATCH v2 6/9] KVM: s390: Fix IRQ injection with SIGP Stop and Store Status

"Christoph Schlameuss" <[email protected]>
Newsgroups org.kernel.vger.linux-kernel,org.kernel.vger.kvm,org.kernel.vger.linux-s390
Message-ID <[email protected]>
On Wed Aug 12, 2026 at 3:11 PM CEST, Claudio Imbrenda wrote:
> On Wed, 12 Aug 2026 14:59:36 +0200
> "Christoph Schlameuss" <[email protected]> wrote:
>
>> On Wed Aug 12, 2026 at 12:44 PM CEST, Claudio Imbrenda wrote:
>> > When __inject_sigp_stop() is called for a Stop and Store Status
>> > operation, if the vCPU is running, the interrupt is marked as pending
>> > and the status is stored by the thread performing the KVM_RUN IOCTL.
>> >
>> > If the vCPU is already stopped, the status is stored immediately.
>> >
>> > Storing the status means writing into userspace, which might fault, and
>> > __inject_sigp_stop() is called from do_inject_vcpu() which in turn is
>> > always called holding a spinlock, which is obviously an issue.
>> >
>> > Fix this by returning -EWOULDBLOCK from __inject_sigp_stop(), and
>> > adding a bool flag to indicate whether a store status is needed. The
>> > callers of do_inject_vcpu() are modified to pass the pointer to the
>> > bool flag; whenever a Store Status operation is needed, the callers can
>> > now perform it outside the spinlock.
>> >
>> > Opportunistically refactor kvm_s390_set_irq_state() to use
>> > scoped_guard() and __free().
>> >
>> > Signed-off-by: Claudio Imbrenda <[email protected]>
>> > ---
>> >  arch/s390/kvm/interrupt.c | 70 +++++++++++++++++++++------------------
>> >  1 file changed, 38 insertions(+), 32 deletions(-)
>> >
>> > diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
>> > index 8e4b88bce31f..6940f4d354e5 100644  
>> 
>> [...]
>> 
>> > @@ -3188,31 +3192,33 @@ int kvm_s390_set_irq_state(struct kvm_vcpu *vcpu, void __user *irqstate, int len
>> >  	if (!buf)
>> >  		return -ENOMEM;
>> >  
>> > -	if (copy_from_user((void *) buf, irqstate, len)) {
>> > -		r = -EFAULT;
>> > -		goto out_free;
>> > -	}
>> > +	if (copy_from_user((void *)buf, irqstate, len))
>> > +		return -EFAULT;
>> >  
>> > -	/*
>> > -	 * Don't allow setting the interrupt state
>> > -	 * when there are already interrupts pending
>> > -	 */
>> > -	spin_lock(&li->lock);
>> > -	if (li->pending_irqs) {
>> > -		r = -EBUSY;
>> > -		goto out_unlock;
>> > -	}
>> > +	scoped_guard(spinlock, &li->lock) {
>> > +		/*
>> > +		 * Don't allow setting the interrupt state
>> > +		 * when there are already interrupts pending
>> > +		 */
>> > +		if (li->pending_irqs)
>> > +			return -EBUSY;
>> >  
>> > -	for (n = 0; n < len / sizeof(*buf); n++) {
>> > -		r = do_inject_vcpu(vcpu, &buf[n]);
>> > -		if (r)
>> > -			break;
>> > +		for (n = 0; n < len / sizeof(*buf); n++) {
>> > +			tmp = false;
>> > +			r = do_inject_vcpu(vcpu, &buf[n], &tmp);
>> > +			if (r == -EWOULDBLOCK && tmp) {
>> > +				storestatus = true;
>> > +				r = 0;
>> > +			}
>> > +			if (r)
>> > +				break;
>> > +		}
>> >  	}
>> >  
>> > -out_unlock:
>> > -	spin_unlock(&li->lock);
>> > -out_free:
>> > -	vfree(buf);
>> > +	if (storestatus) {
>> > +		n = kvm_s390_store_status_unloaded(vcpu, KVM_S390_STORE_STATUS_NOADDR);  
>> 
>> I assume we do not care about loosing n = -EFAULT when we are already on the
>> error path here with r != 0. But are there cases in which we would not want to
>> call kvm_s390_store_status_unloaded() at all here when one of the later
>> do_inject_vcpu() calls failed with a specific error?
>
> no, because the store status should have happened before the failed
> interrupt injections.
>
> The only tricky part is if store status fails, but the other injections
> don't. In that case we should have aborted without injecting the other
> interupts. On the other hand, when the caller receives a -EFAULT it
> will probably just give up on the whole VM.
>

Thanks, that would have been my feeling, just wanted to validate.

Reviewed-by: Christoph Schlameuss <[email protected]>


>> > +		return r ? r : n;
>> > +	}
>> >  
>> >  	return r;
>> >  }  
>> 
>>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.