[PATCH v2 00/27] Thunderbolt security levels and NVM firmware upgrade

From: Mika Westerberg
Date: Fri May 26 2017 - 12:12:34 EST


Hi all,

This patch series adds support for Thunderbolt security levels, which were
first introduced in Intel Falcon Ridge Thunderbolt controller, to prevent
DMA attacks when PCIe is tunneled over Thunderbolt fabric. This is needed
if there is no IOMMU available (or it is not enabled because of various
reasons).

Most PCs out there having Falcon Ridge or newer have security level set to
"user" which means that user authorization is needed before PCIe tunnel is
creaded (the PCIe device appears). This effectively means that without
driver support the user needs to configure security level from BIOS to
"none" to get Thunderbolt devices connected. With these patches the user
can authorize devices using sysfs attributes like:

# echo 1 > /sys/bus/thunderbolt/devices/0-1/authorized

In addition these patches add support for upgrading NVM firmware running on
a host or device by running something like:

# dd if=KYK_TBT_FW_0018.bin of=/sys/bus/thunderbolt/devices/0-0/nvm_non_active0/nvmem
# echo 1 > /sys/bus/thunderbolt/devices/0-0/nvm_authenticate

This is documented in more details in patch [26/27].

This series is based on Amir's networking patches [1] but instead of
splitting the functionality between kernel driver and userspace daemon, we
take advantage of Linux driver core by converting the existing driver to
expose a Linux bus (domain) and devices (switches). Notifications to the
userspace about plugged/unplugged devices is handled by standard uevents
when a device is added to/removed from the Thunderbolt bus.

Since thunderbolt device identification and authorization can be done
directly through sysfs attributes there is no need for userspace daemon.
However, there still should be an application that promps user for unknown
devices and allows selecting between "single connect" and "connect always"
keeping this information in a database or similar persistent storage. This
patch series only provides mechanism for userspace applications to achieve
that.

Where Internal Connection Manager (ICM) firmware is available and usable,
we use it in the driver. This also includes newer Apple Macbooks with
Alpine Ridge. For older Macbooks the driver works as before but in addition
the Thunderbolt bus is available there as well (including possibility to
upgrade NVM firmware of connected devices).

We are also in works of porting Amir's networking driver to work on top of
the new Thunderbolt bus pretty much the same way firewire networking is
currently done. In addition this makes is possible to introduce other
protocols like a char device that allows userspace directly to communicate
accross Thunderbolt domains.

Note for Macs the Linux native PCIe hotplug support does not work well with
the Thunderbolt PCIe topologies where there is need to put all available
resources to the PCIe downstream port where the PCIe chain is extended.
This is something we need to fix. In the mean time is a way to work it
around by passing "pci=hpbussize=10,hpmemsize=2M" or so to the kernel
command line.

These patches use uuid_be from uuid.h but I've learned that there is a work
to remove the type completely in favor of new uuid_t [2]. I'm not sure what
to do regarding that because those patches are not yet in the mainline.

Below is a list of changes from the v1:

- Add tags from Andy and Greg

- Add a patch "thunderbolt: No need to read UID of the root switch on
resume" suggested by Andreas.

- Add a patch "thunderbolt: Allow passing NULL to tb_ctl_free() suggested
by Andy.

- Add a patch "thunderbolt: Refactor and fix parsing of port drom entries"
from Lukas.

[PATCH 04/24] thunderbolt: Add MSI-X support
- Merge ring_map_unmap_msix() into ring_interrupt_active()
- Call flush_work() only when MSI-X is not enabled
- Update comment to mention ring_msix

[PATCH 05/24] thunderbolt: Rework capability handling
- Add kernel-doc comment for structs tb_cap_extended_long/short that
links fields cap and vsec_id to the corresponding enums
- Correct typo in tb_switch_find_cap() kernel doc.

[PATCH 06/24] thunderbolt: Introduce thunderbolt bus and connection manager
- No need to check for tb->ctl != NULL.
- Call ida_destroy() for tb_domain_ida in tb_domain_exit()

[PATCH 07/24] thunderbolt: Convert switch to a device
- Rename label "err" to "err_free_sw_ports"
- Remove extra space after cast
- Reverse order in tb_switch_set_uuid(), first read UUID from
registers and if that does not work, use UID instead with syntetic
UUID following ICM.
- Instead of ATTRIBUTE_GROUPS() we use struct attribute_group
directly. This is because in following patches we are going to add
.is_visible() for the attributes that are conditional.

[PATCH 10/24] thunderbolt: Read vendor and device name from DROM
- Rename tb_drom_parse_generic_entry() to
tb_drom_parse_entry_generic() to follow tb_drom_parse_entry_port().
- Use make sure names get null terminated

[PATCH 15/24] thunderbolt: Rework control channel to be more reliable
- Add missing lock serializing access to kref_put/get of struct tb_cfg_request

[PATCH 16/24] thunderbolt: Add Thunderbolt 3 PCI IDs
- Add missing Win Ridge PCI ID and thus rename the patch since it is
also adding Thunderbotl 2 PCI IDs.

[PATCH 18/24] thunderbolt: Store Thunderbolt generation in the switch structure
- List all known switches. Still default to generation 1.

[PATCH 20/24] thunderbolt: Do not touch the hardware if the NHI is gone on resume
- Use pci_device_is_present() instead of open-coding the same

[PATCH 21/24] thunderbolt: Add support for Internal Connection Manager (ICM)
- Send KOBJ_CHANGE event when switch is authorized to notify userspace
about this.
- Rename TB_PHYS_PORT_FROM_LINK() to tb_switch_phys_port_from_link()
and move it to tb.h
- Use .is_visible() in attribute group to only show key for devices
that support secure connect.

[PATCH 22/24] thunderbolt: Add support for host and device NVM firmware upgrade
- Use kstrtobool() and if else block instead of switch.
- Drop unnecessary (& 0xff) used for already u8 fields major and
minor.
- Need to call ida_destroy() for nvm_ida in the same way we do for
tb_domain_ida.
- Always add nvm_version and nvm_authenticate attributes but their
visibility is determined by the existense of sw->dma_port.

[1] https://lkml.org/lkml/2016/11/9/341
[2] http://git.infradead.org/users/hch/vfs.git/shortlog/refs/heads/uuid-types

Lukas Wunner (1):
thunderbolt: Refactor and fix parsing of port drom entries

Mika Westerberg (26):
thunderbolt: Use const buffer pointer in write operations
thunderbolt: No need to read UID of the root switch on resume
thunderbolt: Do not try to read UID if DROM offset is read as 0
thunderbolt: Do not warn about newer DROM versions
thunderbolt: Add MSI-X support
thunderbolt: Rework capability handling
thunderbolt: Allow passing NULL to tb_ctl_free()
thunderbolt: Introduce thunderbolt bus and connection manager
thunderbolt: Convert switch to a device
thunderbolt: Fail switch adding operation if reading DROM fails
thunderbolt: Do not fail if DROM data CRC32 is invalid
thunderbolt: Read vendor and device name from DROM
thunderbolt: Move control channel messages to tb_msgs.h
thunderbolt: Expose get_route() to other files
thunderbolt: Expose make_header() to other files
thunderbolt: Let the connection manager handle all notifications
thunderbolt: Rework control channel to be more reliable
thunderbolt: Add new Thunderbolt PCI IDs
thunderbolt: Add support for NHI mailbox
thunderbolt: Store Thunderbolt generation in the switch structure
thunderbolt: Add support for DMA configuration based mailbox
thunderbolt: Do not touch the hardware if the NHI is gone on resume
thunderbolt: Add support for Internal Connection Manager (ICM)
thunderbolt: Add support for host and device NVM firmware upgrade
thunderbolt: Add documentation how Thunderbolt bus can be used
MAINTAINERS: Add maintainers for Thunderbolt driver

Documentation/ABI/testing/sysfs-bus-thunderbolt | 108 +++
Documentation/admin-guide/index.rst | 1 +
Documentation/admin-guide/thunderbolt.rst | 197 ++++
MAINTAINERS | 3 +
drivers/thunderbolt/Kconfig | 13 +-
drivers/thunderbolt/Makefile | 2 +-
drivers/thunderbolt/cap.c | 169 ++--
drivers/thunderbolt/ctl.c | 665 +++++++++----
drivers/thunderbolt/ctl.h | 105 +-
drivers/thunderbolt/dma_port.c | 524 ++++++++++
drivers/thunderbolt/dma_port.h | 34 +
drivers/thunderbolt/domain.c | 455 +++++++++
drivers/thunderbolt/eeprom.c | 127 ++-
drivers/thunderbolt/icm.c | 1089 +++++++++++++++++++++
drivers/thunderbolt/nhi.c | 306 +++++-
drivers/thunderbolt/nhi.h | 93 +-
drivers/thunderbolt/nhi_regs.h | 27 +
drivers/thunderbolt/switch.c | 1162 +++++++++++++++++++++--
drivers/thunderbolt/tb.c | 237 +++--
drivers/thunderbolt/tb.h | 251 ++++-
drivers/thunderbolt/tb_msgs.h | 260 +++++
drivers/thunderbolt/tb_regs.h | 50 +-
drivers/thunderbolt/tunnel_pci.c | 17 +-
23 files changed, 5312 insertions(+), 583 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-bus-thunderbolt
create mode 100644 Documentation/admin-guide/thunderbolt.rst
create mode 100644 drivers/thunderbolt/dma_port.c
create mode 100644 drivers/thunderbolt/dma_port.h
create mode 100644 drivers/thunderbolt/domain.c
create mode 100644 drivers/thunderbolt/icm.c
create mode 100644 drivers/thunderbolt/tb_msgs.h

--
2.11.0