Linux virtualization list
 help / color / mirror / Atom feed
From: Dmitry Osipenko <dmitry.osipenko@collabora.com>
To: benjamin@edera.io, David Airlie <airlied@redhat.com>,
	Gerd Hoffmann <kraxel@redhat.com>,
	Gurchetan Singh <gurchetansingh@chromium.org>,
	Chia-I Wu <olvaffe@gmail.com>,
	Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Maxime Ripard <mripard@kernel.org>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	Simona Vetter <simona@ffwll.ch>
Cc: dri-devel@lists.freedesktop.org, virtualization@lists.linux.dev,
	linux-kernel@vger.kernel.org,
	Sashiko AI review <sashiko-bot@kernel.org>
Subject: Re: [PATCH v4] drm/virtio: sync shmem backing on guest-bound transfers
Date: Sun, 20 Sep 2026 21:22:03 +0300	[thread overview]
Message-ID: <e9c843a9-4703-4a07-af5c-d184e52593a4@collabora.com> (raw)
In-Reply-To: <20260814-virtgpu-from-host-sync-v4-1-64dd736b1779@edera.io>

On 8/15/26 01:20, Benjamin Leggett via B4 Relay wrote:
> From: Benjamin Leggett <benjamin@edera.io>
> 
> virtio_gpu_cmd_transfer_to_host_{2d,3d}() sync the shmem backing for the
> device before the transfer, but nothing syncs for the CPU when a transfer
> runs the other way. That breaks two ways. Where the DMA layer bounces, the
> device writes into the bounce buffer while the guest keeps reading the
> original pages. Where DMA is not coherent, the device writes memory while
> the CPU keeps stale cache lines, because nothing reaches
> arch_sync_dma_for_cpu(). Either way DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST
> hands back stale data.
> 
> Sashiko originally found this in
> https://lore.kernel.org/dri-devel/20260806231002.27B4D1F000E9@smtp.kernel.org
> but the suggestion there to fix this with dma_sync_sgtable_for_cpu()
> isn't a sufficient fix, for two reasons.
> 
> - The transfer is asynchronous. virtio_gpu_cmd_transfer_from_host_3d() only
> queues the command, so a sync there would run before the device had written
> anything. It belongs on completion, and ahead of any fence signalling.
> A waiter woken by the fence would otherwise race the sync and read the
> backing pages regardless. It needs its own pass over the reclaim list
> rather than a step inside the existing one, because
> virtio_gpu_fence_event_process() also signals every earlier fence in the
> same context, so any entry in that loop may signal an earlier entry's
> fence.
> 
> - The transfer is also partial, carrying an offset, a level and a box.
> Where the mapping bounces, a sync for the CPU copies the whole mapping
> back, so unless the mapping is primed first the regions the device did not
> write come back holding whatever the bounce buffer contained, discarding
> data the guest owned.
> 
> So the fix: Prime the mapping before queueing, tag the vbuffer, and sync
> for the CPU on completion before the fence is signalled.
> 
> A second transfer must not snapshot the mapping while an earlier one is
> still in flight, or the snapshot would predate whatever the CPU wrote once
> the earlier fence signalled and the later sync would discard it.
> 
> To mitigate this, wait for outstanding fences under the reservation before
> priming.
> 
> Neither sync copies anything unless the mapping genuinely bounces:
> swiotlb_sync_single_for_cpu() and its Xen counterpart look the address up
> in the bounce pool and return early when it is absent. On a platform with
> non-coherent DMA they still perform the necessary cache maintenance.
> 
> The range cannot be narrowed to the box, since for a non-blob resource
> virtio_gpu_transfer_from_host_ioctl() rejects a caller-supplied stride and
> layer_stride, leaving the layout to the host and the guest with no way to
> work out which bytes the device writes. A host3d guest blob does carry
> both, so its extent could be bounded, but the sync is left whole there too
> rather than special-cased: priming makes the untouched regions round-trip
> unchanged either way.
> 
> Behaviour changes worth noting:
> 
> - TRANSFER_FROM_HOST can now block, where before it returned as soon as the
> command was queued. Repeated readbacks of one resource serialise, and a
> readback can wait behind an earlier queued command that touched it, since
> virtio_gpu_array_add_fence() tags uploads, execbufs and plane flushes
> alike with DMA_RESV_USAGE_WRITE. -ERESTARTSYS was already possible here
> via dma_resv_lock_interruptible().
> 
> - A CPU write racing an in-flight transfer to the same resource is now
> lost, where before it survived and the transfer was lost instead. Priming
> captures the pages as of queueing, so a write landing before completion is
> overwritten by the sync.
> 
> - TRANSFER_TO_HOST can also block now, but only while a guest-bound
> transfer on the same resource is outstanding, which happens only for
> callers that issue both without waiting.
> 
> - Where a batch of completions contains a guest-bound transfer, the sync
> pass delays fence signalling for the whole batch. Only bounced pages are
> copied and the swiotlb pool bounds it. A batch with no such transfer is
> unaffected.
> 
> Tested under QEMU on x86 with swiotlb=force and virtio-vga-gl
> iommu_platform=on, which forces both preconditions required to hit the
> original bug.
> 
> Reported-by: Sashiko AI review <sashiko-bot@kernel.org>
> Closes: https://lore.kernel.org/dri-devel/20260806231002.27B4D1F000E9@smtp.kernel.org/
> Signed-off-by: Benjamin Leggett <benjamin@edera.io>
> ---
> This depends on 6a736d2f9d0c ("drm/virtio: use the DMA API for resource backing on Xen"), currently in
> drm-misc-fixes only, so it needs to go through the same branch.
> ---
> Changes in v4:
> - drm/virtio: use DMA_RESV_USAGE_READ.
> - Link to v3: https://lore.kernel.org/r/20260814-virtgpu-from-host-sync-v3-1-f2538afd7d6e@edera.io
> 
> Changes in v3:
> - drm/virtio: use smp_load_acquire()/smp_store_release().
> - Link to v2: https://lore.kernel.org/r/20260814-virtgpu-from-host-sync-v2-1-fa3910caf3e5@edera.io
> 
> Changes in v2:
> - drm/virtio: add guard on virtio_gpu_transfer_to_host_ioctl.
> - Link to v1: https://lore.kernel.org/r/20260814-virtgpu-from-host-sync-v1-1-814e3afb5b08@edera.io
> ---
>  drivers/gpu/drm/virtio/virtgpu_drv.h   |  5 ++++
>  drivers/gpu/drm/virtio/virtgpu_ioctl.c | 43 +++++++++++++++++++++++++++++++
>  drivers/gpu/drm/virtio/virtgpu_vq.c    | 46 ++++++++++++++++++++++++++++++++++
>  3 files changed, 94 insertions(+)

Applied to misc-fixes, thanks!

-- 
Best regards,
Dmitry

      reply	other threads:[~2026-09-20 18:22 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-14 22:20 [PATCH v4] drm/virtio: sync shmem backing on guest-bound transfers Benjamin Leggett via B4 Relay
2026-09-20 18:22 ` Dmitry Osipenko [this message]

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=e9c843a9-4703-4a07-af5c-d184e52593a4@collabora.com \
    --to=dmitry.osipenko@collabora.com \
    --cc=airlied@redhat.com \
    --cc=benjamin@edera.io \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gurchetansingh@chromium.org \
    --cc=kraxel@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=olvaffe@gmail.com \
    --cc=sashiko-bot@kernel.org \
    --cc=simona@ffwll.ch \
    --cc=tzimmermann@suse.de \
    --cc=virtualization@lists.linux.dev \
    /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