From: Shameer Kolothum <skolothumtho@nvidia.com>
To: <kvm@vger.kernel.org>, <linux-pci@vger.kernel.org>,
<linux-kernel@vger.kernel.org>
Cc: <alex@shazbot.org>, <jgg@ziepe.ca>, <kevin.tian@intel.com>,
<kbusch@meta.com>, <michal.winiarski@intel.com>,
<satyanarayana.k.v.p@intel.com>, <sonangp@nvidia.com>,
<ankita@nvidia.com>, <nathanc@nvidia.com>, <mochs@nvidia.com>,
<skolothumtho@nvidia.com>
Subject: [RFC PATCH v2 04/16] vfio/pci: Gate BAR and ROM access
Date: Tue, 29 Sep 2026 18:32:53 +0100 [thread overview]
Message-ID: <20260929173305.204856-5-skolothumtho@nvidia.com> (raw)
In-Reply-To: <20260929173305.204856-1-skolothumtho@nvidia.com>
Protect the common I/O accessors used for BAR, VGA, port I/O and ioeventfd
accesses with access_srcu. Recovery can then block new accesses and wait
for admitted accesses to finish. Keep user copies outside SRCU so a
userspace fault cannot stall recovery.
Return -EIO before runtime resume if region access is already blocked.
This check avoids waking the device unnecessarily; it does not serialize
runtime resume against recovery. The I/O accessors check the gate again
under SRCU before touching hardware.
Hold one SRCU section across ROM mapping, the buffered hardware read and
unmapping. Copy the snapshot to userspace afterward, so recovery cannot
disable ROM decoding between read chunks or wait for a userspace fault.
Assisted-by: LLM
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
---
drivers/vfio/pci/vfio_pci_core.c | 4 ++++
drivers/vfio/pci/vfio_pci_rdwr.c | 22 ++++++++++++++++++++++
2 files changed, 26 insertions(+)
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 88a78766c178..323038cd0ca5 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -1666,6 +1666,10 @@ static ssize_t vfio_pci_rw(struct vfio_pci_core_device *vdev, char __user *buf,
if (index >= VFIO_PCI_NUM_REGIONS + vdev->num_regions)
return -EINVAL;
+ /* Avoid runtime resume when blocked; region handlers check access again. */
+ if (vdev->pci_recovery_supported && READ_ONCE(vdev->access_blocked))
+ return -EIO;
+
ret = pm_runtime_resume_and_get(&vdev->pdev->dev);
if (ret) {
pci_info_ratelimited(vdev->pdev, "runtime resume failed %d\n",
diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c
index b4f2c9d967dd..40c9dd02c3df 100644
--- a/drivers/vfio/pci/vfio_pci_rdwr.c
+++ b/drivers/vfio/pci/vfio_pci_rdwr.c
@@ -44,10 +44,17 @@
int vfio_pci_core_iowrite##size(struct vfio_pci_core_device *vdev, \
bool test_mem, u##size val, void __iomem *io) \
{ \
+ int idx; \
+ \
+ idx = vfio_pci_core_access_begin(vdev); \
+ if (idx < 0) \
+ return idx; \
+ \
if (test_mem) { \
down_read(&vdev->memory_lock); \
if (!__vfio_pci_memory_enabled(vdev)) { \
up_read(&vdev->memory_lock); \
+ vfio_pci_core_access_end(vdev, idx); \
return -EIO; \
} \
} \
@@ -56,6 +63,7 @@ int vfio_pci_core_iowrite##size(struct vfio_pci_core_device *vdev, \
\
if (test_mem) \
up_read(&vdev->memory_lock); \
+ vfio_pci_core_access_end(vdev, idx); \
\
return 0; \
} \
@@ -70,10 +78,17 @@ VFIO_IOWRITE(64)
int vfio_pci_core_ioread##size(struct vfio_pci_core_device *vdev, \
bool test_mem, u##size *val, void __iomem *io) \
{ \
+ int idx; \
+ \
+ idx = vfio_pci_core_access_begin(vdev); \
+ if (idx < 0) \
+ return idx; \
+ \
if (test_mem) { \
down_read(&vdev->memory_lock); \
if (!__vfio_pci_memory_enabled(vdev)) { \
up_read(&vdev->memory_lock); \
+ vfio_pci_core_access_end(vdev, idx); \
return -EIO; \
} \
} \
@@ -82,6 +97,7 @@ int vfio_pci_core_ioread##size(struct vfio_pci_core_device *vdev, \
\
if (test_mem) \
up_read(&vdev->memory_lock); \
+ vfio_pci_core_access_end(vdev, idx); \
\
return 0; \
} \
@@ -209,6 +225,11 @@ static ssize_t vfio_pci_rom_read(struct vfio_pci_core_device *vdev,
void *data = NULL;
void __iomem *io;
ssize_t ret;
+ int idx;
+
+ idx = vfio_pci_core_access_begin(vdev);
+ if (idx < 0)
+ return idx;
/* Serialize ROM decoding with power-state and other ROM accesses. */
down_write(&vdev->memory_lock);
@@ -272,6 +293,7 @@ static ssize_t vfio_pci_rom_read(struct vfio_pci_core_device *vdev,
iounmap(io);
out_unlock:
up_write(&vdev->memory_lock);
+ vfio_pci_core_access_end(vdev, idx);
if (ret < 0)
goto out_free;
--
2.43.0
next prev parent reply other threads:[~2026-09-29 17:34 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-29 17:32 [RFC PATCH v2 00/16] vfio/pci: Handle PCI error recovery and report state to userspace Shameer Kolothum
2026-09-29 17:32 ` [RFC PATCH v2 01/16] vfio/pci: Add a device access gate Shameer Kolothum
2026-09-29 17:32 ` [RFC PATCH v2 02/16] vfio/pci: Gate config space access Shameer Kolothum
2026-09-29 17:32 ` [RFC PATCH v2 03/16] vfio/pci: Buffer ROM reads before copying to userspace Shameer Kolothum
2026-09-29 17:32 ` Shameer Kolothum [this message]
2026-09-29 17:32 ` [RFC PATCH v2 05/16] vfio/pci: Fail BAR faults while access is blocked Shameer Kolothum
2026-09-29 17:32 ` [RFC PATCH v2 06/16] vfio/pci: Gate interrupt configuration Shameer Kolothum
2026-09-29 17:32 ` [RFC PATCH v2 07/16] vfio/pci: Gate function reset and runtime power management Shameer Kolothum
2026-09-29 17:32 ` [RFC PATCH v2 08/16] vfio/pci: Gate device information queries and DMA-BUF export Shameer Kolothum
2026-09-29 17:32 ` [RFC PATCH v2 09/16] vfio/pci: Add PCI error recovery state Shameer Kolothum
2026-09-29 17:32 ` [RFC PATCH v2 10/16] vfio/pci: Quiesce INTx while access is blocked Shameer Kolothum
2026-09-29 17:33 ` [RFC PATCH v2 11/16] vfio/pci: Add INTx recovery start and finish helpers Shameer Kolothum
2026-09-29 17:33 ` [RFC PATCH v2 12/16] vfio/pci: Restore device state from slot_reset() Shameer Kolothum
2026-09-29 17:33 ` [RFC PATCH v2 13/16] vfio/pci: Complete recovery in resume() Shameer Kolothum
2026-09-29 17:33 ` [RFC PATCH v2 14/16] vfio/pci: Block device access during host recovery Shameer Kolothum
2026-09-29 17:33 ` [RFC PATCH v2 15/16] vfio/pci: Add VFIO_DEVICE_FEATURE_PCI_ERROR_RECOVERY Shameer Kolothum
2026-09-29 17:33 ` [RFC PATCH v2 16/16] vfio/pci: Enable host PCI error recovery for vfio-pci Shameer Kolothum
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=20260929173305.204856-5-skolothumtho@nvidia.com \
--to=skolothumtho@nvidia.com \
--cc=alex@shazbot.org \
--cc=ankita@nvidia.com \
--cc=jgg@ziepe.ca \
--cc=kbusch@meta.com \
--cc=kevin.tian@intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=michal.winiarski@intel.com \
--cc=mochs@nvidia.com \
--cc=nathanc@nvidia.com \
--cc=satyanarayana.k.v.p@intel.com \
--cc=sonangp@nvidia.com \
/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
all inboxes | Powered by JetHome®