-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create a virtual machine with virtio-gpu device
Signed-off-by: Yuri Nesterov <yuriy.nesterov@unikie.com>
- Loading branch information
Showing
10 changed files
with
260 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,5 +11,6 @@ | |
./window-manager.nix | ||
./boot.nix | ||
./hardware.nix | ||
./waypipe.nix | ||
]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# | ||
{ | ||
pkgs, | ||
lib, | ||
config, | ||
... | ||
}: let | ||
cfg = config.ghaf.waypipe; | ||
in { | ||
options.ghaf.waypipe = { | ||
enable = lib.mkEnableOption "Waypipe"; | ||
|
||
port = lib.mkOption { | ||
type = lib.types.int; | ||
default = 1100; | ||
description = '' | ||
Waypipe port number to listen for incoming connections | ||
''; | ||
}; | ||
}; | ||
|
||
config = lib.mkIf cfg.enable { | ||
systemd.user.services.waypipe = { | ||
enable = true; | ||
description = "waypipe"; | ||
after = ["weston.service" "labwc.service"]; | ||
serviceConfig = { | ||
Type = "simple"; | ||
ExecStart = "${pkgs.waypipe}/bin/waypipe --vsock -s ${toString cfg.port} client"; | ||
Restart = "always"; | ||
RestartSec = "1"; | ||
}; | ||
startLimitIntervalSec = 0; | ||
wantedBy = ["ghaf-session.target"]; | ||
}; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors | ||
# SPDX-License-Identifier: Apache-2.0 | ||
{ | ||
config, | ||
lib, | ||
pkgs, | ||
... | ||
}: let | ||
configHost = config; | ||
vmName = "virtgpu-vm"; | ||
# The socket is created in /tmp because it is accessible to both microvm and ghaf users | ||
gpuSocket = "/tmp/${vmName}-gpu.sock"; | ||
run-sommelier = with pkgs; | ||
writeScriptBin "run-sommelier" '' | ||
#!${runtimeShell} -e | ||
exec ${sommelier}/bin/sommelier --virtgpu-channel -- $@ | ||
''; | ||
run-wayland-proxy = with pkgs; | ||
writeScriptBin "run-wayland-proxy" '' | ||
#!${runtimeShell} -e | ||
exec ${wayland-proxy-virtwl}/bin/wayland-proxy-virtwl --virtio-gpu -- $@ | ||
''; | ||
run-waypipe = with pkgs; | ||
writeScriptBin "run-waypipe" '' | ||
#!${runtimeShell} -e | ||
exec ${waypipe}/bin/waypipe --vsock -s 2:${toString config.ghaf.waypipe.port} server $@ | ||
''; | ||
virtgpuvmBaseConfiguration = { | ||
imports = [ | ||
(import ./common/vm-networking.nix { | ||
inherit vmName; | ||
macAddress = "02:00:00:03:05:01"; | ||
}) | ||
({ | ||
lib, | ||
pkgs, | ||
... | ||
}: { | ||
ghaf = { | ||
users.accounts.enable = lib.mkDefault configHost.ghaf.users.accounts.enable; | ||
|
||
development = { | ||
ssh.daemon.enable = lib.mkDefault configHost.ghaf.development.ssh.daemon.enable; | ||
debug.tools.enable = lib.mkDefault configHost.ghaf.development.debug.tools.enable; | ||
nix-setup.enable = lib.mkDefault configHost.ghaf.development.nix-setup.enable; | ||
}; | ||
}; | ||
|
||
system.stateVersion = lib.trivial.release; | ||
|
||
nixpkgs.buildPlatform.system = configHost.nixpkgs.buildPlatform.system; | ||
nixpkgs.hostPlatform.system = configHost.nixpkgs.hostPlatform.system; | ||
|
||
environment.systemPackages = with pkgs; [ | ||
sommelier | ||
wayland-proxy-virtwl | ||
waypipe | ||
run-sommelier | ||
run-wayland-proxy | ||
run-waypipe | ||
zathura | ||
chromium | ||
firefox | ||
wayland-utils | ||
]; | ||
|
||
# DRM fbdev emulation is disabled to get rid of the popup console window that appears when running a VM with virtio-gpu device | ||
boot.kernelParams = ["drm_kms_helper.fbdev_emulation=false"]; | ||
|
||
hardware.opengl.enable = true; | ||
|
||
microvm = { | ||
optimize.enable = false; | ||
mem = 4096; | ||
vcpu = 4; | ||
hypervisor = "crosvm"; | ||
shares = [ | ||
{ | ||
tag = "ro-store"; | ||
source = "/nix/store"; | ||
mountPoint = "/nix/.ro-store"; | ||
proto = "virtiofs"; | ||
} | ||
]; | ||
|
||
# GPU device is a separate service which is connected over vhost-user protocol | ||
crosvm.extraArgs = ["--vhost-user" "gpu,socket=${gpuSocket}"]; | ||
|
||
# VSOCK is required for waypipe, 3 is the first available CID | ||
vsock.cid = 3; | ||
}; | ||
|
||
imports = [../../../common]; | ||
}) | ||
]; | ||
}; | ||
cfg = config.ghaf.virtualization.microvm.virtgpuvm; | ||
in { | ||
options.ghaf.virtualization.microvm.virtgpuvm = { | ||
enable = lib.mkEnableOption "VirtgpuVM"; | ||
|
||
extraModules = lib.mkOption { | ||
description = '' | ||
List of additional modules to be imported and evaluated as part of | ||
VirtgpuVM's NixOS configuration. | ||
''; | ||
default = []; | ||
}; | ||
}; | ||
|
||
config = lib.mkIf cfg.enable { | ||
microvm.vms."${vmName}" = { | ||
config = virtgpuvmBaseConfiguration // {imports = virtgpuvmBaseConfiguration.imports ++ cfg.extraModules;}; | ||
specialArgs = {inherit lib;}; | ||
}; | ||
|
||
# This service creates a crosvm backend GPU device | ||
systemd.user.services."${vmName}-gpu" = let | ||
preStartScript = pkgs.writeShellScriptBin "prestart-crosvmgpu" '' | ||
if [[ -z "$WAYLAND_DISPLAY" ]]; then | ||
echo "WAYLAND_DISPLAY is not set" | ||
exit 1 | ||
fi | ||
WAYLAND_SOCK=$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY | ||
if [[ ! -r "$WAYLAND_SOCK" ]]; then | ||
echo "Wayland socket $WAYLAND_SOCK is not readable" | ||
exit 1 | ||
fi | ||
''; | ||
startScript = pkgs.writeShellScriptBin "start-crosvmgpu" '' | ||
rm -f ${gpuSocket} | ||
${pkgs.crosvm}/bin/crosvm device gpu --socket ${gpuSocket} --wayland-sock $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY --params '{"context-types":"virgl:virgl2:cross-domain","egl":true,"vulkan":true}' | ||
''; | ||
postStartScript = pkgs.writeShellScriptBin "poststart-crosvmgpu" '' | ||
while ! [ -S ${gpuSocket} ]; do | ||
sleep .1 | ||
done | ||
chgrp video ${gpuSocket} | ||
chmod 775 ${gpuSocket} | ||
''; | ||
in { | ||
enable = true; | ||
description = "crosvm gpu device"; | ||
after = ["weston.service" "labwc.service"]; | ||
serviceConfig = { | ||
Type = "simple"; | ||
ExecStartPre = "${preStartScript}/bin/prestart-crosvmgpu"; | ||
ExecStart = "${startScript}/bin/start-crosvmgpu"; | ||
ExecStartPost = "${postStartScript}/bin/poststart-crosvmgpu"; | ||
Restart = "always"; | ||
RestartSec = "1"; | ||
}; | ||
startLimitIntervalSec = 0; | ||
wantedBy = ["ghaf-session.target"]; | ||
}; | ||
|
||
users.users."microvm".extraGroups = ["video"]; | ||
|
||
ghaf.waypipe.enable = true; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors | ||
# SPDX-License-Identifier: Apache-2.0 | ||
{ | ||
final, | ||
prev, | ||
}: | ||
prev.crosvm.overrideAttrs (_final: prevAttrs: rec { | ||
version = "122.1"; | ||
src = prev.fetchgit { | ||
url = "https://chromium.googlesource.com/chromiumos/platform/crosvm"; | ||
rev = "562d81eb28a49ed6e0d771a430c21a458cdd33f9"; | ||
sha256 = "sha256-l5sIUInOhhkn3ernQLIEwEpRCyICDH/1k4C/aidy1/I="; | ||
fetchSubmodules = true; | ||
}; | ||
|
||
patches = []; | ||
|
||
cargoBuildFeatures = final.lib.lists.remove "virgl_renderer_next" prevAttrs.cargoBuildFeatures; | ||
cargoCheckFeatures = final.lib.lists.remove "virgl_renderer_next" prevAttrs.cargoCheckFeatures; | ||
CROSVM_USE_SYSTEM_MINIGBM = true; | ||
|
||
cargoDeps = prevAttrs.cargoDeps.overrideAttrs (prev.lib.const { | ||
inherit src; | ||
name = "crosvm-vendor.tar.gz"; | ||
outputHash = "sha256-yTdho6lW+XqB/iGf+bT2iwnAdjz3TrrI7YAaLoenR1U="; | ||
}); | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors | ||
# SPDX-License-Identifier: Apache-2.0 | ||
{ | ||
final, | ||
prev, | ||
}: | ||
prev.sommelier.overrideAttrs (_final: prevAttrs: { | ||
version = "122.0"; | ||
src = prev.fetchzip rec { | ||
url = "https://chromium.googlesource.com/chromiumos/platform2/+archive/${passthru.rev}/vm_tools/sommelier.tar.gz"; | ||
passthru.rev = "2d4f46c679da7a4e8c447c8cf68c74b80f9de3fe"; | ||
stripRoot = false; | ||
sha256 = "sha256-LNGA1r2IO3Ekh+dK6HUge001qC2TFvxwjhM0iaY0DbU="; | ||
}; | ||
|
||
nativeBuildInputs = prevAttrs.nativeBuildInputs ++ [final.python3 final.python3.pkgs.jinja2]; | ||
postPatch = '' | ||
patchShebangs gen-shim.py | ||
''; | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters