Skip to content

Commit 7b22ff5

Browse files
fujitaIngo Molnar
authored andcommitted
x86 gart: allocate size-aligned address for alloc_coherent, v2
This patch changes GART IOMMU to return a size aligned address wrt dma_alloc_coherent, as DMA-mapping.txt defines: The cpu return address and the DMA bus master address are both guaranteed to be aligned to the smallest PAGE_SIZE order which is greater than or equal to the requested size. This invariant exists (for example) to guarantee that if you allocate a chunk which is smaller than or equal to 64 kilobytes, the extent of the buffer you receive will not cross a 64K boundary. Signed-off-by: FUJITA Tomonori <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
1 parent f3efbe5 commit 7b22ff5

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

arch/x86/kernel/pci-gart_64.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ AGPEXTERN __u32 *agp_gatt_table;
8282
static unsigned long next_bit; /* protected by iommu_bitmap_lock */
8383
static int need_flush; /* global flush state. set for each gart wrap */
8484

85-
static unsigned long alloc_iommu(struct device *dev, int size)
85+
static unsigned long alloc_iommu(struct device *dev, int size,
86+
unsigned long align_mask)
8687
{
8788
unsigned long offset, flags;
8889
unsigned long boundary_size;
@@ -95,11 +96,12 @@ static unsigned long alloc_iommu(struct device *dev, int size)
9596

9697
spin_lock_irqsave(&iommu_bitmap_lock, flags);
9798
offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, next_bit,
98-
size, base_index, boundary_size, 0);
99+
size, base_index, boundary_size, align_mask);
99100
if (offset == -1) {
100101
need_flush = 1;
101102
offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, 0,
102-
size, base_index, boundary_size, 0);
103+
size, base_index, boundary_size,
104+
align_mask);
103105
}
104106
if (offset != -1) {
105107
next_bit = offset+size;
@@ -236,10 +238,10 @@ nonforced_iommu(struct device *dev, unsigned long addr, size_t size)
236238
* Caller needs to check if the iommu is needed and flush.
237239
*/
238240
static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
239-
size_t size, int dir)
241+
size_t size, int dir, unsigned long align_mask)
240242
{
241243
unsigned long npages = iommu_num_pages(phys_mem, size);
242-
unsigned long iommu_page = alloc_iommu(dev, npages);
244+
unsigned long iommu_page = alloc_iommu(dev, npages, align_mask);
243245
int i;
244246

245247
if (iommu_page == -1) {
@@ -262,7 +264,11 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
262264
static dma_addr_t
263265
gart_map_simple(struct device *dev, phys_addr_t paddr, size_t size, int dir)
264266
{
265-
dma_addr_t map = dma_map_area(dev, paddr, size, dir);
267+
dma_addr_t map;
268+
unsigned long align_mask;
269+
270+
align_mask = (1UL << get_order(size)) - 1;
271+
map = dma_map_area(dev, paddr, size, dir, align_mask);
266272

267273
flush_gart();
268274

@@ -281,7 +287,8 @@ gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir)
281287
if (!need_iommu(dev, paddr, size))
282288
return paddr;
283289

284-
bus = gart_map_simple(dev, paddr, size, dir);
290+
bus = dma_map_area(dev, paddr, size, dir, 0);
291+
flush_gart();
285292

286293
return bus;
287294
}
@@ -340,7 +347,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
340347
unsigned long addr = sg_phys(s);
341348

342349
if (nonforced_iommu(dev, addr, s->length)) {
343-
addr = dma_map_area(dev, addr, s->length, dir);
350+
addr = dma_map_area(dev, addr, s->length, dir, 0);
344351
if (addr == bad_dma_address) {
345352
if (i > 0)
346353
gart_unmap_sg(dev, sg, i, dir);
@@ -362,7 +369,7 @@ static int __dma_map_cont(struct device *dev, struct scatterlist *start,
362369
int nelems, struct scatterlist *sout,
363370
unsigned long pages)
364371
{
365-
unsigned long iommu_start = alloc_iommu(dev, pages);
372+
unsigned long iommu_start = alloc_iommu(dev, pages, 0);
366373
unsigned long iommu_page = iommu_start;
367374
struct scatterlist *s;
368375
int i;

0 commit comments

Comments
 (0)