From: Alex Williamson <alex.williamson@redhat.com>
To: stable@vger.kernel.org
Cc: Alex Williamson <alex.williamson@redhat.com>,
sashal@kernel.org, gregkh@linuxfoundation.org,
eric.auger@redhat.com,
Reinette Chatre <reinette.chatre@intel.com>,
Kevin Tian <kevin.tian@intel.com>
Subject: [PATCH 5.10.y 5.4.y 2/6] vfio/pci: Lock external INTx masking ops
Date: Mon, 1 Apr 2024 10:52:56 -0600 [thread overview]
Message-ID: <20240401165302.3699643-3-alex.williamson@redhat.com> (raw)
In-Reply-To: <20240401165302.3699643-1-alex.williamson@redhat.com>
[ Upstream commit 810cd4bb53456d0503cc4e7934e063835152c1b7 ]
Mask operations through config space changes to DisINTx may race INTx
configuration changes via ioctl. Create wrappers that add locking for
paths outside of the core interrupt code.
In particular, irq_type is updated holding igate, therefore testing
is_intx() requires holding igate. For example clearing DisINTx from
config space can otherwise race changes of the interrupt configuration.
This aligns interfaces which may trigger the INTx eventfd into two
camps, one side serialized by igate and the other only enabled while
INTx is configured. A subsequent patch introduces synchronization for
the latter flows.
Cc: <stable@vger.kernel.org>
Fixes: 89e1f7d4c66d ("vfio: Add PCI device driver")
Reported-by: Reinette Chatre <reinette.chatre@intel.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Link: https://lore.kernel.org/r/20240308230557.805580-3-alex.williamson@redhat.com
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
---
drivers/vfio/pci/vfio_pci_intrs.c | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c
index 9e002214a45c..c8afb062df26 100644
--- a/drivers/vfio/pci/vfio_pci_intrs.c
+++ b/drivers/vfio/pci/vfio_pci_intrs.c
@@ -33,11 +33,13 @@ static void vfio_send_intx_eventfd(void *opaque, void *unused)
eventfd_signal(vdev->ctx[0].trigger, 1);
}
-void vfio_pci_intx_mask(struct vfio_pci_device *vdev)
+static void __vfio_pci_intx_mask(struct vfio_pci_device *vdev)
{
struct pci_dev *pdev = vdev->pdev;
unsigned long flags;
+ lockdep_assert_held(&vdev->igate);
+
spin_lock_irqsave(&vdev->irqlock, flags);
/*
@@ -65,6 +67,13 @@ void vfio_pci_intx_mask(struct vfio_pci_device *vdev)
spin_unlock_irqrestore(&vdev->irqlock, flags);
}
+void vfio_pci_intx_mask(struct vfio_pci_device *vdev)
+{
+ mutex_lock(&vdev->igate);
+ __vfio_pci_intx_mask(vdev);
+ mutex_unlock(&vdev->igate);
+}
+
/*
* If this is triggered by an eventfd, we can't call eventfd_signal
* or else we'll deadlock on the eventfd wait queue. Return >0 when
@@ -107,12 +116,21 @@ static int vfio_pci_intx_unmask_handler(void *opaque, void *unused)
return ret;
}
-void vfio_pci_intx_unmask(struct vfio_pci_device *vdev)
+static void __vfio_pci_intx_unmask(struct vfio_pci_device *vdev)
{
+ lockdep_assert_held(&vdev->igate);
+
if (vfio_pci_intx_unmask_handler(vdev, NULL) > 0)
vfio_send_intx_eventfd(vdev, NULL);
}
+void vfio_pci_intx_unmask(struct vfio_pci_device *vdev)
+{
+ mutex_lock(&vdev->igate);
+ __vfio_pci_intx_unmask(vdev);
+ mutex_unlock(&vdev->igate);
+}
+
static irqreturn_t vfio_intx_handler(int irq, void *dev_id)
{
struct vfio_pci_device *vdev = dev_id;
@@ -428,11 +446,11 @@ static int vfio_pci_set_intx_unmask(struct vfio_pci_device *vdev,
return -EINVAL;
if (flags & VFIO_IRQ_SET_DATA_NONE) {
- vfio_pci_intx_unmask(vdev);
+ __vfio_pci_intx_unmask(vdev);
} else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
uint8_t unmask = *(uint8_t *)data;
if (unmask)
- vfio_pci_intx_unmask(vdev);
+ __vfio_pci_intx_unmask(vdev);
} else if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
int32_t fd = *(int32_t *)data;
if (fd >= 0)
@@ -455,11 +473,11 @@ static int vfio_pci_set_intx_mask(struct vfio_pci_device *vdev,
return -EINVAL;
if (flags & VFIO_IRQ_SET_DATA_NONE) {
- vfio_pci_intx_mask(vdev);
+ __vfio_pci_intx_mask(vdev);
} else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
uint8_t mask = *(uint8_t *)data;
if (mask)
- vfio_pci_intx_mask(vdev);
+ __vfio_pci_intx_mask(vdev);
} else if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
return -ENOTTY; /* XXX implement me */
}
--
2.44.0
next prev parent reply other threads:[~2024-04-01 16:53 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-01 16:52 [PATCH 5.10.y 5.4.y 0/6] vfio: Interrupt eventfd hardening for 5.10.y, 5.4.y Alex Williamson
2024-04-01 16:52 ` [PATCH 5.10.y 5.4.y 1/6] vfio/pci: Disable auto-enable of exclusive INTx IRQ Alex Williamson
2024-04-01 16:52 ` Alex Williamson [this message]
2024-04-01 16:52 ` [PATCH 5.10.y 5.4.y 3/6] vfio: Introduce interface to flush virqfd inject workqueue Alex Williamson
2024-04-01 16:52 ` [PATCH 5.10.y 5.4.y 4/6] vfio/pci: Create persistent INTx handler Alex Williamson
2024-04-01 16:52 ` [PATCH 5.10.y 5.4.y 5/6] vfio/platform: Create persistent IRQ handlers Alex Williamson
2024-04-01 16:53 ` [PATCH 5.10.y 6/6] vfio/fsl-mc: Block calling interrupt handler without trigger Alex Williamson
2024-04-05 9:16 ` [PATCH 5.10.y 5.4.y 0/6] vfio: Interrupt eventfd hardening for 5.10.y, 5.4.y Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240401165302.3699643-3-alex.williamson@redhat.com \
--to=alex.williamson@redhat.com \
--cc=eric.auger@redhat.com \
--cc=gregkh@linuxfoundation.org \
--cc=kevin.tian@intel.com \
--cc=reinette.chatre@intel.com \
--cc=sashal@kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox