From 3da88be249973f7b74e7b24ed559e6abc2fc5af4 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 10 Nov 2020 11:47:14 +0300 Subject: thunderbolt: Add support for de-authorizing devices In some cases it is useful to be able de-authorize devices. For example if user logs out the userspace can have a policy that disconnects PCIe devices until logged in again. This is only possible for software based connection manager as it directly controls the tunnels. For this reason make the authorized attribute accept writing 0 which makes the software connection manager to tear down the corresponding PCIe tunnel. Userspace can check if this is supported by reading a new domain attribute deauthorization, that holds 1 in that case. While there correct tb_domain_approve_switch() kernel-doc and description of authorized attribute to mention that it is only about PCIe tunnels. Cc: Christian Kellner Signed-off-by: Mika Westerberg Acked-by: Yehezkel Bernat --- Documentation/admin-guide/thunderbolt.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'Documentation/admin-guide') diff --git a/Documentation/admin-guide/thunderbolt.rst b/Documentation/admin-guide/thunderbolt.rst index 613cb24c76c7..0d4348445f91 100644 --- a/Documentation/admin-guide/thunderbolt.rst +++ b/Documentation/admin-guide/thunderbolt.rst @@ -153,6 +153,22 @@ If the user still wants to connect the device they can either approve the device without a key or write a new key and write 1 to the ``authorized`` file to get the new key stored on the device NVM. +De-authorizing devices +---------------------- +It is possible to de-authorize devices by writing ``0`` to their +``authorized`` attribute. This requires support from the connection +manager implementation and can be checked by reading domain +``deauthorization`` attribute. If it reads ``1`` then the feature is +supported. + +When a device is de-authorized the PCIe tunnel from the parent device +PCIe downstream (or root) port to the device PCIe upstream port is torn +down. This is essentially the same thing as PCIe hot-remove and the PCIe +toplogy in question will not be accessible anymore until the device is +authorized again. If there is storage such as NVMe or similar involved, +there is a risk for data loss if the filesystem on that storage is not +properly shut down. You have been warned! + DMA protection utilizing IOMMU ------------------------------ Recent systems from 2018 and forward with Thunderbolt ports may natively -- cgit v1.2.3 From 3cd542e6e6afb6fa6c34d4094d498f42e22110f5 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 3 Sep 2020 13:13:21 +0300 Subject: thunderbolt: Add support for PCIe tunneling disabled (SL5) 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 Acked-by: Yehezkel Bernat --- Documentation/ABI/testing/sysfs-bus-thunderbolt | 2 ++ Documentation/admin-guide/thunderbolt.rst | 7 +++++++ drivers/thunderbolt/domain.c | 12 +++++++++++- drivers/thunderbolt/switch.c | 6 +++++- include/linux/thunderbolt.h | 3 +++ 5 files changed, 28 insertions(+), 2 deletions(-) (limited to 'Documentation/admin-guide') diff --git a/Documentation/ABI/testing/sysfs-bus-thunderbolt b/Documentation/ABI/testing/sysfs-bus-thunderbolt index 581dea95245b..d7f09d011b6d 100644 --- a/Documentation/ABI/testing/sysfs-bus-thunderbolt +++ b/Documentation/ABI/testing/sysfs-bus-thunderbolt @@ -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 diff --git a/Documentation/admin-guide/thunderbolt.rst b/Documentation/admin-guide/thunderbolt.rst index 0d4348445f91..f18e881373c4 100644 --- a/Documentation/admin-guide/thunderbolt.rst +++ b/Documentation/admin-guide/thunderbolt.rst @@ -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 diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c index 9ba2181464cc..a1c79c9c4f66 100644 --- a/drivers/thunderbolt/domain.c +++ b/drivers/thunderbolt/domain.c @@ -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; diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index 5377d0a3390f..b63fecca6c2a 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -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) { diff --git a/include/linux/thunderbolt.h b/include/linux/thunderbolt.h index 034dccf93955..659a0a810fa1 100644 --- a/include/linux/thunderbolt.h +++ b/include/linux/thunderbolt.h @@ -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, }; /** -- cgit v1.2.3