On 2025/12/04 13:01, Joelle van Dyne wrote:
The problem specifically with how Mesa uses it is that
virtgpu_ioctl_map calls the IOCTL DRM_IOCTL_VIRTGPU_MAP which performs
the VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB with an unaligned offset.
The kernel is the one who determines the offset, not Mesa. And I cannot
blame the kernel either because the virtio specification says nothing
about the alignment requirement.
virtio_gpu_virgl_map_resource_blob does not error and hv_vm_map
returns silently without doing any maps. Once that makes it to Mesa,
it will try to mmap() and then use the region with vector instructions
that are not supported by HVF because HVF does not emulate
instructions when ISV=0 (this was a topic of discussion many times for
other features like TPM emulation).
This explains the situation well. Please add a comment with a similar
explanation and change this to perform the check only if
!IS_ENABLED(HOST_AARCH64) && tcg_enabled() (apparently kvm and whpx[1]
have the same issue) so that it won't break other configurations.
[1]
https://lore.kernel.org/qemu-devel/[email protected]/
Regards,
Akihiko Odaki
On Wed, Dec 3, 2025 at 6:56 PM Akihiko Odaki
<[email protected]> wrote:
On 2025/12/03 13:07, Joelle van Dyne wrote:
Currently if a mapping is not page aligned, it will sliently fail and the
guest, assuming it is mapped, will attempt to access the memory and fail.
This is particularly an issue on macOS when the host page size is 16KiB and
the guest page size is 4KiB.
It should work. If I understand correctly, tcg doesn't care the host
page size. hvf will not call hv_vm_map() for misaligned regions and that
causes Data Abort, but it is handled by QEMU to perform memory access. I
think it needs more debugging.
Regards,
Akihiko Odaki
Signed-off-by: Joelle van Dyne <[email protected]>
---
hw/display/virtio-gpu-virgl.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 20c856c04e..adf02ac22b 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -116,6 +116,20 @@ virtio_gpu_virgl_map_resource_blob(VirtIOGPU *g,
return ret;
}
+ if (!QEMU_IS_ALIGNED((uintptr_t)data, qemu_real_host_page_size())) {
+ virgl_renderer_resource_unmap(res->base.resource_id);
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: address %p is not aligned to page
size\n",
+ __func__, data);
+ return -ENOMEM;
+ }
+
+ if (!QEMU_IS_ALIGNED(size, qemu_real_host_page_size())) {
+ virgl_renderer_resource_unmap(res->base.resource_id);
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: size 0x%llx is not aligned to page
size\n",
+ __func__, size);
+ return -ENOMEM;
+ }
+
vmr = g_new0(struct virtio_gpu_virgl_hostmem_region, 1);
vmr->g = g;