@@ -4738,12 +4738,12 @@ const struct attribute_group *intel_iommu_groups[] = {
NULL,
};
-static inline bool has_untrusted_dev(void)
+static inline bool has_external_pci(void)
{
struct pci_dev *pdev = NULL;
for_each_pci_dev(pdev)
- if (pdev->untrusted)
+ if (pdev->external_facing)
return true;
return false;
@@ -4751,7 +4751,7 @@ static inline bool has_untrusted_dev(void)
static int __init platform_optin_force_iommu(void)
{
- if (!dmar_platform_optin() || no_platform_optin || !has_untrusted_dev())
+ if (!dmar_platform_optin() || no_platform_optin || !has_external_pci())
return 0;
if (no_iommu || dmar_disabled)
@@ -42,7 +42,7 @@ void pci_set_bus_of_node(struct pci_bus *bus)
} else {
node = of_node_get(bus->self->dev.of_node);
if (node && of_property_read_bool(node, "external-facing"))
- bus->self->untrusted = true;
+ bus->self->external_facing = true;
}
bus->dev.of_node = node;
@@ -1213,7 +1213,7 @@ static void pci_acpi_optimize_delay(struct pci_dev *pdev,
ACPI_FREE(obj);
}
-static void pci_acpi_set_untrusted(struct pci_dev *dev)
+static void pci_acpi_set_external_facing(struct pci_dev *dev)
{
u8 val;
@@ -1223,12 +1223,12 @@ static void pci_acpi_set_untrusted(struct pci_dev *dev)
return;
/*
- * These root ports expose PCIe (including DMA) outside of the
- * system so make sure we treat them and everything behind as
+ * These root/down ports expose PCIe (including DMA) outside of the
+ * system so make sure we treat everything behind them as
* untrusted.
*/
if (val)
- dev->untrusted = 1;
+ dev->external_facing = 1;
}
static void pci_acpi_setup(struct device *dev)
@@ -1240,7 +1240,7 @@ static void pci_acpi_setup(struct device *dev)
return;
pci_acpi_optimize_delay(pci_dev, adev->handle);
- pci_acpi_set_untrusted(pci_dev);
+ pci_acpi_set_external_facing(pci_dev);
pci_acpi_add_edr_notifier(pci_dev);
pci_acpi_add_pm_notifier(adev, pci_dev);
@@ -1552,7 +1552,7 @@ static void set_pcie_untrusted(struct pci_dev *dev)
* untrusted as well.
*/
parent = pci_upstream_bridge(dev);
- if (parent && parent->untrusted)
+ if (parent && (parent->untrusted || parent->external_facing))
dev->untrusted = true;
}
@@ -432,6 +432,14 @@ struct pci_dev {
* mappings to make sure they cannot access arbitrary memory.
*/
unsigned int untrusted:1;
+ /*
+ * Devices are marked as external-facing using info from platform
+ * (ACPI / devicetree). An external-facing device is still an internal
+ * trusted device, but it faces external untrusted devices. Thus any
+ * device enumerated downstream an external-facing device, is marked
+ * as untrusted.
+ */
+ unsigned int external_facing:1;
unsigned int broken_intx_masking:1; /* INTx masking can't be used */
unsigned int io_window_1k:1; /* Intel bridge 1K I/O windows */
unsigned int irq_managed:1;
The "ExternalFacingPort" devices (root ports) are internal devices that sit on the internal system fabric. Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/pci/dsd-for-pcie-root-ports Currently they were treated (marked as untrusted) at par with other external devices downstream those external facing rootports. Use the platform flag to identify the external facing devices and then treat them at par with internal devices (don't mark them untrusted). Any devices downstream continue to be marked as "untrusted". This was discussed here: https://lore.kernel.org/linux-pci/20200610230906.GA1528594@bjorn-Precision-5520/ Signed-off-by: Rajat Jain <rajatja@google.com> --- v3: * fix commit log and minor code comment * Don't check for "ExternalFacingPort" on PCI_EXP_TYPE_DOWNSTREAM * Check only for pdev->external_facing in iommu.c v2: cosmetic changes in commit log drivers/iommu/intel/iommu.c | 6 +++--- drivers/pci/of.c | 2 +- drivers/pci/pci-acpi.c | 10 +++++----- drivers/pci/probe.c | 2 +- include/linux/pci.h | 8 ++++++++ 5 files changed, 18 insertions(+), 10 deletions(-)