Kernel KVM virtualization development
 help / color / mirror / Atom feed
* [PATCH v6 0/3] vhost: fix device IOTLB feature lifecycle
@ 2026-08-18  4:26 Jia Jia
  2026-08-18  4:26 ` [PATCH v6 1/3] vhost: invalidate vring access on IOTLB transitions Jia Jia
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Jia Jia @ 2026-08-18  4:26 UTC (permalink / raw)
  To: mst
  Cc: jasowangio, eperezma, stefanha, sgarzare, weiyj.lk, kvm,
	virtualization, netdev, linux-kernel, Jia Jia

Both vhost-vsock and vhost-net can leave the device IOTLB attached when
userspace clears VIRTIO_F_ACCESS_PLATFORM. They can also replace an
existing IOTLB with a new empty table when a later feature update keeps
ACCESS_PLATFORM enabled, for example when updating logging.

When the IOTLB mode changes, the vring addresses previously supplied by
userspace no longer have the same address-space meaning. Leaving those
addresses installed would allow an old IOVA to be used as a direct
userspace address after the IOTLB is detached.

This series invalidates the vring access state during IOTLB transitions,
makes IOTLB initialization idempotent, and uses a common teardown helper
for vhost-vsock and vhost-net. IOTLB mode changes are applied even while a
virtqueue backend is attached. The device-wide IOTLB is dropped first, each
virtqueue then clears its IOTLB pointer and cached ring access under its own
mutex, and the old table is freed only after every virtqueue has completed
the handoff.

A successful live mode change leaves the backend attached but invalidates
the cached vring addresses. Userspace must configure the vring addresses for
the new address mode before data processing can resume. When
ACCESS_PLATFORM is enabled, the usual IOTLB miss/update protocol repopulates
the new table.

Changes since v5:
- invalidate desc, avail, used, logging state, and metadata on IOTLB
  transitions;
- apply IOTLB mode changes while a backend is attached, following the
  per-virtqueue handoff suggested in review;
- apply the IOTLB teardown to vhost-net as well as vhost-vsock.

Jia Jia (3):
  vhost: invalidate vring access on IOTLB transitions
  vhost/vsock: discard IOTLB when ACCESS_PLATFORM is cleared
  vhost/net: discard IOTLB when ACCESS_PLATFORM is cleared

 drivers/vhost/net.c   |  8 ++++++--
 drivers/vhost/vhost.c | 53 ++++++++++++++++++++++++++++++++++++++++-
 drivers/vhost/vhost.h |  1 +
 drivers/vhost/vsock.c | 10 ++++++---
 4 files changed, 66 insertions(+), 6 deletions(-)


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v6 1/3] vhost: invalidate vring access on IOTLB transitions
  2026-08-18  4:26 [PATCH v6 0/3] vhost: fix device IOTLB feature lifecycle Jia Jia
@ 2026-08-18  4:26 ` Jia Jia
  2026-08-18  4:26 ` [PATCH v6 2/3] vhost/vsock: discard IOTLB when ACCESS_PLATFORM is cleared Jia Jia
  2026-08-18  4:26 ` [PATCH v6 3/3] vhost/net: " Jia Jia
  2 siblings, 0 replies; 4+ messages in thread
From: Jia Jia @ 2026-08-18  4:26 UTC (permalink / raw)
  To: mst
  Cc: jasowangio, eperezma, stefanha, sgarzare, weiyj.lk, kvm,
	virtualization, netdev, linux-kernel, Jia Jia

When ACCESS_PLATFORM changes, the addresses cached in desc, avail, and
used change meaning with the address space. Clear the cached vring access
state when the device IOTLB is installed or removed so stale IOVAs cannot
be reused as direct userspace addresses.

Keep device IOTLB initialization idempotent and apply the mode change even
when a virtqueue backend is attached. Drop the device-wide IOTLB first,
then clear each VQ state under its own mutex, and keep the old table alive
until every VQ has completed the handoff.

A successful live mode change leaves the backend attached but invalidates
the cached vring addresses. Userspace must configure the vring addresses
for the new address mode before data processing can resume.

Fixes: 6b1e6cc7855b ("vhost: new device IOTLB API")

Signed-off-by: Jia Jia <physicalmtea@gmail.com>
---
 drivers/vhost/vhost.c | 53 ++++++++++++++++++++++++++++++++++++++++++-
 drivers/vhost/vhost.h |  1 +
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 4c525b3e16ea..9f74537b1c1c 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -344,6 +344,17 @@ static void __vhost_vq_meta_reset(struct vhost_virtqueue *vq)
 		vq->meta_iotlb[j] = NULL;
 }
 
+/* Caller must hold the virtqueue mutex. */
+static void vhost_vq_invalidate_access(struct vhost_virtqueue *vq)
+{
+	vq->desc = NULL;
+	vq->avail = NULL;
+	vq->used = NULL;
+	vq->log_used = false;
+	vq->log_addr = -1ull;
+	__vhost_vq_meta_reset(vq);
+}
+
 static void vhost_vq_meta_reset(struct vhost_dev *d)
 {
 	int i;
@@ -1911,6 +1922,9 @@ int vq_meta_prefetch(struct vhost_virtqueue *vq)
 {
 	unsigned int num = vq->num;
 
+	if (!vq->desc || !vq->avail || !vq->used)
+		return 0;
+
 	if (!vq->iotlb)
 		return 1;
 
@@ -2270,11 +2284,48 @@ long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *arg
 }
 EXPORT_SYMBOL_GPL(vhost_vring_ioctl);
 
+/* Caller must hold the device mutex. */
+void vhost_clear_device_iotlb(struct vhost_dev *d)
+{
+	struct vhost_iotlb *iotlb;
+	int i;
+
+	iotlb = d->iotlb;
+	if (!iotlb)
+		return;
+
+	/*
+	 * Drop the device-wide view first.  Each VQ then drops its
+	 * per-VQ view and its cached ring access under its own mutex.
+	 * Keep the old table alive until every VQ has completed this
+	 * handoff, since a worker may still be using it while waiting
+	 * for its VQ mutex.
+	 */
+	d->iotlb = NULL;
+
+	for (i = 0; i < d->nvqs; ++i) {
+		struct vhost_virtqueue *vq = d->vqs[i];
+
+		mutex_lock(&vq->mutex);
+		vq->iotlb = NULL;
+		vhost_vq_invalidate_access(vq);
+		mutex_unlock(&vq->mutex);
+	}
+
+	vhost_clear_msg(d);
+	vhost_iotlb_free(iotlb);
+	wake_up_interruptible_poll(&d->wait, EPOLLIN | EPOLLRDNORM);
+}
+EXPORT_SYMBOL_GPL(vhost_clear_device_iotlb);
+
 int vhost_init_device_iotlb(struct vhost_dev *d)
 {
 	struct vhost_iotlb *niotlb, *oiotlb;
 	int i;
 
+	if (d->iotlb)
+		return 0;
+
 	niotlb = iotlb_alloc();
 	if (!niotlb)
 		return -ENOMEM;
@@ -2287,7 +2338,7 @@ int vhost_init_device_iotlb(struct vhost_dev *d)
 
 		mutex_lock(&vq->mutex);
 		vq->iotlb = niotlb;
-		__vhost_vq_meta_reset(vq);
+		vhost_vq_invalidate_access(vq);
 		mutex_unlock(&vq->mutex);
 	}
 
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 0192ade6e749..3c75e8089373 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -277,6 +277,7 @@ ssize_t vhost_chr_read_iter(struct vhost_dev *dev, struct iov_iter *to,
 			    int noblock);
 ssize_t vhost_chr_write_iter(struct vhost_dev *dev,
 			     struct iov_iter *from);
+void vhost_clear_device_iotlb(struct vhost_dev *d);
 int vhost_init_device_iotlb(struct vhost_dev *d);
 
 void vhost_iotlb_map_free(struct vhost_iotlb *iotlb,


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v6 2/3] vhost/vsock: discard IOTLB when ACCESS_PLATFORM is cleared
  2026-08-18  4:26 [PATCH v6 0/3] vhost: fix device IOTLB feature lifecycle Jia Jia
  2026-08-18  4:26 ` [PATCH v6 1/3] vhost: invalidate vring access on IOTLB transitions Jia Jia
@ 2026-08-18  4:26 ` Jia Jia
  2026-08-18  4:26 ` [PATCH v6 3/3] vhost/net: " Jia Jia
  2 siblings, 0 replies; 4+ messages in thread
From: Jia Jia @ 2026-08-18  4:26 UTC (permalink / raw)
  To: mst
  Cc: jasowangio, eperezma, stefanha, sgarzare, weiyj.lk, kvm,
	virtualization, netdev, linux-kernel, Jia Jia

Clear the device IOTLB when userspace clears VIRTIO_F_ACCESS_PLATFORM.
Otherwise descriptor translation can continue to use mappings installed
before the feature change.

The common helper invalidates cached vring access and applies the
transition even while a backend is attached. The backend remains attached,
but userspace must configure the vring addresses for the new address mode
after a successful live transition.

Fixes: e13a6915a03f ("vhost/vsock: add IOTLB API support")

Suggested-by: Michael S. Tsirkin <mst@redhat.com>

Signed-off-by: Jia Jia <physicalmtea@gmail.com>
---
 drivers/vhost/vsock.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 9aaab6bb8061..77a5a6775c86 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -854,6 +854,7 @@ static int vhost_vsock_set_cid(struct vhost_vsock *vsock, u64 guest_cid)
 static int vhost_vsock_set_features(struct vhost_vsock *vsock, u64 features)
 {
 	struct vhost_virtqueue *vq;
+	int ret = -EFAULT;
 	int i;
 
 	if (features & ~VHOST_VSOCK_FEATURES)
@@ -865,9 +866,12 @@ static int vhost_vsock_set_features(struct vhost_vsock *vsock, u64 features)
 		goto err;
 	}
 
-	if ((features & (1ULL << VIRTIO_F_ACCESS_PLATFORM))) {
-		if (vhost_init_device_iotlb(&vsock->dev))
+	if (features & (1ULL << VIRTIO_F_ACCESS_PLATFORM)) {
+		ret = vhost_init_device_iotlb(&vsock->dev);
+		if (ret)
 			goto err;
+	} else {
+		vhost_clear_device_iotlb(&vsock->dev);
 	}
 
 	vsock->seqpacket_allow = features & (1ULL << VIRTIO_VSOCK_F_SEQPACKET);
@@ -883,7 +887,7 @@ static int vhost_vsock_set_features(struct vhost_vsock *vsock, u64 features)
 
 err:
 	mutex_unlock(&vsock->dev.mutex);
-	return -EFAULT;
+	return ret;
 }
 
 static long vhost_vsock_dev_ioctl(struct file *f, unsigned int ioctl,


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v6 3/3] vhost/net: discard IOTLB when ACCESS_PLATFORM is cleared
  2026-08-18  4:26 [PATCH v6 0/3] vhost: fix device IOTLB feature lifecycle Jia Jia
  2026-08-18  4:26 ` [PATCH v6 1/3] vhost: invalidate vring access on IOTLB transitions Jia Jia
  2026-08-18  4:26 ` [PATCH v6 2/3] vhost/vsock: discard IOTLB when ACCESS_PLATFORM is cleared Jia Jia
@ 2026-08-18  4:26 ` Jia Jia
  2 siblings, 0 replies; 4+ messages in thread
From: Jia Jia @ 2026-08-18  4:26 UTC (permalink / raw)
  To: mst
  Cc: jasowangio, eperezma, stefanha, sgarzare, weiyj.lk, kvm,
	virtualization, netdev, linux-kernel, Jia Jia

Apply the common device IOTLB teardown when userspace clears
VIRTIO_F_ACCESS_PLATFORM. This drops stale translations and avoids
rebuilding an existing IOTLB during feature updates that keep
ACCESS_PLATFORM enabled.

The transition invalidates cached vring access even with an attached
backend. The backend remains attached, but userspace must configure the
vring addresses for the new address mode after a successful live
transition.

Fixes: 6b1e6cc7855b ("vhost: new device IOTLB API")

Link: https://lore.kernel.org/all/20260726141158.1652386-1-physicalmtea@gmail.com/

Signed-off-by: Jia Jia <physicalmtea@gmail.com>
---
 drivers/vhost/net.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 77b59f49bddb..64671cf77a35 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -1673,6 +1673,7 @@ static long vhost_net_reset_owner(struct vhost_net *n)
 static int vhost_net_set_features(struct vhost_net *n, const u64 *features)
 {
 	size_t vhost_hlen, sock_hlen, hdr_len;
+	int ret = -EFAULT;
 	int i;
 
 	hdr_len = virtio_features_test_bit(features, VIRTIO_NET_F_MRG_RXBUF) ||
@@ -1701,8 +1702,11 @@ static int vhost_net_set_features(struct vhost_net *n, const u64 *features)
 		goto out_unlock;
 
 	if (virtio_features_test_bit(features, VIRTIO_F_ACCESS_PLATFORM)) {
-		if (vhost_init_device_iotlb(&n->dev))
+		ret = vhost_init_device_iotlb(&n->dev);
+		if (ret)
 			goto out_unlock;
+	} else {
+		vhost_clear_device_iotlb(&n->dev);
 	}
 
 	for (i = 0; i < VHOST_NET_VQ_MAX; ++i) {
@@ -1718,7 +1722,7 @@ static int vhost_net_set_features(struct vhost_net *n, const u64 *features)
 
 out_unlock:
 	mutex_unlock(&n->dev.mutex);
-	return -EFAULT;
+	return ret;
 }
 
 static long vhost_net_set_owner(struct vhost_net *n)


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-08-18  4:27 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-18  4:26 [PATCH v6 0/3] vhost: fix device IOTLB feature lifecycle Jia Jia
2026-08-18  4:26 ` [PATCH v6 1/3] vhost: invalidate vring access on IOTLB transitions Jia Jia
2026-08-18  4:26 ` [PATCH v6 2/3] vhost/vsock: discard IOTLB when ACCESS_PLATFORM is cleared Jia Jia
2026-08-18  4:26 ` [PATCH v6 3/3] vhost/net: " Jia Jia

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox