mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
Add virtio-related options to interfaces
<interface type='user'> <mac address='52:54:56:5a:5c:5e'/> <model type='virtio'/> <driver iommu='on' ats='on'/> </interface> https://bugzilla.redhat.com/show_bug.cgi?id=1283251 Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
parent
d1feb4773d
commit
fd51864340
@ -3451,6 +3451,19 @@
|
|||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
<h4><a name="elementsVirtio">Virtio-related options</a></h4>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
QEMU's virtio devices have some attributes related to the virtio transport under
|
||||||
|
the <code>driver</code> element:
|
||||||
|
The <code>iommu</code> attribute enables the use of emulated IOMMU
|
||||||
|
by the device. The attribute <code>ats</code> controls the Address
|
||||||
|
Translation Service support for PCIe devices. This is needed to make use
|
||||||
|
of IOTLB support (see <a href="#elementsIommu">IOMMU device</a>).
|
||||||
|
Possible values are <code>on</code> or <code>off</code>.
|
||||||
|
<span class="since">Since 3.5.0</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
<h4><a name="elementsControllers">Controllers</a></h4>
|
<h4><a name="elementsControllers">Controllers</a></h4>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -5142,6 +5155,12 @@ qemu-kvm -net nic,model=? /dev/null
|
|||||||
<b>In general you should leave this option alone, unless you
|
<b>In general you should leave this option alone, unless you
|
||||||
are very certain you know what you are doing.</b>
|
are very certain you know what you are doing.</b>
|
||||||
</dd>
|
</dd>
|
||||||
|
<dt>virtio options</dt>
|
||||||
|
<dd>
|
||||||
|
For virtio interfaces,
|
||||||
|
<a href="#elementsVirtio">Virtio-specific options</a> can also be
|
||||||
|
set. (<span class="since">Since 3.5.0</span>)
|
||||||
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<p>
|
<p>
|
||||||
Offloading options for the host and guest can be configured using
|
Offloading options for the host and guest can be configured using
|
||||||
|
@ -2686,6 +2686,7 @@
|
|||||||
</optional>
|
</optional>
|
||||||
</group>
|
</group>
|
||||||
</choice>
|
</choice>
|
||||||
|
<ref name="virtioOptions"/>
|
||||||
<interleave>
|
<interleave>
|
||||||
<optional>
|
<optional>
|
||||||
<element name='host'>
|
<element name='host'>
|
||||||
@ -5006,6 +5007,17 @@
|
|||||||
</element>
|
</element>
|
||||||
</define>
|
</define>
|
||||||
|
|
||||||
|
<define name="virtioOptions">
|
||||||
|
<optional>
|
||||||
|
<attribute name="iommu">
|
||||||
|
<ref name="virOnOff"/>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="ats">
|
||||||
|
<ref name="virOnOff"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
</define>
|
||||||
|
|
||||||
<define name="usbmaster">
|
<define name="usbmaster">
|
||||||
<element name="master">
|
<element name="master">
|
||||||
<attribute name="startport">
|
<attribute name="startport">
|
||||||
|
@ -1112,6 +1112,46 @@ virDomainXMLOptionGetNamespace(virDomainXMLOptionPtr xmlopt)
|
|||||||
return &xmlopt->ns;
|
return &xmlopt->ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virDomainVirtioOptionsParseXML(xmlXPathContextPtr ctxt,
|
||||||
|
virDomainVirtioOptionsPtr *virtio)
|
||||||
|
{
|
||||||
|
char *str = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
int val;
|
||||||
|
virDomainVirtioOptionsPtr res;
|
||||||
|
|
||||||
|
if (VIR_ALLOC(*virtio) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
res = *virtio;
|
||||||
|
|
||||||
|
if ((str = virXPathString("string(./driver/@iommu)", ctxt))) {
|
||||||
|
if ((val = virTristateSwitchTypeFromString(str)) <= 0) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
|
_("invalid iommu value"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
res->iommu = val;
|
||||||
|
}
|
||||||
|
VIR_FREE(str);
|
||||||
|
|
||||||
|
if ((str = virXPathString("string(./driver/@ats)", ctxt))) {
|
||||||
|
if ((val = virTristateSwitchTypeFromString(str)) <= 0) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
|
_("invalid ats value"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
res->ats = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(str);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
virSaveCookieCallbacksPtr
|
virSaveCookieCallbacksPtr
|
||||||
virDomainXMLOptionGetSaveCookie(virDomainXMLOptionPtr xmlopt)
|
virDomainXMLOptionGetSaveCookie(virDomainXMLOptionPtr xmlopt)
|
||||||
@ -1966,6 +2006,7 @@ virDomainNetDefClear(virDomainNetDefPtr def)
|
|||||||
VIR_FREE(def->ifname);
|
VIR_FREE(def->ifname);
|
||||||
VIR_FREE(def->ifname_guest);
|
VIR_FREE(def->ifname_guest);
|
||||||
VIR_FREE(def->ifname_guest_actual);
|
VIR_FREE(def->ifname_guest_actual);
|
||||||
|
VIR_FREE(def->virtio);
|
||||||
|
|
||||||
virNetDevIPInfoClear(&def->guestIP);
|
virNetDevIPInfoClear(&def->guestIP);
|
||||||
virNetDevIPInfoClear(&def->hostIP);
|
virNetDevIPInfoClear(&def->hostIP);
|
||||||
@ -4339,6 +4380,28 @@ virDomainHostdevDefPostParse(virDomainHostdevDefPtr dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virDomainCheckVirtioOptions(virDomainVirtioOptionsPtr virtio)
|
||||||
|
{
|
||||||
|
if (!virtio)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (virtio->iommu != VIR_TRISTATE_SWITCH_ABSENT) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
|
_("iommu driver option is only supported "
|
||||||
|
"for virtio devices"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (virtio->ats != VIR_TRISTATE_SWITCH_ABSENT) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
|
_("ats driver option is only supported "
|
||||||
|
"for virtio devices"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virDomainDeviceDefPostParseInternal(virDomainDeviceDefPtr dev,
|
virDomainDeviceDefPostParseInternal(virDomainDeviceDefPtr dev,
|
||||||
const virDomainDef *def,
|
const virDomainDef *def,
|
||||||
@ -4437,6 +4500,13 @@ virDomainDeviceDefPostParseInternal(virDomainDeviceDefPtr dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dev->type == VIR_DOMAIN_DEVICE_NET) {
|
||||||
|
virDomainNetDefPtr net = dev->data.net;
|
||||||
|
if (STRNEQ_NULLABLE(net->model, "virtio") &&
|
||||||
|
virDomainCheckVirtioOptions(net->virtio) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5235,6 +5305,24 @@ virDomainDefValidate(virDomainDefPtr def,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
virDomainVirtioOptionsFormat(virBufferPtr buf,
|
||||||
|
virDomainVirtioOptionsPtr virtio)
|
||||||
|
{
|
||||||
|
if (!virtio)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (virtio->iommu != VIR_TRISTATE_SWITCH_ABSENT) {
|
||||||
|
virBufferAsprintf(buf, " iommu='%s'",
|
||||||
|
virTristateSwitchTypeToString(virtio->iommu));
|
||||||
|
}
|
||||||
|
if (virtio->ats != VIR_TRISTATE_SWITCH_ABSENT) {
|
||||||
|
virBufferAsprintf(buf, " ats='%s'",
|
||||||
|
virTristateSwitchTypeToString(virtio->ats));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Generate a string representation of a device address
|
/* Generate a string representation of a device address
|
||||||
* @info address Device address to stringify
|
* @info address Device address to stringify
|
||||||
*/
|
*/
|
||||||
@ -10381,6 +10469,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virDomainVirtioOptionsParseXML(ctxt, &def->virtio) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
ctxt->node = oldnode;
|
ctxt->node = oldnode;
|
||||||
VIR_FREE(macaddr);
|
VIR_FREE(macaddr);
|
||||||
@ -19004,6 +19095,30 @@ virDomainDeviceInfoCheckABIStability(virDomainDeviceInfoPtr src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
virDomainVirtioOptionsCheckABIStability(virDomainVirtioOptionsPtr src,
|
||||||
|
virDomainVirtioOptionsPtr dst)
|
||||||
|
{
|
||||||
|
if (src->iommu != dst->iommu) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("Target device iommu option '%s' does not "
|
||||||
|
"match source '%s'"),
|
||||||
|
virTristateSwitchTypeToString(dst->iommu),
|
||||||
|
virTristateSwitchTypeToString(src->iommu));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (src->ats != dst->ats) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("Target device ats option '%s' does not "
|
||||||
|
"match source '%s'"),
|
||||||
|
virTristateSwitchTypeToString(dst->ats),
|
||||||
|
virTristateSwitchTypeToString(src->ats));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
virDomainDiskDefCheckABIStability(virDomainDiskDefPtr src,
|
virDomainDiskDefCheckABIStability(virDomainDiskDefPtr src,
|
||||||
virDomainDiskDefPtr dst)
|
virDomainDiskDefPtr dst)
|
||||||
@ -19163,6 +19278,10 @@ virDomainNetDefCheckABIStability(virDomainNetDefPtr src,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (src->virtio && dst->virtio &&
|
||||||
|
!virDomainVirtioOptionsCheckABIStability(src->virtio, dst->virtio))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!virDomainDeviceInfoCheckABIStability(&src->info, &dst->info))
|
if (!virDomainDeviceInfoCheckABIStability(&src->info, &dst->info))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -22118,6 +22237,8 @@ virDomainVirtioNetDriverFormat(char **outstr,
|
|||||||
virBufferAsprintf(&buf, " rx_queue_size='%u'",
|
virBufferAsprintf(&buf, " rx_queue_size='%u'",
|
||||||
def->driver.virtio.rx_queue_size);
|
def->driver.virtio.rx_queue_size);
|
||||||
|
|
||||||
|
virDomainVirtioOptionsFormat(&buf, def->virtio);
|
||||||
|
|
||||||
if (virBufferCheckError(&buf) < 0)
|
if (virBufferCheckError(&buf) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -156,6 +156,9 @@ typedef virDomainTPMDef *virDomainTPMDefPtr;
|
|||||||
typedef struct _virDomainIOMMUDef virDomainIOMMUDef;
|
typedef struct _virDomainIOMMUDef virDomainIOMMUDef;
|
||||||
typedef virDomainIOMMUDef *virDomainIOMMUDefPtr;
|
typedef virDomainIOMMUDef *virDomainIOMMUDefPtr;
|
||||||
|
|
||||||
|
typedef struct _virDomainVirtioOptions virDomainVirtioOptions;
|
||||||
|
typedef virDomainVirtioOptions *virDomainVirtioOptionsPtr;
|
||||||
|
|
||||||
/* Flags for the 'type' field in virDomainDeviceDef */
|
/* Flags for the 'type' field in virDomainDeviceDef */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
VIR_DOMAIN_DEVICE_NONE = 0,
|
VIR_DOMAIN_DEVICE_NONE = 0,
|
||||||
@ -1040,6 +1043,7 @@ struct _virDomainNetDef {
|
|||||||
int linkstate;
|
int linkstate;
|
||||||
unsigned int mtu;
|
unsigned int mtu;
|
||||||
virNetDevCoalescePtr coalesce;
|
virNetDevCoalescePtr coalesce;
|
||||||
|
virDomainVirtioOptionsPtr virtio;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -2215,6 +2219,12 @@ struct _virDomainIOMMUDef {
|
|||||||
virTristateSwitch eim;
|
virTristateSwitch eim;
|
||||||
virTristateSwitch iotlb;
|
virTristateSwitch iotlb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _virDomainVirtioOptions {
|
||||||
|
virTristateSwitch iommu;
|
||||||
|
virTristateSwitch ats;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Guest VM main configuration
|
* Guest VM main configuration
|
||||||
*
|
*
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
<interface type='user'>
|
<interface type='user'>
|
||||||
<mac address='52:54:56:58:5a:5c'/>
|
<mac address='52:54:56:58:5a:5c'/>
|
||||||
<model type='virtio'/>
|
<model type='virtio'/>
|
||||||
|
<driver iommu='on' ats='on'/>
|
||||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
|
||||||
</interface>
|
</interface>
|
||||||
<input type='mouse' bus='virtio'>
|
<input type='mouse' bus='virtio'>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user