Skip to content

Commit 3e86082

Browse files
nesteroffastro
authored andcommitted
Add support for creating PCIe root ports in QEMU
1 parent 43104cd commit 3e86082

File tree

2 files changed

+95
-8
lines changed

2 files changed

+95
-8
lines changed

lib/runners/qemu.nix

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ let
5454
else "threads";
5555

5656
inherit (microvmConfig) hostName vcpu mem balloon initialBalloonMem deflateOnOOM hotplugMem hotpluggedMem user interfaces shares socket forwardPorts devices vsock graphics storeOnDisk kernel initrdPath storeDisk credentialFiles;
57-
inherit (microvmConfig.qemu) machine extraArgs serialConsole;
57+
inherit (microvmConfig.qemu) machine extraArgs serialConsole pcieRootPorts;
5858

5959

6060
volumes = withDriveLetters microvmConfig;
@@ -197,11 +197,24 @@ lib.warnIf (mem == 2048) ''
197197

198198
"-chardev" "stdio,id=stdio,signal=off"
199199
"-device" "virtio-rng-${devType}"
200-
])
200+
] ++
201+
# Create PCIe root ports before vfio-pci devices that might require them
202+
builtins.concatMap ({ id, bus, chassis, slot, addr, ... }:
203+
[ "-device" "pcie-root-port,id=${id}${
204+
lib.optionalString (bus != null) ",bus=${bus}" +
205+
lib.optionalString (chassis != null) ",chassis=${toString chassis}" +
206+
lib.optionalString (slot != null) ",slot=${slot}" +
207+
lib.optionalString (addr != null) ",addr=${addr}"
208+
}"
209+
]
210+
) pcieRootPorts
211+
)
201212
+ " " + # Move vfio-pci outside of escapeShellArgs
202213
lib.concatStringsSep " " (lib.concatMap ({ bus, path, qemu,... }: {
203214
pci = [
204215
"-device" "vfio-pci,host=${path},multifunction=on${
216+
lib.optionalString (qemu.id != null) ",id=${qemu.id}" +
217+
lib.optionalString (qemu.bus != null) ",bus=${qemu.bus}" +
205218
# Allow to pass additional arguments to pci device
206219
lib.optionalString (qemu.deviceExtraArgs != null) ",${qemu.deviceExtraArgs}"
207220
}"

nixos-modules/microvm/options.nix

Lines changed: 80 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -421,12 +421,28 @@ in
421421
Identification of the device on its bus
422422
'';
423423
};
424-
qemu.deviceExtraArgs = mkOption {
425-
type = with types; nullOr str;
426-
default = null;
427-
description = ''
428-
Device additional arguments (optional)
429-
'';
424+
qemu = {
425+
id = mkOption {
426+
type = nullOr str;
427+
default = null;
428+
description = ''
429+
QEMU device identifier (optional)
430+
'';
431+
};
432+
bus = mkOption {
433+
type = nullOr str;
434+
default = null;
435+
description = ''
436+
QEMU bus to which this device is attached (optional)
437+
'';
438+
};
439+
deviceExtraArgs = mkOption {
440+
type = nullOr str;
441+
default = null;
442+
description = ''
443+
Device additional arguments (optional)
444+
'';
445+
};
430446
};
431447
};
432448
});
@@ -559,6 +575,64 @@ in
559575
'';
560576
};
561577

578+
qemu.pcieRootPorts = mkOption {
579+
description = ''
580+
A list of PCIe root ports that can be used for hot-plugging PCIe devices.
581+
This is particularly useful on the Q35 machine type, which does not support
582+
hot-plugging on the base PCIe root bus (pcie.0). Creating root ports allows
583+
attaching and detaching PCIe devices at runtime and can also be useful for
584+
devices that require their own dedicated PCIe slot with a fixed address, etc.
585+
For additional details see the QEMU PCI Express Guidelines:
586+
<https://gitlab.com/qemu-project/qemu/-/blob/master/docs/pcie.txt>
587+
'';
588+
default = [];
589+
example = literalExpression /* nix */ ''
590+
[ {
591+
bus = "pcie.0";
592+
id = "pci_port_0";
593+
chassis = 0;
594+
} ]
595+
'';
596+
type = with types; listOf (submodule {
597+
options = {
598+
id = mkOption {
599+
type = str;
600+
description = ''
601+
A unique identifier for this PCIe root port.
602+
'';
603+
};
604+
bus = mkOption {
605+
type = nullOr str;
606+
default = null;
607+
description = ''
608+
The PCIe bus on which the root port will be created.
609+
'';
610+
};
611+
chassis = mkOption {
612+
type = nullOr int;
613+
default = null;
614+
description = ''
615+
The chassis number associated with this PCIe root port.
616+
'';
617+
};
618+
slot = mkOption {
619+
type = nullOr str;
620+
default = null;
621+
description = ''
622+
PCIe slot number.
623+
'';
624+
};
625+
addr = mkOption {
626+
type = nullOr str;
627+
default = null;
628+
description = ''
629+
PCIe address on the parent bus.
630+
'';
631+
};
632+
};
633+
});
634+
};
635+
562636
cloud-hypervisor.platformOEMStrings = mkOption {
563637
type = with types; listOf str;
564638
default = [];

0 commit comments

Comments
 (0)