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(a)snewbury.org.uk>
---
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