PCI: add ACS validation utility
In a PCI environment, transactions aren't always required to reach the root bus before being re-routed. Intermediate switches between an endpoint and the root bus can redirect DMA back downstream before things like IOMMUs have a chance to intervene. Legacy PCI is always susceptible to this as it operates on a shared bus. PCIe added a new capability to describe and control this behavior, Access Control Services, or ACS. The utility function pci_acs_enabled() allows us to test the ACS capabilities of an individual devices against a set of flags while pci_acs_path_enabled() tests a complete path from a given downstream device up to the specified upstream device. We also include the ability to add device specific tests as it's likely we'll see devices that do not implement ACS, but want to indicate support for various capabilities in this space. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
parent
12ea6cad1c
commit
ad805758c0
3 changed files with 111 additions and 1 deletions
|
@ -1490,6 +1490,7 @@ enum pci_fixup_pass {
|
|||
#ifdef CONFIG_PCI_QUIRKS
|
||||
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
|
||||
struct pci_dev *pci_get_dma_source(struct pci_dev *dev);
|
||||
int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags);
|
||||
#else
|
||||
static inline void pci_fixup_device(enum pci_fixup_pass pass,
|
||||
struct pci_dev *dev) {}
|
||||
|
@ -1497,6 +1498,11 @@ static inline struct pci_dev *pci_get_dma_source(struct pci_dev *dev)
|
|||
{
|
||||
return pci_dev_get(dev);
|
||||
}
|
||||
static inline int pci_dev_specific_acs_enabled(struct pci_dev *dev,
|
||||
u16 acs_flags)
|
||||
{
|
||||
return -ENOTTY;
|
||||
}
|
||||
#endif
|
||||
|
||||
void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen);
|
||||
|
@ -1599,7 +1605,9 @@ static inline bool pci_is_pcie(struct pci_dev *dev)
|
|||
}
|
||||
|
||||
void pci_request_acs(void);
|
||||
|
||||
bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags);
|
||||
bool pci_acs_path_enabled(struct pci_dev *start,
|
||||
struct pci_dev *end, u16 acs_flags);
|
||||
|
||||
#define PCI_VPD_LRDT 0x80 /* Large Resource Data Type */
|
||||
#define PCI_VPD_LRDT_ID(x) (x | PCI_VPD_LRDT)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue