From b4dff4441612c326edb7e50919e17c76657cc3b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Fri, 15 Dec 2023 12:02:14 +0100 Subject: [PATCH] qemu-wayland: add patch to fix vulkaninfo --- ...-t-clone-wayland-memfd-file-descript.patch | 6 +- ...er-ugly-workaround-to-get-private-ke.patch | 6 +- ...-stale-cross-domain-keymap-resources.patch | 204 ++++++++++++++++++ pkgs/rutabaga-gfx-ffi/default.nix | 1 + 4 files changed, 211 insertions(+), 6 deletions(-) create mode 100644 pkgs/rutabaga-gfx-ffi/0003-rutabaga_gfx-fix-stale-cross-domain-keymap-resources.patch diff --git a/pkgs/rutabaga-gfx-ffi/0001-rutabaga_gfx-don-t-clone-wayland-memfd-file-descript.patch b/pkgs/rutabaga-gfx-ffi/0001-rutabaga_gfx-don-t-clone-wayland-memfd-file-descript.patch index c4b36826e..2bcd72af0 100644 --- a/pkgs/rutabaga-gfx-ffi/0001-rutabaga_gfx-don-t-clone-wayland-memfd-file-descript.patch +++ b/pkgs/rutabaga-gfx-ffi/0001-rutabaga_gfx-don-t-clone-wayland-memfd-file-descript.patch @@ -1,7 +1,7 @@ -From 91ad77f0d41ce7043a0bc4cfc3887d64b9763ba9 Mon Sep 17 00:00:00 2001 +From 7ca362d01f265ef7eac0532e0e2b3b8acce1287c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Thu, 7 Dec 2023 17:09:28 +0100 -Subject: [PATCH 1/2] rutabaga_gfx: don't clone wayland memfd file descriptor +Subject: [PATCH 1/3] rutabaga_gfx: don't clone wayland memfd file descriptor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -51,7 +51,7 @@ index d15fe81bd..885c6c9d8 100644 map_info: u32, ) -> RutabagaResult { diff --git a/rutabaga_gfx/src/rutabaga_os/sys/linux/memory_mapping.rs b/rutabaga_gfx/src/rutabaga_os/sys/linux/memory_mapping.rs -index 629e4f9e7..e16c32747 100644 +index 73e5db169..f18e3b80a 100644 --- a/rutabaga_gfx/src/rutabaga_os/sys/linux/memory_mapping.rs +++ b/rutabaga_gfx/src/rutabaga_os/sys/linux/memory_mapping.rs @@ -38,7 +38,7 @@ fn drop(&mut self) { diff --git a/pkgs/rutabaga-gfx-ffi/0002-rutabaga_gfx-super-ugly-workaround-to-get-private-ke.patch b/pkgs/rutabaga-gfx-ffi/0002-rutabaga_gfx-super-ugly-workaround-to-get-private-ke.patch index e78110dc8..ef184a209 100644 --- a/pkgs/rutabaga-gfx-ffi/0002-rutabaga_gfx-super-ugly-workaround-to-get-private-ke.patch +++ b/pkgs/rutabaga-gfx-ffi/0002-rutabaga_gfx-super-ugly-workaround-to-get-private-ke.patch @@ -1,7 +1,7 @@ -From d0173b741cface0b49fc105bd66dc8c8d9276591 Mon Sep 17 00:00:00 2001 +From 76c69111118b9a63cde378f754897f8bdaf123dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Thu, 7 Dec 2023 18:45:37 +0100 -Subject: [PATCH 2/2] rutabaga_gfx: super ugly workaround to get private +Subject: [PATCH 2/3] rutabaga_gfx: super ugly workaround to get private keyboard resources forwarded MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -13,7 +13,7 @@ Signed-off-by: Jörg Thalheim 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/rutabaga_gfx/src/rutabaga_os/sys/linux/memory_mapping.rs b/rutabaga_gfx/src/rutabaga_os/sys/linux/memory_mapping.rs -index e16c32747..b37e2c351 100644 +index f18e3b80a..fe5eb684e 100644 --- a/rutabaga_gfx/src/rutabaga_os/sys/linux/memory_mapping.rs +++ b/rutabaga_gfx/src/rutabaga_os/sys/linux/memory_mapping.rs @@ -9,6 +9,7 @@ diff --git a/pkgs/rutabaga-gfx-ffi/0003-rutabaga_gfx-fix-stale-cross-domain-keymap-resources.patch b/pkgs/rutabaga-gfx-ffi/0003-rutabaga_gfx-fix-stale-cross-domain-keymap-resources.patch new file mode 100644 index 000000000..b8995b3ef --- /dev/null +++ b/pkgs/rutabaga-gfx-ffi/0003-rutabaga_gfx-fix-stale-cross-domain-keymap-resources.patch @@ -0,0 +1,204 @@ +From 37d51bb5bcf329bd098a0365dcbfbafc2222fddf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= +Date: Thu, 14 Dec 2023 14:54:51 +0100 +Subject: [PATCH 3/3] rutabaga_gfx: fix stale cross-domain keymap resources +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +when running vulkaninfo and other apps it seems that this resource +is requested multiple times and it fails after the first time. +After this patch vulkaninfo no longer produces any qemu errors. + +Signed-off-by: Jörg Thalheim +--- + rutabaga_gfx/src/cross_domain/mod.rs | 155 ++++++++++++--------------- + 1 file changed, 68 insertions(+), 87 deletions(-) + +diff --git a/rutabaga_gfx/src/cross_domain/mod.rs b/rutabaga_gfx/src/cross_domain/mod.rs +index 6eb7ec988..34b51d4da 100644 +--- a/rutabaga_gfx/src/cross_domain/mod.rs ++++ b/rutabaga_gfx/src/cross_domain/mod.rs +@@ -69,7 +69,7 @@ pub enum CrossDomainToken { + + pub(crate) enum CrossDomainItem { + ImageRequirements(ImageMemoryRequirements), +- WaylandKeymap(SafeDescriptor), ++ WaylandKeymap(Arc), + #[allow(dead_code)] // `WaylandReadPipe` is never constructed on Windows. + WaylandReadPipe(File), + WaylandWritePipe(File), +@@ -340,7 +340,10 @@ fn handle_fence( + *identifier = match *identifier_type { + CROSS_DOMAIN_ID_TYPE_VIRTGPU_BLOB => add_item( + &self.item_state, +- CrossDomainItem::WaylandKeymap(file.into()), ++ CrossDomainItem::WaylandKeymap(Arc::new(RutabagaHandle { ++ os_handle: file.into(), ++ handle_type: RUTABAGA_MEM_HANDLE_TYPE_SHM, ++ })), + ), + CROSS_DOMAIN_ID_TYPE_WRITE_PIPE => add_item( + &self.item_state, +@@ -670,95 +673,73 @@ fn context_create_blob( + ) -> RutabagaResult { + let item_id = resource_create_blob.blob_id as u32; + +- // We don't want to remove requirements blobs, since they can be used for subsequent +- // allocations. We do want to remove Wayland keymaps, since they are mapped the guest +- // and then never used again. The current protocol encodes this as divisiblity by 2. +- if item_id % 2 == 0 { +- let items = self.item_state.lock().unwrap(); +- let item = items +- .table +- .get(&item_id) +- .ok_or(RutabagaError::InvalidCrossDomainItemId)?; +- +- match item { +- CrossDomainItem::ImageRequirements(reqs) => { +- if reqs.size != resource_create_blob.size { +- return Err(RutabagaError::SpecViolation("blob size mismatch")); +- } +- +- // Strictly speaking, it's against the virtio-gpu spec to allocate memory in the context +- // create blob function, which says "the actual allocation is done via +- // VIRTIO_GPU_CMD_SUBMIT_3D." However, atomic resource creation is easiest for the +- // cross-domain use case, so whatever. +- let hnd = match handle_opt { +- Some(handle) => handle, +- None => self.gralloc.lock().unwrap().allocate_memory(*reqs)?, +- }; +- +- let info_3d = Resource3DInfo { +- width: reqs.info.width, +- height: reqs.info.height, +- drm_fourcc: reqs.info.drm_format.into(), +- strides: reqs.strides, +- offsets: reqs.offsets, +- modifier: reqs.modifier, +- guest_cpu_mappable: (resource_create_blob.blob_flags +- & RUTABAGA_BLOB_FLAG_USE_MAPPABLE) +- != 0, +- }; ++ let items = self.item_state.lock().unwrap(); ++ let item = items ++ .table ++ .get(&item_id) ++ .ok_or(RutabagaError::InvalidCrossDomainItemId)?; + +- Ok(RutabagaResource { +- resource_id, +- handle: Some(Arc::new(hnd)), +- blob: true, +- blob_mem: resource_create_blob.blob_mem, +- blob_flags: resource_create_blob.blob_flags, +- map_info: Some(reqs.map_info | RUTABAGA_MAP_ACCESS_RW), +- info_2d: None, +- info_3d: Some(info_3d), +- vulkan_info: reqs.vulkan_info, +- backing_iovecs: None, +- component_mask: 1 << (RutabagaComponentType::CrossDomain as u8), +- size: resource_create_blob.size, +- mapping: None, +- }) +- } +- _ => Err(RutabagaError::InvalidCrossDomainItemType), ++ match item { ++ CrossDomainItem::WaylandKeymap(handle) => { ++ Ok(RutabagaResource { ++ resource_id, ++ handle: Some(Arc::clone(handle)), ++ blob: true, ++ blob_mem: resource_create_blob.blob_mem, ++ blob_flags: resource_create_blob.blob_flags, ++ map_info: Some(RUTABAGA_MAP_CACHE_CACHED | RUTABAGA_MAP_ACCESS_READ), ++ info_2d: None, ++ info_3d: None, ++ vulkan_info: None, ++ backing_iovecs: None, ++ component_mask: 1 << (RutabagaComponentType::CrossDomain as u8), ++ size: resource_create_blob.size, ++ mapping: None, ++ }) + } +- } else { +- let item = self +- .item_state +- .lock() +- .unwrap() +- .table +- .remove(&item_id) +- .ok_or(RutabagaError::InvalidCrossDomainItemId)?; +- +- match item { +- CrossDomainItem::WaylandKeymap(descriptor) => { +- let hnd = RutabagaHandle { +- os_handle: descriptor, +- handle_type: RUTABAGA_MEM_HANDLE_TYPE_SHM, +- }; +- +- Ok(RutabagaResource { +- resource_id, +- handle: Some(Arc::new(hnd)), +- blob: true, +- blob_mem: resource_create_blob.blob_mem, +- blob_flags: resource_create_blob.blob_flags, +- map_info: Some(RUTABAGA_MAP_CACHE_CACHED | RUTABAGA_MAP_ACCESS_READ), +- info_2d: None, +- info_3d: None, +- vulkan_info: None, +- backing_iovecs: None, +- component_mask: 1 << (RutabagaComponentType::CrossDomain as u8), +- size: resource_create_blob.size, +- mapping: None, +- }) ++ CrossDomainItem::ImageRequirements(reqs) => { ++ if reqs.size != resource_create_blob.size { ++ return Err(RutabagaError::SpecViolation("blob size mismatch")); + } +- _ => Err(RutabagaError::InvalidCrossDomainItemType), ++ ++ // Strictly speaking, it's against the virtio-gpu spec to allocate memory in the context ++ // create blob function, which says "the actual allocation is done via ++ // VIRTIO_GPU_CMD_SUBMIT_3D." However, atomic resource creation is easiest for the ++ // cross-domain use case, so whatever. ++ let hnd = match handle_opt { ++ Some(handle) => handle, ++ None => self.gralloc.lock().unwrap().allocate_memory(*reqs)?, ++ }; ++ ++ let info_3d = Resource3DInfo { ++ width: reqs.info.width, ++ height: reqs.info.height, ++ drm_fourcc: reqs.info.drm_format.into(), ++ strides: reqs.strides, ++ offsets: reqs.offsets, ++ modifier: reqs.modifier, ++ guest_cpu_mappable: (resource_create_blob.blob_flags ++ & RUTABAGA_BLOB_FLAG_USE_MAPPABLE) ++ != 0, ++ }; ++ ++ Ok(RutabagaResource { ++ resource_id, ++ handle: Some(Arc::new(hnd)), ++ blob: true, ++ blob_mem: resource_create_blob.blob_mem, ++ blob_flags: resource_create_blob.blob_flags, ++ map_info: Some(reqs.map_info | RUTABAGA_MAP_ACCESS_RW), ++ info_2d: None, ++ info_3d: Some(info_3d), ++ vulkan_info: reqs.vulkan_info, ++ backing_iovecs: None, ++ component_mask: 1 << (RutabagaComponentType::CrossDomain as u8), ++ size: resource_create_blob.size, ++ mapping: None, ++ }) + } ++ id => Err(RutabagaError::InvalidCrossDomainItemType), + } + } + +-- +2.42.0 + diff --git a/pkgs/rutabaga-gfx-ffi/default.nix b/pkgs/rutabaga-gfx-ffi/default.nix index 00c6c45a9..41c55fdaf 100644 --- a/pkgs/rutabaga-gfx-ffi/default.nix +++ b/pkgs/rutabaga-gfx-ffi/default.nix @@ -21,6 +21,7 @@ rustPlatform.buildRustPackage { patches = [ ./0001-rutabaga_gfx-don-t-clone-wayland-memfd-file-descript.patch ./0002-rutabaga_gfx-super-ugly-workaround-to-get-private-ke.patch + ./0003-rutabaga_gfx-fix-stale-cross-domain-keymap-resources.patch ]; buildPhase = ''