[SPARC64]: IOMMU allocations using iommu-helper layer.

Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

David S. Miller and committed by
David S. Miller
d284142c 19814ea2

+112 -110
+4
arch/sparc64/Kconfig
··· 40 40 bool 41 41 default y 42 42 43 + config IOMMU_HELPER 44 + bool 45 + default y 46 + 43 47 config QUICKLIST 44 48 bool 45 49 default y
+81 -44
arch/sparc64/kernel/iommu.c
··· 1 1 /* iommu.c: Generic sparc64 IOMMU support. 2 2 * 3 - * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) 3 + * Copyright (C) 1999, 2007, 2008 David S. Miller (davem@davemloft.net) 4 4 * Copyright (C) 1999, 2000 Jakub Jelinek (jakub@redhat.com) 5 5 */ 6 6 ··· 10 10 #include <linux/device.h> 11 11 #include <linux/dma-mapping.h> 12 12 #include <linux/errno.h> 13 + #include <linux/iommu-helper.h> 13 14 14 15 #ifdef CONFIG_PCI 15 16 #include <linux/pci.h> ··· 42 41 "i" (ASI_PHYS_BYPASS_EC_E)) 43 42 44 43 /* Must be invoked under the IOMMU lock. */ 45 - static void __iommu_flushall(struct iommu *iommu) 44 + static void iommu_flushall(struct iommu *iommu) 46 45 { 47 46 if (iommu->iommu_flushinv) { 48 47 iommu_write(iommu->iommu_flushinv, ~(u64)0); ··· 84 83 iopte_val(*iopte) = val; 85 84 } 86 85 87 - /* Based largely upon the ppc64 iommu allocator. */ 88 - static long arena_alloc(struct iommu *iommu, unsigned long npages) 86 + /* Based almost entirely upon the ppc64 iommu allocator. If you use the 'handle' 87 + * facility it must all be done in one pass while under the iommu lock. 88 + * 89 + * On sun4u platforms, we only flush the IOMMU once every time we've passed 90 + * over the entire page table doing allocations. Therefore we only ever advance 91 + * the hint and cannot backtrack it. 92 + */ 93 + unsigned long iommu_range_alloc(struct device *dev, 94 + struct iommu *iommu, 95 + unsigned long npages, 96 + unsigned long *handle) 89 97 { 98 + unsigned long n, end, start, limit, boundary_size; 90 99 struct iommu_arena *arena = &iommu->arena; 91 - unsigned long n, i, start, end, limit; 92 - int pass; 100 + int pass = 0; 101 + 102 + /* This allocator was derived from x86_64's bit string search */ 103 + 104 + /* Sanity check */ 105 + if (unlikely(npages == 0)) { 106 + if (printk_ratelimit()) 107 + WARN_ON(1); 108 + return DMA_ERROR_CODE; 109 + } 110 + 111 + if (handle && *handle) 112 + start = *handle; 113 + else 114 + start = arena->hint; 93 115 94 116 limit = arena->limit; 95 - start = arena->hint; 96 - pass = 0; 97 117 98 - again: 99 - n = find_next_zero_bit(arena->map, limit, start); 100 - end = n + npages; 101 - if (unlikely(end >= limit)) { 118 + /* The case below can happen if we have a small segment appended 119 + * to a large, or when the previous alloc was at the very end of 120 + * the available space. If so, go back to the beginning and flush. 121 + */ 122 + if (start >= limit) { 123 + start = 0; 124 + if (iommu->flush_all) 125 + iommu->flush_all(iommu); 126 + } 127 + 128 + again: 129 + 130 + if (dev) 131 + boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, 132 + 1 << IO_PAGE_SHIFT); 133 + else 134 + boundary_size = ALIGN(1UL << 32, 1 << IO_PAGE_SHIFT); 135 + 136 + n = iommu_area_alloc(arena->map, limit, start, npages, 0, 137 + boundary_size >> IO_PAGE_SHIFT, 0); 138 + if (n == -1) { 102 139 if (likely(pass < 1)) { 103 - limit = start; 140 + /* First failure, rescan from the beginning. */ 104 141 start = 0; 105 - __iommu_flushall(iommu); 142 + if (iommu->flush_all) 143 + iommu->flush_all(iommu); 106 144 pass++; 107 145 goto again; 108 146 } else { 109 - /* Scanned the whole thing, give up. */ 110 - return -1; 147 + /* Second failure, give up */ 148 + return DMA_ERROR_CODE; 111 149 } 112 150 } 113 151 114 - for (i = n; i < end; i++) { 115 - if (test_bit(i, arena->map)) { 116 - start = i + 1; 117 - goto again; 118 - } 119 - } 120 - 121 - for (i = n; i < end; i++) 122 - __set_bit(i, arena->map); 152 + end = n + npages; 123 153 124 154 arena->hint = end; 155 + 156 + /* Update handle for SG allocations */ 157 + if (handle) 158 + *handle = end; 125 159 126 160 return n; 127 161 } 128 162 129 - static void arena_free(struct iommu_arena *arena, unsigned long base, unsigned long npages) 163 + void iommu_range_free(struct iommu *iommu, dma_addr_t dma_addr, unsigned long npages) 130 164 { 131 - unsigned long i; 165 + struct iommu_arena *arena = &iommu->arena; 166 + unsigned long entry; 132 167 133 - for (i = base; i < (base + npages); i++) 134 - __clear_bit(i, arena->map); 168 + entry = (dma_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT; 169 + 170 + iommu_area_free(arena->map, entry, npages); 135 171 } 136 172 137 173 int iommu_table_init(struct iommu *iommu, int tsbsize, ··· 193 155 return -ENOMEM; 194 156 } 195 157 iommu->arena.limit = num_tsb_entries; 158 + 159 + if (tlb_type != hypervisor) 160 + iommu->flush_all = iommu_flushall; 196 161 197 162 /* Allocate and initialize the dummy page which we 198 163 * set inactive IO PTEs to point to. ··· 233 192 return -ENOMEM; 234 193 } 235 194 236 - static inline iopte_t *alloc_npages(struct iommu *iommu, unsigned long npages) 195 + static inline iopte_t *alloc_npages(struct device *dev, struct iommu *iommu, 196 + unsigned long npages) 237 197 { 238 - long entry; 198 + unsigned long entry; 239 199 240 - entry = arena_alloc(iommu, npages); 241 - if (unlikely(entry < 0)) 200 + entry = iommu_range_alloc(dev, iommu, npages, NULL); 201 + if (unlikely(entry == DMA_ERROR_CODE)) 242 202 return NULL; 243 203 244 204 return iommu->page_table + entry; 245 - } 246 - 247 - static inline void free_npages(struct iommu *iommu, dma_addr_t base, unsigned long npages) 248 - { 249 - arena_free(&iommu->arena, base >> IO_PAGE_SHIFT, npages); 250 205 } 251 206 252 207 static int iommu_alloc_ctx(struct iommu *iommu) ··· 295 258 iommu = dev->archdata.iommu; 296 259 297 260 spin_lock_irqsave(&iommu->lock, flags); 298 - iopte = alloc_npages(iommu, size >> IO_PAGE_SHIFT); 261 + iopte = alloc_npages(dev, iommu, size >> IO_PAGE_SHIFT); 299 262 spin_unlock_irqrestore(&iommu->lock, flags); 300 263 301 264 if (unlikely(iopte == NULL)) { ··· 333 296 334 297 spin_lock_irqsave(&iommu->lock, flags); 335 298 336 - free_npages(iommu, dvma - iommu->page_table_map_base, npages); 299 + iommu_range_free(iommu, dvma, npages); 337 300 338 301 spin_unlock_irqrestore(&iommu->lock, flags); 339 302 ··· 364 327 npages >>= IO_PAGE_SHIFT; 365 328 366 329 spin_lock_irqsave(&iommu->lock, flags); 367 - base = alloc_npages(iommu, npages); 330 + base = alloc_npages(dev, iommu, npages); 368 331 ctx = 0; 369 332 if (iommu->iommu_ctxflush) 370 333 ctx = iommu_alloc_ctx(iommu); ··· 502 465 for (i = 0; i < npages; i++) 503 466 iopte_make_dummy(iommu, base + i); 504 467 505 - free_npages(iommu, bus_addr - iommu->page_table_map_base, npages); 468 + iommu_range_free(iommu, bus_addr, npages); 506 469 507 470 iommu_free_ctx(iommu, ctx); 508 471 ··· 540 503 541 504 spin_lock_irqsave(&iommu->lock, flags); 542 505 543 - base = alloc_npages(iommu, npages); 506 + base = alloc_npages(dev, iommu, npages); 544 507 ctx = 0; 545 508 if (iommu->iommu_ctxflush) 546 509 ctx = iommu_alloc_ctx(iommu); ··· 629 592 for (i = 0; i < npages; i++) 630 593 iopte_make_dummy(iommu, base + i); 631 594 632 - free_npages(iommu, bus_addr - iommu->page_table_map_base, npages); 595 + iommu_range_free(iommu, bus_addr, npages); 633 596 634 597 iommu_free_ctx(iommu, ctx); 635 598
+8
arch/sparc64/kernel/iommu_common.h
··· 58 58 return npages; 59 59 } 60 60 61 + extern unsigned long iommu_range_alloc(struct device *dev, 62 + struct iommu *iommu, 63 + unsigned long npages, 64 + unsigned long *handle); 65 + extern void iommu_range_free(struct iommu *iommu, 66 + dma_addr_t dma_addr, 67 + unsigned long npages); 68 + 61 69 #endif /* _IOMMU_COMMON_H */
+18 -66
arch/sparc64/kernel/pci_sun4v.c
··· 1 1 /* pci_sun4v.c: SUN4V specific PCI controller support. 2 2 * 3 - * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net) 3 + * Copyright (C) 2006, 2007, 2008 David S. Miller (davem@davemloft.net) 4 4 */ 5 5 6 6 #include <linux/kernel.h> ··· 113 113 return iommu_batch_flush(p); 114 114 } 115 115 116 - static long arena_alloc(struct iommu_arena *arena, unsigned long npages) 117 - { 118 - unsigned long n, i, start, end, limit; 119 - int pass; 120 - 121 - limit = arena->limit; 122 - start = arena->hint; 123 - pass = 0; 124 - 125 - again: 126 - n = find_next_zero_bit(arena->map, limit, start); 127 - end = n + npages; 128 - if (unlikely(end >= limit)) { 129 - if (likely(pass < 1)) { 130 - limit = start; 131 - start = 0; 132 - pass++; 133 - goto again; 134 - } else { 135 - /* Scanned the whole thing, give up. */ 136 - return -1; 137 - } 138 - } 139 - 140 - for (i = n; i < end; i++) { 141 - if (test_bit(i, arena->map)) { 142 - start = i + 1; 143 - goto again; 144 - } 145 - } 146 - 147 - for (i = n; i < end; i++) 148 - __set_bit(i, arena->map); 149 - 150 - arena->hint = end; 151 - 152 - return n; 153 - } 154 - 155 - static void arena_free(struct iommu_arena *arena, unsigned long base, 156 - unsigned long npages) 157 - { 158 - unsigned long i; 159 - 160 - for (i = base; i < (base + npages); i++) 161 - __clear_bit(i, arena->map); 162 - } 163 - 164 116 static void *dma_4v_alloc_coherent(struct device *dev, size_t size, 165 117 dma_addr_t *dma_addrp, gfp_t gfp) 166 118 { ··· 137 185 iommu = dev->archdata.iommu; 138 186 139 187 spin_lock_irqsave(&iommu->lock, flags); 140 - entry = arena_alloc(&iommu->arena, npages); 188 + entry = iommu_range_alloc(dev, iommu, npages, NULL); 141 189 spin_unlock_irqrestore(&iommu->lock, flags); 142 190 143 - if (unlikely(entry < 0L)) 144 - goto arena_alloc_fail; 191 + if (unlikely(entry == DMA_ERROR_CODE)) 192 + goto range_alloc_fail; 145 193 146 194 *dma_addrp = (iommu->page_table_map_base + 147 195 (entry << IO_PAGE_SHIFT)); ··· 171 219 iommu_map_fail: 172 220 /* Interrupts are disabled. */ 173 221 spin_lock(&iommu->lock); 174 - arena_free(&iommu->arena, entry, npages); 222 + iommu_range_free(iommu, *dma_addrp, npages); 175 223 spin_unlock_irqrestore(&iommu->lock, flags); 176 224 177 - arena_alloc_fail: 225 + range_alloc_fail: 178 226 free_pages(first_page, order); 179 227 return NULL; 180 228 } ··· 195 243 196 244 spin_lock_irqsave(&iommu->lock, flags); 197 245 198 - arena_free(&iommu->arena, entry, npages); 246 + iommu_range_free(iommu, dvma, npages); 199 247 200 248 do { 201 249 unsigned long num; ··· 233 281 npages >>= IO_PAGE_SHIFT; 234 282 235 283 spin_lock_irqsave(&iommu->lock, flags); 236 - entry = arena_alloc(&iommu->arena, npages); 284 + entry = iommu_range_alloc(dev, iommu, npages, NULL); 237 285 spin_unlock_irqrestore(&iommu->lock, flags); 238 286 239 - if (unlikely(entry < 0L)) 287 + if (unlikely(entry == DMA_ERROR_CODE)) 240 288 goto bad; 241 289 242 290 bus_addr = (iommu->page_table_map_base + ··· 271 319 iommu_map_fail: 272 320 /* Interrupts are disabled. */ 273 321 spin_lock(&iommu->lock); 274 - arena_free(&iommu->arena, entry, npages); 322 + iommu_range_free(iommu, bus_addr, npages); 275 323 spin_unlock_irqrestore(&iommu->lock, flags); 276 324 277 325 return DMA_ERROR_CODE; ··· 302 350 303 351 spin_lock_irqsave(&iommu->lock, flags); 304 352 305 - entry = (bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT; 306 - arena_free(&iommu->arena, entry, npages); 353 + iommu_range_free(iommu, bus_addr, npages); 307 354 355 + entry = (bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT; 308 356 do { 309 357 unsigned long num; 310 358 ··· 321 369 int nelems, enum dma_data_direction direction) 322 370 { 323 371 unsigned long flags, npages, i, prot; 372 + u32 dma_base, orig_dma_base; 324 373 struct scatterlist *sg; 325 374 struct iommu *iommu; 326 375 long entry, err; 327 - u32 dma_base; 328 376 329 377 /* Fast path single entry scatterlists. */ 330 378 if (nelems == 1) { ··· 345 393 npages = calc_npages(sglist, nelems); 346 394 347 395 spin_lock_irqsave(&iommu->lock, flags); 348 - entry = arena_alloc(&iommu->arena, npages); 396 + entry = iommu_range_alloc(dev, iommu, npages, NULL); 349 397 spin_unlock_irqrestore(&iommu->lock, flags); 350 398 351 - if (unlikely(entry < 0L)) 399 + if (unlikely(entry == DMA_ERROR_CODE)) 352 400 goto bad; 353 401 354 - dma_base = iommu->page_table_map_base + 402 + orig_dma_base = dma_base = iommu->page_table_map_base + 355 403 (entry << IO_PAGE_SHIFT); 356 404 357 405 prot = HV_PCI_MAP_ATTR_READ; ··· 401 449 402 450 iommu_map_failed: 403 451 spin_lock_irqsave(&iommu->lock, flags); 404 - arena_free(&iommu->arena, entry, npages); 452 + iommu_range_free(iommu, orig_dma_base, npages); 405 453 spin_unlock_irqrestore(&iommu->lock, flags); 406 454 407 455 return 0; ··· 433 481 434 482 spin_lock_irqsave(&iommu->lock, flags); 435 483 436 - arena_free(&iommu->arena, entry, npages); 484 + iommu_range_free(iommu, bus_addr, npages); 437 485 438 486 do { 439 487 unsigned long num;
+1
include/asm-sparc64/iommu.h
··· 26 26 struct iommu { 27 27 spinlock_t lock; 28 28 struct iommu_arena arena; 29 + void (*flush_all)(struct iommu *); 29 30 iopte_t *page_table; 30 31 u32 page_table_map_base; 31 32 unsigned long iommu_control;