diff --git a/modules/common/services/audio.nix b/modules/common/services/audio.nix index d187292b00..c7c0a620ef 100644 --- a/modules/common/services/audio.nix +++ b/modules/common/services/audio.nix @@ -29,6 +29,16 @@ in default = 4714; description = "TCP port used by Pipewire-pulseaudio control"; }; + pulseaudioUnixSocketPath = mkOption { + type = types.path; + default = "/run/pipewire/pulseaudio-0"; + description = "Path to Unix socket used by Pipewire-pulseaudio service"; + }; + pulseaudioUseShmem = mkOption { + type = types.bool; + default = false; + description = "Use shared memory for audio service"; + }; }; config = mkIf cfg.enable { @@ -46,10 +56,14 @@ in { name = "libpipewire-module-protocol-pulse"; args = { - # Enable TCP socket for VMs pulseaudio clients + # Enable Unix or TCP socket for VMs pulseaudio clients "server.address" = [ { - address = "tcp:0.0.0.0:${toString cfg.pulseaudioTcpPort}"; + address = + if cfg.pulseaudioUseShmem then + "unix:${cfg.pulseaudioUnixSocketPath}" + else + "tcp:0.0.0.0:${toString cfg.pulseaudioTcpPort}"; "client.access" = "restricted"; } ]; diff --git a/modules/hardware/common/shared-mem.nix b/modules/hardware/common/shared-mem.nix index 36103ba65f..27f2d1de94 100644 --- a/modules/hardware/common/shared-mem.nix +++ b/modules/hardware/common/shared-mem.nix @@ -13,12 +13,62 @@ let cfg = config.ghaf.shm; inherit (lib) foldl' - lists mkMerge mkIf mkOption types ; + enabledServices = lib.filterAttrs (_name: serverAttrs: serverAttrs.enabled) cfg.service; + enabledVmServices = + isVM: + lib.filterAttrs (_name: serverAttrs: serverAttrs.serverConfig.runsOnVm == isVM) enabledServices; + clientsPerService = + service: + lib.flatten ( + lib.mapAttrsToList ( + name: value: if (name == service || service == "all") then value.clients else [ ] + ) enabledServices + ); + allVMs = lib.unique ( + lib.concatLists ( + map (s: (lib.filter (client: client != "host") s.clients) ++ [ s.server ]) ( + builtins.attrValues enabledServices + ) + ) + ); + clientServicePairs = lib.unique ( + lib.concatLists ( + map ( + s: + map (c: { + service = s.name; + client = c; + }) s.clients + ) (lib.mapAttrsToList (name: attrs: attrs // { inherit name; }) enabledServices) + ) + ); + clientServiceWithID = lib.foldl' ( + acc: pair: acc ++ [ (pair // { id = builtins.length acc; }) ] + ) [ ] clientServicePairs; + clientID = + client: service: + let + filtered = builtins.filter (x: x.client == client && x.service == service) clientServiceWithID; + in + if filtered != [ ] then (builtins.toString (builtins.head filtered).id) else null; + clientsArg = lib.foldl' ( + acc: pair: + ( + acc + // { + "${pair.service}" = + if (builtins.hasAttr "${pair.service}" acc) then + acc.${pair.service} + "," + (builtins.toString pair.id) + else + (builtins.toString pair.id); + } + ) + ) { } clientServiceWithID; in { options.ghaf.shm = { @@ -26,12 +76,19 @@ in type = types.bool; default = false; description = '' - Enables shared memory communication between virtual machines (VMs) + Enables shared memory communication between virtual machines (VMs) and the host + ''; + }; + gui = mkOption { + type = types.bool; + default = false; + description = '' + Enables shared memory for transferring GUI data between virtual machines ''; }; memSize = mkOption { type = types.int; - default = 16; + default = 32; description = '' Specifies the size of the shared memory region, measured in megabytes (MB) @@ -51,6 +108,101 @@ in else value; }; + + service = mkOption { + type = types.attrsOf types.anything; + default = + let + stdConfig = service: { + server = "${service}-vm"; + clientSocketPath = "/run/memsocket/${service}-client.sock"; + serverSocketPath = service: suffix: "/run/memsocket/${service}${suffix}.sock"; + userService = false; + serverConfig = { + runsOnVm = true; + }; + }; + in + { + gui = + let + enabled = cfg.enable && cfg.gui; + in + mkIf cfg.enable ( + lib.attrsets.recursiveUpdate (stdConfig "gui") { + inherit enabled; + serverSocketPath = service: suffix: "/tmp/${service}${suffix}.sock"; + serverConfig = { + userService = true; + systemdParams = service: suffix: { + wantedBy = [ "ghaf-session.target" ]; + after = [ "waypipe${builtins.replaceStrings [ "-vm" ] [ "" ] suffix}.service" ]; + partOf = [ "waypipe${builtins.replaceStrings [ "-vm" ] [ "" ] suffix}.service" ]; + bindsTo = [ "waypipe${builtins.replaceStrings [ "-vm" ] [ "" ] suffix}.service" ]; + serviceConfig = { + KillSignal = "SIGTERM"; + ExecStop = "${pkgs.coreutils}/bin/rm -f ${cfg.service.gui.serverSocketPath service suffix}"; + }; + }; + multiProcess = true; + }; + clients = config.ghaf.reference.appvms.shm-gui-enabled-vms; + clientConfig = { + userService = false; + systemdParams = { + wantedBy = [ "default.target" ]; + serviceConfig = { + KillSignal = "SIGTERM"; + User = "appuser"; + Group = "users"; + }; + }; + }; + } + ); + audio = + let + enabled = cfg.enable && config.ghaf.services.audio.pulseaudioUseShmem; + in + mkIf cfg.enable ( + lib.attrsets.recursiveUpdate (stdConfig "audio") { + inherit enabled; + serverSocketPath = _service: _suffix: config.ghaf.services.audio.pulseaudioUnixSocketPath; + serverConfig = { + userService = false; + systemdParams = _a: _b: { + wantedBy = [ "default.target" ]; + after = [ + "pipewire.service" + "pipewire-pulse.socket" + ]; + serviceConfig = { + User = "pipewire"; + Group = "pipewire"; + }; + }; + }; + clients = config.ghaf.reference.appvms.shm-audio-enabled-vms; + clientConfig = { + userService = false; + systemdParams = { + wantedBy = [ "default.target" ]; + serviceConfig = { + User = "appuser"; + Group = "users"; + }; + }; + }; + } + ); + }; + description = '' + Specifies the configuration of shared memory services: + server and client VMs. The server VMs are named after the + service name. + ''; + }; + hostSocketPath = mkOption { type = types.path; default = "/tmp/ivshmem_socket"; # The value is hardcoded in the application @@ -68,60 +220,128 @@ in conflicts with other memory areas, such as PCI regions. ''; }; - vms_enabled = mkOption { - type = types.listOf types.str; - default = [ ]; - description = '' - List of vms having access to shared memory - ''; - }; - enable_host = mkOption { - type = types.bool; - default = false; - description = '' - Enables the memsocket functionality on the host system - ''; - }; - instancesCount = mkOption { + shmSlots = mkOption { type = types.int; - default = - if cfg.enable_host then (builtins.length cfg.vms_enabled) + 1 else builtins.length cfg.vms_enabled; + default = builtins.length clientServiceWithID; description = '' Number of memory slots allocated in the shared memory region ''; }; - serverSocketPath = mkOption { - type = types.path; - default = "/run/user/${builtins.toString config.ghaf.users.loginUser.uid}/memsocket-server.sock"; - description = '' - Specifies the path of the listening socket, which is used by Waypipe - or other server applications as the output socket in server mode for - data transmission - ''; - }; - clientSocketPath = mkOption { - type = types.path; - default = "/run/user/${builtins.toString config.ghaf.users.loginUser.uid}/memsocket-client.sock"; - description = '' - Specifies the location of the output socket, which will connected to - in order to receive data from AppVMs. This socket must be created by - another application, such as Waypipe, when operating in client mode - ''; - }; - display = mkOption { - type = types.bool; - default = false; - description = '' - Enables the use of shared memory with Waypipe for Wayland-enabled - applications running on virtual machines (VMs), facilitating - efficient inter-VM communication - ''; - }; }; config = let user = "microvm"; group = "kvm"; + memsocket = pkgs.memsocket-app.override { + inherit (cfg) shmSlots; + debug = false; + }; + vectors = toString (2 * cfg.shmSlots); + defaultClientConfig = + data: + lib.attrsets.recursiveUpdate { + enable = true; + description = "memsocket"; + serviceConfig = { + Type = "simple"; + ExecStart = + let + hostOpt = if data.client == "host" then "-h ${cfg.hostSocketPath}" else ""; + in + "${memsocket}/bin/memsocket ${hostOpt} -c ${ + cfg.service.${data.service}.clientSocketPath + } ${builtins.toString (clientID data.client data.service)}"; + Restart = "always"; + RestartSec = "1"; + RuntimeDirectory = "memsocket"; + RuntimeDirectoryMode = "0770"; + }; + } cfg.service.${data.service}.clientConfig.systemdParams; + clientConfigTemplate = + data: + let + base = + if cfg.service.${data.service}.clientConfig.userService then + { + user.services."memsocket-${data.service}-client" = defaultClientConfig data; + } + else + { + services."memsocket-${data.service}-client" = defaultClientConfig data; + }; + + in + if data.client == "host" then + base + else + { + "${data.client}".config.config.systemd = base; + }; + + defaultServerConfig = + clientSuffix: clientId: service: runsOnVm: + lib.attrsets.recursiveUpdate { + enable = true; + description = "memsocket"; + serviceConfig = { + Type = "simple"; + ExecStart = + let + hostOpt = if !runsOnVm then "-h ${cfg.hostSocketPath}" else ""; + in + "${memsocket}/bin/memsocket -s ${ + cfg.service.${service}.serverSocketPath service clientSuffix + } ${hostOpt} -l ${clientId}"; + Restart = "always"; + RestartSec = "1"; + RuntimeDirectory = "memsocket"; + RuntimeDirectoryMode = "0750"; + }; + } (cfg.service.${service}.serverConfig.systemdParams service clientSuffix); + serverConfigTemplate = + clientSuffix: clientId: service: + let + base = + if cfg.service.${service}.serverConfig.userService then + { + user.services."memsocket-${service}${clientSuffix}-service" = + defaultServerConfig clientSuffix clientId service + cfg.service.${service}.serverConfig.runsOnVm; + } + else + { + services."memsocket-${service}${clientSuffix}-service" = + defaultServerConfig clientSuffix clientId service + cfg.service.${service}.serverConfig.runsOnVm; + }; + in + if cfg.service.${service}.serverConfig.runsOnVm then + { + "${cfg.service.${service}.server}".config.config.systemd = base; + } + else + base; + serverConfig = + service: + let + multiProcess = + if lib.attrsets.hasAttr "multiProcess" cfg.service.${service}.serverConfig then + cfg.service.${service}.serverConfig.multiProcess + else + false; + in + if multiProcess then + (lib.foldl' lib.attrsets.recursiveUpdate { } ( + map (client: serverConfigTemplate "-${client}" (clientID client service) service) ( + clientsPerService service + ) + )) + else + (serverConfigTemplate "" # clientSuffix + clientsArg.${service} + service + ); + in mkIf cfg.enable (mkMerge [ { @@ -139,9 +359,9 @@ in "d /dev/hugepages 0755 ${user} ${group} - -" ]; } - (mkIf cfg.enable_host { + (mkIf cfg.enable { environment.systemPackages = [ - (pkgs.memsocket.override { vms = cfg.instancesCount; }) + memsocket ]; }) { @@ -150,7 +370,7 @@ in pidFilePath = "/tmp/ivshmem-server.pid"; ivShMemSrv = let - vectors = toString (2 * cfg.instancesCount); + vectors = toString (2 * cfg.shmSlots); in pkgs.writeShellScriptBin "ivshmemsrv" '' if [ -S ${cfg.hostSocketPath} ]; then @@ -162,7 +382,7 @@ in in { enable = true; - description = "Start qemu ivshmem memory server"; + description = "qemu ivshmem memory server"; path = [ ivShMemSrv ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { @@ -176,12 +396,22 @@ in }; }; } + # add host systemd client services + { + systemd = foldl' lib.attrsets.recursiveUpdate { } ( + map clientConfigTemplate (lib.filter (data: data.client == "host") clientServicePairs) + ); + } + # add host systemd server services + { + systemd = lib.foldl' lib.attrsets.recursiveUpdate { } ( + map serverConfig (builtins.attrNames (enabledVmServices false)) + ); + } { microvm.vms = let - memsocket = pkgs.memsocket.override { vms = cfg.instancesCount; }; - vectors = toString (2 * cfg.instancesCount); - makeAssignment = vmName: { + configCommon = vmName: { ${vmName} = { config = { config = { @@ -197,10 +427,9 @@ in kernelParams = [ "kvm_ivshmem.flataddr=${cfg.flataddr}" ]; }; boot.extraModulePackages = [ - # TODO: fix this to not call back to packages dir - (pkgs.linuxPackages.callPackage ../../../packages/pkgs-by-name/memsocket/module.nix { + (pkgs.memsocket-module.override { inherit (config.microvm.vms.${vmName}.config.config.boot.kernelPackages) kernel; - vmCount = cfg.instancesCount; + inherit (cfg) shmSlots; }) ]; services = { @@ -213,47 +442,23 @@ in environment.systemPackages = [ memsocket ]; - systemd.user.services.memsocket = - if vmName == "gui-vm" then - { - enable = true; - description = "memsocket"; - after = [ "labwc.service" ]; - serviceConfig = { - Type = "simple"; - ExecStart = "${memsocket}/bin/memsocket -c ${cfg.clientSocketPath}"; - Restart = "always"; - RestartSec = "1"; - }; - wantedBy = [ "ghaf-session.target" ]; - } - else - # machines connecting to gui-vm - let - vmIndex = lists.findFirstIndex (vm: vm == vmName) null cfg.vms_enabled; - in - { - enable = true; - description = "memsocket"; - serviceConfig = { - Type = "simple"; - ExecStart = "${memsocket}/bin/memsocket -s ${cfg.serverSocketPath} ${builtins.toString vmIndex}"; - Restart = "always"; - RestartSec = "1"; - }; - wantedBy = [ "default.target" ]; - }; }; }; }; }; + # generate config for memsocket services running in client mode on VMs + clientsConfig = foldl' lib.attrsets.recursiveUpdate { } ( + map clientConfigTemplate (lib.filter (data: data.client != "host") clientServicePairs) + ); + # generate config for memsocket services running in server mode on VMs + clientsAndServers = lib.foldl' lib.attrsets.recursiveUpdate clientsConfig ( + map serverConfig (builtins.attrNames (enabledVmServices true)) + ); + finalMicroVmsConfig = foldl' lib.attrsets.recursiveUpdate clientsAndServers ( + map configCommon allVMs + ); in - foldl' lib.attrsets.recursiveUpdate { } (map makeAssignment cfg.vms_enabled); - } - { - microvm.vms.gui-vm.config.config.boot.kernelParams = [ - "kvm_ivshmem.flataddr=${cfg.flataddr}" - ]; + finalMicroVmsConfig; } ]); } diff --git a/modules/microvm/appvm.nix b/modules/microvm/appvm.nix index c7c0404880..3bf648386c 100644 --- a/modules/microvm/appvm.nix +++ b/modules/microvm/appvm.nix @@ -46,7 +46,10 @@ let vmName ; }) - ./common/ghaf-audio.nix + + (import (./common/ghaf-audio.nix) { + inherit configHost; + }) ./common/storagevm.nix ./common/xdgitems.nix ./common/xdghandlers.nix diff --git a/modules/microvm/common/ghaf-audio.nix b/modules/microvm/common/ghaf-audio.nix index 961243b7d8..c26dfe3c09 100644 --- a/modules/microvm/common/ghaf-audio.nix +++ b/modules/microvm/common/ghaf-audio.nix @@ -1,5 +1,8 @@ # Copyright 2022-2024 TII (SSRC) and the Ghaf contributors # SPDX-License-Identifier: Apache-2.0 +{ + configHost, +}: { config, lib, @@ -10,7 +13,11 @@ let cfg = config.ghaf.ghaf-audio; audiovmHost = "audio-vm"; audiovmPort = config.ghaf.services.audio.pulseaudioTcpPort; - address = "tcp:${audiovmHost}:${toString audiovmPort}"; + address = + if configHost.ghaf.shm.service.audio.enabled then + "unix:${configHost.ghaf.shm.service.audio.clientSocketPath}" + else + "tcp:${audiovmHost}:${toString audiovmPort}"; reconnectMs = 1000; in { diff --git a/modules/microvm/common/waypipe.nix b/modules/microvm/common/waypipe.nix index d2d5afecbc..a1d96f618e 100644 --- a/modules/microvm/common/waypipe.nix +++ b/modules/microvm/common/waypipe.nix @@ -15,23 +15,27 @@ }: let cfg = config.ghaf.waypipe; + cfgShm = configHost.ghaf.shm.service; waypipePort = configHost.ghaf.virtualization.microvm.appvm.waypipeBasePort + vmIndex; waypipeBorder = lib.optionalString ( cfg.waypipeBorder && vm.borderColor != null ) "--border \"${vm.borderColor}\""; + displayOptServer = + if cfgShm.gui.enabled then + "-s " + cfgShm.gui.serverSocketPath "gui" "-${vm.name}-vm" + else + "--vsock -s ${toString waypipePort}"; + displayOptClient = + if cfgShm.gui.enabled && (lib.lists.elem "${vm.name}-vm" cfgShm.gui.clients) then + "-s " + cfgShm.gui.clientSocketPath + else + "--vsock -s ${toString waypipePort}"; runWaypipe = let - script = - if configHost.ghaf.shm.display then - '' - #!${pkgs.runtimeShell} -e - ${pkgs.waypipe}/bin/waypipe -s ${configHost.ghaf.shm.serverSocketPath} server "$@" - '' - else - '' - #!${pkgs.runtimeShell} -e - ${pkgs.waypipe}/bin/waypipe --vsock -s ${toString waypipePort} server "$@" - ''; + script = '' + #!${pkgs.runtimeShell} -e + ${pkgs.waypipe}/bin/waypipe ${displayOptClient} server "$@" + ''; in pkgs.writeScriptBin "run-waypipe" script; guivmCID = configHost.ghaf.virtualization.microvm.guivm.vsockCID; @@ -77,11 +81,10 @@ in Type = "simple"; Restart = "always"; RestartSec = "1"; - ExecStart = - if configHost.ghaf.shm.display then - "${pkgs.waypipe}/bin/waypipe --secctx \"${vm.name}\" ${waypipeBorder} -s ${configHost.ghaf.shm.clientSocketPath} client" - else - "${pkgs.waypipe}/bin/waypipe --vsock --secctx \"${vm.name}\" ${waypipeBorder} -s ${toString waypipePort} client"; + ExecStart = "${pkgs.waypipe}/bin/waypipe --secctx \"${vm.name}\" ${waypipeBorder} ${displayOptServer} client"; + # Waypipe does not handle the SIGTERM signal properly, which is the default signal sent + # by systemd when stopping a service + KillSignal = "SIGINT"; }; startLimitIntervalSec = 0; partOf = [ "ghaf-session.target" ]; diff --git a/modules/profiles/laptop-x86.nix b/modules/profiles/laptop-x86.nix index f17ab400ac..f005031dc9 100644 --- a/modules/profiles/laptop-x86.nix +++ b/modules/profiles/laptop-x86.nix @@ -110,6 +110,10 @@ in host = { networking.enable = true; }; + + # Shared memory configuration + shm.enable = true; + shm.gui = true; }; }; } diff --git a/modules/reference/appvms/default.nix b/modules/reference/appvms/default.nix index 293720326d..753b022842 100644 --- a/modules/reference/appvms/default.nix +++ b/modules/reference/appvms/default.nix @@ -32,6 +32,20 @@ in List of appvms to include in the Ghaf reference appvms module ''; }; + shm-audio-enabled-vms = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + description = '' + List of appvms that use shared memory to handle audio data + ''; + }; + shm-gui-enabled-vms = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + description = '' + List of appvms that use shared memory to handle GUI data + ''; + }; }; config = lib.mkIf cfg.enable { diff --git a/modules/reference/profiles/mvp-user-trial.nix b/modules/reference/profiles/mvp-user-trial.nix index 493cf481ac..9d33335ef2 100644 --- a/modules/reference/profiles/mvp-user-trial.nix +++ b/modules/reference/profiles/mvp-user-trial.nix @@ -37,29 +37,44 @@ in "chrome-vm" ]; - reference = { - appvms = { - enable = true; - chrome-vm = true; - gala-vm = true; - zathura-vm = true; - comms-vm = true; - business-vm = true; - }; + reference = + let + vms = { + chrome-vm = true; + gala-vm = true; + zathura-vm = true; + comms-vm = true; + business-vm = true; + }; + in + { + appvms = + { + enable = true; + } + // vms + // { + # Allow the above app VMs to access shared memory for GUI data handling + shm-gui-enabled-vms = builtins.attrNames vms; + } + # Allow the above app VMs to access shared memory for audio data handling + // { + shm-audio-enabled-vms = builtins.attrNames vms; + }; - services = { - enable = true; - dendrite = true; - proxy-business = lib.mkForce config.ghaf.reference.appvms.business-vm; - google-chromecast = true; - }; + services = { + enable = true; + dendrite = true; + proxy-business = lib.mkForce config.ghaf.reference.appvms.business-vm; + google-chromecast = true; + }; - personalize = { - keys.enable = true; - }; + personalize = { + keys.enable = true; + }; - desktop.applications.enable = true; - }; + desktop.applications.enable = true; + }; profiles = { laptop-x86 = { diff --git a/overlays/custom-packages/qemu/0001-ivshmem-flat-memory-support.patch b/overlays/custom-packages/qemu/0001-ivshmem-flat-memory-support.patch index c8292d9a01..100cf9156f 100644 --- a/overlays/custom-packages/qemu/0001-ivshmem-flat-memory-support.patch +++ b/overlays/custom-packages/qemu/0001-ivshmem-flat-memory-support.patch @@ -1,17 +1,17 @@ -From 13229d9e11eaf15eb6679be036364b9d0256f1c1 Mon Sep 17 00:00:00 2001 +From 51f29d8e1946bd5008f5e5f640ed93df58a2f4d9 Mon Sep 17 00:00:00 2001 From: Jaroslaw Kurowski -Date: Wed, 10 Jul 2024 15:21:07 +0400 +Date: Tue, 31 Dec 2024 13:53:19 +0400 Subject: ivshmem flat memory support --- - contrib/ivshmem-server/ivshmem-server.c | 6 +- + contrib/ivshmem-server/ivshmem-server.c | 7 ++-- hw/i386/pc_q35.c | 2 + - hw/misc/ivshmem.c | 74 ++++++++++++++++++++++--- + hw/misc/ivshmem.c | 54 ++++++++++++++++++++++++- include/hw/misc/ivshmem.h | 1 + - 4 files changed, 71 insertions(+), 12 deletions(-) + 4 files changed, 60 insertions(+), 4 deletions(-) diff --git a/contrib/ivshmem-server/ivshmem-server.c b/contrib/ivshmem-server/ivshmem-server.c -index 2f3c732..906c5d0 100644 +index 2f3c732..e7c7774 100644 --- a/contrib/ivshmem-server/ivshmem-server.c +++ b/contrib/ivshmem-server/ivshmem-server.c @@ -11,6 +11,7 @@ @@ -36,6 +36,14 @@ index 2f3c732..906c5d0 100644 g_free(filename); } +@@ -347,6 +347,7 @@ ivshmem_server_start(IvshmemServer *server) + + server->sock_fd = sock_fd; + server->shm_fd = shm_fd; ++ server->cur_id = 1; + + return 0; + diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index c7bc8a2..d76939e 100644 --- a/hw/i386/pc_q35.c @@ -57,7 +65,7 @@ index c7bc8a2..d76939e 100644 pc_q35_compat_defaults, pc_q35_compat_defaults_len); } diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c -index de49d1b..b1761b3 100644 +index de49d1b..1a65fb8 100644 --- a/hw/misc/ivshmem.c +++ b/hw/misc/ivshmem.c @@ -36,6 +36,7 @@ @@ -114,7 +122,7 @@ index de49d1b..b1761b3 100644 if (s->ivshmem_bar2) { error_setg(errp, "server sent unexpected shared memory message"); -@@ -494,13 +511,26 @@ static void process_msg_shmem(IVShmemState *s, int fd, Error **errp) +@@ -494,13 +511,25 @@ static void process_msg_shmem(IVShmemState *s, int fd, Error **errp) size = buf.st_size; @@ -132,68 +140,16 @@ index de49d1b..b1761b3 100644 + } + /* mmap the region and map into the BAR2 */ -- if (!memory_region_init_ram_from_fd(&s->server_bar2, OBJECT(s), -- "ivshmem.bar2", size, RAM_SHARED, -- fd, 0, errp)) { -+ memory_region_init_ram_from_fd(&s->server_bar2, OBJECT(s), "ivshmem.bar2", -+ size, RAM_SHARED, fd, 0, &local_err); -+ if (local_err) { -+ error_propagate(errp, local_err); + if (!memory_region_init_ram_from_fd(&s->server_bar2, OBJECT(s), + "ivshmem.bar2", size, RAM_SHARED, + fd, 0, errp)) { return; } - s->ivshmem_bar2 = &s->server_bar2; } -@@ -832,7 +862,6 @@ static void ivshmem_write_config(PCIDevice *pdev, uint32_t address, - - static void ivshmem_common_realize(PCIDevice *dev, Error **errp) - { -- ERRP_GUARD(); - IVShmemState *s = IVSHMEM_COMMON(dev); - Error *err = NULL; - uint8_t *pci_conf; -@@ -902,7 +931,8 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp) - if (!ivshmem_is_master(s)) { - error_setg(&s->migration_blocker, - "Migration is disabled when using feature 'peer mode' in device 'ivshmem'"); -- if (migrate_add_blocker(&s->migration_blocker, errp) < 0) { -+ if (migrate_add_blocker(&s->migration_blocker, errp) < 0) { -+ error_free(s->migration_blocker); - return; - } - } -@@ -920,7 +950,10 @@ static void ivshmem_exit(PCIDevice *dev) - IVShmemState *s = IVSHMEM_COMMON(dev); - int i; - -- migrate_del_blocker(&s->migration_blocker); -+ if (s->migration_blocker) { -+ migrate_del_blocker(&s->migration_blocker); -+ error_free(s->migration_blocker); -+ } - - if (memory_region_is_mapped(s->ivshmem_bar2)) { - if (!s->hostmem) { -@@ -1014,7 +1047,7 @@ static const VMStateDescription ivshmem_plain_vmsd = { - .minimum_version_id = 0, - .pre_load = ivshmem_pre_load, - .post_load = ivshmem_post_load, -- .fields = (const VMStateField[]) { -+ .fields = (VMStateField[]) { - VMSTATE_PCI_DEVICE(parent_obj, IVShmemState), - VMSTATE_UINT32(intrstatus, IVShmemState), - VMSTATE_UINT32(intrmask, IVShmemState), -@@ -1068,7 +1101,7 @@ static const VMStateDescription ivshmem_doorbell_vmsd = { - .minimum_version_id = 0, - .pre_load = ivshmem_pre_load, - .post_load = ivshmem_post_load, -- .fields = (const VMStateField[]) { -+ .fields = (VMStateField[]) { - VMSTATE_PCI_DEVICE(parent_obj, IVShmemState), - VMSTATE_MSIX(parent_obj, IVShmemState), - VMSTATE_UINT32(intrstatus, IVShmemState), -@@ -1083,6 +1116,7 @@ static Property ivshmem_doorbell_properties[] = { +@@ -1083,6 +1112,7 @@ static Property ivshmem_doorbell_properties[] = { DEFINE_PROP_BIT("ioeventfd", IVShmemState, features, IVSHMEM_IOEVENTFD, true), DEFINE_PROP_ON_OFF_AUTO("master", IVShmemState, master, ON_OFF_AUTO_OFF), @@ -201,7 +157,7 @@ index de49d1b..b1761b3 100644 DEFINE_PROP_END_OF_LIST(), }; -@@ -1115,6 +1149,20 @@ static void ivshmem_doorbell_class_init(ObjectClass *klass, void *data) +@@ -1115,6 +1145,20 @@ static void ivshmem_doorbell_class_init(ObjectClass *klass, void *data) dc->vmsd = &ivshmem_doorbell_vmsd; } @@ -222,7 +178,7 @@ index de49d1b..b1761b3 100644 static const TypeInfo ivshmem_doorbell_info = { .name = TYPE_IVSHMEM_DOORBELL, .parent = TYPE_IVSHMEM_COMMON, -@@ -1123,11 +1171,19 @@ static const TypeInfo ivshmem_doorbell_info = { +@@ -1123,11 +1167,19 @@ static const TypeInfo ivshmem_doorbell_info = { .class_init = ivshmem_doorbell_class_init, }; @@ -254,5 +210,5 @@ index 433ef53..43aeab7 100644 #endif /* IVSHMEM_H */ -- -2.45.2 +2.47.1 diff --git a/packages/ghaf-powercontrol/package.nix b/packages/ghaf-powercontrol/package.nix index 0290ad42bc..0aace6519a 100644 --- a/packages/ghaf-powercontrol/package.nix +++ b/packages/ghaf-powercontrol/package.nix @@ -67,6 +67,8 @@ writeShellApplication { ;; logout) wayland-logout + loginctl terminate-user "$USER" + sleep 3 loginctl kill-user "$USER" -s SIGKILL ;; help|--help) diff --git a/packages/own-pkgs-overlay.nix b/packages/own-pkgs-overlay.nix index 5151f50b8e..f01bc57fb6 100644 --- a/packages/own-pkgs-overlay.nix +++ b/packages/own-pkgs-overlay.nix @@ -23,7 +23,8 @@ final.callPackage ./pkgs-by-name/kernel-hardening-checker/package.nix { }; make-checks = final.callPackage ./pkgs-by-name/make-checks/package.nix { }; - memsocket = final.callPackage ./pkgs-by-name/memsocket/package.nix { }; + memsocket-app = final.callPackage ./pkgs-by-name/memsocket/package.nix { }; + memsocket-module = final.callPackage ./pkgs-by-name/memsocket/module.nix { }; open-normal-extension = final.callPackage ./pkgs-by-name/open-normal-extension/package.nix { }; qemuqmp = final.callPackage ./pkgs-by-name/qemuqmp/package.nix { }; vhotplug = final.callPackage ./pkgs-by-name/vhotplug/package.nix { }; diff --git a/packages/pkgs-by-name/memsocket/module.nix b/packages/pkgs-by-name/memsocket/module.nix index e4ee0c06a4..03f1d5c679 100644 --- a/packages/pkgs-by-name/memsocket/module.nix +++ b/packages/pkgs-by-name/memsocket/module.nix @@ -3,20 +3,20 @@ { stdenv, lib, - kernel, + kernel ? null, fetchFromGitHub, - vmCount, + shmSlots ? null, ... }: stdenv.mkDerivation { - inherit vmCount; + inherit shmSlots; name = "ivshmem-driver-${kernel.version}"; src = fetchFromGitHub { owner = "tiiuae"; repo = "shmsockproxy"; - rev = "2357926b94ed12c050fdbfbfc0f248393a4c9ea1"; - sha256 = "sha256-9KlHuVbe5qvjRUXj7oyJ1X7CLvqj7/OoVGDWRqpIY2s="; + rev = "ea446dfe3be66004867b6b369950eb16dc04c421"; + sha256 = "sha256-qxrDHxM2z/bIVsTuNx45zZOjp4+BLheWrvco946OMQM="; }; sourceRoot = "source/module"; @@ -26,11 +26,21 @@ stdenv.mkDerivation { ]; nativeBuildInputs = kernel.moduleBuildDependencies; - makeFlags = [ - "KDIR=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build" - "MODULEDIR=$(out)/lib/modules/${kernel.modDirVersion}/kernel/drivers/char" - "CFLAGS_kvm_ivshmem.o=\"-DCONFIG_KVM_IVSHMEM_VM_COUNT=${builtins.toString vmCount}\"" - ]; + makeFlags = + [ + "KDIR=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build" + "MODULEDIR=$(out)/lib/modules/${kernel.modDirVersion}/kernel/drivers/char" + "CFLAGS_kvm_ivshmem.o=\"-DCONFIG_KVM_IVSHMEM_SHM_SLOTS=${builtins.toString shmSlots}\"" + "ARCH=${stdenv.hostPlatform.linuxArch}" + "INSTALL_MOD_PATH=${placeholder "out"}" + ] + ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ + "CROSS_COMPILE=${stdenv.cc}/bin/${stdenv.cc.targetPrefix}" + ]; + + CROSS_COMPILE = lib.optionalString ( + stdenv.hostPlatform != stdenv.buildPlatform + ) "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}"; meta = with lib; { description = "Shared memory Linux kernel module"; diff --git a/packages/pkgs-by-name/memsocket/package.nix b/packages/pkgs-by-name/memsocket/package.nix index 1e41cc2a13..05379a813d 100644 --- a/packages/pkgs-by-name/memsocket/package.nix +++ b/packages/pkgs-by-name/memsocket/package.nix @@ -3,7 +3,7 @@ { stdenv, debug ? false, - vms ? 0, + shmSlots ? null, fetchFromGitHub, ... }: @@ -13,11 +13,11 @@ stdenv.mkDerivation { src = fetchFromGitHub { owner = "tiiuae"; repo = "shmsockproxy"; - rev = "2357926b94ed12c050fdbfbfc0f248393a4c9ea1"; - sha256 = "sha256-9KlHuVbe5qvjRUXj7oyJ1X7CLvqj7/OoVGDWRqpIY2s="; + rev = "ea446dfe3be66004867b6b369950eb16dc04c421"; + sha256 = "sha256-qxrDHxM2z/bIVsTuNx45zZOjp4+BLheWrvco946OMQM="; }; - CFLAGS = "-O2 -DVM_COUNT=" + (toString vms) + (if debug then " -DDEBUG_ON" else ""); + CFLAGS = "-O2 -DSHM_SLOTS=" + (toString shmSlots) + (if debug then " -DDEBUG_ON" else ""); sourceRoot = "source/app"; installPhase = ''