* [PATCH v4 1/3] vhost: add helper to clear device IOTLB
2026-08-14 7:29 [PATCH v4 0/3] vhost/vsock: fix device IOTLB feature lifecycle Jia Jia
@ 2026-08-14 7:29 ` Jia Jia
2026-08-14 7:58 ` Stefano Garzarella
2026-08-14 7:29 ` [PATCH v4 2/3] vhost/vsock: discard IOTLB when ACCESS_PLATFORM is cleared Jia Jia
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Jia Jia @ 2026-08-14 7:29 UTC (permalink / raw)
To: Stefan Hajnoczi, Stefano Garzarella, Michael S . Tsirkin,
Jason Wang
Cc: Eugenio Pérez, kvm, virtualization, netdev, linux-kernel
The device IOTLB is shared by vhost backends, but clearing it requires
dropping each virtqueue's IOTLB pointer and metadata cache before the
old table is freed. Add a common helper for this teardown sequence so
backend-specific feature code only needs to decide when the table must
be cleared.
The caller must hold the device mutex. The helper does not update
acked_features; backends continue to update that state in their own
virtqueue loops.
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
---
drivers/vhost/vhost.c | 24 ++++++++++++++++++++++++
drivers/vhost/vhost.h | 1 +
2 files changed, 25 insertions(+)
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 269efad90369..7eaa61d9ceeb 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -2283,6 +2283,30 @@ long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp)
}
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;
+ 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_meta_reset(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;
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,
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v4 1/3] vhost: add helper to clear device IOTLB
2026-08-14 7:29 ` [PATCH v4 1/3] vhost: add helper to clear device IOTLB Jia Jia
@ 2026-08-14 7:58 ` Stefano Garzarella
0 siblings, 0 replies; 8+ messages in thread
From: Stefano Garzarella @ 2026-08-14 7:58 UTC (permalink / raw)
To: Jia Jia
Cc: Stefan Hajnoczi, Michael S . Tsirkin, Jason Wang,
Eugenio Pérez, kvm, virtualization, netdev, linux-kernel
On Fri, Aug 14, 2026 at 03:29:01PM +0800, Jia Jia wrote:
>The device IOTLB is shared by vhost backends, but clearing it requires
>dropping each virtqueue's IOTLB pointer and metadata cache before the
>old table is freed. Add a common helper for this teardown sequence so
>backend-specific feature code only needs to decide when the table must
>be cleared.
>
>The caller must hold the device mutex. The helper does not update
>acked_features; backends continue to update that state in their own
>virtqueue loops.
>
>Signed-off-by: Jia Jia <physicalmtea@gmail.com>
>---
> drivers/vhost/vhost.c | 24 ++++++++++++++++++++++++
> drivers/vhost/vhost.h | 1 +
> 2 files changed, 25 insertions(+)
>
>diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
>index 269efad90369..7eaa61d9ceeb 100644
>--- a/drivers/vhost/vhost.c
>+++ b/drivers/vhost/vhost.c
>@@ -2283,6 +2283,30 @@ long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp)
> }
> 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;
Should we move the check of `d->iotlb` here? so the callers doesn't need
to access to an internal details.
Stefano
>+
>+ iotlb = d->iotlb;
>+ 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_meta_reset(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;
>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,
>--
>2.34.1
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v4 2/3] vhost/vsock: discard IOTLB when ACCESS_PLATFORM is cleared
2026-08-14 7:29 [PATCH v4 0/3] vhost/vsock: fix device IOTLB feature lifecycle Jia Jia
2026-08-14 7:29 ` [PATCH v4 1/3] vhost: add helper to clear device IOTLB Jia Jia
@ 2026-08-14 7:29 ` Jia Jia
2026-08-14 7:58 ` Stefano Garzarella
2026-08-14 7:29 ` [PATCH v4 3/3] vhost/vsock: keep IOTLB across feature updates Jia Jia
2026-08-14 7:52 ` [PATCH v4 0/3] vhost/vsock: fix device IOTLB feature lifecycle Stefano Garzarella
3 siblings, 1 reply; 8+ messages in thread
From: Jia Jia @ 2026-08-14 7:29 UTC (permalink / raw)
To: Stefan Hajnoczi, Stefano Garzarella, Michael S . Tsirkin,
Jason Wang
Cc: Eugenio Pérez, kvm, virtualization, netdev, linux-kernel
vhost_vsock_set_features() leaves the device IOTLB attached when
userspace clears VIRTIO_F_ACCESS_PLATFORM. Descriptors can therefore
continue to use translations installed before the feature change,
including HVAs made stale by a later memory table update.
Use the common vhost helper to detach the device IOTLB before
acknowledging a feature mask without ACCESS_PLATFORM. The helper clears
each virtqueue's IOTLB pointer and metadata cache under its mutex, then
frees the old IOTLB after all virtqueues have dropped their references.
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 | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 9aaab6bb8061..b69c260eaeff 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -863,7 +863,11 @@ static int vhost_vsock_set_features(struct vhost_vsock *vsock, u64 features)
if ((features & (1 << VHOST_F_LOG_ALL)) &&
!vhost_log_access_ok(&vsock->dev)) {
goto err;
}
+ if (!(features & (1ULL << VIRTIO_F_ACCESS_PLATFORM)) &&
+ vsock->dev.iotlb)
+ vhost_clear_device_iotlb(&vsock->dev);
+
if ((features & (1ULL << VIRTIO_F_ACCESS_PLATFORM))) {
if (vhost_init_device_iotlb(&vsock->dev))
goto err;
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v4 2/3] vhost/vsock: discard IOTLB when ACCESS_PLATFORM is cleared
2026-08-14 7:29 ` [PATCH v4 2/3] vhost/vsock: discard IOTLB when ACCESS_PLATFORM is cleared Jia Jia
@ 2026-08-14 7:58 ` Stefano Garzarella
0 siblings, 0 replies; 8+ messages in thread
From: Stefano Garzarella @ 2026-08-14 7:58 UTC (permalink / raw)
To: Jia Jia
Cc: Stefan Hajnoczi, Michael S . Tsirkin, Jason Wang,
Eugenio Pérez, kvm, virtualization, netdev, linux-kernel
On Fri, Aug 14, 2026 at 03:29:02PM +0800, Jia Jia wrote:
>vhost_vsock_set_features() leaves the device IOTLB attached when
>userspace clears VIRTIO_F_ACCESS_PLATFORM. Descriptors can therefore
>continue to use translations installed before the feature change,
>including HVAs made stale by a later memory table update.
>
>Use the common vhost helper to detach the device IOTLB before
>acknowledging a feature mask without ACCESS_PLATFORM. The helper clears
>each virtqueue's IOTLB pointer and metadata cache under its mutex, then
>frees the old IOTLB after all virtqueues have dropped their references.
>
>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 | 4 ++++
> 1 file changed, 4 insertions(+)
>
>diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
>index 9aaab6bb8061..b69c260eaeff 100644
>--- a/drivers/vhost/vsock.c
>+++ b/drivers/vhost/vsock.c
>@@ -863,7 +863,11 @@ static int vhost_vsock_set_features(struct vhost_vsock *vsock, u64 features)
> if ((features & (1 << VHOST_F_LOG_ALL)) &&
> !vhost_log_access_ok(&vsock->dev)) {
> goto err;
> }
>
>+ if (!(features & (1ULL << VIRTIO_F_ACCESS_PLATFORM)) &&
>+ vsock->dev.iotlb)
>+ vhost_clear_device_iotlb(&vsock->dev);
>+
Why checking the feature again instead of adding an `else if` in the
already existing check?
I mean this...
> if ((features & (1ULL << VIRTIO_F_ACCESS_PLATFORM))) {
> if (vhost_init_device_iotlb(&vsock->dev))
> goto err;
} else if (vsock->dev.iotlb) {
vhost_clear_device_iotlb(&vsock->dev);
}
>-- 2.34.1
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v4 3/3] vhost/vsock: keep IOTLB across feature updates
2026-08-14 7:29 [PATCH v4 0/3] vhost/vsock: fix device IOTLB feature lifecycle Jia Jia
2026-08-14 7:29 ` [PATCH v4 1/3] vhost: add helper to clear device IOTLB Jia Jia
2026-08-14 7:29 ` [PATCH v4 2/3] vhost/vsock: discard IOTLB when ACCESS_PLATFORM is cleared Jia Jia
@ 2026-08-14 7:29 ` Jia Jia
2026-08-14 8:02 ` Stefano Garzarella
2026-08-14 7:52 ` [PATCH v4 0/3] vhost/vsock: fix device IOTLB feature lifecycle Stefano Garzarella
3 siblings, 1 reply; 8+ messages in thread
From: Jia Jia @ 2026-08-14 7:29 UTC (permalink / raw)
To: Stefan Hajnoczi, Stefano Garzarella, Michael S . Tsirkin,
Jason Wang
Cc: Eugenio Pérez, kvm, virtualization, netdev, linux-kernel
VHOST_SET_FEATURES is also used to update logging while a device is
running. When ACCESS_PLATFORM stays enabled, allocating a new empty
IOTLB on every call drops valid translations and forces avoidable
misses.
Initialize the device IOTLB only when one does not already exist.
Fixes: e13a6915a03f ("vhost/vsock: add IOTLB API support")
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
---
drivers/vhost/vsock.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index b69c260eaeff..9142fa1143b2 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -869,6 +869,7 @@ static int vhost_vsock_set_features(struct vhost_vsock *vsock, u64 features)
vsock->dev.iotlb)
vhost_clear_device_iotlb(&vsock->dev);
- if ((features & (1ULL << VIRTIO_F_ACCESS_PLATFORM))) {
+ if ((features & (1ULL << VIRTIO_F_ACCESS_PLATFORM)) &&
+ !vsock->dev.iotlb) {
if (vhost_init_device_iotlb(&vsock->dev))
goto err;
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v4 3/3] vhost/vsock: keep IOTLB across feature updates
2026-08-14 7:29 ` [PATCH v4 3/3] vhost/vsock: keep IOTLB across feature updates Jia Jia
@ 2026-08-14 8:02 ` Stefano Garzarella
0 siblings, 0 replies; 8+ messages in thread
From: Stefano Garzarella @ 2026-08-14 8:02 UTC (permalink / raw)
To: Jia Jia
Cc: Stefan Hajnoczi, Michael S . Tsirkin, Jason Wang,
Eugenio Pérez, kvm, virtualization, netdev, linux-kernel
On Fri, Aug 14, 2026 at 03:29:03PM +0800, Jia Jia wrote:
>VHOST_SET_FEATURES is also used to update logging while a device is
>running. When ACCESS_PLATFORM stays enabled, allocating a new empty
>IOTLB on every call drops valid translations and forces avoidable
>misses.
>
>Initialize the device IOTLB only when one does not already exist.
>
>Fixes: e13a6915a03f ("vhost/vsock: add IOTLB API support")
>Signed-off-by: Jia Jia <physicalmtea@gmail.com>
>---
> drivers/vhost/vsock.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
>diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
>index b69c260eaeff..9142fa1143b2 100644
>--- a/drivers/vhost/vsock.c
>+++ b/drivers/vhost/vsock.c
>@@ -869,6 +869,7 @@ static int vhost_vsock_set_features(struct vhost_vsock *vsock, u64 features)
> vsock->dev.iotlb)
> vhost_clear_device_iotlb(&vsock->dev);
>
Ah, okay, now I see why you did it in the other patch, but if we move
dev.iotlb checks in the functions we can still do that.
>- if ((features & (1ULL << VIRTIO_F_ACCESS_PLATFORM))) {
>+ if ((features & (1ULL << VIRTIO_F_ACCESS_PLATFORM)) &&
>+ !vsock->dev.iotlb) {
> if (vhost_init_device_iotlb(&vsock->dev))
IIUC vhost_init_device_iotlb() handles the case where dev.iotlb is
already initialized and override it. Here we are preventing that.
Will we do the same in vhost-net? If yes, all the callers will call
vhost_init_device_iotlb() with `dev.iotlb` NULL, so should we remove
that behaviour and add the check we are adding here inside the
vhost_init_device_iotlb()?
Or there is an use case where vhost_init_device_iotlb() is called with
an already initialized dev.iotlb ?
Thanks,
Stefano
> goto err;
>--
>2.34.1
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v4 0/3] vhost/vsock: fix device IOTLB feature lifecycle
2026-08-14 7:29 [PATCH v4 0/3] vhost/vsock: fix device IOTLB feature lifecycle Jia Jia
` (2 preceding siblings ...)
2026-08-14 7:29 ` [PATCH v4 3/3] vhost/vsock: keep IOTLB across feature updates Jia Jia
@ 2026-08-14 7:52 ` Stefano Garzarella
3 siblings, 0 replies; 8+ messages in thread
From: Stefano Garzarella @ 2026-08-14 7:52 UTC (permalink / raw)
To: Jia Jia
Cc: Stefan Hajnoczi, Michael S . Tsirkin, Jason Wang,
Eugenio Pérez, kvm, virtualization, netdev, linux-kernel
On Fri, Aug 14, 2026 at 03:29:00PM +0800, Jia Jia wrote:
>vhost-vsock leaves the device IOTLB attached when userspace clears
>VIRTIO_F_ACCESS_PLATFORM. It also replaces an existing IOTLB with an
>empty one whenever a later feature update keeps ACCESS_PLATFORM enabled.
>
>Patch 1 adds a common vhost helper that detaches the device IOTLB from
>all virtqueues, clears their metadata caches, drops queued IOTLB miss
>messages, and frees the old table after all virtqueues have released
>their pointers.
In the v3 you mentioned that this could be used also in vhost-net and
maybe vhost-scsi. Would it be better to include the other patches in
this series as well, since we're basically fixing the same issues, or
have they already been merged?
Thanks,
Stefano
>
>Patch 2 uses the helper when vhost-vsock clears ACCESS_PLATFORM. The
>acked_features update remains in the vhost-vsock-specific loop.
>
>Patch 3 avoids replacing an existing IOTLB when ACCESS_PLATFORM remains
>enabled across a feature update.
>
>Changes since v3:
>- move the IOTLB teardown helper from vhost-vsock into common vhost code
>- keep acked_features updates in the backend-specific loop
>- add the common helper as a separate first patch
>
>Jia Jia (3):
> vhost: add helper to clear device IOTLB
> vhost/vsock: discard IOTLB when ACCESS_PLATFORM is cleared
> vhost/vsock: keep IOTLB across feature updates
>
> drivers/vhost/vhost.c | 24 ++++++++++++++++++++++++
> drivers/vhost/vhost.h | 1 +
> drivers/vhost/vsock.c | 7 ++++++-
> 3 files changed, 31 insertions(+), 1 deletion(-)
>
>--
>2.34.1
>
^ permalink raw reply [flat|nested] 8+ messages in thread