thunderbolt: Add support for PCIe tunneling disabled (SL5)
authorMika Westerberg <mika.westerberg@linux.intel.com>
Thu, 3 Sep 2020 10:13:21 +0000 (13:13 +0300)
committerMika Westerberg <mika.westerberg@linux.intel.com>
Thu, 4 Feb 2021 07:45:24 +0000 (10:45 +0300)
Recent Intel Thunderbolt firmware connection manager has support for
another security level, SL5, that disables PCIe tunneling. This option
can be turned on from the BIOS.

When this is set the driver exposes a new security level "nopcie" to the
userspace and hides the authorized attribute under connected devices.

While there we also hide it when "dponly" security level is enabled
since it is not really usable in that case anyway.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Yehezkel Bernat <YehezkelShB@gmail.com>
Documentation/ABI/testing/sysfs-bus-thunderbolt
Documentation/admin-guide/thunderbolt.rst
drivers/thunderbolt/domain.c
drivers/thunderbolt/switch.c
include/linux/thunderbolt.h

index 581dea95245bd415d3ceb29bd419073f297b9ae0..d7f09d011b6d29bc693f42ea527abc8697913ae0 100644 (file)
@@ -85,6 +85,8 @@ Description:  This attribute holds current Thunderbolt security level
                usbonly  Automatically tunnel USB controller of the
                         connected Thunderbolt dock (and Display Port). All
                         PCIe links downstream of the dock are removed.
+               nopcie   USB4 system where PCIe tunneling is disabled from
+                        the BIOS.
                =======  ==================================================
 
 What: /sys/bus/thunderbolt/devices/.../authorized
index 0d4348445f91c5482d3c07a2d852e667e07abbf7..f18e881373c4070b7ebd7bacdbb544a4625874d1 100644 (file)
@@ -47,6 +47,9 @@ be DMA masters and thus read contents of the host memory without CPU and OS
 knowing about it. There are ways to prevent this by setting up an IOMMU but
 it is not always available for various reasons.
 
+Some USB4 systems have a BIOS setting to disable PCIe tunneling. This is
+treated as another security level (nopcie).
+
 The security levels are as follows:
 
   none
@@ -77,6 +80,10 @@ The security levels are as follows:
     Display Port in a dock. All PCIe links downstream of the dock are
     removed.
 
+  nopcie
+    PCIe tunneling is disabled/forbidden from the BIOS. Available in some
+    USB4 systems.
+
 The current security level can be read from
 ``/sys/bus/thunderbolt/devices/domainX/security`` where ``domainX`` is
 the Thunderbolt domain the host controller manages. There is typically
index 9ba2181464cc66ad995c5a2ea19e9f05b3f20fe6..a1c79c9c4f669c096ef218b00d81234f6f7ba45a 100644 (file)
@@ -118,6 +118,7 @@ static const char * const tb_security_names[] = {
        [TB_SECURITY_SECURE] = "secure",
        [TB_SECURITY_DPONLY] = "dponly",
        [TB_SECURITY_USBONLY] = "usbonly",
+       [TB_SECURITY_NOPCIE] = "nopcie",
 };
 
 static ssize_t boot_acl_show(struct device *dev, struct device_attribute *attr,
@@ -243,8 +244,14 @@ static ssize_t deauthorization_show(struct device *dev,
                                    char *buf)
 {
        const struct tb *tb = container_of(dev, struct tb, dev);
+       bool deauthorization = false;
 
-       return sprintf(buf, "%d\n", !!tb->cm_ops->disapprove_switch);
+       /* Only meaningful if authorization is supported */
+       if (tb->security_level == TB_SECURITY_USER ||
+           tb->security_level == TB_SECURITY_SECURE)
+               deauthorization = !!tb->cm_ops->disapprove_switch;
+
+       return sprintf(buf, "%d\n", deauthorization);
 }
 static DEVICE_ATTR_RO(deauthorization);
 
@@ -452,6 +459,9 @@ int tb_domain_add(struct tb *tb)
                        goto err_ctl_stop;
        }
 
+       tb_dbg(tb, "security level set to %s\n",
+              tb_security_names[tb->security_level]);
+
        ret = device_add(&tb->dev);
        if (ret)
                goto err_ctl_stop;
index 5377d0a3390f3609d0ec0c4294db41068d440d30..b63fecca6c2a1fa9862c7aa77df41338ff89ffa5 100644 (file)
@@ -1774,7 +1774,11 @@ static umode_t switch_attr_is_visible(struct kobject *kobj,
        struct device *dev = kobj_to_dev(kobj);
        struct tb_switch *sw = tb_to_switch(dev);
 
-       if (attr == &dev_attr_device.attr) {
+       if (attr == &dev_attr_authorized.attr) {
+               if (sw->tb->security_level == TB_SECURITY_NOPCIE ||
+                   sw->tb->security_level == TB_SECURITY_DPONLY)
+                       return 0;
+       } else if (attr == &dev_attr_device.attr) {
                if (!sw->device)
                        return 0;
        } else if (attr == &dev_attr_device_name.attr) {
index 034dccf93955a1381f298af2045644f862834e36..659a0a810fa17f76e54d72b74cec051e706952c7 100644 (file)
@@ -45,6 +45,8 @@ enum tb_cfg_pkg_type {
  * @TB_SECURITY_USBONLY: Only tunnel USB controller of the connected
  *                      Thunderbolt dock (and Display Port). All PCIe
  *                      links downstream of the dock are removed.
+ * @TB_SECURITY_NOPCIE: For USB4 systems this level is used when the
+ *                     PCIe tunneling is disabled from the BIOS.
  */
 enum tb_security_level {
        TB_SECURITY_NONE,
@@ -52,6 +54,7 @@ enum tb_security_level {
        TB_SECURITY_SECURE,
        TB_SECURITY_DPONLY,
        TB_SECURITY_USBONLY,
+       TB_SECURITY_NOPCIE,
 };
 
 /**