When using a passthrough GPU with libvirt there is no option to pass "x-vga=on" to the device specification. This means legacy VGA support isn't available which prevents any non-UEFI cards from POSTing and prevents some drivers from initialising for example Windows 10 NVIDIA driver for GeForce 8800. Signed-off-by: Steven Newbury <steve@xxxxxxxxxxxxxxx> --- src/conf/device_conf.c | 9 +++++++++ src/conf/domain_conf.c | 4 ++++ src/qemu/qemu_capabilities.c | 1 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 4 ++++ src/util/virpci.h | 1 + tools/virsh-domain.c | 6 ++++++ 7 files changed, 26 insertions(+) diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c index 87bf32bbc6..02d226747e 100644 --- a/src/conf/device_conf.c +++ b/src/conf/device_conf.c @@ -215,6 +215,7 @@ virPCIDeviceAddressParseXML(xmlNodePtr node, g_autofree char *slot = virXMLPropString(node, "slot"); g_autofree char *function = virXMLPropString(node, "function"); g_autofree char *multi = virXMLPropString(node, "multifunction"); + g_autofree char *vga = virXMLPropString(node, "vga"); memset(addr, 0, sizeof(*addr)); @@ -253,6 +254,14 @@ virPCIDeviceAddressParseXML(xmlNodePtr node, multi); return -1; + } + if (vga && + ((addr->vga = virTristateSwitchTypeFromString(vga)) <= 0)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unknown value '%s' for <address> 'vga' attribute"), + vga); + return -1; + } if (!virPCIDeviceAddressIsEmpty(addr) && !virPCIDeviceAddressIsValid(addr, true)) return -1; diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c003b5c030..048b0f4028 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -7587,6 +7587,10 @@ virDomainDeviceInfoFormat(virBufferPtr buf, virBufferAsprintf(&attrBuf, " multifunction='%s'", virTristateSwitchTypeToString(info->addr.pci.multi)); } + if (info->addr.pci.vga) { + virBufferAsprintf(&attrBuf, " vga='%s'", + virTristateSwitchTypeToString(info->addr.pci.vga)); + } if (virZPCIDeviceAddressIsPresent(&info->addr.pci.zpci)) { virBufferAsprintf(&childBuf, diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 38b901a6c4..b2864c1e9b 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -600,6 +600,7 @@ VIR_ENUM_IMPL(virQEMUCaps, /* 380 */ "usb-host.hostdevice", + "pci-vga", ); diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 107056ba17..d2d456fc43 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -580,6 +580,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ /* 380 */ QEMU_CAPS_USB_HOST_HOSTDEVICE, /* -device usb-host.hostdevice */ + X_QEMU_CAPS_PCI_VGA, /* -device x-vga=on|off */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 476cf6972e..b4285425ed 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -350,6 +350,10 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, virBufferAddLit(buf, ",multifunction=on"); else if (info->addr.pci.multi == VIR_TRISTATE_SWITCH_OFF) virBufferAddLit(buf, ",multifunction=off"); + if (info->addr.pci.vga == VIR_TRISTATE_SWITCH_ON) + virBufferAddLit(buf, ",x-vga=on"); + else if (info->addr.pci.vga == VIR_TRISTATE_SWITCH_OFF) + virBufferAddLit(buf, ",x-vga=off"); virBufferAsprintf(buf, ",addr=0x%x", info->addr.pci.slot); if (info->addr.pci.function != 0) virBufferAsprintf(buf, ".0x%x", info->addr.pci.function); diff --git a/src/util/virpci.h b/src/util/virpci.h index b3322ba61b..1ec2e3ba34 100644 --- a/src/util/virpci.h +++ b/src/util/virpci.h @@ -61,6 +61,7 @@ struct _virPCIDeviceAddress { unsigned int slot; unsigned int function; int multi; /* virTristateSwitch */ + int vga; /* virTristateSwitch */ int extFlags; /* enum virPCIDeviceAddressExtensionFlags */ virZPCIDeviceAddress zpci; /* Don't forget to update virPCIDeviceAddressCopy if needed. */ diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 8f11393197..587efbdb2a 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -294,6 +294,10 @@ static const vshCmdOptDef opts_attach_disk[] = { .type = VSH_OT_BOOL, .help = N_("use multifunction pci under specified address") }, + {.name = "vga", + .type = VSH_OT_BOOL, + .help = N_("enable legacy VGA") + }, {.name = "print-xml", .type = VSH_OT_BOOL, .help = N_("print XML document rather than attach the disk") @@ -694,6 +698,8 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd) diskAddr.addr.pci.slot, diskAddr.addr.pci.function); if (vshCommandOptBool(cmd, "multifunction")) virBufferAddLit(&buf, " multifunction='on'"); + if (vshCommandOptBool(cmd, "vga")) + virBufferAddLit(&buf, " vga='on'"); virBufferAddLit(&buf, "/>\n"); } else if (diskAddr.type == DISK_ADDR_TYPE_CCW) { virBufferAsprintf(&buf, -- 2.28.0