Patrick Williams | 2194f50 | 2022-10-16 14:26:09 -0500 | [diff] [blame^] | 1 | From ba5ed426f6587d96418bc8bbe4ae908329d4a7a9 Mon Sep 17 00:00:00 2001 |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 2 | From: Manoj Kumar <manoj.kumar3@arm.com> |
| 3 | Date: Tue, 31 Aug 2021 16:15:38 +0000 |
Patrick Williams | 8dd6848 | 2022-10-04 07:57:18 -0500 | [diff] [blame] | 4 | Subject: [PATCH] n1sdp: pci_quirk: add acs override for PCI devices |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 5 | |
| 6 | Patch taken from: |
| 7 | https://gitlab.com/Queuecumber/linux-acs-override/raw/master/workspaces/5.4/acso.patch |
| 8 | |
| 9 | Change-Id: Ib926bf50524ce9990fbaa2f2f8670fe84bd571f9 |
| 10 | Signed-off-by: Manoj Kumar <manoj.kumar3@arm.com> |
Patrick Williams | 8dd6848 | 2022-10-04 07:57:18 -0500 | [diff] [blame] | 11 | |
| 12 | Upstream-Status: Inappropriate [will not be submitted as its a workaround to address hardware issue] |
| 13 | Signed-off-by: Khasim Syed Mohammed <khasim.mohammed@arm.com> |
Patrick Williams | 2194f50 | 2022-10-16 14:26:09 -0500 | [diff] [blame^] | 14 | Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com> |
| 15 | Signed-off-by: Adam Johnston <adam.johnston@arm.com> |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 16 | --- |
| 17 | .../admin-guide/kernel-parameters.txt | 8 ++ |
| 18 | drivers/pci/quirks.c | 102 ++++++++++++++++++ |
| 19 | 2 files changed, 110 insertions(+) |
| 20 | |
| 21 | diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt |
Patrick Williams | 2194f50 | 2022-10-16 14:26:09 -0500 | [diff] [blame^] | 22 | index 09836f2f1e74..b465592aa068 100644 |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 23 | --- a/Documentation/admin-guide/kernel-parameters.txt |
| 24 | +++ b/Documentation/admin-guide/kernel-parameters.txt |
Patrick Williams | 2194f50 | 2022-10-16 14:26:09 -0500 | [diff] [blame^] | 25 | @@ -4084,6 +4084,14 @@ |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 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. |
| 40 | diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c |
Patrick Williams | 2194f50 | 2022-10-16 14:26:09 -0500 | [diff] [blame^] | 41 | index 2e68f50bc7ae..2d32fa0df411 100644 |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 42 | --- a/drivers/pci/quirks.c |
| 43 | +++ b/drivers/pci/quirks.c |
Patrick Williams | 2194f50 | 2022-10-16 14:26:09 -0500 | [diff] [blame^] | 44 | @@ -3601,6 +3601,107 @@ static void quirk_no_bus_reset(struct pci_dev *dev) |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 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. |
Patrick Williams | 2194f50 | 2022-10-16 14:26:09 -0500 | [diff] [blame^] | 152 | @@ -4969,6 +5070,7 @@ static const struct pci_dev_acs_enabled { |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 153 | { 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 | |