summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorFarhan Ali <alifm@linux.ibm.com>2026-07-23 15:14:08 -0700
committerChristian Borntraeger <borntraeger@linux.ibm.com>2026-07-24 11:26:54 +0200
commit5580c9858f1e00f60191eb09c3add359836d60b6 (patch)
treeff47d387fe9b25c714ec5cc600204f41c431ee8e /arch
parent8bf09b9b7d3232806df95f409581f8a9fd99a3fa (diff)
downloadlinux-next-5580c9858f1e00f60191eb09c3add359836d60b6.tar.gz
linux-next-5580c9858f1e00f60191eb09c3add359836d60b6.zip
KVM: s390: pci: Fix resource leak on IRQ registration failure
Currently if kvm_zpci_set_airq() fails, kvm_s390_pci_aif_enable() returns the error code but doesn't do any resource cleanup thus leaking resources. Fix this by cleaning up all the resources such as the GAITE, AIBV, AISB and unpinning any pinned pages. While at it, remove dead code that stored FIB values that were never referenced. As part of the cleanup, we are also holding the aift_lock a bit longer, as we hold the lock while executing the MPCIFC instruction. Though this is not strictly necessary, it means we don't have to drop and re-acquire in the error case. Fixes: 3c5a1b6f0a18 ("KVM: s390: pci: provide routines for enabling/disabling interrupt forwarding") Cc: stable@vger.kernel.org Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com> Reviewed-by: Christian Borntraeger <borntraeger@linux.ibm.com> Signed-off-by: Farhan Ali <alifm@linux.ibm.com> Tested-by: Matthew Rosato <mjrosato@linux.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/kvm/pci.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/arch/s390/kvm/pci.c b/arch/s390/kvm/pci.c
index 1eb127fc9f89..50f495bc8303 100644
--- a/arch/s390/kvm/pci.c
+++ b/arch/s390/kvm/pci.c
@@ -344,19 +344,32 @@ static int kvm_s390_pci_aif_enable(struct zpci_dev *zdev, struct zpci_fib *fib,
aift->kzdev[zdev->aisb] = zdev->kzdev;
spin_unlock_irq(&aift->gait_lock);
- /* Update guest FIB for re-issue */
- fib->fmt0.aisbo = zdev->aisb & 63;
- fib->fmt0.aisb = virt_to_phys(aift->sbv->vector) + (zdev->aisb / 64) * 8;
- fib->fmt0.isc = gisc;
-
/* Save some guest fib values in the host for later use */
- zdev->kzdev->fib.fmt0.isc = fib->fmt0.isc;
+ zdev->kzdev->fib.fmt0.isc = gisc;
zdev->kzdev->fib.fmt0.aibv = fib->fmt0.aibv;
- mutex_unlock(&aift->aift_lock);
/* Issue the clp to setup the irq now */
rc = kvm_zpci_set_airq(zdev);
- return rc;
+ if (!rc) {
+ mutex_unlock(&aift->aift_lock);
+ return rc;
+ }
+
+ /* Start cleanup */
+ zdev->kzdev->fib.fmt0.isc = 0;
+ zdev->kzdev->fib.fmt0.aibv = 0;
+
+ spin_lock_irq(&aift->gait_lock);
+ gaite->count--;
+ gaite->aisb = 0;
+ gaite->gisc = 0;
+ gaite->aisbo = 0;
+ gaite->gisa = 0;
+ aift->kzdev[zdev->aisb] = NULL;
+ spin_unlock_irq(&aift->gait_lock);
+
+ airq_iv_release(zdev->aibv);
+ zdev->aibv = NULL;
free_aisb:
airq_iv_free_bit(aift->sbv, zdev->aisb);