[PATCH] GPU acceleration
This exposes GPU acceleration to VMs via virtio-GPU native contexts on AMD and Qualcomm GPUs. Apple GPU support also exists but might require patches to virglrenderer that are not upstream yet. On a system with an AMD GPU, this has been tested by running vkcube in the VM. It reports that the AMD GPU is being used for rendering. Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com> --- I used an empty string for the hashes in 'gitfetch' and 'buildRustPackage'. This is, of course, incorrect. The correct value according to my own testing is "sha256-EOMkQ0aPRjsowdGuZjy5K1yKyKEzd5AVYxaECTz7n6k=" (git hash) and "sha256-k3dmxIuCQoOrn/VwauTdzuRw/XKQB6LPLgO5ql0rE7E=" (cargoHash). However, these should be validated before applying them, which is why I didn't include them in the patch themselves. This is a security precaution: anyone who wants to inject malicious content must serve it to multiple people, not just one. --- .../template/data/service/vhost-user-gpu/run | 2 +- img/app/Makefile | 2 +- img/app/default.nix | 14 ++++++++++++-- img/app/image/etc/mdev.conf | 1 + .../notification-fd | 0 .../notification-fd.license | 0 .../{wayland-proxy-virtwl => wl-cross-domain-proxy}/run | 17 +++++------------ .../type | 0 .../type.license | 0 9 files changed, 20 insertions(+), 16 deletions(-) diff --git a/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run b/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run index fb9ac9971aef82dabe0b54c1299ac8c66d133eb5..87d72f55e293ea81b6f4aa12786a993bafc623e2 100755 --- a/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run +++ b/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run @@ -42,4 +42,4 @@ bwrap crosvm --no-syslog device gpu --fd 0 --wayland-sock $WAYLAND_DISPLAY - --params "{\"context-types\":\"cross-domain\"}" + --params "{\"context-types\":\"cross-domain:drm\"}" diff --git a/img/app/Makefile b/img/app/Makefile index 2e720a91b4cc98a780aae90435f018ba2dd2d965..d34bcf2604d43eaa55d9100711374eba689bfdce 100644 --- a/img/app/Makefile +++ b/img/app/Makefile @@ -77,7 +77,7 @@ start-vhost-user-gpu: $(CROSVM_DEVICE_GPU) \ --socket build/vhost-user-gpu.sock \ --wayland-sock "$$XDG_RUNTIME_DIR/$$WAYLAND_DISPLAY" \ - --params '{"context-types":"cross-domain"}' & + --params '{"context-types":"cross-domain:drm"}' & while ! [ -S build/vhost-user-gpu.sock ] && sleep .1; do :; done .PHONY: start-vhost-user-gpu diff --git a/img/app/default.nix b/img/app/default.nix index 71e6fa02e78553d027d59f5b2ff728830276d480..1ce32258edf3f0ae535e050745e60d1d193a838e 100644 --- a/img/app/default.nix +++ b/img/app/default.nix @@ -5,10 +5,20 @@ import ../../lib/call-package.nix ( { spectrum-app-tools, spectrum-build-tools, src, terminfo , lib, appimageTools, buildFHSEnv, runCommand, stdenvNoCC, writeClosure , erofs-utils, jq, s6-rc, util-linux, xorg -, cacert, linux_latest +, cacert, linux_latest, rustPlatform, fetchgit }: let + wl-cross-domain-proxy = rustPlatform.buildRustPackage rec { + pname = "wl-cross-domain-proxy"; + version = "0.0.0"; + src = fetchgit { + url = "https://codeberg.org/drakulix/wl-cross-domain-proxy"; + rev = "167b5ade788d297cd19929c2f367484a09a87316"; + hash = ""; + }; + cargoHash = ""; + }; kernelTarget = if stdenvNoCC.hostPlatform.isx86 then # vmlinux.bin is the stripped version of vmlinux. @@ -75,7 +85,6 @@ let pkgs.s6-rc pkgs.socat pkgs.systemd - pkgs.wayland-proxy-virtwl pkgs.wireplumber pkgs.xdg-desktop-portal pkgs.xdg-desktop-portal-gtk @@ -84,6 +93,7 @@ let kernel.modules spectrum-app-tools terminfo + wl-cross-domain-proxy ]; })).fhsenv; diff --git a/img/app/image/etc/mdev.conf b/img/app/image/etc/mdev.conf index 33a07d6b1001bd883a3d54e706bc2eb30ca32d0b..bdfdf4b1688dff612c8a5a219c6530c7434668e7 100644 --- a/img/app/image/etc/mdev.conf +++ b/img/app/image/etc/mdev.conf @@ -5,6 +5,7 @@ $INTERFACE=.* 0:0 0 ! +/etc/mdev/iface $MODALIAS=virtio:d0000001Av.* 0:0 0 ! +/etc/mdev/virtiofs dri/card0 user:user 660 +background { /etc/mdev/listen card0 } +dri/renderD128 user:user 660 +background { /etc/mdev/listen renderD128 } -SUBSYSTEM=sound;.* pipewire:pipewire 660 snd/controlC0 pipewire:pipewire 660 +background { /etc/mdev/listen controlC0 } diff --git a/img/app/image/etc/s6-rc/wayland-proxy-virtwl/notification-fd b/img/app/image/etc/s6-rc/wl-cross-domain-proxy/notification-fd similarity index 100% rename from img/app/image/etc/s6-rc/wayland-proxy-virtwl/notification-fd rename to img/app/image/etc/s6-rc/wl-cross-domain-proxy/notification-fd diff --git a/img/app/image/etc/s6-rc/wayland-proxy-virtwl/notification-fd.license b/img/app/image/etc/s6-rc/wl-cross-domain-proxy/notification-fd.license similarity index 100% rename from img/app/image/etc/s6-rc/wayland-proxy-virtwl/notification-fd.license rename to img/app/image/etc/s6-rc/wl-cross-domain-proxy/notification-fd.license diff --git a/img/app/image/etc/s6-rc/wayland-proxy-virtwl/run b/img/app/image/etc/s6-rc/wl-cross-domain-proxy/run similarity index 50% rename from img/app/image/etc/s6-rc/wayland-proxy-virtwl/run rename to img/app/image/etc/s6-rc/wl-cross-domain-proxy/run index 5d06b7aea93d790a0aff4c3aed0e821caddadfee..5ae3b96aa639053ff2f70e6b7ddc420fae3c53f1 100755 --- a/img/app/image/etc/s6-rc/wayland-proxy-virtwl/run +++ b/img/app/image/etc/s6-rc/wl-cross-domain-proxy/run @@ -1,19 +1,11 @@ #!/bin/execlineb -P # SPDX-License-Identifier: EUPL-1.2+ # SPDX-FileCopyrightText: 2023-2024 Alyssa Ross <hi@alyssa.is> -# -# Directory creation (if it's copyrightable): -# SPDX-License-Identifier: MIT -# SPDX-FileCopyrightText: 2022 Unikie - -foreground { mkdir /tmp/.X11-unix } +# SPDX-FileCopyrightText: 2026 Demi Marie Obenour <demiobenour@gmail.com> s6-ipcserver-socketbinder -B /run/wayland fdmove -c 3 0 -s6-ipcserver-socketbinder -B /tmp/.X11-unix/X0 -fdmove -c 4 0 - redirfd -r 0 /dev/null # Notify readiness. @@ -21,11 +13,12 @@ if { fdmove 1 5 echo } fdclose 5 if { /etc/mdev/wait card0 } +if { /etc/mdev/wait renderD128 } -export LISTEN_FDS 2 -export LISTEN_FDNAMES wayland:x11 +export LISTEN_FDS 1 +export LISTEN_FDNAMES wayland getpid LISTEN_PID s6-setuidgid user -wayland-proxy-virtwl --virtio-gpu --x-display=0 +wl-cross-domain-proxy --listen-fd diff --git a/img/app/image/etc/s6-rc/wayland-proxy-virtwl/type b/img/app/image/etc/s6-rc/wl-cross-domain-proxy/type similarity index 100% rename from img/app/image/etc/s6-rc/wayland-proxy-virtwl/type rename to img/app/image/etc/s6-rc/wl-cross-domain-proxy/type diff --git a/img/app/image/etc/s6-rc/wayland-proxy-virtwl/type.license b/img/app/image/etc/s6-rc/wl-cross-domain-proxy/type.license similarity index 100% rename from img/app/image/etc/s6-rc/wayland-proxy-virtwl/type.license rename to img/app/image/etc/s6-rc/wl-cross-domain-proxy/type.license --- base-commit: 8a6e4f03951d80382e5dcf1a159d37dec8376a0b change-id: 20260120-gpu-accel-2-7eec0ac9b071 -- Sincerely, Demi Marie Obenour (she/her/hers)
Demi Marie Obenour <demiobenour@gmail.com> writes:
I used an empty string for the hashes in 'gitfetch' and 'buildRustPackage'. This is, of course, incorrect. The correct value according to my own testing is "sha256-EOMkQ0aPRjsowdGuZjy5K1yKyKEzd5AVYxaECTz7n6k=" (git hash) and "sha256-k3dmxIuCQoOrn/VwauTdzuRw/XKQB6LPLgO5ql0rE7E=" (cargoHash). However, these should be validated before applying them, which is why I didn't include them in the patch themselves. This is a security precaution: anyone who wants to inject malicious content must serve it to multiple people, not just one.
Even if you had included the hashes, I'd still have had to download the resources myself, so they'd still have had to serve the malicious content to me, too. I don't have access to your cached downloads. If anything, including the hashes would have been of benefit, because then I'd have had something to compare mine too. (Not that it's a substantial threat in any case.)
Worth marking patches like this as RFC or similar in future, so everybody looking at it is on the same page about its status. (I'm assuming this was meant as a proof of concept and not meant to be applied as is.) Demi Marie Obenour <demiobenour@gmail.com> writes:
This exposes GPU acceleration to VMs via virtio-GPU native contexts on AMD and Qualcomm GPUs. Apple GPU support also exists but might require patches to virglrenderer that are not upstream yet.
On a system with an AMD GPU, this has been tested by running vkcube in the VM. It reports that the AMD GPU is being used for rendering.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com> --- I used an empty string for the hashes in 'gitfetch' and 'buildRustPackage'. This is, of course, incorrect. The correct value according to my own testing is "sha256-EOMkQ0aPRjsowdGuZjy5K1yKyKEzd5AVYxaECTz7n6k=" (git hash) and "sha256-k3dmxIuCQoOrn/VwauTdzuRw/XKQB6LPLgO5ql0rE7E=" (cargoHash). However, these should be validated before applying them, which is why I didn't include them in the patch themselves. This is a security precaution: anyone who wants to inject malicious content must serve it to multiple people, not just one. --- .../template/data/service/vhost-user-gpu/run | 2 +- img/app/Makefile | 2 +- img/app/default.nix | 14 ++++++++++++-- img/app/image/etc/mdev.conf | 1 + .../notification-fd | 0 .../notification-fd.license | 0 .../{wayland-proxy-virtwl => wl-cross-domain-proxy}/run | 17 +++++------------ .../type | 0 .../type.license | 0 9 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run b/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run index fb9ac9971aef82dabe0b54c1299ac8c66d133eb5..87d72f55e293ea81b6f4aa12786a993bafc623e2 100755 --- a/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run +++ b/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run @@ -42,4 +42,4 @@ bwrap crosvm --no-syslog device gpu --fd 0 --wayland-sock $WAYLAND_DISPLAY - --params "{\"context-types\":\"cross-domain\"}" + --params "{\"context-types\":\"cross-domain:drm\"}"
I suppose we'll need to get some sort of graceful fallback into crosvm/rutabaga, or to somehow detect native contexts support in this script before we enable it on the crosvm command line? 2026-01-29 14:06:30.082434936 [2026-01-29T14:06:30.082073581+00:00 ERROR rutabaga_gfx::virgl_renderer] failed to initialize drm renderer 2026-01-29 14:06:30.082842461 [2026-01-29T14:06:30.082652949+00:00 WARN rutabaga_gfx::rutabaga_core] error initializing gpu backend=virglrenderer, falling back to 2d. 2026-01-29 14:06:30.099779984 [2026-01-29T14:06:30.099379669+00:00 WARN devices::virtio::gpu::virtio_gpu] virtio-gpu get_capset_info(index=1) failed. intentionally poisoning response --- FYI: I needed the following additional diff to test the rootfs with this patch: diff --git a/img/app/default.nix b/img/app/default.nix index 1ce3225..d19f5f8 100644 --- a/img/app/default.nix +++ b/img/app/default.nix @@ -15,9 +15,9 @@ let src = fetchgit { url = "https://codeberg.org/drakulix/wl-cross-domain-proxy"; rev = "167b5ade788d297cd19929c2f367484a09a87316"; - hash = ""; + hash = "sha256-EOMkQ0aPRjsowdGuZjy5K1yKyKEzd5AVYxaECTz7n6k="; }; - cargoHash = ""; + cargoHash = "sha256-k3dmxIuCQoOrn/VwauTdzuRw/XKQB6LPLgO5ql0rE7E="; }; kernelTarget = if stdenvNoCC.hostPlatform.isx86 then diff --git a/img/app/file-list.mk b/img/app/file-list.mk index 815b63a..443e6f2 100644 --- a/img/app/file-list.mk +++ b/img/app/file-list.mk @@ -41,7 +41,6 @@ LINKS = \ S6_RC_FILES = \ image/etc/s6-rc/app/dependencies.d/dbus \ image/etc/s6-rc/app/dependencies.d/pipewire \ - image/etc/s6-rc/app/dependencies.d/wayland-proxy-virtwl \ image/etc/s6-rc/app/run \ image/etc/s6-rc/app/type \ image/etc/s6-rc/dbus-vsock/notification-fd \ @@ -64,10 +63,10 @@ S6_RC_FILES = \ image/etc/s6-rc/pipewire/notification-fd \ image/etc/s6-rc/pipewire/run \ image/etc/s6-rc/pipewire/type \ - image/etc/s6-rc/wayland-proxy-virtwl/notification-fd \ - image/etc/s6-rc/wayland-proxy-virtwl/run \ - image/etc/s6-rc/wayland-proxy-virtwl/type \ image/etc/s6-rc/wireplumber/dependencies.d/dbus \ image/etc/s6-rc/wireplumber/dependencies.d/pipewire \ image/etc/s6-rc/wireplumber/run \ - image/etc/s6-rc/wireplumber/type + image/etc/s6-rc/wireplumber/type \ + image/etc/s6-rc/wl-cross-domain-proxy/notification-fd \ + image/etc/s6-rc/wl-cross-domain-proxy/run \ + image/etc/s6-rc/wl-cross-domain-proxy/type diff --git a/img/app/image/etc/s6-rc/app/dependencies.d/wayland-proxy-virtwl b/img/app/image/etc/s6-rc/app/dependencies.d/wayland-proxy-virtwl deleted file mode 100644 index e69de29..0000000
On 1/29/26 09:10, Alyssa Ross wrote:
Worth marking patches like this as RFC or similar in future, so everybody looking at it is on the same page about its status. (I'm assuming this was meant as a proof of concept and not meant to be applied as is.)
With the hash change, I was hoping it could be applied. I forgot to run scripts/genfiles.sh, though, and completely missed the missing fallback in crosvm.
Demi Marie Obenour <demiobenour@gmail.com> writes:
This exposes GPU acceleration to VMs via virtio-GPU native contexts on AMD and Qualcomm GPUs. Apple GPU support also exists but might require patches to virglrenderer that are not upstream yet.
On a system with an AMD GPU, this has been tested by running vkcube in the VM. It reports that the AMD GPU is being used for rendering.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com> --- I used an empty string for the hashes in 'gitfetch' and 'buildRustPackage'. This is, of course, incorrect. The correct value according to my own testing is "sha256-EOMkQ0aPRjsowdGuZjy5K1yKyKEzd5AVYxaECTz7n6k=" (git hash) and "sha256-k3dmxIuCQoOrn/VwauTdzuRw/XKQB6LPLgO5ql0rE7E=" (cargoHash). However, these should be validated before applying them, which is why I didn't include them in the patch themselves. This is a security precaution: anyone who wants to inject malicious content must serve it to multiple people, not just one. --- .../template/data/service/vhost-user-gpu/run | 2 +- img/app/Makefile | 2 +- img/app/default.nix | 14 ++++++++++++-- img/app/image/etc/mdev.conf | 1 + .../notification-fd | 0 .../notification-fd.license | 0 .../{wayland-proxy-virtwl => wl-cross-domain-proxy}/run | 17 +++++------------ .../type | 0 .../type.license | 0 9 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run b/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run index fb9ac9971aef82dabe0b54c1299ac8c66d133eb5..87d72f55e293ea81b6f4aa12786a993bafc623e2 100755 --- a/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run +++ b/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run @@ -42,4 +42,4 @@ bwrap crosvm --no-syslog device gpu --fd 0 --wayland-sock $WAYLAND_DISPLAY - --params "{\"context-types\":\"cross-domain\"}" + --params "{\"context-types\":\"cross-domain:drm\"}"
I suppose we'll need to get some sort of graceful fallback into crosvm/rutabaga, or to somehow detect native contexts support in this script before we enable it on the crosvm command line?
2026-01-29 14:06:30.082434936 [2026-01-29T14:06:30.082073581+00:00 ERROR rutabaga_gfx::virgl_renderer] failed to initialize drm renderer 2026-01-29 14:06:30.082842461 [2026-01-29T14:06:30.082652949+00:00 WARN rutabaga_gfx::rutabaga_core] error initializing gpu backend=virglrenderer, falling back to 2d. 2026-01-29 14:06:30.099779984 [2026-01-29T14:06:30.099379669+00:00 WARN devices::virtio::gpu::virtio_gpu] virtio-gpu get_capset_info(index=1) failed. intentionally poisoning response
Ideally crosvm would fallback automatically, but on ChromeOS it never needs to because it is built specifically for its target hardware. It should be sufficient to detect if an AMD or Qualcomm GPU is available and the user has enabled GPU acceleration. As an aside, Thunderbird complains that the digital signature on your message is invalid. -- Sincerely, Demi Marie Obenour (she/her/hers)
Demi Marie Obenour <demiobenour@gmail.com> writes:
On 1/29/26 09:10, Alyssa Ross wrote:
Worth marking patches like this as RFC or similar in future, so everybody looking at it is on the same page about its status. (I'm assuming this was meant as a proof of concept and not meant to be applied as is.)
With the hash change, I was hoping it could be applied. I forgot to run scripts/genfiles.sh, though, and completely missed the missing fallback in crosvm.
Demi Marie Obenour <demiobenour@gmail.com> writes:
This exposes GPU acceleration to VMs via virtio-GPU native contexts on AMD and Qualcomm GPUs. Apple GPU support also exists but might require patches to virglrenderer that are not upstream yet.
On a system with an AMD GPU, this has been tested by running vkcube in the VM. It reports that the AMD GPU is being used for rendering.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com> --- I used an empty string for the hashes in 'gitfetch' and 'buildRustPackage'. This is, of course, incorrect. The correct value according to my own testing is "sha256-EOMkQ0aPRjsowdGuZjy5K1yKyKEzd5AVYxaECTz7n6k=" (git hash) and "sha256-k3dmxIuCQoOrn/VwauTdzuRw/XKQB6LPLgO5ql0rE7E=" (cargoHash). However, these should be validated before applying them, which is why I didn't include them in the patch themselves. This is a security precaution: anyone who wants to inject malicious content must serve it to multiple people, not just one. --- .../template/data/service/vhost-user-gpu/run | 2 +- img/app/Makefile | 2 +- img/app/default.nix | 14 ++++++++++++-- img/app/image/etc/mdev.conf | 1 + .../notification-fd | 0 .../notification-fd.license | 0 .../{wayland-proxy-virtwl => wl-cross-domain-proxy}/run | 17 +++++------------ .../type | 0 .../type.license | 0 9 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run b/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run index fb9ac9971aef82dabe0b54c1299ac8c66d133eb5..87d72f55e293ea81b6f4aa12786a993bafc623e2 100755 --- a/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run +++ b/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run @@ -42,4 +42,4 @@ bwrap crosvm --no-syslog device gpu --fd 0 --wayland-sock $WAYLAND_DISPLAY - --params "{\"context-types\":\"cross-domain\"}" + --params "{\"context-types\":\"cross-domain:drm\"}"
I suppose we'll need to get some sort of graceful fallback into crosvm/rutabaga, or to somehow detect native contexts support in this script before we enable it on the crosvm command line?
2026-01-29 14:06:30.082434936 [2026-01-29T14:06:30.082073581+00:00 ERROR rutabaga_gfx::virgl_renderer] failed to initialize drm renderer 2026-01-29 14:06:30.082842461 [2026-01-29T14:06:30.082652949+00:00 WARN rutabaga_gfx::rutabaga_core] error initializing gpu backend=virglrenderer, falling back to 2d. 2026-01-29 14:06:30.099779984 [2026-01-29T14:06:30.099379669+00:00 WARN devices::virtio::gpu::virtio_gpu] virtio-gpu get_capset_info(index=1) failed. intentionally poisoning response
Ideally crosvm would fallback automatically, but on ChromeOS it never needs to because it is built specifically for its target hardware.
Okay, but crosvm is open to contributions. They're willing to accept affordances for non-Chrome OS use. Even Google doesn't use it exclusively on Chrome OS…
It should be sufficient to detect if an AMD or Qualcomm GPU is available and the user has enabled GPU acceleration.
That doesn't sound very good, because then we'll have to keep updating it as new GPUs are supported.
participants (2)
-
Alyssa Ross -
Demi Marie Obenour