From: Chris Wright Date: Fri, 4 Dec 2009 20:15:21 +0000 (-0800) Subject: PCI: add pci_request_acs X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=5d990b627537e59a3a2f039ff588a4750e9c1a6a;p=linux-beck.git PCI: add pci_request_acs Commit ae21ee65e8bc228416bbcc8a1da01c56a847a60c "PCI: acs p2p upsteram forwarding enabling" doesn't actually enable ACS. Add a function to pci core to allow an IOMMU to request that ACS be enabled. The existing mechanism of using iommu_found() in the pci core to know when ACS should be enabled doesn't actually work due to initialization order; iommu has only been detected not initialized. Have Intel and AMD IOMMUs request ACS, and Xen does as well during early init of dom0. Cc: Allen Kay Cc: David Woodhouse Cc: Jeremy Fitzhardinge Cc: Joerg Roedel Signed-off-by: Chris Wright Signed-off-by: Jesse Barnes --- diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index b4b61d462dcc..e60530a5f524 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c @@ -1330,6 +1330,8 @@ void __init amd_iommu_detect(void) gart_iommu_aperture_disabled = 1; gart_iommu_aperture = 0; #endif + /* Make sure ACS will be enabled */ + pci_request_acs(); } } diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 5bccd706232c..e2511bccbc8d 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -1170,7 +1171,11 @@ asmlinkage void __init xen_start_kernel(void) add_preferred_console("xenboot", 0, NULL); add_preferred_console("tty", 0, NULL); add_preferred_console("hvc", 0, NULL); + } else { + /* Make sure ACS will be enabled */ + pci_request_acs(); } + xen_raw_console_write("about to get started...\n"); diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index e01ca4d6b3e6..0e98f6b6f515 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -614,8 +614,11 @@ void __init detect_intel_iommu(void) #endif #ifdef CONFIG_DMAR if (ret && !no_iommu && !iommu_detected && !swiotlb && - !dmar_disabled) + !dmar_disabled) { iommu_detected = 1; + /* Make sure ACS will be enabled */ + pci_request_acs(); + } #endif } early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 6af212c509c5..cd9b375f49d5 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1550,6 +1550,16 @@ void pci_enable_ari(struct pci_dev *dev) bridge->ari_enabled = 1; } +static int pci_acs_enable; + +/** + * pci_request_acs - ask for ACS to be enabled if supported + */ +void pci_request_acs(void) +{ + pci_acs_enable = 1; +} + /** * pci_enable_acs - enable ACS if hardware support it * @dev: the PCI device @@ -1560,6 +1570,9 @@ void pci_enable_acs(struct pci_dev *dev) u16 cap; u16 ctrl; + if (!pci_acs_enable) + return; + if (!pci_is_pcie(dev)) return; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2fdffc02a308..98ffb2de22e9 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -10,9 +10,7 @@ #include #include #include -#include #include -#include #include "pci.h" #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ @@ -1029,8 +1027,7 @@ static void pci_init_capabilities(struct pci_dev *dev) pci_iov_init(dev); /* Enable ACS P2P upstream forwarding */ - if (iommu_found() || xen_initial_domain()) - pci_enable_acs(dev); + pci_enable_acs(dev); } void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) diff --git a/include/linux/pci.h b/include/linux/pci.h index 2891c3d3e51a..04771b9c3316 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1328,5 +1328,7 @@ static inline bool pci_is_pcie(struct pci_dev *dev) return !!pci_pcie_cap(dev); } +void pci_request_acs(void); + #endif /* __KERNEL__ */ #endif /* LINUX_PCI_H */