]> git.proxmox.com Git - pve-kernel-3.10.0.git/blob - override_for_missing_acs_capabilities.patch
update intel network drivers
[pve-kernel-3.10.0.git] / override_for_missing_acs_capabilities.patch
1 From d4ed2b803ac71237701ecd08e46b0e30bdad099c Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= <ayufan@ayufan.eu>
3 Date: Fri, 13 Jun 2014 23:40:11 +0200
4 Subject: [PATCH 3/4] override_for_missing_acs_capabilities.patch
5
6
7 Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
8 ---
9 Documentation/kernel-parameters.txt | 10 ++++
10 drivers/pci/quirks.c | 103 +++++++++++++++++++++++++++++++++++
11 2 files changed, 113 insertions(+)
12
13 diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
14 index 30a8ad0d..ea1b3fe 100644
15 --- a/Documentation/kernel-parameters.txt
16 +++ b/Documentation/kernel-parameters.txt
17 @@ -2554,6 +2554,16 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
18 nomsi Do not use MSI for native PCIe PME signaling (this makes
19 all PCIe root ports use INTx for all services).
20
21 + pcie_acs_override =
22 + [PCIE] Override missing PCIe ACS support for:
23 + downstream
24 + All downstream ports - full ACS capabilties
25 + multifunction
26 + All multifunction devices - multifunction ACS subset
27 + id:nnnn:nnnn
28 + Specfic device - full ACS capabilities
29 + Specified as vid:did (vendor/device ID) in hex
30 +
31 pcmv= [HW,PCMCIA] BadgePAD 4
32
33 pd_ignore_unused
34 diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
35 index e729206..e38c80d 100644
36 --- a/drivers/pci/quirks.c
37 +++ b/drivers/pci/quirks.c
38 @@ -3384,6 +3384,107 @@ struct pci_dev *pci_get_dma_source(struct pci_dev *dev)
39 return pci_dev_get(dev);
40 }
41
42 +static bool acs_on_downstream;
43 +static bool acs_on_multifunction;
44 +
45 +#define NUM_ACS_IDS 16
46 +struct acs_on_id {
47 + unsigned short vendor;
48 + unsigned short device;
49 +};
50 +static struct acs_on_id acs_on_ids[NUM_ACS_IDS];
51 +static u8 max_acs_id;
52 +
53 +static __init int pcie_acs_override_setup(char *p)
54 +{
55 + if (!p)
56 + return -EINVAL;
57 +
58 + while (*p) {
59 + if (!strncmp(p, "downstream", 10))
60 + acs_on_downstream = true;
61 + if (!strncmp(p, "multifunction", 13))
62 + acs_on_multifunction = true;
63 + if (!strncmp(p, "id:", 3)) {
64 + char opt[5];
65 + int ret;
66 + long val;
67 +
68 + if (max_acs_id >= NUM_ACS_IDS - 1) {
69 + pr_warn("Out of PCIe ACS override slots (%d)\n",
70 + NUM_ACS_IDS);
71 + goto next;
72 + }
73 +
74 + p += 3;
75 + snprintf(opt, 5, "%s", p);
76 + ret = kstrtol(opt, 16, &val);
77 + if (ret) {
78 + pr_warn("PCIe ACS ID parse error %d\n", ret);
79 + goto next;
80 + }
81 + acs_on_ids[max_acs_id].vendor = val;
82 +
83 + p += strcspn(p, ":");
84 + if (*p != ':') {
85 + pr_warn("PCIe ACS invalid ID\n");
86 + goto next;
87 + }
88 +
89 + p++;
90 + snprintf(opt, 5, "%s", p);
91 + ret = kstrtol(opt, 16, &val);
92 + if (ret) {
93 + pr_warn("PCIe ACS ID parse error %d\n", ret);
94 + goto next;
95 + }
96 + acs_on_ids[max_acs_id].device = val;
97 + max_acs_id++;
98 + }
99 +next:
100 + p += strcspn(p, ",");
101 + if (*p == ',')
102 + p++;
103 + }
104 +
105 + if (acs_on_downstream || acs_on_multifunction || max_acs_id)
106 + pr_warn("Warning: PCIe ACS overrides enabled; This may allow non-IOMMU protected peer-to-peer DMA\n");
107 +
108 + return 0;
109 +}
110 +early_param("pcie_acs_override", pcie_acs_override_setup);
111 +
112 +static int pcie_acs_overrides(struct pci_dev *dev, u16 acs_flags)
113 +{
114 + int i;
115 +
116 + /* Never override ACS for legacy devices or devices with ACS caps */
117 + if (!pci_is_pcie(dev) ||
118 + pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS))
119 + return -ENOTTY;
120 +
121 + for (i = 0; i < max_acs_id; i++)
122 + if (acs_on_ids[i].vendor == dev->vendor &&
123 + acs_on_ids[i].device == dev->device)
124 + return 1;
125 +
126 + switch (pci_pcie_type(dev)) {
127 + case PCI_EXP_TYPE_DOWNSTREAM:
128 + case PCI_EXP_TYPE_ROOT_PORT:
129 + if (acs_on_downstream)
130 + return 1;
131 + break;
132 + case PCI_EXP_TYPE_ENDPOINT:
133 + case PCI_EXP_TYPE_UPSTREAM:
134 + case PCI_EXP_TYPE_LEG_END:
135 + case PCI_EXP_TYPE_RC_END:
136 + if (acs_on_multifunction && dev->multifunction)
137 + return 1;
138 + }
139 +
140 + return -ENOTTY;
141 +}
142 +
143 /*
144 * AMD has indicated that the devices below do not support peer-to-peer
145 * in any system where they are found in the southbridge with an AMD
146 @@ -3483,6 +3584,7 @@ static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags)
147 return acs_flags & ~flags ? 0 : 1;
148 }
149
150 +
151 static const struct pci_dev_acs_enabled {
152 u16 vendor;
153 u16 device;
154 @@ -3495,6 +3597,7 @@ static const struct pci_dev_acs_enabled {
155 { PCI_VENDOR_ID_ATI, 0x4384, pci_quirk_amd_sb_acs },
156 { PCI_VENDOR_ID_ATI, 0x4399, pci_quirk_amd_sb_acs },
157 { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs },
158 + { PCI_ANY_ID, PCI_ANY_ID, pcie_acs_overrides },
159 { 0 }
160 };
161
162 --
163 1.7.10.4
164