mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-03 04:45:46 +00:00
Xen: Add writeFiltering option for PCI devices
By default Xen only allows guests to write "known safe" values into PCI configuration space, yet many devices require writes to other areas of the configuration space in order to operate properly. To allow writing any values Xen supports the 'permissive' setting, see xl.cfg(5) man page. This change models Xen's permissive setting by adding a writeFiltering attribute on the <source> element of a PCI hostdev. When writeFiltering is set to 'no', the Xen permissive setting will be enabled and guests will be able to write any values into the device's configuration space. The permissive setting remains disabled in the absense of the writeFiltering attribute, of if it is explicitly set to 'yes'. Signed-off-by: Jim Fehlig <jfehlig@suse.com> Signed-off-by: Simon Gaiser <simon@invisiblethingslab.com> Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
2ad009eadd
commit
9d15647dcb
@ -3733,7 +3733,7 @@ or:
|
|||||||
...
|
...
|
||||||
<devices>
|
<devices>
|
||||||
<hostdev mode='subsystem' type='pci' managed='yes'>
|
<hostdev mode='subsystem' type='pci' managed='yes'>
|
||||||
<source>
|
<source writeFiltering='no'>
|
||||||
<address domain='0x0000' bus='0x06' slot='0x02' function='0x0'/>
|
<address domain='0x0000' bus='0x06' slot='0x02' function='0x0'/>
|
||||||
</source>
|
</source>
|
||||||
<boot order='1'/>
|
<boot order='1'/>
|
||||||
@ -3899,6 +3899,11 @@ or:
|
|||||||
|
|
||||||
``pci``
|
``pci``
|
||||||
PCI devices can only be described by their ``address``.
|
PCI devices can only be described by their ``address``.
|
||||||
|
:since:`Since 6.8.0 (Xen only)` , the ``source`` element of a PCI device
|
||||||
|
may contain the ``writeFiltering`` attribute to control write access to
|
||||||
|
the PCI configuration space. By default Xen only allows writes of known
|
||||||
|
safe values to the configuration space. Setting ``writeFiltering='no'``
|
||||||
|
will allow all writes to the device's PCI configuration space.
|
||||||
``scsi``
|
``scsi``
|
||||||
SCSI devices are described by both the ``adapter`` and ``address``
|
SCSI devices are described by both the ``adapter`` and ``address``
|
||||||
elements. The ``address`` element includes a ``bus`` attribute (a 2-digit
|
elements. The ``address`` element includes a ``bus`` attribute (a 2-digit
|
||||||
|
@ -5021,6 +5021,11 @@
|
|||||||
<optional>
|
<optional>
|
||||||
<ref name="startupPolicy"/>
|
<ref name="startupPolicy"/>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="writeFiltering">
|
||||||
|
<ref name="virYesNo"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
<element name="address">
|
<element name="address">
|
||||||
<ref name="pciaddress"/>
|
<ref name="pciaddress"/>
|
||||||
</element>
|
</element>
|
||||||
|
@ -8137,8 +8137,18 @@ virDomainHostdevSubsysPCIDefParseXML(xmlNodePtr node,
|
|||||||
virDomainHostdevDefPtr def,
|
virDomainHostdevDefPtr def,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
|
g_autofree char *filtering = NULL;
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
|
|
||||||
|
if ((filtering = virXMLPropString(node, "writeFiltering"))) {
|
||||||
|
if ((def->writeFiltering = virTristateBoolTypeFromString(filtering)) < 0) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("unknown pci writeFiltering setting '%s'"),
|
||||||
|
filtering);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cur = node->children;
|
cur = node->children;
|
||||||
while (cur != NULL) {
|
while (cur != NULL) {
|
||||||
if (cur->type == XML_ELEMENT_NODE) {
|
if (cur->type == XML_ELEMENT_NODE) {
|
||||||
@ -26247,6 +26257,10 @@ virDomainHostdevDefFormatSubsysPCI(virBufferPtr buf,
|
|||||||
g_auto(virBuffer) origstatesChildBuf = VIR_BUFFER_INIT_CHILD(&sourceChildBuf);
|
g_auto(virBuffer) origstatesChildBuf = VIR_BUFFER_INIT_CHILD(&sourceChildBuf);
|
||||||
virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci;
|
virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci;
|
||||||
|
|
||||||
|
if (def->writeFiltering != VIR_TRISTATE_BOOL_ABSENT)
|
||||||
|
virBufferAsprintf(&sourceAttrBuf, " writeFiltering='%s'",
|
||||||
|
virTristateBoolTypeToString(def->writeFiltering));
|
||||||
|
|
||||||
if (pcisrc->backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) {
|
if (pcisrc->backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) {
|
||||||
const char *backend = virDomainHostdevSubsysPCIBackendTypeToString(pcisrc->backend);
|
const char *backend = virDomainHostdevSubsysPCIBackendTypeToString(pcisrc->backend);
|
||||||
|
|
||||||
|
@ -347,6 +347,7 @@ struct _virDomainHostdevDef {
|
|||||||
bool missing;
|
bool missing;
|
||||||
bool readonly;
|
bool readonly;
|
||||||
bool shareable;
|
bool shareable;
|
||||||
|
virTristateBool writeFiltering;
|
||||||
union {
|
union {
|
||||||
virDomainHostdevSubsys subsys;
|
virDomainHostdevSubsys subsys;
|
||||||
virDomainHostdevCaps caps;
|
virDomainHostdevCaps caps;
|
||||||
|
@ -2286,6 +2286,7 @@ libxlMakePCI(virDomainHostdevDefPtr hostdev, libxl_device_pci *pcidev)
|
|||||||
pcidev->bus = pcisrc->addr.bus;
|
pcidev->bus = pcisrc->addr.bus;
|
||||||
pcidev->dev = pcisrc->addr.slot;
|
pcidev->dev = pcisrc->addr.slot;
|
||||||
pcidev->func = pcisrc->addr.function;
|
pcidev->func = pcisrc->addr.function;
|
||||||
|
pcidev->permissive = hostdev->writeFiltering == VIR_TRISTATE_BOOL_NO;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1836,6 +1836,13 @@ qemuValidateDomainDeviceDefHostdev(const virDomainHostdevDef *hostdev,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hostdev->writeFiltering != VIR_TRISTATE_BOOL_ABSENT) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
|
_("Write filtering of PCI device configuration "
|
||||||
|
"space is not supported by qemu"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
|
||||||
|
@ -88,6 +88,12 @@
|
|||||||
"dev": 16,
|
"dev": 16,
|
||||||
"bus": 10,
|
"bus": 10,
|
||||||
"rdm_policy": "invalid"
|
"rdm_policy": "invalid"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"dev": 8,
|
||||||
|
"bus": 10,
|
||||||
|
"permissive": true,
|
||||||
|
"rdm_policy": "invalid"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"vfbs": [
|
"vfbs": [
|
||||||
|
@ -48,6 +48,11 @@
|
|||||||
<address type='pci' domain='0x0000' bus='0x0a' slot='0x10' function='0x0'/>
|
<address type='pci' domain='0x0000' bus='0x0a' slot='0x10' function='0x0'/>
|
||||||
</source>
|
</source>
|
||||||
</interface>
|
</interface>
|
||||||
|
<hostdev mode='subsystem' type='pci' managed='yes'>
|
||||||
|
<source writeFiltering='no'>
|
||||||
|
<address domain='0x0000' bus='0x0a' slot='0x08' function='0x0'/>
|
||||||
|
</source>
|
||||||
|
</hostdev>
|
||||||
<graphics type='vnc'/>
|
<graphics type='vnc'/>
|
||||||
<video>
|
<video>
|
||||||
<model type='cirrus' vram='8192' heads='1' primary='yes'/>
|
<model type='cirrus' vram='8192' heads='1' primary='yes'/>
|
||||||
|
Loading…
Reference in New Issue
Block a user