On Mon, Oct 19, 2026 at 03:14:46PM +0800, Wang Haoran wrote: > Eugenio previously offered some additional suggestions in reply to > my patch email. Should these also be addressed?
The following seems to work for me. Testing would be appreciated. From: Michael S. Tsirkin <[email protected]> Subject: [PATCH v2] vringh: use get_user/put_user in the use_va path getu16_iotlb()/putu16_iotlb() pass the address produced by iotlb_translate() straight to __get_user()/__put_user(), without access_ok checked anywhere. Not good. Switch to get_user()/put_user(), which are always correct, and safer. But the fact is that accessing user memory like this will sometimes (rarely) race with page being swapped out, trigger EFAULT, and it should be retried from a worker, and vdpa_sim currently does not do this. Fixes: 42823a871fd4 ("vringh: support VA with iotlb") Cc: Stefano Garzarella <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> --- Notes (changelog): v1->v2: Use get_user()/put_user() wrapped in pagefault_disable() instead of access_ok() followed by __get_user()/__put_user(); the helpers are reached from BH-disabled sections, and __get_user() is not a valid way around that (David Laight, Linus Torvalds) drivers/vdpa/vdpa_sim/vdpa_sim_blk.c | 2 ++ drivers/vdpa/vdpa_sim/vdpa_sim_net.c | 2 ++ drivers/vhost/vringh.c | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c b/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c index 76dd5b0828d7..325ec8f0ab85 100644 --- a/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c +++ b/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c @@ -347,8 +347,10 @@ static void vdpasim_blk_work(struct vdpasim *vdpasim) smp_wmb(); local_bh_disable(); + pagefault_disable(); if (vringh_need_notify_iotlb(&vq->vring) > 0) vringh_notify(&vq->vring); + pagefault_enable(); local_bh_enable(); if (++reqs > 4) { diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim_net.c b/drivers/vdpa/vdpa_sim/vdpa_sim_net.c index a6514b5ccd86..964cdf422467 100644 --- a/drivers/vdpa/vdpa_sim/vdpa_sim_net.c +++ b/drivers/vdpa/vdpa_sim/vdpa_sim_net.c @@ -77,8 +77,10 @@ static void vdpasim_net_complete(struct vdpasim_virtqueue *vq, size_t len) smp_wmb(); local_bh_disable(); + pagefault_disable(); if (vringh_need_notify_iotlb(&vq->vring) > 0) vringh_notify(&vq->vring); + pagefault_enable(); local_bh_enable(); } diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c index 9066f9f12ba1..74836eb60c7a 100644 --- a/drivers/vhost/vringh.c +++ b/drivers/vhost/vringh.c @@ -1213,7 +1213,7 @@ static inline int getu16_iotlb(const struct vringh *vrh, return ret; if (vrh->use_va) { - ret = __get_user(tmp, (__virtio16 __user *)ivec.iov.iovec[0].iov_base); + ret = get_user(tmp, (__virtio16 __user *)ivec.iov.iovec[0].iov_base); if (ret) return ret; } else { @@ -1251,7 +1251,7 @@ static inline int putu16_iotlb(const struct vringh *vrh, tmp = cpu_to_vringh16(vrh, val); if (vrh->use_va) { - ret = __put_user(tmp, (__virtio16 __user *)ivec.iov.iovec[0].iov_base); + ret = put_user(tmp, (__virtio16 __user *)ivec.iov.iovec[0].iov_base); if (ret) return ret; } else {
