]> git.proxmox.com Git - ovs.git/commitdiff
netdev-dpdk: vHost IOMMU support
authorMark Kavanagh <mark.b.kavanagh@intel.com>
Fri, 8 Dec 2017 10:53:47 +0000 (10:53 +0000)
committerIan Stokes <ian.stokes@intel.com>
Fri, 8 Dec 2017 21:42:54 +0000 (21:42 +0000)
DPDK v17.11 introduces support for the vHost IOMMU feature.
This is a security feature, which restricts the vhost memory
that a virtio device may access.

This feature also enables the vhost REPLY_ACK protocol, the
implementation of which is known to work in newer versions of
QEMU (i.e. v2.10.0), but is buggy in older versions (v2.7.0 -
v2.9.0, inclusive). As such, the feature is disabled by default
in (and should remain so), for the aforementioned older QEMU
verions. Starting with QEMU v2.9.1, vhost-iommu-support can
safely be enabled, even without having an IOMMU device, with
no performance penalty.

This patch adds a new global config option, vhost-iommu-support,
that controls enablement of the vhost IOMMU feature:

    ovs-vsctl set Open_vSwitch . other_config:vhost-iommu-support=true

This value defaults to false; to enable IOMMU support, this field
should be set to true when setting other global parameters on init
(such as "dpdk-socket-mem", for example). Changing the value at
runtime is not supported, and requires restarting the vswitch daemon.

Signed-off-by: Mark Kavanagh <mark.b.kavanagh@intel.com>
Acked-by: Kevin Traynor <ktraynor@redhat.com>
Signed-off-by: Ian Stokes <ian.stokes@intel.com>
Documentation/topics/dpdk/vhost-user.rst
NEWS
lib/dpdk-stub.c
lib/dpdk.c
lib/dpdk.h
lib/netdev-dpdk.c
vswitchd/vswitch.xml

index a43affaa70cd65b34a106be3c14564512f575e6c..8447e2deec30949c074eeae455bddd540764963b 100644 (file)
@@ -273,6 +273,34 @@ One benefit of using this mode is the ability for vHost ports to 'reconnect' in
 event of the switch crashing or being brought down. Once it is brought back up,
 the vHost ports will reconnect automatically and normal service will resume.
 
+vhost-user-client IOMMU Support
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+vhost IOMMU is a feature which restricts the vhost memory that a virtio device
+can access, and as such is useful in deployments in which security is a
+concern.
+
+IOMMU support may be enabled via a global config value,
+```vhost-iommu-support```. Setting this to true enables vhost IOMMU support for
+all vhost ports when/where available::
+
+    $ ovs-vsctl set Open_vSwitch . other_config:vhost-iommu-support=true
+
+The default value is false.
+
+.. important::
+
+    Changing this value requires restarting the daemon.
+
+.. important::
+
+    Enabling the IOMMU feature also enables the vhost user reply-ack protocol;
+    this is known to work on QEMU v2.10.0, but is buggy on older versions
+    (2.7.0 - 2.9.0, inclusive). Consequently, the IOMMU feature is disabled by
+    default (and should remain so if using the aforementioned versions of
+    QEMU). Starting with QEMU v2.9.1, vhost-iommu-support can safely be
+    enabled, even without having an IOMMU device, with no performance penalty.
+
 .. _dpdk-testpmd:
 
 DPDK in the Guest
diff --git a/NEWS b/NEWS
index ff8e2a6257c2e93ce2cb543e3259c4c5d384d762..d45904e9c1be3cb3117dabc21e676508bb6b844c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,7 @@ Post-v2.8.0
      delete a specific connection tracking entry.
    - DPDK:
      * Add support for DPDK v17.11
+     * Add support for vHost IOMMU
 
 v2.8.0 - 31 Aug 2017
 --------------------
index daef7291f7630f51c903f1578a0bd77fa3de673e..36021807c3912b08486f4aa68198840ebc3add97 100644 (file)
@@ -48,3 +48,9 @@ dpdk_get_vhost_sock_dir(void)
 {
     return NULL;
 }
+
+bool
+dpdk_vhost_iommu_enabled(void)
+{
+    return false;
+}
index 8da6c324407e3b926ee5db0db7ec2156ce00335b..6710d10fcb4a2d9b85bb2c9a1c4c1cbb9d32a583 100644 (file)
@@ -41,6 +41,7 @@ VLOG_DEFINE_THIS_MODULE(dpdk);
 static FILE *log_stream = NULL;       /* Stream for DPDK log redirection */
 
 static char *vhost_sock_dir = NULL;   /* Location of vhost-user sockets */
+static bool vhost_iommu_enabled = false; /* Status of vHost IOMMU support */
 
 static int
 process_vhost_flags(char *flag, const char *default_val, int size,
@@ -345,6 +346,11 @@ dpdk_init__(const struct smap *ovs_other_config)
         vhost_sock_dir = sock_dir_subcomponent;
     }
 
+    vhost_iommu_enabled = smap_get_bool(ovs_other_config,
+                                        "vhost-iommu-support", false);
+    VLOG_INFO("IOMMU support for vhost-user-client %s.",
+               vhost_iommu_enabled ? "enabled" : "disabled");
+
     argv = grow_argv(&argv, 0, 1);
     argc = 1;
     argv[0] = xstrdup(ovs_get_program_name());
@@ -482,6 +488,12 @@ dpdk_get_vhost_sock_dir(void)
     return vhost_sock_dir;
 }
 
+bool
+dpdk_vhost_iommu_enabled(void)
+{
+    return vhost_iommu_enabled;
+}
+
 void
 dpdk_set_lcore_id(unsigned cpu)
 {
index 673a1f17efdde81b592c1d926436f386447b5a98..dc58d968afdf94254fcd502979ead5f5fead0581 100644 (file)
@@ -17,6 +17,8 @@
 #ifndef DPDK_H
 #define DPDK_H
 
+#include <stdbool.h>
+
 #ifdef DPDK_NETDEV
 
 #include <rte_config.h>
@@ -35,5 +37,6 @@ struct smap;
 void dpdk_init(const struct smap *ovs_other_config);
 void dpdk_set_lcore_id(unsigned cpu);
 const char *dpdk_get_vhost_sock_dir(void);
+bool dpdk_vhost_iommu_enabled(void);
 
 #endif /* dpdk.h */
index e4f0045b3c4cc4fc513eb48f43daf48415a38352..62fe21ff7c120a8586ec32950831dd9ae8f9b111 100644 (file)
@@ -3269,6 +3269,7 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev)
 {
     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
     int err;
+    uint64_t vhost_flags = 0;
 
     ovs_mutex_lock(&dev->mutex);
 
@@ -3279,16 +3280,21 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev)
      */
     if (!(dev->vhost_driver_flags & RTE_VHOST_USER_CLIENT)
             && strlen(dev->vhost_id)) {
-        /* Register client-mode device */
-        err = rte_vhost_driver_register(dev->vhost_id,
-                                        RTE_VHOST_USER_CLIENT);
+        /* Register client-mode device. */
+        vhost_flags |= RTE_VHOST_USER_CLIENT;
+
+        /* Enable IOMMU support, if explicitly requested. */
+        if (dpdk_vhost_iommu_enabled()) {
+            vhost_flags |= RTE_VHOST_USER_IOMMU_SUPPORT;
+        }
+        err = rte_vhost_driver_register(dev->vhost_id, vhost_flags);
         if (err) {
             VLOG_ERR("vhost-user device setup failure for device %s\n",
                      dev->vhost_id);
             goto unlock;
         } else {
             /* Configuration successful */
-            dev->vhost_driver_flags |= RTE_VHOST_USER_CLIENT;
+            dev->vhost_driver_flags |= vhost_flags;
             VLOG_INFO("vHost User device '%s' created in 'client' mode, "
                       "using client socket '%s'",
                       dev->up.name, dev->vhost_id);
index c145e1a59abb245203e50b103fbf6bdd45e0489f..4c317d062a32eb6c084b1fa82ffa63e67fd37e3d 100644 (file)
         </p>
       </column>
 
+      <column name="other_config" key="vhost-iommu-support"
+              type='{"type": "boolean"}'>
+        <p>
+          vHost IOMMU is a security feature, which restricts the vhost memory
+          that a virtio device may access. vHost IOMMU support is disabled by
+          default, due to a bug in QEMU implementations of the vhost REPLY_ACK
+          protocol, (on which vHost IOMMU relies) prior to v2.9.1. Setting this
+          value to <code>true</code> enables vHost IOMMU support for vHost User
+          Client ports in OvS-DPDK, starting from DPDK v17.11.
+        </p>
+        <p>
+          Changing this value requires restarting the daemon.
+        </p>
+      </column>
+
       <column name="other_config" key="n-handler-threads"
               type='{"type": "integer", "minInteger": 1}'>
         <p>