Skip to content

Commit 7ce3f91

Browse files
Sinan Kayabjorn-helgaas
authored andcommitted
PCI: Enable PASID only if entire path supports End-End TLP prefixes
A PCIe endpoint carries the process address space identifier (PASID) in the TLP prefix as part of the memory read/write transaction. The address information in the TLP is relevant only for a given PASID context. An IOMMU takes PASID value and the address information from the TLP to look up the physical address in the system. PASID is an End-End TLP Prefix (PCIe r4.0, sec 6.20). Sec 2.2.10.2 says It is an error to receive a TLP with an End-End TLP Prefix by a Receiver that does not support End-End TLP Prefixes. A TLP in violation of this rule is handled as a Malformed TLP. This is a reported error associated with the Receiving Port (see Section 6.2). Prevent error condition by proactively requiring End-End TLP prefix to be supported on the entire data path between the endpoint and the root port before enabling PASID. Signed-off-by: Sinan Kaya <[email protected]> Signed-off-by: Bjorn Helgaas <[email protected]>
1 parent ce397d2 commit 7ce3f91

File tree

4 files changed

+29
-0
lines changed

4 files changed

+29
-0
lines changed

drivers/pci/ats.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,9 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
273273
if (WARN_ON(pdev->pasid_enabled))
274274
return -EBUSY;
275275

276+
if (!pdev->eetlp_prefix_path)
277+
return -EINVAL;
278+
276279
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
277280
if (!pos)
278281
return -EINVAL;

drivers/pci/probe.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2042,6 +2042,29 @@ static void pci_configure_ltr(struct pci_dev *dev)
20422042
#endif
20432043
}
20442044

2045+
static void pci_configure_eetlp_prefix(struct pci_dev *dev)
2046+
{
2047+
#ifdef CONFIG_PCI_PASID
2048+
struct pci_dev *bridge;
2049+
u32 cap;
2050+
2051+
if (!pci_is_pcie(dev))
2052+
return;
2053+
2054+
pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap);
2055+
if (!(cap & PCI_EXP_DEVCAP2_EE_PREFIX))
2056+
return;
2057+
2058+
if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
2059+
dev->eetlp_prefix_path = 1;
2060+
else {
2061+
bridge = pci_upstream_bridge(dev);
2062+
if (bridge && bridge->eetlp_prefix_path)
2063+
dev->eetlp_prefix_path = 1;
2064+
}
2065+
#endif
2066+
}
2067+
20452068
static void pci_configure_device(struct pci_dev *dev)
20462069
{
20472070
struct hotplug_params hpp;
@@ -2051,6 +2074,7 @@ static void pci_configure_device(struct pci_dev *dev)
20512074
pci_configure_extended_tags(dev, NULL);
20522075
pci_configure_relaxed_ordering(dev);
20532076
pci_configure_ltr(dev);
2077+
pci_configure_eetlp_prefix(dev);
20542078

20552079
memset(&hpp, 0, sizeof(hpp));
20562080
ret = pci_get_hp_params(dev, &hpp);

include/linux/pci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ struct pci_dev {
350350
unsigned int ltr_path:1; /* Latency Tolerance Reporting
351351
supported from root to here */
352352
#endif
353+
unsigned int eetlp_prefix_path:1; /* End-to-End TLP Prefix */
353354

354355
pci_channel_state_t error_state; /* Current connectivity state */
355356
struct device dev; /* Generic device interface */

include/uapi/linux/pci_regs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@
636636
#define PCI_EXP_DEVCAP2_OBFF_MASK 0x000c0000 /* OBFF support mechanism */
637637
#define PCI_EXP_DEVCAP2_OBFF_MSG 0x00040000 /* New message signaling */
638638
#define PCI_EXP_DEVCAP2_OBFF_WAKE 0x00080000 /* Re-use WAKE# for OBFF */
639+
#define PCI_EXP_DEVCAP2_EE_PREFIX 0x00200000 /* End-End TLP Prefix */
639640
#define PCI_EXP_DEVCTL2 40 /* Device Control 2 */
640641
#define PCI_EXP_DEVCTL2_COMP_TIMEOUT 0x000f /* Completion Timeout Value */
641642
#define PCI_EXP_DEVCTL2_COMP_TMOUT_DIS 0x0010 /* Completion Timeout Disable */

0 commit comments

Comments
 (0)