Skip to content

Commit 3a9ad0b

Browse files
Yinghai Lubjorn-helgaas
authored andcommitted
PCI: Add pci_bus_addr_t
David Ahern reported that d63e2e1 ("sparc/PCI: Clip bridge windows to fit in upstream windows") fails to boot on sparc/T5-8: pci 0000:06:00.0: reg 0x184: can't handle BAR above 4GB (bus address 0x110204000) The problem is that sparc64 assumed that dma_addr_t only needed to hold DMA addresses, i.e., bus addresses returned via the DMA API (dma_map_single(), etc.), while the PCI core assumed dma_addr_t could hold *any* bus address, including raw BAR values. On sparc64, all DMA addresses fit in 32 bits, so dma_addr_t is a 32-bit type. However, BAR values can be 64 bits wide, so they don't fit in a dma_addr_t. d63e2e1 added new checking that tripped over this mismatch. Add pci_bus_addr_t, which is wide enough to hold any PCI bus address, including both raw BAR values and DMA addresses. This will be 64 bits on 64-bit platforms and on platforms with a 64-bit dma_addr_t. Then dma_addr_t only needs to be wide enough to hold addresses from the DMA API. [bhelgaas: changelog, bugzilla, Kconfig to ensure pci_bus_addr_t is at least as wide as dma_addr_t, documentation] Fixes: d63e2e1 ("sparc/PCI: Clip bridge windows to fit in upstream windows") Fixes: 23b13bc ("PCI: Fail safely if we can't handle BARs larger than 4GB") Link: http://lkml.kernel.org/r/CAE9FiQU1gJY1LYrxs+ma5LCTEEe4xmtjRG0aXJ9K_Tsu+m9Wuw@mail.gmail.com Link: http://lkml.kernel.org/r/[email protected] Link: https://bugzilla.kernel.org/show_bug.cgi?id=96231 Reported-by: David Ahern <[email protected]> Tested-by: David Ahern <[email protected]> Signed-off-by: Yinghai Lu <[email protected]> Signed-off-by: Bjorn Helgaas <[email protected]> Acked-by: David S. Miller <[email protected]> CC: [email protected] # v3.19+
1 parent 5ebe6af commit 3a9ad0b

File tree

7 files changed

+66
-43
lines changed

7 files changed

+66
-43
lines changed

Documentation/DMA-API-HOWTO.txt

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,18 @@ physical addresses. These are the addresses in /proc/iomem. The physical
2525
address is not directly useful to a driver; it must use ioremap() to map
2626
the space and produce a virtual address.
2727

28-
I/O devices use a third kind of address: a "bus address" or "DMA address".
29-
If a device has registers at an MMIO address, or if it performs DMA to read
30-
or write system memory, the addresses used by the device are bus addresses.
31-
In some systems, bus addresses are identical to CPU physical addresses, but
32-
in general they are not. IOMMUs and host bridges can produce arbitrary
28+
I/O devices use a third kind of address: a "bus address". If a device has
29+
registers at an MMIO address, or if it performs DMA to read or write system
30+
memory, the addresses used by the device are bus addresses. In some
31+
systems, bus addresses are identical to CPU physical addresses, but in
32+
general they are not. IOMMUs and host bridges can produce arbitrary
3333
mappings between physical and bus addresses.
3434

35+
From a device's point of view, DMA uses the bus address space, but it may
36+
be restricted to a subset of that space. For example, even if a system
37+
supports 64-bit addresses for main memory and PCI BARs, it may use an IOMMU
38+
so devices only need to use 32-bit DMA addresses.
39+
3540
Here's a picture and some examples:
3641

3742
CPU CPU Bus
@@ -72,11 +77,11 @@ can use virtual address X to access the buffer, but the device itself
7277
cannot because DMA doesn't go through the CPU virtual memory system.
7378

7479
In some simple systems, the device can do DMA directly to physical address
75-
Y. But in many others, there is IOMMU hardware that translates bus
80+
Y. But in many others, there is IOMMU hardware that translates DMA
7681
addresses to physical addresses, e.g., it translates Z to Y. This is part
7782
of the reason for the DMA API: the driver can give a virtual address X to
7883
an interface like dma_map_single(), which sets up any required IOMMU
79-
mapping and returns the bus address Z. The driver then tells the device to
84+
mapping and returns the DMA address Z. The driver then tells the device to
8085
do DMA to Z, and the IOMMU maps it to the buffer at address Y in system
8186
RAM.
8287

@@ -98,7 +103,7 @@ First of all, you should make sure
98103
#include <linux/dma-mapping.h>
99104

100105
is in your driver, which provides the definition of dma_addr_t. This type
101-
can hold any valid DMA or bus address for the platform and should be used
106+
can hold any valid DMA address for the platform and should be used
102107
everywhere you hold a DMA address returned from the DMA mapping functions.
103108

104109
What memory is DMA'able?
@@ -316,7 +321,7 @@ There are two types of DMA mappings:
316321
Think of "consistent" as "synchronous" or "coherent".
317322

318323
The current default is to return consistent memory in the low 32
319-
bits of the bus space. However, for future compatibility you should
324+
bits of the DMA space. However, for future compatibility you should
320325
set the consistent mask even if this default is fine for your
321326
driver.
322327

@@ -403,7 +408,7 @@ dma_alloc_coherent() returns two values: the virtual address which you
403408
can use to access it from the CPU and dma_handle which you pass to the
404409
card.
405410

406-
The CPU virtual address and the DMA bus address are both
411+
The CPU virtual address and the DMA address are both
407412
guaranteed to be aligned to the smallest PAGE_SIZE order which
408413
is greater than or equal to the requested size. This invariant
409414
exists (for example) to guarantee that if you allocate a chunk
@@ -645,8 +650,8 @@ PLEASE NOTE: The 'nents' argument to the dma_unmap_sg call must be
645650
dma_map_sg call.
646651

647652
Every dma_map_{single,sg}() call should have its dma_unmap_{single,sg}()
648-
counterpart, because the bus address space is a shared resource and
649-
you could render the machine unusable by consuming all bus addresses.
653+
counterpart, because the DMA address space is a shared resource and
654+
you could render the machine unusable by consuming all DMA addresses.
650655

651656
If you need to use the same streaming DMA region multiple times and touch
652657
the data in between the DMA transfers, the buffer needs to be synced

Documentation/DMA-API.txt

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ Part I - dma_ API
1818
To get the dma_ API, you must #include <linux/dma-mapping.h>. This
1919
provides dma_addr_t and the interfaces described below.
2020

21-
A dma_addr_t can hold any valid DMA or bus address for the platform. It
22-
can be given to a device to use as a DMA source or target. A CPU cannot
23-
reference a dma_addr_t directly because there may be translation between
24-
its physical address space and the bus address space.
21+
A dma_addr_t can hold any valid DMA address for the platform. It can be
22+
given to a device to use as a DMA source or target. A CPU cannot reference
23+
a dma_addr_t directly because there may be translation between its physical
24+
address space and the DMA address space.
2525

2626
Part Ia - Using large DMA-coherent buffers
2727
------------------------------------------
@@ -42,7 +42,7 @@ It returns a pointer to the allocated region (in the processor's virtual
4242
address space) or NULL if the allocation failed.
4343

4444
It also returns a <dma_handle> which may be cast to an unsigned integer the
45-
same width as the bus and given to the device as the bus address base of
45+
same width as the bus and given to the device as the DMA address base of
4646
the region.
4747

4848
Note: consistent memory can be expensive on some platforms, and the
@@ -193,7 +193,7 @@ dma_map_single(struct device *dev, void *cpu_addr, size_t size,
193193
enum dma_data_direction direction)
194194

195195
Maps a piece of processor virtual memory so it can be accessed by the
196-
device and returns the bus address of the memory.
196+
device and returns the DMA address of the memory.
197197

198198
The direction for both APIs may be converted freely by casting.
199199
However the dma_ API uses a strongly typed enumerator for its
@@ -212,20 +212,20 @@ contiguous piece of memory. For this reason, memory to be mapped by
212212
this API should be obtained from sources which guarantee it to be
213213
physically contiguous (like kmalloc).
214214

215-
Further, the bus address of the memory must be within the
215+
Further, the DMA address of the memory must be within the
216216
dma_mask of the device (the dma_mask is a bit mask of the
217-
addressable region for the device, i.e., if the bus address of
218-
the memory ANDed with the dma_mask is still equal to the bus
217+
addressable region for the device, i.e., if the DMA address of
218+
the memory ANDed with the dma_mask is still equal to the DMA
219219
address, then the device can perform DMA to the memory). To
220220
ensure that the memory allocated by kmalloc is within the dma_mask,
221221
the driver may specify various platform-dependent flags to restrict
222-
the bus address range of the allocation (e.g., on x86, GFP_DMA
223-
guarantees to be within the first 16MB of available bus addresses,
222+
the DMA address range of the allocation (e.g., on x86, GFP_DMA
223+
guarantees to be within the first 16MB of available DMA addresses,
224224
as required by ISA devices).
225225

226226
Note also that the above constraints on physical contiguity and
227227
dma_mask may not apply if the platform has an IOMMU (a device which
228-
maps an I/O bus address to a physical memory address). However, to be
228+
maps an I/O DMA address to a physical memory address). However, to be
229229
portable, device driver writers may *not* assume that such an IOMMU
230230
exists.
231231

@@ -296,7 +296,7 @@ reduce current DMA mapping usage or delay and try again later).
296296
dma_map_sg(struct device *dev, struct scatterlist *sg,
297297
int nents, enum dma_data_direction direction)
298298

299-
Returns: the number of bus address segments mapped (this may be shorter
299+
Returns: the number of DMA address segments mapped (this may be shorter
300300
than <nents> passed in if some elements of the scatter/gather list are
301301
physically or virtually adjacent and an IOMMU maps them with a single
302302
entry).
@@ -340,7 +340,7 @@ must be the same as those and passed in to the scatter/gather mapping
340340
API.
341341

342342
Note: <nents> must be the number you passed in, *not* the number of
343-
bus address entries returned.
343+
DMA address entries returned.
344344

345345
void
346346
dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
@@ -507,7 +507,7 @@ it's asked for coherent memory for this device.
507507
phys_addr is the CPU physical address to which the memory is currently
508508
assigned (this will be ioremapped so the CPU can access the region).
509509

510-
device_addr is the bus address the device needs to be programmed
510+
device_addr is the DMA address the device needs to be programmed
511511
with to actually address this memory (this will be handed out as the
512512
dma_addr_t in dma_alloc_coherent()).
513513

drivers/pci/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
#
22
# PCI configuration
33
#
4+
config PCI_BUS_ADDR_T_64BIT
5+
def_bool y if (ARCH_DMA_ADDR_T_64BIT || 64BIT)
6+
depends on PCI
7+
48
config PCI_MSI
59
bool "Message Signaled Interrupts (MSI and MSI-X)"
610
depends on PCI

drivers/pci/bus.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,11 @@ void pci_bus_remove_resources(struct pci_bus *bus)
9292
}
9393

9494
static struct pci_bus_region pci_32_bit = {0, 0xffffffffULL};
95-
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
95+
#ifdef CONFIG_PCI_BUS_ADDR_T_64BIT
9696
static struct pci_bus_region pci_64_bit = {0,
97-
(dma_addr_t) 0xffffffffffffffffULL};
98-
static struct pci_bus_region pci_high = {(dma_addr_t) 0x100000000ULL,
99-
(dma_addr_t) 0xffffffffffffffffULL};
97+
(pci_bus_addr_t) 0xffffffffffffffffULL};
98+
static struct pci_bus_region pci_high = {(pci_bus_addr_t) 0x100000000ULL,
99+
(pci_bus_addr_t) 0xffffffffffffffffULL};
100100
#endif
101101

102102
/*
@@ -200,7 +200,7 @@ int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
200200
resource_size_t),
201201
void *alignf_data)
202202
{
203-
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
203+
#ifdef CONFIG_PCI_BUS_ADDR_T_64BIT
204204
int rc;
205205

206206
if (res->flags & IORESOURCE_MEM_64) {

drivers/pci/probe.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
254254
}
255255

256256
if (res->flags & IORESOURCE_MEM_64) {
257-
if ((sizeof(dma_addr_t) < 8 || sizeof(resource_size_t) < 8) &&
258-
sz64 > 0x100000000ULL) {
257+
if ((sizeof(pci_bus_addr_t) < 8 || sizeof(resource_size_t) < 8)
258+
&& sz64 > 0x100000000ULL) {
259259
res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
260260
res->start = 0;
261261
res->end = 0;
@@ -264,7 +264,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
264264
goto out;
265265
}
266266

267-
if ((sizeof(dma_addr_t) < 8) && l) {
267+
if ((sizeof(pci_bus_addr_t) < 8) && l) {
268268
/* Above 32-bit boundary; try to reallocate */
269269
res->flags |= IORESOURCE_UNSET;
270270
res->start = 0;
@@ -399,7 +399,7 @@ static void pci_read_bridge_mmio_pref(struct pci_bus *child)
399399
struct pci_dev *dev = child->self;
400400
u16 mem_base_lo, mem_limit_lo;
401401
u64 base64, limit64;
402-
dma_addr_t base, limit;
402+
pci_bus_addr_t base, limit;
403403
struct pci_bus_region region;
404404
struct resource *res;
405405

@@ -426,8 +426,8 @@ static void pci_read_bridge_mmio_pref(struct pci_bus *child)
426426
}
427427
}
428428

429-
base = (dma_addr_t) base64;
430-
limit = (dma_addr_t) limit64;
429+
base = (pci_bus_addr_t) base64;
430+
limit = (pci_bus_addr_t) limit64;
431431

432432
if (base != base64) {
433433
dev_err(&dev->dev, "can't handle bridge window above 4GB (bus address %#010llx)\n",

include/linux/pci.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -577,9 +577,15 @@ int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
577577
int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
578578
int reg, int len, u32 val);
579579

580+
#ifdef CONFIG_PCI_BUS_ADDR_T_64BIT
581+
typedef u64 pci_bus_addr_t;
582+
#else
583+
typedef u32 pci_bus_addr_t;
584+
#endif
585+
580586
struct pci_bus_region {
581-
dma_addr_t start;
582-
dma_addr_t end;
587+
pci_bus_addr_t start;
588+
pci_bus_addr_t end;
583589
};
584590

585591
struct pci_dynids {
@@ -1128,7 +1134,7 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
11281134

11291135
int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr);
11301136

1131-
static inline dma_addr_t pci_bus_address(struct pci_dev *pdev, int bar)
1137+
static inline pci_bus_addr_t pci_bus_address(struct pci_dev *pdev, int bar)
11321138
{
11331139
struct pci_bus_region region;
11341140

include/linux/types.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,20 @@ typedef unsigned long blkcnt_t;
139139
*/
140140
#define pgoff_t unsigned long
141141

142-
/* A dma_addr_t can hold any valid DMA or bus address for the platform */
142+
/*
143+
* A dma_addr_t can hold any valid DMA address, i.e., any address returned
144+
* by the DMA API.
145+
*
146+
* If the DMA API only uses 32-bit addresses, dma_addr_t need only be 32
147+
* bits wide. Bus addresses, e.g., PCI BARs, may be wider than 32 bits,
148+
* but drivers do memory-mapped I/O to ioremapped kernel virtual addresses,
149+
* so they don't care about the size of the actual bus addresses.
150+
*/
143151
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
144152
typedef u64 dma_addr_t;
145153
#else
146154
typedef u32 dma_addr_t;
147-
#endif /* dma_addr_t */
155+
#endif
148156

149157
typedef unsigned __bitwise__ gfp_t;
150158
typedef unsigned __bitwise__ fmode_t;

0 commit comments

Comments
 (0)