On Thu, May 13, 2021 at 04:27:01PM -0700, Rajat Jain wrote: > A PCI device is "external_facing" if it's a Root Port with the ACPI > "ExternalFacingPort" property or if it has the DT "external-facing" > property. We consider everything downstream from such a device to > be removable by user. > > We're mainly concerned with consumer platforms with user accessible > Thunderbolt ports that are vulnerable to DMA attacks, and we expect those > ports to be identified by firmware as "ExternalFacingPort". Devices in > traditional hotplug slots can technically be removed, but the expectation > is that unless the port is marked with "ExternalFacingPort", such devices > are less accessible to user / may not be removed by end user, and thus not > exposed as "removable" to userspace. > > This can be used to implement userspace policies tailored for > user removable devices. Eg usage: > https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2591812 > https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2795038 > (code uses such an attribute to remove external PCI devices or disable > features on them as needed by the policy desired) > > Signed-off-by: Rajat Jain <rajatja@xxxxxxxxxx> Acked-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx> Greg, feel free to merge both these via your tree. > --- > v4: - code comments, commit log updates > - Make "removable" attribute show up only under devices that are > really removable. > v3: - commit log updated > - Rename set_pci_dev_removable() -> pci_set_removable() > - Call it after applying early PCI quirks. > v2: Add documentation > > .../ABI/testing/sysfs-devices-removable | 3 ++- > drivers/pci/probe.c | 22 +++++++++++++++++++ > 2 files changed, 24 insertions(+), 1 deletion(-) > > diff --git a/Documentation/ABI/testing/sysfs-devices-removable b/Documentation/ABI/testing/sysfs-devices-removable > index acf7766e800b..bda6c320c8d3 100644 > --- a/Documentation/ABI/testing/sysfs-devices-removable > +++ b/Documentation/ABI/testing/sysfs-devices-removable > @@ -14,4 +14,5 @@ Description: > > Currently this is only supported by USB (which infers the > information from a combination of hub descriptor bits and > - platform-specific data such as ACPI). > + platform-specific data such as ACPI) and PCI (which gets this > + from ACPI / device tree). > diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c > index 3a62d09b8869..812e0d7fd7a7 100644 > --- a/drivers/pci/probe.c > +++ b/drivers/pci/probe.c > @@ -1575,6 +1575,26 @@ static void set_pcie_untrusted(struct pci_dev *dev) > dev->untrusted = true; > } > > +static void pci_set_removable(struct pci_dev *dev) > +{ > + struct pci_dev *parent = pci_upstream_bridge(dev); > + > + /* > + * We (only) consider everything downstream from an external_facing > + * device to be removable by the user. We're mainly concerned with > + * consumer platforms with user accessible thunderbolt ports that are > + * vulnerable to DMA attacks, and we expect those ports to be marked by > + * the firmware as external_facing. Devices in traditional hotplug > + * slots can technically be removed, but the expectation is that unless > + * the port is marked with external_facing, such devices are less > + * accessible to user / may not be removed by end user, and thus not > + * exposed as "removable" to userspace. > + */ > + if (parent && > + (parent->external_facing || dev_is_removable(&parent->dev))) > + dev_set_removable(&dev->dev, DEVICE_REMOVABLE); > +} > + > /** > * pci_ext_cfg_is_aliased - Is ext config space just an alias of std config? > * @dev: PCI device > @@ -1822,6 +1842,8 @@ int pci_setup_device(struct pci_dev *dev) > /* Early fixups, before probing the BARs */ > pci_fixup_device(pci_fixup_early, dev); > > + pci_set_removable(dev); > + > pci_info(dev, "[%04x:%04x] type %02x class %#08x\n", > dev->vendor, dev->device, dev->hdr_type, dev->class); > > -- > 2.31.1.751.gd2f1c929bd-goog >