mirror of https://gitee.com/openkylin/libvirt.git
conf: formatter/parser/RNG/docs for hostdev <driver name='kvm|vfio'/>
A domain's <interface> or <hostdev>, as well as a <network>'s <forward>, can now have an optional <driver name='kvm|vfio'/> element. As of this patch, there is no functionality behind this new knob - this patch adds support to the domain and network formatter/parser, and to the RNG and documentation. When the backend is added, legacy KVM PCI device assignment will continue to be used when no driver name is specified (or if <driver name='kvm'/> is specified), but if driver name is 'vfio', the new UEFI Secure Boot compatible VFIO device assignment will be used. Note that the parser doesn't automatically insert the current default value of this setting. This is done on purpose because the two possibilities are functionally equivalent from the guest's point of view, and we want to be able to automatically start using vfio as the default (even for existing domains) at some time in the future. This is similar to what was done with the "vhost" driver option in <interface>.
This commit is contained in:
parent
9f80fc1bd5
commit
c4f63ef080
|
@ -2369,7 +2369,22 @@
|
|||
the device as can be found with the <code>lspci</code> or
|
||||
with <code>virsh
|
||||
nodedev-list</code>. <a href="#elementsAddress">See above</a> for
|
||||
more details on the address element.
|
||||
more details on the address element.</dd>
|
||||
<dt><code>driver</code></dt>
|
||||
<dd>
|
||||
PCI devices can have an optional <code>driver</code>
|
||||
subelement that specifies which backend driver to use for PCI
|
||||
device assignment. Use the <code>name</code> attribute to
|
||||
select either "vfio" (for the new VFIO device assignment
|
||||
backend, which is compatible with UEFI SecureBoot) or "kvm"
|
||||
(for the legacy device assignment handled directly by the KVM
|
||||
kernel module)<span class="since">Since 1.0.5 (QEMU and KVM
|
||||
only, requires kernel 3.6 or newer)</span>. Currently, "kvm"
|
||||
is the default used by libvirt when not explicitly provided,
|
||||
but since the two are functionally equivalent, this default
|
||||
could be changed in the future with no impact to domains that
|
||||
don't specify anything.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
|
@ -2975,6 +2990,18 @@
|
|||
<span class="since">Since 0.9.11</span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To use VFIO device assignment rather than traditional/legacy KVM
|
||||
device assignment (VFIO is a new method of device assignment
|
||||
that is compatible with UEFI Secure Boot), a type='hostdev'
|
||||
interface can have an optional <code>driver</code> sub-element
|
||||
with a <code>name</code> attribute set to "vfio". To use legacy
|
||||
KVM device assignment you can set <code>name</code> to "kvm" (or
|
||||
simply omit the <code><driver></code> element, since "kvm"
|
||||
is currently the default).
|
||||
<span class="since">Since 1.0.5 (QEMU and KVM only, requires kernel 3.6 or newer)</span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Note that this "intelligent passthrough" of network devices is
|
||||
very similar to the functionality of a standard <hostdev>
|
||||
|
@ -2993,6 +3020,7 @@
|
|||
...
|
||||
<devices>
|
||||
<interface type='hostdev'>
|
||||
<driver name='vfio'/>
|
||||
<source>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
|
||||
</source>
|
||||
|
@ -3124,6 +3152,19 @@ qemu-kvm -net nic,model=? /dev/null
|
|||
to 'qemu' without error.
|
||||
<span class="since">Since 0.8.8 (QEMU and KVM only)</span>
|
||||
</dd>
|
||||
<dd>
|
||||
For interfaces of type='hostdev' (PCI passthrough devices)
|
||||
the <code>name</code> attribute can optionally be set to
|
||||
"vfio" or "kvm". "vfio" tells libvirt to use VFIO device
|
||||
assignment rather than traditional KVM device assignment (VFIO
|
||||
is a new method of device assignment that is compatible with
|
||||
UEFI Secure Boot), and "kvm" tells libvirt to use the legacy
|
||||
device assignment performed directly by the kvm kernel module
|
||||
(the default is currently "kvm", but is subject to change).
|
||||
<span class="since">Since 1.0.5 (QEMU and KVM only, requires
|
||||
kernel 3.6 or newer)</span>
|
||||
</dd>
|
||||
|
||||
<dt><code>txmode</code></dt>
|
||||
<dd>
|
||||
The <code>txmode</code> attribute specifies how to handle
|
||||
|
|
|
@ -279,6 +279,20 @@
|
|||
use the traditional <code>< hostdev></code> device
|
||||
definition. <span class="since"> Since 0.10.0</span>
|
||||
|
||||
<p>
|
||||
To use VFIO device assignment rather than
|
||||
traditional/legacy KVM device assignment (VFIO is a new
|
||||
method of device assignment that is compatible with UEFI
|
||||
Secure Boot), a <forward type='hostdev'> interface
|
||||
can have an optional <code>driver</code> sub-element
|
||||
with a <code>name</code> attribute set to "vfio". To use
|
||||
legacy KVM device assignment you can
|
||||
set <code>name</code> to "kvm" (or simply omit the
|
||||
<driver> element, since "kvm" is currently the
|
||||
default).
|
||||
<span class="since">Since 1.0.5 (QEMU and KVM only, requires kernel 3.6 or newer)</span>
|
||||
</p>
|
||||
|
||||
<p>Note that this "intelligent passthrough" of network
|
||||
devices is very similar to the functionality of a
|
||||
standard <code>< hostdev></code> device, the
|
||||
|
@ -360,6 +374,7 @@
|
|||
<pre>
|
||||
...
|
||||
<forward mode='hostdev' managed='yes'>
|
||||
<driver name='vfio'/>
|
||||
<address type='pci' domain='0' bus='4' slot='0' function='1'/>
|
||||
<address type='pci' domain='0' bus='4' slot='0' function='2'/>
|
||||
<address type='pci' domain='0' bus='4' slot='0' function='3'/>
|
||||
|
|
|
@ -1939,28 +1939,40 @@
|
|||
</optional>
|
||||
<optional>
|
||||
<element name="driver">
|
||||
<optional>
|
||||
<attribute name="name">
|
||||
<choice>
|
||||
<value>qemu</value>
|
||||
<value>vhost</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="txmode">
|
||||
<choice>
|
||||
<value>iothread</value>
|
||||
<value>timer</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="ioeventfd"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="event_idx"/>
|
||||
</optional>
|
||||
<choice>
|
||||
<group>
|
||||
<attribute name="name">
|
||||
<choice>
|
||||
<value>kvm</value>
|
||||
<value>vfio</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
</group>
|
||||
<group>
|
||||
<optional>
|
||||
<attribute name="name">
|
||||
<choice>
|
||||
<value>qemu</value>
|
||||
<value>vhost</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="txmode">
|
||||
<choice>
|
||||
<value>iothread</value>
|
||||
<value>timer</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="ioeventfd"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="event_idx"/>
|
||||
</optional>
|
||||
</group>
|
||||
</choice>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
|
@ -3107,14 +3119,27 @@
|
|||
<attribute name="type">
|
||||
<value>pci</value>
|
||||
</attribute>
|
||||
<element name="source">
|
||||
<interleave>
|
||||
<optional>
|
||||
<ref name="startupPolicy"/>
|
||||
<element name="driver">
|
||||
<attribute name="name">
|
||||
<choice>
|
||||
<value>kvm</value>
|
||||
<value>vfio</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
<element name="address">
|
||||
<ref name="pciaddress"/>
|
||||
<element name="source">
|
||||
<optional>
|
||||
<ref name="startupPolicy"/>
|
||||
</optional>
|
||||
<element name="address">
|
||||
<ref name="pciaddress"/>
|
||||
</element>
|
||||
</element>
|
||||
</element>
|
||||
</interleave>
|
||||
</define>
|
||||
|
||||
<define name="hostdevsubsysusb">
|
||||
|
|
|
@ -149,6 +149,17 @@
|
|||
</attribute>
|
||||
</element>
|
||||
</optional>
|
||||
<optional>
|
||||
<element name="driver">
|
||||
<attribute name="name">
|
||||
<choice>
|
||||
<value>kvm</value>
|
||||
<value>vfio</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
</interleave>
|
||||
</element>
|
||||
</optional>
|
||||
|
|
|
@ -587,6 +587,12 @@ VIR_ENUM_IMPL(virDomainHostdevSubsys, VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST,
|
|||
"usb",
|
||||
"pci")
|
||||
|
||||
VIR_ENUM_IMPL(virDomainHostdevSubsysPciBackend,
|
||||
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST,
|
||||
"default",
|
||||
"kvm",
|
||||
"vfio")
|
||||
|
||||
VIR_ENUM_IMPL(virDomainHostdevCaps, VIR_DOMAIN_HOSTDEV_CAPS_TYPE_LAST,
|
||||
"storage",
|
||||
"misc",
|
||||
|
@ -3683,6 +3689,8 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
|
|||
{
|
||||
xmlNodePtr sourcenode;
|
||||
char *managed = NULL;
|
||||
char *backendStr = NULL;
|
||||
int backend;
|
||||
int ret = -1;
|
||||
|
||||
/* @managed can be read from the xml document - it is always an
|
||||
|
@ -3735,7 +3743,20 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
|
|||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
|
||||
if (virDomainHostdevSubsysPciDefParseXML(sourcenode, def, flags) < 0)
|
||||
goto error;
|
||||
|
||||
backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_DEFAULT;
|
||||
if ((backendStr = virXPathString("string(./driver/@name)", ctxt)) &&
|
||||
(((backend = virDomainHostdevSubsysPciBackendTypeFromString(backendStr)) < 0) ||
|
||||
backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_DEFAULT)) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Unknown PCI device <driver name='%s'/> "
|
||||
"has been specified"), backendStr);
|
||||
goto error;
|
||||
}
|
||||
def->source.subsys.u.pci.backend = backend;
|
||||
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
|
||||
if (virDomainHostdevSubsysUsbDefParseXML(sourcenode, def) < 0)
|
||||
goto error;
|
||||
|
@ -3746,9 +3767,11 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
|
|||
virDomainHostdevSubsysTypeToString(def->source.subsys.type));
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
error:
|
||||
VIR_FREE(managed);
|
||||
VIR_FREE(backendStr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -13822,6 +13845,19 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
|
|||
unsigned int flags,
|
||||
bool includeTypeInAddr)
|
||||
{
|
||||
if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
|
||||
def->source.subsys.u.pci.backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_DEFAULT) {
|
||||
const char *backend = virDomainHostdevSubsysPciBackendTypeToString(def->source.subsys.u.pci.backend);
|
||||
|
||||
if (!backend) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("unexpected pci hostdev driver name type %d"),
|
||||
def->source.subsys.u.pci.backend);
|
||||
return -1;
|
||||
}
|
||||
virBufferAsprintf(buf, "<driver name='%s'/>\n", backend);
|
||||
}
|
||||
|
||||
virBufferAddLit(buf, "<source");
|
||||
if (def->startupPolicy) {
|
||||
const char *policy;
|
||||
|
|
|
@ -389,6 +389,16 @@ enum virDomainHostdevSubsysType {
|
|||
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST
|
||||
};
|
||||
|
||||
/* the backend driver used for PCI hostdev devices */
|
||||
typedef enum {
|
||||
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_DEFAULT, /* currently kvm, could change */
|
||||
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_KVM, /* force legacy kvm style */
|
||||
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO, /* force vfio */
|
||||
|
||||
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST
|
||||
} virDomainHostdevSubsysPciBackendType;
|
||||
|
||||
VIR_ENUM_DECL(virDomainHostdevSubsysPciBackend)
|
||||
|
||||
typedef struct _virDomainHostdevSubsys virDomainHostdevSubsys;
|
||||
typedef virDomainHostdevSubsys *virDomainHostdevSubsysPtr;
|
||||
|
@ -406,6 +416,7 @@ struct _virDomainHostdevSubsys {
|
|||
} usb;
|
||||
struct {
|
||||
virDevicePCIAddress addr; /* host address */
|
||||
int backend; /* enum virDomainHostdevSubsysPciBackendType */
|
||||
} pci;
|
||||
} u;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue