From 788624398d67a8e3c7338fd8539d3be1d9a49049 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 26 Jun 2023 12:21:10 +0200 Subject: [qemu] Passthrough: Find free PCI slot on primary PCI bus Explicitly assign a slot number on the primary PCI bus to the VGA card, otherwise the two functions of the GPU (gfx and sound) might end up in different slots or even on different buses, which might cause issues. We now put all parts of the GPU in one slot and copy the original function IDs. --- ...sformationSpecificQemuGpuPassthroughNvidia.java | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'core/modules/qemu') diff --git a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/TransformationSpecificQemuGpuPassthroughNvidia.java b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/TransformationSpecificQemuGpuPassthroughNvidia.java index e06c4419..23e5fe18 100644 --- a/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/TransformationSpecificQemuGpuPassthroughNvidia.java +++ b/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/TransformationSpecificQemuGpuPassthroughNvidia.java @@ -12,6 +12,7 @@ import org.openslx.libvirt.domain.device.HostdevPciDeviceAddress; import org.openslx.libvirt.domain.device.HostdevPciDeviceDescription; import org.openslx.libvirt.domain.device.Shmem; import org.openslx.libvirt.domain.device.Video; +import org.openslx.libvirt.domain.device.Device; import org.openslx.libvirt.domain.device.Graphics.ListenType; import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs; import org.openslx.runvirt.plugin.qemu.virtualization.LibvirtHypervisorQemu; @@ -212,12 +213,36 @@ public class TransformationSpecificQemuGpuPassthroughNvidia final String errorMsg = "IOMMU support is not available on the hypervisor but required for GPU passthrough!"; throw new TransformationException( errorMsg ); } + // Check config for PCI addresses already in use + boolean inUse[] = new boolean[ 64 ]; + inUse[0] = true; + inUse[1] = true; + for ( Device dev : config.getDevices() ) { + HostdevPciDeviceAddress target = dev.getPciTarget(); + if ( target == null ) + continue; + if ( target.getPciDomain() != 0 || target.getPciBus() != 0 ) + continue; // Ignore non-primary bus + if ( target.getPciDevice() >= inUse.length ) + continue; + inUse[target.getPciDevice()] = true; + } + // Use first free one. Usually 00:02:00 is primary VGA + int devAddr; + for ( devAddr = 0; devAddr < inUse.length; ++devAddr ) { + if ( !inUse[devAddr] ) + break; + } // passthrough PCI devices of the GPU for ( final HostdevPciDeviceAddress pciDeviceAddress : pciDeviceAddresses ) { final HostdevPci pciDevice = config.addHostdevPciDevice(); pciDevice.setManaged( true ); pciDevice.setSource( pciDeviceAddress ); + if ( pciDeviceAddress.getPciFunction() == 0 && pciDeviceAddresses.size() > 1 ) { + pciDevice.setMultifunction( true ); + } + pciDevice.setPciTarget( new HostdevPciDeviceAddress( 0, devAddr, pciDeviceAddress.getPciFunction() ) ); } // add shared memory device for Looking Glass -- cgit v1.2.3-55-g7522