All that follows is relating to muxless/non-MXM Optimus cards, i.e. those that
have no display outputs and show as 3D Controller
in lspci
output. If you
have a MXM / output-providing card (shows as VGA Controller
in lspci
), then
this is not for you. For such devices, see
@Misairu-G's guide
- Compute workloads (via render nodes) on GVT device
- You can find a sample program that dispatches a compute shader via render nodes here
- Compute workloads (via render nodes) on nvidia card (nouveau)
- Render workloads on the nvidia card with the nouveau driver, with a GVT device
as the guest's primary GPU
- I have only tested this with q35. i440fx is untested
- Subsystem vendor & device Id's must be set with x-pci-sub-vendor-id and x-pci-sub-device-id on the qemu vfio-pci device for the nvidia card
- Nvidia VBIOS must be provided to the guest via libvirt's
<rom file=...>
/ qemu'sromfile
option on the device- VBIOS can be obtained under linux by extracting a BIOS update using coderobe/VBiosFinder
- Alternatively, when using Windows the VBIOS can be obtained by dumping the system firmware with
Universal Bios Backup Toolkit
and using MMTool to extract the VBIOS fromthe "Option ROMs" section
- This needs to be done under bare-metal Windows. I use a Windows-To-Go install of Server 2016 on a USB (UAS) SSD for this, to leave my machine's internal storage alone.
- I've only tested this with OVMF/UEFI. It may or may not work with seabios VMs
- My dumped VBIOS did not have EFI support, but I don't think that is
necessary when the card has no outputs. rom-parser output for reference:
Valid ROM signature found @0h, PCIR offset 190h PCIR: type 0, vendor: 10de, device: 139b, class: 030200 PCIR: revision 3, vendor revision: 1 Last image ```
- Guest kernel must booted via OVMF directly, or via a bootloader that
supports the EFI handover protocol
- Failure to do this will result in nouveau failing to load vbios via the
FIRMWARE
interface - Mainline GRUB does not have EFI handover support. Fedora (and maybe
other distros) have their own patches adding support for this in the form
of the
linuxefi
command
- Failure to do this will result in nouveau failing to load vbios via the
- No local display output at present; remote display must be used.
- Render workloads on the nvidia card with the nvidia driver, with the GVT
device as secondary, linked with PRIME
- Requires a patch to the nvidia driver to fake loading VBIOS from ACPI. See below
- Render workloads on the GVT device, with the GVT device as the guest's primary
GPU
- Only tested on q35 + OVMF
- No VBIOS needed, everything should Just Work™
- No local display output at present; remote display must be used.
- Binary nvidia driver (Linux)
- For Optimus cards, it will only attempt to load VBIOS via ACPI _ROM method, which won't exist in the guest.
- We can probably patch
nv_acpi_rom_method
inkernel/nvidia/nv-acpi.c
to simply return our VBIOS from a hard-coded buffer, just for testing - Long term we need to build a custom ACPI table (provided to qemu with the
-acpitable
option) that has_ROM
implemented at the correct path. The_ROM
implementationm would need to seek over a hard-coded buffer stored elsewhere and return the VBIOS in 4kb chunks as expected by nvidia driver
- Windows guest
- Will need custom ACPI table to get VBIOS, as detailed above
- Reverse PRIME to mirror GVT display to QXL device to use Qemu's built in spice
server
- The
modesetting
DDX must be used with QXL, as theqxl
DDX lacks PRIME support - The QXL-backed modesetting instance can be set up as a PRIME output provider successfully, and modes will show as available on the newly created Virtual-X-Y output (where X and Y will vary depending on your xorg server's layout)
- Attempting to set any mode on the Virtual-X-Y output will fail with the
following errors from the kernel:
qxl 0000:00:03.0: swiotlb buffer is full (sz: 299008 bytes) qxl 0000:00:03.0: DMA: Out of SW-IOMMU space for 299008 bytes
- Next step may be to try with Qemu's emulated
intel-iommu
device and see if this helps
- Next step may be to try with Qemu's emulated
- The
- QXL as primary xorg GPU with GVT/nvidia as secondary
- QXL-backed modesetting provides only the
Sink Output
capability.Sink Offload
is required for render offloading to a device withSource Offload
- Maybe QXL could be improved to have the
Sink Offload
capability?
- Maybe QXL could be improved to have the
- Attempting to set up nouveau as the
Source Offload
for the GVT card (which hasSink Offload
) will crash Xorg with the following assertion failure:xorg-server-1.19.5/dix/dispatch.c:4035: AttachOutputGPU: Assertion 'new->current_master == pScreen' failed.
This suggests that PRIME render offload requires the destination device (the one being used as aSink Offload
to be the primary Xorg GPU
- QXL-backed modesetting provides only the
- Bumblebee
- Attempting to use bumblebee without a GVT device will fail as
bumblebeed
will bail out at startup upon not finding an Intel card- Patching out this check will allow
bumblebeed
to start.
- Patching out this check will allow
- Once
bumblebeed
has started, it is unable to successfully start the secondary X server, as the nvidia card has no outputs and Xorg bails out due to no outputs existing.- Nouveau does not support/have the
AllowEmptyInitialConfiguration
option that the proprietary nvidia driver has.
- Nouveau does not support/have the
- Attempting to use bumblebee without a GVT device will fail as
- Using the nvidia card in the guest as the sole GPU
- As non-MXM Optimus cards lack any outputs, xorg will not start as there are no outputs available
- xf86-video-dummy cannot be used as the primary GPU as it lacks PRIME support
- Wayland
- A way to obtain a dump of nvidia VBIOS under Linux
- Custom ACPI tables embedding nvidia VBIOS and exposing it via the
_ROM
method at the appropriate path