aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci
diff options
context:
space:
mode:
authorJan Beulich <JBeulich@novell.com>2011-07-22 03:13:05 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2011-07-22 11:25:41 -0400
commitdb34a363b992e0c8063f432607561520d79fbfb8 (patch)
treed57b4e848eeccade7dd81e39832215bdec3f52b7 /arch/x86/pci
parent688398bb7b9c6ac115da7749ea808d3ef69e029f (diff)
x86/PCI: config space accessor functions should not ignore the segment argument
Without this change, the majority of the raw PCI config space access functions silently ignore a non-zero segment argument, which is certainly wrong. Apart from pci_direct_conf1, all other non-MMCFG access methods get used only for non-extended accesses (i.e. assigned to raw_pci_ops only). Consequently, with the way raw_pci_{read,write}() work, it would be a coding error to call these functions with a non-zero segment (with the current call flow this cannot happen afaict). The access method 1 accessor, as it can be used for extended accesses (on AMD systems) instead gets checks added for the passed in segment to be zero. This would be the case when on such a system having multiple PCI segments (don't know whether any exist in practice) MMCFG for some reason is not usable, and method 1 gets selected for doing extended accesses. Rather than accessing the wrong device's config space, the function will now error out. v2: Convert BUG_ON() to WARN_ON(), and extend description as per Ingo's request. Signed-off-by: Jan Beulich <jbeulich@novell.com> Reviewed-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'arch/x86/pci')
-rw-r--r--arch/x86/pci/ce4100.c2
-rw-r--r--arch/x86/pci/direct.c6
-rw-r--r--arch/x86/pci/numaq_32.c2
-rw-r--r--arch/x86/pci/olpc.c4
-rw-r--r--arch/x86/pci/pcbios.c2
5 files changed, 14 insertions, 2 deletions
diff --git a/arch/x86/pci/ce4100.c b/arch/x86/pci/ce4100.c
index 67858be4b52b..99176094500b 100644
--- a/arch/x86/pci/ce4100.c
+++ b/arch/x86/pci/ce4100.c
@@ -257,6 +257,7 @@ static int ce4100_conf_read(unsigned int seg, unsigned int bus,
257{ 257{
258 int i; 258 int i;
259 259
260 WARN_ON(seg);
260 if (bus == 1) { 261 if (bus == 1) {
261 for (i = 0; i < ARRAY_SIZE(bus1_fixups); i++) { 262 for (i = 0; i < ARRAY_SIZE(bus1_fixups); i++) {
262 if (bus1_fixups[i].dev_func == devfn && 263 if (bus1_fixups[i].dev_func == devfn &&
@@ -282,6 +283,7 @@ static int ce4100_conf_write(unsigned int seg, unsigned int bus,
282{ 283{
283 int i; 284 int i;
284 285
286 WARN_ON(seg);
285 if (bus == 1) { 287 if (bus == 1) {
286 for (i = 0; i < ARRAY_SIZE(bus1_fixups); i++) { 288 for (i = 0; i < ARRAY_SIZE(bus1_fixups); i++) {
287 if (bus1_fixups[i].dev_func == devfn && 289 if (bus1_fixups[i].dev_func == devfn &&
diff --git a/arch/x86/pci/direct.c b/arch/x86/pci/direct.c
index e6fd8473fb7b..4f2c70439d7f 100644
--- a/arch/x86/pci/direct.c
+++ b/arch/x86/pci/direct.c
@@ -22,7 +22,7 @@ static int pci_conf1_read(unsigned int seg, unsigned int bus,
22{ 22{
23 unsigned long flags; 23 unsigned long flags;
24 24
25 if ((bus > 255) || (devfn > 255) || (reg > 4095)) { 25 if (seg || (bus > 255) || (devfn > 255) || (reg > 4095)) {
26 *value = -1; 26 *value = -1;
27 return -EINVAL; 27 return -EINVAL;
28 } 28 }
@@ -53,7 +53,7 @@ static int pci_conf1_write(unsigned int seg, unsigned int bus,
53{ 53{
54 unsigned long flags; 54 unsigned long flags;
55 55
56 if ((bus > 255) || (devfn > 255) || (reg > 4095)) 56 if (seg || (bus > 255) || (devfn > 255) || (reg > 4095))
57 return -EINVAL; 57 return -EINVAL;
58 58
59 raw_spin_lock_irqsave(&pci_config_lock, flags); 59 raw_spin_lock_irqsave(&pci_config_lock, flags);
@@ -97,6 +97,7 @@ static int pci_conf2_read(unsigned int seg, unsigned int bus,
97 unsigned long flags; 97 unsigned long flags;
98 int dev, fn; 98 int dev, fn;
99 99
100 WARN_ON(seg);
100 if ((bus > 255) || (devfn > 255) || (reg > 255)) { 101 if ((bus > 255) || (devfn > 255) || (reg > 255)) {
101 *value = -1; 102 *value = -1;
102 return -EINVAL; 103 return -EINVAL;
@@ -138,6 +139,7 @@ static int pci_conf2_write(unsigned int seg, unsigned int bus,
138 unsigned long flags; 139 unsigned long flags;
139 int dev, fn; 140 int dev, fn;
140 141
142 WARN_ON(seg);
141 if ((bus > 255) || (devfn > 255) || (reg > 255)) 143 if ((bus > 255) || (devfn > 255) || (reg > 255))
142 return -EINVAL; 144 return -EINVAL;
143 145
diff --git a/arch/x86/pci/numaq_32.c b/arch/x86/pci/numaq_32.c
index 5c9e2458df4e..512a88c41501 100644
--- a/arch/x86/pci/numaq_32.c
+++ b/arch/x86/pci/numaq_32.c
@@ -34,6 +34,7 @@ static int pci_conf1_mq_read(unsigned int seg, unsigned int bus,
34 unsigned long flags; 34 unsigned long flags;
35 void *adr __iomem = XQUAD_PORT_ADDR(0xcfc, BUS2QUAD(bus)); 35 void *adr __iomem = XQUAD_PORT_ADDR(0xcfc, BUS2QUAD(bus));
36 36
37 WARN_ON(seg);
37 if (!value || (bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255)) 38 if (!value || (bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255))
38 return -EINVAL; 39 return -EINVAL;
39 40
@@ -73,6 +74,7 @@ static int pci_conf1_mq_write(unsigned int seg, unsigned int bus,
73 unsigned long flags; 74 unsigned long flags;
74 void *adr __iomem = XQUAD_PORT_ADDR(0xcfc, BUS2QUAD(bus)); 75 void *adr __iomem = XQUAD_PORT_ADDR(0xcfc, BUS2QUAD(bus));
75 76
77 WARN_ON(seg);
76 if ((bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255)) 78 if ((bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255))
77 return -EINVAL; 79 return -EINVAL;
78 80
diff --git a/arch/x86/pci/olpc.c b/arch/x86/pci/olpc.c
index 13700ec8e2e4..5262603b04d9 100644
--- a/arch/x86/pci/olpc.c
+++ b/arch/x86/pci/olpc.c
@@ -206,6 +206,8 @@ static int pci_olpc_read(unsigned int seg, unsigned int bus,
206{ 206{
207 uint32_t *addr; 207 uint32_t *addr;
208 208
209 WARN_ON(seg);
210
209 /* Use the hardware mechanism for non-simulated devices */ 211 /* Use the hardware mechanism for non-simulated devices */
210 if (!is_simulated(bus, devfn)) 212 if (!is_simulated(bus, devfn))
211 return pci_direct_conf1.read(seg, bus, devfn, reg, len, value); 213 return pci_direct_conf1.read(seg, bus, devfn, reg, len, value);
@@ -264,6 +266,8 @@ static int pci_olpc_read(unsigned int seg, unsigned int bus,
264static int pci_olpc_write(unsigned int seg, unsigned int bus, 266static int pci_olpc_write(unsigned int seg, unsigned int bus,
265 unsigned int devfn, int reg, int len, uint32_t value) 267 unsigned int devfn, int reg, int len, uint32_t value)
266{ 268{
269 WARN_ON(seg);
270
267 /* Use the hardware mechanism for non-simulated devices */ 271 /* Use the hardware mechanism for non-simulated devices */
268 if (!is_simulated(bus, devfn)) 272 if (!is_simulated(bus, devfn))
269 return pci_direct_conf1.write(seg, bus, devfn, reg, len, value); 273 return pci_direct_conf1.write(seg, bus, devfn, reg, len, value);
diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c
index a5f7d0d63de0..f68553551467 100644
--- a/arch/x86/pci/pcbios.c
+++ b/arch/x86/pci/pcbios.c
@@ -181,6 +181,7 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
181 unsigned long flags; 181 unsigned long flags;
182 unsigned long bx = (bus << 8) | devfn; 182 unsigned long bx = (bus << 8) | devfn;
183 183
184 WARN_ON(seg);
184 if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) 185 if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
185 return -EINVAL; 186 return -EINVAL;
186 187
@@ -247,6 +248,7 @@ static int pci_bios_write(unsigned int seg, unsigned int bus,
247 unsigned long flags; 248 unsigned long flags;
248 unsigned long bx = (bus << 8) | devfn; 249 unsigned long bx = (bus << 8) | devfn;
249 250
251 WARN_ON(seg);
250 if ((bus > 255) || (devfn > 255) || (reg > 255)) 252 if ((bus > 255) || (devfn > 255) || (reg > 255))
251 return -EINVAL; 253 return -EINVAL;
252 254