On 2026/01/23 15:17, Vivek Kasireddy wrote:
> If the Guest provides a DMA address that is associated with a ram
> device (such as a PCI device region and not its system memory),
> then we can obtain the hva (host virtual address) by invoking
> address_space_translate() followed by memory_region_get_ram_ptr().
>
> This is because the ram device's address space is not accessible
> to virtio-gpu directly and hence dma_memory_map() cannot be used.
This description is a bit confusing.
The first problem is with the phrase "the ram device's address space".
The address space we are dealing with is always
VIRTIO_DEVICE(g)->dma_as. More precisely it is a memory region, not
address space.
The second problem is that it says the ram device's memory region is not
directly accessible. It is usually true, but here we are directly
accessing it anyway because the guest knows how to do so.
Regards,
Akihiko Odaki
> Therefore, we first need to identify the memory region associated
> with the DMA address and add the offset to the pointer returned
> from memory_region_get_ram_ptr() to obtain the host address.
>
> Note that we take a reference on the memory region but we would
> still eventually call dma_memory_unmap() (to unref the mr).
>
> Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
> Cc: Alex Bennée <alex.bennee@linaro.org>
> Cc: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
> Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> Cc: Alex Williamson <alex@shazbot.org>
> Cc: Cédric Le Goater <clg@redhat.com>
> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
> ---
> hw/display/virtio-gpu.c | 21 ++++++++++++++++++---
> 1 file changed, 18 insertions(+), 3 deletions(-)
>
> diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
> index 3d58cebf4b..9930a21317 100644
> --- a/hw/display/virtio-gpu.c
> +++ b/hw/display/virtio-gpu.c
> @@ -798,6 +798,23 @@ static void virtio_gpu_set_scanout_blob(VirtIOGPU *g,
> &fb, res, &ss.r, &cmd->error);
> }
>
> +static void *virtio_gpu_dma_memory_map(VirtIOGPU *g,
> + struct virtio_gpu_ctrl_command *cmd,
> + uint64_t a, hwaddr *len)
> +{
> + MemoryRegion *mr;
> + hwaddr xlat;
> +
> + mr = address_space_translate(VIRTIO_DEVICE(g)->dma_as, a, &xlat, len,
> + DMA_DIRECTION_TO_DEVICE,
> + MEMTXATTRS_UNSPECIFIED);
> + if (memory_region_is_ram(mr)) {
> + memory_region_ref(mr);
> + return memory_region_get_ram_ptr(mr) + xlat;
> + }
> + return NULL;
> +}
> +
> int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
> uint32_t nr_entries, uint32_t offset,
> struct virtio_gpu_ctrl_command *cmd,
> @@ -839,9 +856,7 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
>
> do {
> len = l;
> - map = dma_memory_map(VIRTIO_DEVICE(g)->dma_as, a, &len,
> - DMA_DIRECTION_TO_DEVICE,
> - MEMTXATTRS_UNSPECIFIED);
> + map = virtio_gpu_dma_memory_map(g, cmd, a, &len);
> if (!map) {
> qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for"
> " element %d\n", __func__, e);