blob: 6fc83fbdfb3a5ace923a0467d2d48004bb1b7f9e [file] [log] [blame]
Patrick Williams2194f502022-10-16 14:26:09 -05001From ba5ed426f6587d96418bc8bbe4ae908329d4a7a9 Mon Sep 17 00:00:00 2001
Brad Bishopbec4ebc2022-08-03 09:55:16 -04002From: Manoj Kumar <manoj.kumar3@arm.com>
3Date: Tue, 31 Aug 2021 16:15:38 +0000
Patrick Williams8dd68482022-10-04 07:57:18 -05004Subject: [PATCH] n1sdp: pci_quirk: add acs override for PCI devices
Brad Bishopbec4ebc2022-08-03 09:55:16 -04005
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>
Patrick Williams8dd68482022-10-04 07:57:18 -050011
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>
Patrick Williams2194f502022-10-16 14:26:09 -050014Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
15Signed-off-by: Adam Johnston <adam.johnston@arm.com>
Brad Bishopbec4ebc2022-08-03 09:55:16 -040016---
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
Patrick Williams2194f502022-10-16 14:26:09 -050022index 09836f2f1e74..b465592aa068 100644
Brad Bishopbec4ebc2022-08-03 09:55:16 -040023--- a/Documentation/admin-guide/kernel-parameters.txt
24+++ b/Documentation/admin-guide/kernel-parameters.txt
Patrick Williams2194f502022-10-16 14:26:09 -050025@@ -4084,6 +4084,14 @@
Brad Bishopbec4ebc2022-08-03 09:55:16 -040026 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
Patrick Williams2194f502022-10-16 14:26:09 -050041index 2e68f50bc7ae..2d32fa0df411 100644
Brad Bishopbec4ebc2022-08-03 09:55:16 -040042--- a/drivers/pci/quirks.c
43+++ b/drivers/pci/quirks.c
Patrick Williams2194f502022-10-16 14:26:09 -050044@@ -3601,6 +3601,107 @@ static void quirk_no_bus_reset(struct pci_dev *dev)
Brad Bishopbec4ebc2022-08-03 09:55:16 -040045 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.
Patrick Williams2194f502022-10-16 14:26:09 -0500152@@ -4969,6 +5070,7 @@ static const struct pci_dev_acs_enabled {
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400153 { PCI_VENDOR_ID_NXP, 0x8d9b, pci_quirk_nxp_rp_acs },
154 /* Zhaoxin Root/Downstream Ports */
155 { PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs },
156+ { PCI_ANY_ID, PCI_ANY_ID, pcie_acs_overrides },
157 { 0 }
158 };
159