>
> On Tue, Aug 18, 2026 at 12:26:11PM +0800, Jia Jia wrote:
> >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")
> >
>
> Please don't leave spaces here!
>
> >Signed-off-by: Jia Jia <[email protected]>
> >---
> > drivers/vhost/vhost.c | 53 ++++++++++++++++++++++++++++++++++++++++++-
> > drivers/vhost/vhost.h | 1 +
> > 2 files changed, 53 insertions(+), 1 deletion(-)
>
>
> This patch doesn't apply, I tried vhost tree, net tree, and master.
> On which tree is this based?
>
> Stefano
>
Thanks for checking. I confirmed that v6 was generated from an older
local linux-next snapshot with local changes on top,
so it does not apply cleanly to the current tree. Sorry for taking up
your time. I will fix this first. Thanks again.
> >
> >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,
> >
>