diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 8d4330329e..f325c3c08c 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -2369,7 +2369,22 @@ the device as can be found with the lspci or with virsh nodedev-list. See above for - more details on the address element. + more details on the address element. +
driver
+
+ PCI devices can have an optional driver + subelement that specifies which backend driver to use for PCI + device assignment. Use the name 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)Since 1.0.5 (QEMU and KVM + only, requires kernel 3.6 or newer). 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. +
@@ -2975,6 +2990,18 @@ Since 0.9.11

+

+ 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 driver sub-element + with a name attribute set to "vfio". To use legacy + KVM device assignment you can set name to "kvm" (or + simply omit the <driver> element, since "kvm" + is currently the default). + Since 1.0.5 (QEMU and KVM only, requires kernel 3.6 or newer) +

+

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. Since 0.8.8 (QEMU and KVM only) +

+ For interfaces of type='hostdev' (PCI passthrough devices) + the name 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). + Since 1.0.5 (QEMU and KVM only, requires + kernel 3.6 or newer) +
+
txmode
The txmode attribute specifies how to handle diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in index 4dd0415df4..b1888968a6 100644 --- a/docs/formatnetwork.html.in +++ b/docs/formatnetwork.html.in @@ -279,6 +279,20 @@ use the traditional < hostdev> device definition. Since 0.10.0 +

+ 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 driver sub-element + with a name attribute set to "vfio". To use + legacy KVM device assignment you can + set name to "kvm" (or simply omit the + <driver> element, since "kvm" is currently the + default). + Since 1.0.5 (QEMU and KVM only, requires kernel 3.6 or newer) +

+

Note that this "intelligent passthrough" of network devices is very similar to the functionality of a standard < hostdev> device, the @@ -360,6 +374,7 @@

 ...
   <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'/>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 97859e71e9..10596dc0c0 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1939,28 +1939,40 @@
       
       
         
-          
-            
-              
-                qemu
-                vhost
-              
-            
-          
-          
-            
-              
-                iothread
-                timer
-              
-            
-          
-          
-            
-          
-          
-            
-          
+          
+            
+              
+                
+                  kvm
+                  vfio
+                
+              
+            
+            
+              
+                
+                  
+                    qemu
+                    vhost
+                  
+                
+              
+              
+                
+                  
+                    iothread
+                    timer
+                  
+                
+              
+              
+                
+              
+              
+                
+              
+            
+          
           
         
       
@@ -3107,14 +3119,27 @@
     
       pci
     
-    
+    
       
-        
+        
+          
+            
+              kvm
+              vfio
+            
+          
+          
+        
       
-      
-        
+      
+        
+          
+        
+        
+          
+        
       
-    
+    
   
 
   
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 6c3fae25a9..493edaeb64 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -149,6 +149,17 @@
                   
                 
               
+              
+                
+                  
+                    
+                      kvm
+                      vfio
+                    
+                  
+                  
+                
+              
             
           
         
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 5ed8faf2e9..3c6d260ed8 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -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  "
+                             "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, "\n", backend);
+    }
+
     virBufferAddLit(buf, "startupPolicy) {
         const char *policy;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 9f257bf229..b2f281580d 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -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;
 };