conf: allow display and ramfb for vfio pci hostdevs

We already allow the user to specify display="on" and ramfb="on" for
mdev host devices. But newer GPU models will no longer use the mdev
framework, so we should enable this same functionality for other
non-mdev passthrough PCI devices.

Resolves: https://issues.redhat.com/browse/RHEL-28808

Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Jonathon Jongsma 2024-03-13 10:53:06 -05:00
parent 16d37076be
commit 092f933a62
5 changed files with 57 additions and 19 deletions

View File

@ -4390,6 +4390,14 @@ or:
starting the guest or hot-plugging the device and starting the guest or hot-plugging the device and
``virNodeDeviceReAttach`` (or ``virsh nodedev-reattach``) after hot-unplug ``virNodeDeviceReAttach`` (or ``virsh nodedev-reattach``) after hot-unplug
or stopping the guest. or stopping the guest.
:since:`Since 10.3.0` an optional ``display`` attribute may be used to
enable using a vgpu device as a display device for the guest. Supported
values are either ``on`` or ``off`` (default). There is also an optional
``ramfb`` attribute with values of either ``on`` or ``off`` (default).
When enabled, the ``ramfb`` attribute provides a memory framebuffer device
to the guest. This framebuffer allows the vgpu to be used as a boot display
before the gpu driver is loaded within the guest. ``ramfb`` requires the
``display`` attribute to be set to ``on``.
``scsi`` ``scsi``
For SCSI devices, user is responsible to make sure the device is not used For SCSI devices, user is responsible to make sure the device is not used
by host. If supported by the hypervisor and OS, the optional ``sgio`` ( by host. If supported by the hypervisor and OS, the optional ``sgio`` (

View File

@ -6306,6 +6306,16 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
VIR_XML_PROP_NONE, VIR_XML_PROP_NONE,
&mdevsrc->ramfb) < 0) &mdevsrc->ramfb) < 0)
return -1; return -1;
} else if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
if (virXMLPropTristateSwitch(node, "display",
VIR_XML_PROP_NONE,
&pcisrc->display) < 0)
return -1;
if (virXMLPropTristateSwitch(node, "ramfb",
VIR_XML_PROP_NONE,
&pcisrc->ramfb) < 0)
return -1;
} }
switch (def->source.subsys.type) { switch (def->source.subsys.type) {
@ -26251,6 +26261,7 @@ virDomainHostdevDefFormat(virBuffer *buf,
const char *mode = virDomainHostdevModeTypeToString(def->mode); const char *mode = virDomainHostdevModeTypeToString(def->mode);
virDomainHostdevSubsysSCSI *scsisrc = &def->source.subsys.u.scsi; virDomainHostdevSubsysSCSI *scsisrc = &def->source.subsys.u.scsi;
virDomainHostdevSubsysMediatedDev *mdevsrc = &def->source.subsys.u.mdev; virDomainHostdevSubsysMediatedDev *mdevsrc = &def->source.subsys.u.mdev;
virDomainHostdevSubsysPCI *pcisrc = &def->source.subsys.u.pci;
virDomainHostdevSubsysSCSIVHost *scsihostsrc = &def->source.subsys.u.scsi_host; virDomainHostdevSubsysSCSIVHost *scsihostsrc = &def->source.subsys.u.scsi_host;
const char *type; const char *type;
@ -26319,7 +26330,14 @@ virDomainHostdevDefFormat(virBuffer *buf,
virBufferAsprintf(buf, " ramfb='%s'", virBufferAsprintf(buf, " ramfb='%s'",
virTristateSwitchTypeToString(mdevsrc->ramfb)); virTristateSwitchTypeToString(mdevsrc->ramfb));
} }
if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
if (pcisrc->display != VIR_TRISTATE_SWITCH_ABSENT)
virBufferAsprintf(buf, " display='%s'",
virTristateSwitchTypeToString(pcisrc->display));
if (pcisrc->ramfb != VIR_TRISTATE_SWITCH_ABSENT)
virBufferAsprintf(buf, " ramfb='%s'",
virTristateSwitchTypeToString(pcisrc->ramfb));
}
} }
virBufferAddLit(buf, ">\n"); virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 2); virBufferAdjustIndent(buf, 2);

View File

@ -236,6 +236,8 @@ struct _virDomainHostdevSubsysUSB {
struct _virDomainHostdevSubsysPCI { struct _virDomainHostdevSubsysPCI {
virPCIDeviceAddress addr; /* host address */ virPCIDeviceAddress addr; /* host address */
virDeviceHostdevPCIDriverInfo driver; virDeviceHostdevPCIDriverInfo driver;
virTristateSwitch display;
virTristateSwitch ramfb;
virBitmap *origstates; virBitmap *origstates;
}; };

View File

@ -1291,15 +1291,20 @@ virDomainDefHostdevValidate(const virDomainDef *def)
} }
} }
if (dev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && if (dev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
dev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV && virTristateSwitch *ramfbsetting = NULL;
dev->source.subsys.u.mdev.ramfb == VIR_TRISTATE_SWITCH_ON) { if (dev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV)
if (ramfbEnabled) { ramfbsetting = &dev->source.subsys.u.mdev.ramfb;
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", else if (dev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
_("Only one vgpu device can have 'ramfb' enabled")); ramfbsetting = &dev->source.subsys.u.pci.ramfb;
return -1; if (ramfbsetting && *ramfbsetting == VIR_TRISTATE_SWITCH_ON) {
if (ramfbEnabled) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Only one vgpu device can have 'ramfb' enabled"));
return -1;
}
ramfbEnabled = true;
} }
ramfbEnabled = true;
} }
} }

View File

@ -6267,6 +6267,7 @@
<ref name="pciaddress"/> <ref name="pciaddress"/>
</element> </element>
</element> </element>
<ref name="hostdevsubsysvfiodisplay"/>
</interleave> </interleave>
</define> </define>
@ -6386,6 +6387,19 @@
</element> </element>
</define> </define>
<define name="hostdevsubsysvfiodisplay">
<optional>
<attribute name="ramfb">
<ref name="virOnOff"/>
</attribute>
</optional>
<optional>
<attribute name="display">
<ref name="virOnOff"/>
</attribute>
</optional>
</define>
<define name="hostdevsubsysmdev"> <define name="hostdevsubsysmdev">
<attribute name="type"> <attribute name="type">
<value>mdev</value> <value>mdev</value>
@ -6397,16 +6411,7 @@
<value>vfio-ap</value> <value>vfio-ap</value>
</choice> </choice>
</attribute> </attribute>
<optional> <ref name="hostdevsubsysvfiodisplay"/>
<attribute name="ramfb">
<ref name="virOnOff"/>
</attribute>
</optional>
<optional>
<attribute name="display">
<ref name="virOnOff"/>
</attribute>
</optional>
<element name="source"> <element name="source">
<ref name="mdevaddress"/> <ref name="mdevaddress"/>
</element> </element>