1From fc8605e74b51d9e0ab8efd0489eca2e11d807f07 Mon Sep 17 00:00:00 2001 2From: Manoj Kumar <manoj.kumar3@arm.com> 3Date: Tue, 31 Aug 2021 16:15:38 +0000 4Subject: [PATCH] n1sdp: pci_quirk: add acs override for PCI devices 5 6Patch taken from: 7https://gitlab.com/Queuecumber/linux-acs-override/raw/master/workspaces/5.4/acso.patch 8 9Change-Id: Ib926bf50524ce9990fbaa2f2f8670fe84bd571f9 10Signed-off-by: Manoj Kumar <manoj.kumar3@arm.com> 11 12Upstream-Status: Inappropriate [will not be submitted as its a workaround to address hardware issue] 13Signed-off-by: Khasim Syed Mohammed <khasim.mohammed@arm.com> 14Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com> 15Signed-off-by: Adam Johnston <adam.johnston@arm.com> 16--- 17 .../admin-guide/kernel-parameters.txt | 8 ++ 18 drivers/pci/quirks.c | 102 ++++++++++++++++++ 19 2 files changed, 110 insertions(+) 20 21diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt 22index 963cdaecabcb..8e94af513b9f 100644 23--- a/Documentation/admin-guide/kernel-parameters.txt 24+++ b/Documentation/admin-guide/kernel-parameters.txt 25@@ -4162,6 +4162,14 @@ 26 nomsi [MSI] If the PCI_MSI kernel config parameter is 27 enabled, this kernel boot option can be used to 28 disable the use of MSI interrupts system-wide. 29+ pcie_acs_override [PCIE] Override missing PCIe ACS support for 30+ downstream 31+ All downstream ports - full ACS capabilities 32+ multfunction 33+ All multifunction devices - multifunction ACS subset 34+ id:nnnn:nnnn 35+ Specfic device - full ACS capabilities 36+ Specified as vid:did (vendor/device ID) in hex 37 noioapicquirk [APIC] Disable all boot interrupt quirks. 38 Safety option to keep boot IRQs enabled. This 39 should never be necessary. 40diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c 41index 285acc4aaccc..d6ebef1f30db 100644 42--- a/drivers/pci/quirks.c 43+++ b/drivers/pci/quirks.c 44@@ -3612,6 +3612,107 @@ static void quirk_no_bus_reset(struct pci_dev *dev) 45 dev->dev_flags |= PCI_DEV_FLAGS_NO_BUS_RESET; 46 } 47 48+static bool acs_on_downstream; 49+static bool acs_on_multifunction; 50+ 51+#define NUM_ACS_IDS 16 52+struct acs_on_id { 53+ unsigned short vendor; 54+ unsigned short device; 55+}; 56+static struct acs_on_id acs_on_ids[NUM_ACS_IDS]; 57+static u8 max_acs_id; 58+ 59+static __init int pcie_acs_override_setup(char *p) 60+{ 61+ if (!p) 62+ return -EINVAL; 63+ 64+ while (*p) { 65+ if (!strncmp(p, "downstream", 10)) 66+ acs_on_downstream = true; 67+ if (!strncmp(p, "multifunction", 13)) 68+ acs_on_multifunction = true; 69+ if (!strncmp(p, "id:", 3)) { 70+ char opt[5]; 71+ int ret; 72+ long val; 73+ 74+ if (max_acs_id >= NUM_ACS_IDS - 1) { 75+ pr_warn("Out of PCIe ACS override slots (%d)\n", 76+ NUM_ACS_IDS); 77+ goto next; 78+ } 79+ 80+ p += 3; 81+ snprintf(opt, 5, "%s", p); 82+ ret = kstrtol(opt, 16, &val); 83+ if (ret) { 84+ pr_warn("PCIe ACS ID parse error %d\n", ret); 85+ goto next; 86+ } 87+ acs_on_ids[max_acs_id].vendor = val; 88+ 89+ p += strcspn(p, ":"); 90+ if (*p != ':') { 91+ pr_warn("PCIe ACS invalid ID\n"); 92+ goto next; 93+ } 94+ 95+ p++; 96+ snprintf(opt, 5, "%s", p); 97+ ret = kstrtol(opt, 16, &val); 98+ if (ret) { 99+ pr_warn("PCIe ACS ID parse error %d\n", ret); 100+ goto next; 101+ } 102+ acs_on_ids[max_acs_id].device = val; 103+ max_acs_id++; 104+ } 105+next: 106+ p += strcspn(p, ","); 107+ if (*p == ',') 108+ p++; 109+ } 110+ 111+ if (acs_on_downstream || acs_on_multifunction || max_acs_id) 112+ pr_warn("Warning: PCIe ACS overrides enabled; This may allow non-IOMMU protected peer-to-peer DMA\n"); 113+ 114+ return 0; 115+} 116+early_param("pcie_acs_override", pcie_acs_override_setup); 117+ 118+static int pcie_acs_overrides(struct pci_dev *dev, u16 acs_flags) 119+{ 120+ int i; 121+ 122+ /* Never override ACS for legacy devices or devices with ACS caps */ 123+ if (!pci_is_pcie(dev) || 124+ pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS)) 125+ return -ENOTTY; 126+ 127+ for (i = 0; i < max_acs_id; i++) 128+ if (acs_on_ids[i].vendor == dev->vendor && 129+ acs_on_ids[i].device == dev->device) 130+ return 1; 131+ 132+ switch (pci_pcie_type(dev)) { 133+ case PCI_EXP_TYPE_DOWNSTREAM: 134+ case PCI_EXP_TYPE_ROOT_PORT: 135+ if (acs_on_downstream) 136+ return 1; 137+ break; 138+ case PCI_EXP_TYPE_ENDPOINT: 139+ case PCI_EXP_TYPE_UPSTREAM: 140+ case PCI_EXP_TYPE_LEG_END: 141+ case PCI_EXP_TYPE_RC_END: 142+ if (acs_on_multifunction && dev->multifunction) 143+ return 1; 144+ } 145+ 146+ return -ENOTTY; 147+} 148+ 149 /* 150 * Some NVIDIA GPU devices do not work with bus reset, SBR needs to be 151 * prevented for those affected devices. 152@@ -4980,6 +5081,7 @@ static const struct pci_dev_acs_enabled { 153 { PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs }, 154 /* Wangxun nics */ 155 { PCI_VENDOR_ID_WANGXUN, PCI_ANY_ID, pci_quirk_wangxun_nic_acs }, 156+ { PCI_ANY_ID, PCI_ANY_ID, pcie_acs_overrides }, 157 { 0 } 158 }; 159 160