Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus-for-3.6-rc1' of git://git.linaro.org/people/mszyprowski/linux-dma-mapping

Pull DMA-mapping updates from Marek Szyprowski:
"Those patches are continuation of my earlier work.

They contains extensions to DMA-mapping framework to remove limitation
of the current ARM implementation (like limited total size of DMA
coherent/write combine buffers), improve performance of buffer sharing
between devices (attributes to skip cpu cache operations or creation
of additional kernel mapping for some specific use cases) as well as
some unification of the common code for dma_mmap_attrs() and
dma_mmap_coherent() functions. All extensions have been implemented
and tested for ARM architecture."

* 'for-linus-for-3.6-rc1' of git://git.linaro.org/people/mszyprowski/linux-dma-mapping:
ARM: dma-mapping: add support for DMA_ATTR_SKIP_CPU_SYNC attribute
common: DMA-mapping: add DMA_ATTR_SKIP_CPU_SYNC attribute
ARM: dma-mapping: add support for dma_get_sgtable()
common: dma-mapping: introduce dma_get_sgtable() function
ARM: dma-mapping: add support for DMA_ATTR_NO_KERNEL_MAPPING attribute
common: DMA-mapping: add DMA_ATTR_NO_KERNEL_MAPPING attribute
common: dma-mapping: add support for generic dma_mmap_* calls
ARM: dma-mapping: fix error path for memory allocation failure
ARM: dma-mapping: add more sanity checks in arm_dma_mmap()
ARM: dma-mapping: remove custom consistent dma region
mm: vmalloc: use const void * for caller argument
scatterlist: add sg_alloc_table_from_pages function

+512 -397
+42
Documentation/DMA-attributes.txt
··· 49 49 consistent or non-consistent memory as it sees fit. By using this API, 50 50 you are guaranteeing to the platform that you have all the correct and 51 51 necessary sync points for this memory in the driver. 52 + 53 + DMA_ATTR_NO_KERNEL_MAPPING 54 + -------------------------- 55 + 56 + DMA_ATTR_NO_KERNEL_MAPPING lets the platform to avoid creating a kernel 57 + virtual mapping for the allocated buffer. On some architectures creating 58 + such mapping is non-trivial task and consumes very limited resources 59 + (like kernel virtual address space or dma consistent address space). 60 + Buffers allocated with this attribute can be only passed to user space 61 + by calling dma_mmap_attrs(). By using this API, you are guaranteeing 62 + that you won't dereference the pointer returned by dma_alloc_attr(). You 63 + can threat it as a cookie that must be passed to dma_mmap_attrs() and 64 + dma_free_attrs(). Make sure that both of these also get this attribute 65 + set on each call. 66 + 67 + Since it is optional for platforms to implement 68 + DMA_ATTR_NO_KERNEL_MAPPING, those that do not will simply ignore the 69 + attribute and exhibit default behavior. 70 + 71 + DMA_ATTR_SKIP_CPU_SYNC 72 + ---------------------- 73 + 74 + By default dma_map_{single,page,sg} functions family transfer a given 75 + buffer from CPU domain to device domain. Some advanced use cases might 76 + require sharing a buffer between more than one device. This requires 77 + having a mapping created separately for each device and is usually 78 + performed by calling dma_map_{single,page,sg} function more than once 79 + for the given buffer with device pointer to each device taking part in 80 + the buffer sharing. The first call transfers a buffer from 'CPU' domain 81 + to 'device' domain, what synchronizes CPU caches for the given region 82 + (usually it means that the cache has been flushed or invalidated 83 + depending on the dma direction). However, next calls to 84 + dma_map_{single,page,sg}() for other devices will perform exactly the 85 + same sychronization operation on the CPU cache. CPU cache sychronization 86 + might be a time consuming operation, especially if the buffers are 87 + large, so it is highly recommended to avoid it if possible. 88 + DMA_ATTR_SKIP_CPU_SYNC allows platform code to skip synchronization of 89 + the CPU cache for the given buffer assuming that it has been already 90 + transferred to 'device' domain. This attribute can be also used for 91 + dma_unmap_{single,page,sg} functions family to force buffer to stay in 92 + device domain after releasing a mapping for it. Use this attribute with 93 + care!
+1 -1
Documentation/kernel-parameters.txt
··· 526 526 527 527 coherent_pool=nn[KMG] [ARM,KNL] 528 528 Sets the size of memory pool for coherent, atomic dma 529 - allocations if Contiguous Memory Allocator (CMA) is used. 529 + allocations, by default set to 256K. 530 530 531 531 code_bytes [X86] How many bytes of object code to print 532 532 in an oops report.
+1
arch/arm/common/dmabounce.c
··· 452 452 .alloc = arm_dma_alloc, 453 453 .free = arm_dma_free, 454 454 .mmap = arm_dma_mmap, 455 + .get_sgtable = arm_dma_get_sgtable, 455 456 .map_page = dmabounce_map_page, 456 457 .unmap_page = dmabounce_unmap_page, 457 458 .sync_single_for_cpu = dmabounce_sync_for_cpu,
+4 -20
arch/arm/include/asm/dma-mapping.h
··· 186 186 void *cpu_addr, dma_addr_t dma_addr, size_t size, 187 187 struct dma_attrs *attrs); 188 188 189 - #define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL) 190 - 191 - static inline int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, 192 - void *cpu_addr, dma_addr_t dma_addr, 193 - size_t size, struct dma_attrs *attrs) 194 - { 195 - struct dma_map_ops *ops = get_dma_ops(dev); 196 - BUG_ON(!ops); 197 - return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs); 198 - } 199 - 200 189 static inline void *dma_alloc_writecombine(struct device *dev, size_t size, 201 190 dma_addr_t *dma_handle, gfp_t flag) 202 191 { ··· 202 213 return dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs); 203 214 } 204 215 205 - static inline int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma, 206 - void *cpu_addr, dma_addr_t dma_addr, size_t size) 207 - { 208 - DEFINE_DMA_ATTRS(attrs); 209 - dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs); 210 - return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs); 211 - } 212 - 213 216 /* 214 217 * This can be called during boot to increase the size of the consistent 215 218 * DMA region above it's default value of 2MB. It must be called before the 216 219 * memory allocator is initialised, i.e. before any core_initcall. 217 220 */ 218 - extern void __init init_consistent_dma_size(unsigned long size); 221 + static inline void init_consistent_dma_size(unsigned long size) { } 219 222 220 223 /* 221 224 * For SA-1111, IXP425, and ADI systems the dma-mapping functions are "magic" ··· 261 280 enum dma_data_direction); 262 281 extern void arm_dma_sync_sg_for_device(struct device *, struct scatterlist *, int, 263 282 enum dma_data_direction); 283 + extern int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt, 284 + void *cpu_addr, dma_addr_t dma_addr, size_t size, 285 + struct dma_attrs *attrs); 264 286 265 287 #endif /* __KERNEL__ */ 266 288 #endif
+234 -341
arch/arm/mm/dma-mapping.c
··· 22 22 #include <linux/memblock.h> 23 23 #include <linux/slab.h> 24 24 #include <linux/iommu.h> 25 + #include <linux/io.h> 25 26 #include <linux/vmalloc.h> 26 27 #include <linux/sizes.h> 27 28 ··· 73 72 unsigned long offset, size_t size, enum dma_data_direction dir, 74 73 struct dma_attrs *attrs) 75 74 { 76 - if (!arch_is_coherent()) 75 + if (!arch_is_coherent() && !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) 77 76 __dma_page_cpu_to_dev(page, offset, size, dir); 78 77 return pfn_to_dma(dev, page_to_pfn(page)) + offset; 79 78 } ··· 96 95 size_t size, enum dma_data_direction dir, 97 96 struct dma_attrs *attrs) 98 97 { 99 - if (!arch_is_coherent()) 98 + if (!arch_is_coherent() && !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) 100 99 __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)), 101 100 handle & ~PAGE_MASK, size, dir); 102 101 } ··· 125 124 .alloc = arm_dma_alloc, 126 125 .free = arm_dma_free, 127 126 .mmap = arm_dma_mmap, 127 + .get_sgtable = arm_dma_get_sgtable, 128 128 .map_page = arm_dma_map_page, 129 129 .unmap_page = arm_dma_unmap_page, 130 130 .map_sg = arm_dma_map_sg, ··· 219 217 } 220 218 221 219 #ifdef CONFIG_MMU 222 - 223 - #define CONSISTENT_OFFSET(x) (((unsigned long)(x) - consistent_base) >> PAGE_SHIFT) 224 - #define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - consistent_base) >> PMD_SHIFT) 225 - 226 - /* 227 - * These are the page tables (2MB each) covering uncached, DMA consistent allocations 228 - */ 229 - static pte_t **consistent_pte; 230 - 231 - #define DEFAULT_CONSISTENT_DMA_SIZE SZ_2M 232 - 233 - static unsigned long consistent_base = CONSISTENT_END - DEFAULT_CONSISTENT_DMA_SIZE; 234 - 235 - void __init init_consistent_dma_size(unsigned long size) 236 - { 237 - unsigned long base = CONSISTENT_END - ALIGN(size, SZ_2M); 238 - 239 - BUG_ON(consistent_pte); /* Check we're called before DMA region init */ 240 - BUG_ON(base < VMALLOC_END); 241 - 242 - /* Grow region to accommodate specified size */ 243 - if (base < consistent_base) 244 - consistent_base = base; 245 - } 246 - 247 - #include "vmregion.h" 248 - 249 - static struct arm_vmregion_head consistent_head = { 250 - .vm_lock = __SPIN_LOCK_UNLOCKED(&consistent_head.vm_lock), 251 - .vm_list = LIST_HEAD_INIT(consistent_head.vm_list), 252 - .vm_end = CONSISTENT_END, 253 - }; 254 - 255 220 #ifdef CONFIG_HUGETLB_PAGE 256 221 #error ARM Coherent DMA allocator does not (yet) support huge TLB 257 222 #endif 258 223 259 - /* 260 - * Initialise the consistent memory allocation. 261 - */ 262 - static int __init consistent_init(void) 263 - { 264 - int ret = 0; 265 - pgd_t *pgd; 266 - pud_t *pud; 267 - pmd_t *pmd; 268 - pte_t *pte; 269 - int i = 0; 270 - unsigned long base = consistent_base; 271 - unsigned long num_ptes = (CONSISTENT_END - base) >> PMD_SHIFT; 272 - 273 - if (IS_ENABLED(CONFIG_CMA) && !IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) 274 - return 0; 275 - 276 - consistent_pte = kmalloc(num_ptes * sizeof(pte_t), GFP_KERNEL); 277 - if (!consistent_pte) { 278 - pr_err("%s: no memory\n", __func__); 279 - return -ENOMEM; 280 - } 281 - 282 - pr_debug("DMA memory: 0x%08lx - 0x%08lx:\n", base, CONSISTENT_END); 283 - consistent_head.vm_start = base; 284 - 285 - do { 286 - pgd = pgd_offset(&init_mm, base); 287 - 288 - pud = pud_alloc(&init_mm, pgd, base); 289 - if (!pud) { 290 - pr_err("%s: no pud tables\n", __func__); 291 - ret = -ENOMEM; 292 - break; 293 - } 294 - 295 - pmd = pmd_alloc(&init_mm, pud, base); 296 - if (!pmd) { 297 - pr_err("%s: no pmd tables\n", __func__); 298 - ret = -ENOMEM; 299 - break; 300 - } 301 - WARN_ON(!pmd_none(*pmd)); 302 - 303 - pte = pte_alloc_kernel(pmd, base); 304 - if (!pte) { 305 - pr_err("%s: no pte tables\n", __func__); 306 - ret = -ENOMEM; 307 - break; 308 - } 309 - 310 - consistent_pte[i++] = pte; 311 - base += PMD_SIZE; 312 - } while (base < CONSISTENT_END); 313 - 314 - return ret; 315 - } 316 - core_initcall(consistent_init); 317 - 318 224 static void *__alloc_from_contiguous(struct device *dev, size_t size, 319 225 pgprot_t prot, struct page **ret_page); 320 226 321 - static struct arm_vmregion_head coherent_head = { 322 - .vm_lock = __SPIN_LOCK_UNLOCKED(&coherent_head.vm_lock), 323 - .vm_list = LIST_HEAD_INIT(coherent_head.vm_list), 227 + static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp, 228 + pgprot_t prot, struct page **ret_page, 229 + const void *caller); 230 + 231 + static void * 232 + __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot, 233 + const void *caller) 234 + { 235 + struct vm_struct *area; 236 + unsigned long addr; 237 + 238 + /* 239 + * DMA allocation can be mapped to user space, so lets 240 + * set VM_USERMAP flags too. 241 + */ 242 + area = get_vm_area_caller(size, VM_ARM_DMA_CONSISTENT | VM_USERMAP, 243 + caller); 244 + if (!area) 245 + return NULL; 246 + addr = (unsigned long)area->addr; 247 + area->phys_addr = __pfn_to_phys(page_to_pfn(page)); 248 + 249 + if (ioremap_page_range(addr, addr + size, area->phys_addr, prot)) { 250 + vunmap((void *)addr); 251 + return NULL; 252 + } 253 + return (void *)addr; 254 + } 255 + 256 + static void __dma_free_remap(void *cpu_addr, size_t size) 257 + { 258 + unsigned int flags = VM_ARM_DMA_CONSISTENT | VM_USERMAP; 259 + struct vm_struct *area = find_vm_area(cpu_addr); 260 + if (!area || (area->flags & flags) != flags) { 261 + WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr); 262 + return; 263 + } 264 + unmap_kernel_range((unsigned long)cpu_addr, size); 265 + vunmap(cpu_addr); 266 + } 267 + 268 + struct dma_pool { 269 + size_t size; 270 + spinlock_t lock; 271 + unsigned long *bitmap; 272 + unsigned long nr_pages; 273 + void *vaddr; 274 + struct page *page; 324 275 }; 325 276 326 - static size_t coherent_pool_size = DEFAULT_CONSISTENT_DMA_SIZE / 8; 277 + static struct dma_pool atomic_pool = { 278 + .size = SZ_256K, 279 + }; 327 280 328 281 static int __init early_coherent_pool(char *p) 329 282 { 330 - coherent_pool_size = memparse(p, &p); 283 + atomic_pool.size = memparse(p, &p); 331 284 return 0; 332 285 } 333 286 early_param("coherent_pool", early_coherent_pool); ··· 290 333 /* 291 334 * Initialise the coherent pool for atomic allocations. 292 335 */ 293 - static int __init coherent_init(void) 336 + static int __init atomic_pool_init(void) 294 337 { 338 + struct dma_pool *pool = &atomic_pool; 295 339 pgprot_t prot = pgprot_dmacoherent(pgprot_kernel); 296 - size_t size = coherent_pool_size; 340 + unsigned long nr_pages = pool->size >> PAGE_SHIFT; 341 + unsigned long *bitmap; 297 342 struct page *page; 298 343 void *ptr; 344 + int bitmap_size = BITS_TO_LONGS(nr_pages) * sizeof(long); 299 345 300 - if (!IS_ENABLED(CONFIG_CMA)) 301 - return 0; 346 + bitmap = kzalloc(bitmap_size, GFP_KERNEL); 347 + if (!bitmap) 348 + goto no_bitmap; 302 349 303 - ptr = __alloc_from_contiguous(NULL, size, prot, &page); 350 + if (IS_ENABLED(CONFIG_CMA)) 351 + ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page); 352 + else 353 + ptr = __alloc_remap_buffer(NULL, pool->size, GFP_KERNEL, prot, 354 + &page, NULL); 304 355 if (ptr) { 305 - coherent_head.vm_start = (unsigned long) ptr; 306 - coherent_head.vm_end = (unsigned long) ptr + size; 307 - printk(KERN_INFO "DMA: preallocated %u KiB pool for atomic coherent allocations\n", 308 - (unsigned)size / 1024); 356 + spin_lock_init(&pool->lock); 357 + pool->vaddr = ptr; 358 + pool->page = page; 359 + pool->bitmap = bitmap; 360 + pool->nr_pages = nr_pages; 361 + pr_info("DMA: preallocated %u KiB pool for atomic coherent allocations\n", 362 + (unsigned)pool->size / 1024); 309 363 return 0; 310 364 } 311 - printk(KERN_ERR "DMA: failed to allocate %u KiB pool for atomic coherent allocation\n", 312 - (unsigned)size / 1024); 365 + kfree(bitmap); 366 + no_bitmap: 367 + pr_err("DMA: failed to allocate %u KiB pool for atomic coherent allocation\n", 368 + (unsigned)pool->size / 1024); 313 369 return -ENOMEM; 314 370 } 315 371 /* 316 372 * CMA is activated by core_initcall, so we must be called after it. 317 373 */ 318 - postcore_initcall(coherent_init); 374 + postcore_initcall(atomic_pool_init); 319 375 320 376 struct dma_contig_early_reserve { 321 377 phys_addr_t base; ··· 376 406 } 377 407 } 378 408 379 - static void * 380 - __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot, 381 - const void *caller) 382 - { 383 - struct arm_vmregion *c; 384 - size_t align; 385 - int bit; 386 - 387 - if (!consistent_pte) { 388 - pr_err("%s: not initialised\n", __func__); 389 - dump_stack(); 390 - return NULL; 391 - } 392 - 393 - /* 394 - * Align the virtual region allocation - maximum alignment is 395 - * a section size, minimum is a page size. This helps reduce 396 - * fragmentation of the DMA space, and also prevents allocations 397 - * smaller than a section from crossing a section boundary. 398 - */ 399 - bit = fls(size - 1); 400 - if (bit > SECTION_SHIFT) 401 - bit = SECTION_SHIFT; 402 - align = 1 << bit; 403 - 404 - /* 405 - * Allocate a virtual address in the consistent mapping region. 406 - */ 407 - c = arm_vmregion_alloc(&consistent_head, align, size, 408 - gfp & ~(__GFP_DMA | __GFP_HIGHMEM), caller); 409 - if (c) { 410 - pte_t *pte; 411 - int idx = CONSISTENT_PTE_INDEX(c->vm_start); 412 - u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1); 413 - 414 - pte = consistent_pte[idx] + off; 415 - c->priv = page; 416 - 417 - do { 418 - BUG_ON(!pte_none(*pte)); 419 - 420 - set_pte_ext(pte, mk_pte(page, prot), 0); 421 - page++; 422 - pte++; 423 - off++; 424 - if (off >= PTRS_PER_PTE) { 425 - off = 0; 426 - pte = consistent_pte[++idx]; 427 - } 428 - } while (size -= PAGE_SIZE); 429 - 430 - dsb(); 431 - 432 - return (void *)c->vm_start; 433 - } 434 - return NULL; 435 - } 436 - 437 - static void __dma_free_remap(void *cpu_addr, size_t size) 438 - { 439 - struct arm_vmregion *c; 440 - unsigned long addr; 441 - pte_t *ptep; 442 - int idx; 443 - u32 off; 444 - 445 - c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr); 446 - if (!c) { 447 - pr_err("%s: trying to free invalid coherent area: %p\n", 448 - __func__, cpu_addr); 449 - dump_stack(); 450 - return; 451 - } 452 - 453 - if ((c->vm_end - c->vm_start) != size) { 454 - pr_err("%s: freeing wrong coherent size (%ld != %d)\n", 455 - __func__, c->vm_end - c->vm_start, size); 456 - dump_stack(); 457 - size = c->vm_end - c->vm_start; 458 - } 459 - 460 - idx = CONSISTENT_PTE_INDEX(c->vm_start); 461 - off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1); 462 - ptep = consistent_pte[idx] + off; 463 - addr = c->vm_start; 464 - do { 465 - pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep); 466 - 467 - ptep++; 468 - addr += PAGE_SIZE; 469 - off++; 470 - if (off >= PTRS_PER_PTE) { 471 - off = 0; 472 - ptep = consistent_pte[++idx]; 473 - } 474 - 475 - if (pte_none(pte) || !pte_present(pte)) 476 - pr_crit("%s: bad page in kernel page table\n", 477 - __func__); 478 - } while (size -= PAGE_SIZE); 479 - 480 - flush_tlb_kernel_range(c->vm_start, c->vm_end); 481 - 482 - arm_vmregion_free(&consistent_head, c); 483 - } 484 - 485 409 static int __dma_update_pte(pte_t *pte, pgtable_t token, unsigned long addr, 486 410 void *data) 487 411 { ··· 416 552 return ptr; 417 553 } 418 554 419 - static void *__alloc_from_pool(struct device *dev, size_t size, 420 - struct page **ret_page, const void *caller) 555 + static void *__alloc_from_pool(size_t size, struct page **ret_page) 421 556 { 422 - struct arm_vmregion *c; 557 + struct dma_pool *pool = &atomic_pool; 558 + unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; 559 + unsigned int pageno; 560 + unsigned long flags; 561 + void *ptr = NULL; 423 562 size_t align; 424 563 425 - if (!coherent_head.vm_start) { 426 - printk(KERN_ERR "%s: coherent pool not initialised!\n", 427 - __func__); 428 - dump_stack(); 564 + if (!pool->vaddr) { 565 + WARN(1, "coherent pool not initialised!\n"); 429 566 return NULL; 430 567 } 431 568 ··· 436 571 * size. This helps reduce fragmentation of the DMA space. 437 572 */ 438 573 align = PAGE_SIZE << get_order(size); 439 - c = arm_vmregion_alloc(&coherent_head, align, size, 0, caller); 440 - if (c) { 441 - void *ptr = (void *)c->vm_start; 442 - struct page *page = virt_to_page(ptr); 443 - *ret_page = page; 444 - return ptr; 574 + 575 + spin_lock_irqsave(&pool->lock, flags); 576 + pageno = bitmap_find_next_zero_area(pool->bitmap, pool->nr_pages, 577 + 0, count, (1 << align) - 1); 578 + if (pageno < pool->nr_pages) { 579 + bitmap_set(pool->bitmap, pageno, count); 580 + ptr = pool->vaddr + PAGE_SIZE * pageno; 581 + *ret_page = pool->page + pageno; 445 582 } 446 - return NULL; 583 + spin_unlock_irqrestore(&pool->lock, flags); 584 + 585 + return ptr; 447 586 } 448 587 449 - static int __free_from_pool(void *cpu_addr, size_t size) 588 + static int __free_from_pool(void *start, size_t size) 450 589 { 451 - unsigned long start = (unsigned long)cpu_addr; 452 - unsigned long end = start + size; 453 - struct arm_vmregion *c; 590 + struct dma_pool *pool = &atomic_pool; 591 + unsigned long pageno, count; 592 + unsigned long flags; 454 593 455 - if (start < coherent_head.vm_start || end > coherent_head.vm_end) 594 + if (start < pool->vaddr || start > pool->vaddr + pool->size) 456 595 return 0; 457 596 458 - c = arm_vmregion_find_remove(&coherent_head, (unsigned long)start); 459 - 460 - if ((c->vm_end - c->vm_start) != size) { 461 - printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n", 462 - __func__, c->vm_end - c->vm_start, size); 463 - dump_stack(); 464 - size = c->vm_end - c->vm_start; 597 + if (start + size > pool->vaddr + pool->size) { 598 + WARN(1, "freeing wrong coherent size from pool\n"); 599 + return 0; 465 600 } 466 601 467 - arm_vmregion_free(&coherent_head, c); 602 + pageno = (start - pool->vaddr) >> PAGE_SHIFT; 603 + count = size >> PAGE_SHIFT; 604 + 605 + spin_lock_irqsave(&pool->lock, flags); 606 + bitmap_clear(pool->bitmap, pageno, count); 607 + spin_unlock_irqrestore(&pool->lock, flags); 608 + 468 609 return 1; 469 610 } 470 611 ··· 515 644 516 645 #define __get_dma_pgprot(attrs, prot) __pgprot(0) 517 646 #define __alloc_remap_buffer(dev, size, gfp, prot, ret, c) NULL 518 - #define __alloc_from_pool(dev, size, ret_page, c) NULL 647 + #define __alloc_from_pool(size, ret_page) NULL 519 648 #define __alloc_from_contiguous(dev, size, prot, ret) NULL 520 649 #define __free_from_pool(cpu_addr, size) 0 521 650 #define __free_from_contiguous(dev, page, size) do { } while (0) ··· 573 702 574 703 if (arch_is_coherent() || nommu()) 575 704 addr = __alloc_simple_buffer(dev, size, gfp, &page); 705 + else if (gfp & GFP_ATOMIC) 706 + addr = __alloc_from_pool(size, &page); 576 707 else if (!IS_ENABLED(CONFIG_CMA)) 577 708 addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller); 578 - else if (gfp & GFP_ATOMIC) 579 - addr = __alloc_from_pool(dev, size, &page, caller); 580 709 else 581 710 addr = __alloc_from_contiguous(dev, size, prot, &page); 582 711 ··· 612 741 { 613 742 int ret = -ENXIO; 614 743 #ifdef CONFIG_MMU 744 + unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; 745 + unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; 615 746 unsigned long pfn = dma_to_pfn(dev, dma_addr); 747 + unsigned long off = vma->vm_pgoff; 748 + 616 749 vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot); 617 750 618 751 if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) 619 752 return ret; 620 753 621 - ret = remap_pfn_range(vma, vma->vm_start, 622 - pfn + vma->vm_pgoff, 623 - vma->vm_end - vma->vm_start, 624 - vma->vm_page_prot); 754 + if (off < nr_pages && nr_vma_pages <= (nr_pages - off)) { 755 + ret = remap_pfn_range(vma, vma->vm_start, 756 + pfn + off, 757 + vma->vm_end - vma->vm_start, 758 + vma->vm_page_prot); 759 + } 625 760 #endif /* CONFIG_MMU */ 626 761 627 762 return ret; ··· 660 783 WARN_ON(irqs_disabled()); 661 784 __free_from_contiguous(dev, page, size); 662 785 } 786 + } 787 + 788 + int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt, 789 + void *cpu_addr, dma_addr_t handle, size_t size, 790 + struct dma_attrs *attrs) 791 + { 792 + struct page *page = pfn_to_page(dma_to_pfn(dev, handle)); 793 + int ret; 794 + 795 + ret = sg_alloc_table(sgt, 1, GFP_KERNEL); 796 + if (unlikely(ret)) 797 + return ret; 798 + 799 + sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0); 800 + return 0; 663 801 } 664 802 665 803 static void dma_cache_maint_page(struct page *page, unsigned long offset, ··· 890 998 891 999 static int __init dma_debug_do_init(void) 892 1000 { 893 - #ifdef CONFIG_MMU 894 - arm_vmregion_create_proc("dma-mappings", &consistent_head); 895 - #endif 896 1001 dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); 897 1002 return 0; 898 1003 } ··· 977 1088 978 1089 return pages; 979 1090 error: 980 - while (--i) 1091 + while (i--) 981 1092 if (pages[i]) 982 1093 __free_pages(pages[i], 0); 983 1094 if (array_size <= PAGE_SIZE) ··· 1006 1117 * Create a CPU mapping for a specified pages 1007 1118 */ 1008 1119 static void * 1009 - __iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot) 1120 + __iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot, 1121 + const void *caller) 1010 1122 { 1011 - struct arm_vmregion *c; 1012 - size_t align; 1013 - size_t count = size >> PAGE_SHIFT; 1014 - int bit; 1123 + unsigned int i, nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; 1124 + struct vm_struct *area; 1125 + unsigned long p; 1015 1126 1016 - if (!consistent_pte[0]) { 1017 - pr_err("%s: not initialised\n", __func__); 1018 - dump_stack(); 1127 + area = get_vm_area_caller(size, VM_ARM_DMA_CONSISTENT | VM_USERMAP, 1128 + caller); 1129 + if (!area) 1019 1130 return NULL; 1131 + 1132 + area->pages = pages; 1133 + area->nr_pages = nr_pages; 1134 + p = (unsigned long)area->addr; 1135 + 1136 + for (i = 0; i < nr_pages; i++) { 1137 + phys_addr_t phys = __pfn_to_phys(page_to_pfn(pages[i])); 1138 + if (ioremap_page_range(p, p + PAGE_SIZE, phys, prot)) 1139 + goto err; 1140 + p += PAGE_SIZE; 1020 1141 } 1021 - 1022 - /* 1023 - * Align the virtual region allocation - maximum alignment is 1024 - * a section size, minimum is a page size. This helps reduce 1025 - * fragmentation of the DMA space, and also prevents allocations 1026 - * smaller than a section from crossing a section boundary. 1027 - */ 1028 - bit = fls(size - 1); 1029 - if (bit > SECTION_SHIFT) 1030 - bit = SECTION_SHIFT; 1031 - align = 1 << bit; 1032 - 1033 - /* 1034 - * Allocate a virtual address in the consistent mapping region. 1035 - */ 1036 - c = arm_vmregion_alloc(&consistent_head, align, size, 1037 - gfp & ~(__GFP_DMA | __GFP_HIGHMEM), NULL); 1038 - if (c) { 1039 - pte_t *pte; 1040 - int idx = CONSISTENT_PTE_INDEX(c->vm_start); 1041 - int i = 0; 1042 - u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1); 1043 - 1044 - pte = consistent_pte[idx] + off; 1045 - c->priv = pages; 1046 - 1047 - do { 1048 - BUG_ON(!pte_none(*pte)); 1049 - 1050 - set_pte_ext(pte, mk_pte(pages[i], prot), 0); 1051 - pte++; 1052 - off++; 1053 - i++; 1054 - if (off >= PTRS_PER_PTE) { 1055 - off = 0; 1056 - pte = consistent_pte[++idx]; 1057 - } 1058 - } while (i < count); 1059 - 1060 - dsb(); 1061 - 1062 - return (void *)c->vm_start; 1063 - } 1142 + return area->addr; 1143 + err: 1144 + unmap_kernel_range((unsigned long)area->addr, size); 1145 + vunmap(area->addr); 1064 1146 return NULL; 1065 1147 } 1066 1148 ··· 1090 1230 return 0; 1091 1231 } 1092 1232 1233 + static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs) 1234 + { 1235 + struct vm_struct *area; 1236 + 1237 + if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) 1238 + return cpu_addr; 1239 + 1240 + area = find_vm_area(cpu_addr); 1241 + if (area && (area->flags & VM_ARM_DMA_CONSISTENT)) 1242 + return area->pages; 1243 + return NULL; 1244 + } 1245 + 1093 1246 static void *arm_iommu_alloc_attrs(struct device *dev, size_t size, 1094 1247 dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs) 1095 1248 { ··· 1121 1248 if (*handle == DMA_ERROR_CODE) 1122 1249 goto err_buffer; 1123 1250 1124 - addr = __iommu_alloc_remap(pages, size, gfp, prot); 1251 + if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) 1252 + return pages; 1253 + 1254 + addr = __iommu_alloc_remap(pages, size, gfp, prot, 1255 + __builtin_return_address(0)); 1125 1256 if (!addr) 1126 1257 goto err_mapping; 1127 1258 ··· 1142 1265 void *cpu_addr, dma_addr_t dma_addr, size_t size, 1143 1266 struct dma_attrs *attrs) 1144 1267 { 1145 - struct arm_vmregion *c; 1268 + unsigned long uaddr = vma->vm_start; 1269 + unsigned long usize = vma->vm_end - vma->vm_start; 1270 + struct page **pages = __iommu_get_pages(cpu_addr, attrs); 1146 1271 1147 1272 vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot); 1148 - c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr); 1149 1273 1150 - if (c) { 1151 - struct page **pages = c->priv; 1274 + if (!pages) 1275 + return -ENXIO; 1152 1276 1153 - unsigned long uaddr = vma->vm_start; 1154 - unsigned long usize = vma->vm_end - vma->vm_start; 1155 - int i = 0; 1277 + do { 1278 + int ret = vm_insert_page(vma, uaddr, *pages++); 1279 + if (ret) { 1280 + pr_err("Remapping memory failed: %d\n", ret); 1281 + return ret; 1282 + } 1283 + uaddr += PAGE_SIZE; 1284 + usize -= PAGE_SIZE; 1285 + } while (usize > 0); 1156 1286 1157 - do { 1158 - int ret; 1159 - 1160 - ret = vm_insert_page(vma, uaddr, pages[i++]); 1161 - if (ret) { 1162 - pr_err("Remapping memory, error: %d\n", ret); 1163 - return ret; 1164 - } 1165 - 1166 - uaddr += PAGE_SIZE; 1167 - usize -= PAGE_SIZE; 1168 - } while (usize > 0); 1169 - } 1170 1287 return 0; 1171 1288 } 1172 1289 ··· 1171 1300 void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr, 1172 1301 dma_addr_t handle, struct dma_attrs *attrs) 1173 1302 { 1174 - struct arm_vmregion *c; 1303 + struct page **pages = __iommu_get_pages(cpu_addr, attrs); 1175 1304 size = PAGE_ALIGN(size); 1176 1305 1177 - c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr); 1178 - if (c) { 1179 - struct page **pages = c->priv; 1180 - __dma_free_remap(cpu_addr, size); 1181 - __iommu_remove_mapping(dev, handle, size); 1182 - __iommu_free_buffer(dev, pages, size); 1306 + if (!pages) { 1307 + WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr); 1308 + return; 1183 1309 } 1310 + 1311 + if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) { 1312 + unmap_kernel_range((unsigned long)cpu_addr, size); 1313 + vunmap(cpu_addr); 1314 + } 1315 + 1316 + __iommu_remove_mapping(dev, handle, size); 1317 + __iommu_free_buffer(dev, pages, size); 1318 + } 1319 + 1320 + static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt, 1321 + void *cpu_addr, dma_addr_t dma_addr, 1322 + size_t size, struct dma_attrs *attrs) 1323 + { 1324 + unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; 1325 + struct page **pages = __iommu_get_pages(cpu_addr, attrs); 1326 + 1327 + if (!pages) 1328 + return -ENXIO; 1329 + 1330 + return sg_alloc_table_from_pages(sgt, pages, count, 0, size, 1331 + GFP_KERNEL); 1184 1332 } 1185 1333 1186 1334 /* ··· 1207 1317 */ 1208 1318 static int __map_sg_chunk(struct device *dev, struct scatterlist *sg, 1209 1319 size_t size, dma_addr_t *handle, 1210 - enum dma_data_direction dir) 1320 + enum dma_data_direction dir, struct dma_attrs *attrs) 1211 1321 { 1212 1322 struct dma_iommu_mapping *mapping = dev->archdata.mapping; 1213 1323 dma_addr_t iova, iova_base; ··· 1226 1336 phys_addr_t phys = page_to_phys(sg_page(s)); 1227 1337 unsigned int len = PAGE_ALIGN(s->offset + s->length); 1228 1338 1229 - if (!arch_is_coherent()) 1339 + if (!arch_is_coherent() && 1340 + !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) 1230 1341 __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir); 1231 1342 1232 1343 ret = iommu_map(mapping->domain, iova, phys, len, 0); ··· 1274 1383 1275 1384 if (s->offset || (size & ~PAGE_MASK) || size + s->length > max) { 1276 1385 if (__map_sg_chunk(dev, start, size, &dma->dma_address, 1277 - dir) < 0) 1386 + dir, attrs) < 0) 1278 1387 goto bad_mapping; 1279 1388 1280 1389 dma->dma_address += offset; ··· 1287 1396 } 1288 1397 size += s->length; 1289 1398 } 1290 - if (__map_sg_chunk(dev, start, size, &dma->dma_address, dir) < 0) 1399 + if (__map_sg_chunk(dev, start, size, &dma->dma_address, dir, attrs) < 0) 1291 1400 goto bad_mapping; 1292 1401 1293 1402 dma->dma_address += offset; ··· 1321 1430 if (sg_dma_len(s)) 1322 1431 __iommu_remove_mapping(dev, sg_dma_address(s), 1323 1432 sg_dma_len(s)); 1324 - if (!arch_is_coherent()) 1433 + if (!arch_is_coherent() && 1434 + !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) 1325 1435 __dma_page_dev_to_cpu(sg_page(s), s->offset, 1326 1436 s->length, dir); 1327 1437 } ··· 1384 1492 dma_addr_t dma_addr; 1385 1493 int ret, len = PAGE_ALIGN(size + offset); 1386 1494 1387 - if (!arch_is_coherent()) 1495 + if (!arch_is_coherent() && !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) 1388 1496 __dma_page_cpu_to_dev(page, offset, size, dir); 1389 1497 1390 1498 dma_addr = __alloc_iova(mapping, len); ··· 1423 1531 if (!iova) 1424 1532 return; 1425 1533 1426 - if (!arch_is_coherent()) 1534 + if (!arch_is_coherent() && !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) 1427 1535 __dma_page_dev_to_cpu(page, offset, size, dir); 1428 1536 1429 1537 iommu_unmap(mapping->domain, iova, len); ··· 1463 1571 .alloc = arm_iommu_alloc_attrs, 1464 1572 .free = arm_iommu_free_attrs, 1465 1573 .mmap = arm_iommu_mmap_attrs, 1574 + .get_sgtable = arm_iommu_get_sgtable, 1466 1575 1467 1576 .map_page = arm_iommu_map_page, 1468 1577 .unmap_page = arm_iommu_unmap_page,
+3
arch/arm/mm/mm.h
··· 59 59 #define VM_ARM_MTYPE(mt) ((mt) << 20) 60 60 #define VM_ARM_MTYPE_MASK (0x1f << 20) 61 61 62 + /* consistent regions used by dma_alloc_attrs() */ 63 + #define VM_ARM_DMA_CONSISTENT 0x20000000 64 + 62 65 #endif 63 66 64 67 #ifdef CONFIG_ZONE_DMA
+4 -4
arch/powerpc/include/asm/dma-mapping.h
··· 27 27 extern void dma_direct_free_coherent(struct device *dev, size_t size, 28 28 void *vaddr, dma_addr_t dma_handle, 29 29 struct dma_attrs *attrs); 30 - 30 + extern int dma_direct_mmap_coherent(struct device *dev, 31 + struct vm_area_struct *vma, 32 + void *cpu_addr, dma_addr_t handle, 33 + size_t size, struct dma_attrs *attrs); 31 34 32 35 #ifdef CONFIG_NOT_COHERENT_CACHE 33 36 /* ··· 210 207 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) 211 208 #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) 212 209 213 - extern int dma_mmap_coherent(struct device *, struct vm_area_struct *, 214 - void *, dma_addr_t, size_t); 215 210 #define ARCH_HAS_DMA_MMAP_COHERENT 216 - 217 211 218 212 static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, 219 213 enum dma_data_direction direction)
+1
arch/powerpc/kernel/dma-iommu.c
··· 109 109 struct dma_map_ops dma_iommu_ops = { 110 110 .alloc = dma_iommu_alloc_coherent, 111 111 .free = dma_iommu_free_coherent, 112 + .mmap = dma_direct_mmap_coherent, 112 113 .map_sg = dma_iommu_map_sg, 113 114 .unmap_sg = dma_iommu_unmap_sg, 114 115 .dma_supported = dma_iommu_dma_supported,
+1
arch/powerpc/kernel/dma-swiotlb.c
··· 49 49 struct dma_map_ops swiotlb_dma_ops = { 50 50 .alloc = dma_direct_alloc_coherent, 51 51 .free = dma_direct_free_coherent, 52 + .mmap = dma_direct_mmap_coherent, 52 53 .map_sg = swiotlb_map_sg_attrs, 53 54 .unmap_sg = swiotlb_unmap_sg_attrs, 54 55 .dma_supported = swiotlb_dma_supported,
+19 -17
arch/powerpc/kernel/dma.c
··· 67 67 #endif 68 68 } 69 69 70 + int dma_direct_mmap_coherent(struct device *dev, struct vm_area_struct *vma, 71 + void *cpu_addr, dma_addr_t handle, size_t size, 72 + struct dma_attrs *attrs) 73 + { 74 + unsigned long pfn; 75 + 76 + #ifdef CONFIG_NOT_COHERENT_CACHE 77 + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 78 + pfn = __dma_get_coherent_pfn((unsigned long)cpu_addr); 79 + #else 80 + pfn = page_to_pfn(virt_to_page(cpu_addr)); 81 + #endif 82 + return remap_pfn_range(vma, vma->vm_start, 83 + pfn + vma->vm_pgoff, 84 + vma->vm_end - vma->vm_start, 85 + vma->vm_page_prot); 86 + } 87 + 70 88 static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, 71 89 int nents, enum dma_data_direction direction, 72 90 struct dma_attrs *attrs) ··· 174 156 struct dma_map_ops dma_direct_ops = { 175 157 .alloc = dma_direct_alloc_coherent, 176 158 .free = dma_direct_free_coherent, 159 + .mmap = dma_direct_mmap_coherent, 177 160 .map_sg = dma_direct_map_sg, 178 161 .unmap_sg = dma_direct_unmap_sg, 179 162 .dma_supported = dma_direct_dma_supported, ··· 238 219 } 239 220 fs_initcall(dma_init); 240 221 241 - int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma, 242 - void *cpu_addr, dma_addr_t handle, size_t size) 243 - { 244 - unsigned long pfn; 245 - 246 - #ifdef CONFIG_NOT_COHERENT_CACHE 247 - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 248 - pfn = __dma_get_coherent_pfn((unsigned long)cpu_addr); 249 - #else 250 - pfn = page_to_pfn(virt_to_page(cpu_addr)); 251 - #endif 252 - return remap_pfn_range(vma, vma->vm_start, 253 - pfn + vma->vm_pgoff, 254 - vma->vm_end - vma->vm_start, 255 - vma->vm_page_prot); 256 - } 257 - EXPORT_SYMBOL_GPL(dma_mmap_coherent);
+1
arch/powerpc/kernel/vio.c
··· 611 611 struct dma_map_ops vio_dma_mapping_ops = { 612 612 .alloc = vio_dma_iommu_alloc_coherent, 613 613 .free = vio_dma_iommu_free_coherent, 614 + .mmap = dma_direct_mmap_coherent, 614 615 .map_sg = vio_dma_iommu_map_sg, 615 616 .unmap_sg = vio_dma_iommu_unmap_sg, 616 617 .map_page = vio_dma_iommu_map_page,
+49
drivers/base/dma-mapping.c
··· 10 10 #include <linux/dma-mapping.h> 11 11 #include <linux/export.h> 12 12 #include <linux/gfp.h> 13 + #include <asm-generic/dma-coherent.h> 13 14 14 15 /* 15 16 * Managed DMA API ··· 218 217 } 219 218 EXPORT_SYMBOL(dmam_release_declared_memory); 220 219 220 + /* 221 + * Create scatter-list for the already allocated DMA buffer. 222 + */ 223 + int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, 224 + void *cpu_addr, dma_addr_t handle, size_t size) 225 + { 226 + struct page *page = virt_to_page(cpu_addr); 227 + int ret; 228 + 229 + ret = sg_alloc_table(sgt, 1, GFP_KERNEL); 230 + if (unlikely(ret)) 231 + return ret; 232 + 233 + sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0); 234 + return 0; 235 + } 236 + EXPORT_SYMBOL(dma_common_get_sgtable); 237 + 221 238 #endif 239 + 240 + /* 241 + * Create userspace mapping for the DMA-coherent memory. 242 + */ 243 + int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, 244 + void *cpu_addr, dma_addr_t dma_addr, size_t size) 245 + { 246 + int ret = -ENXIO; 247 + #ifdef CONFIG_MMU 248 + unsigned long user_count = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; 249 + unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; 250 + unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr)); 251 + unsigned long off = vma->vm_pgoff; 252 + 253 + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 254 + 255 + if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) 256 + return ret; 257 + 258 + if (off < count && user_count <= (count - off)) { 259 + ret = remap_pfn_range(vma, vma->vm_start, 260 + pfn + off, 261 + user_count << PAGE_SHIFT, 262 + vma->vm_page_prot); 263 + } 264 + #endif /* CONFIG_MMU */ 265 + 266 + return ret; 267 + } 268 + EXPORT_SYMBOL(dma_common_mmap);
+1
include/asm-generic/dma-coherent.h
··· 29 29 #else 30 30 #define dma_alloc_from_coherent(dev, size, handle, ret) (0) 31 31 #define dma_release_from_coherent(dev, order, vaddr) (0) 32 + #define dma_mmap_from_coherent(dev, vma, vaddr, order, ret) (0) 32 33 #endif 33 34 34 35 #endif
+55
include/asm-generic/dma-mapping-common.h
··· 176 176 #define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL) 177 177 #define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL) 178 178 179 + extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, 180 + void *cpu_addr, dma_addr_t dma_addr, size_t size); 181 + 182 + /** 183 + * dma_mmap_attrs - map a coherent DMA allocation into user space 184 + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices 185 + * @vma: vm_area_struct describing requested user mapping 186 + * @cpu_addr: kernel CPU-view address returned from dma_alloc_attrs 187 + * @handle: device-view address returned from dma_alloc_attrs 188 + * @size: size of memory originally requested in dma_alloc_attrs 189 + * @attrs: attributes of mapping properties requested in dma_alloc_attrs 190 + * 191 + * Map a coherent DMA buffer previously allocated by dma_alloc_attrs 192 + * into user space. The coherent DMA buffer must not be freed by the 193 + * driver until the user space mapping has been released. 194 + */ 195 + static inline int 196 + dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr, 197 + dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs) 198 + { 199 + struct dma_map_ops *ops = get_dma_ops(dev); 200 + BUG_ON(!ops); 201 + if (ops->mmap) 202 + return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs); 203 + return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size); 204 + } 205 + 206 + #define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL) 207 + 208 + static inline int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma, 209 + void *cpu_addr, dma_addr_t dma_addr, size_t size) 210 + { 211 + DEFINE_DMA_ATTRS(attrs); 212 + dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs); 213 + return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs); 214 + } 215 + 216 + int 217 + dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, 218 + void *cpu_addr, dma_addr_t dma_addr, size_t size); 219 + 220 + static inline int 221 + dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr, 222 + dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs) 223 + { 224 + struct dma_map_ops *ops = get_dma_ops(dev); 225 + BUG_ON(!ops); 226 + if (ops->get_sgtable) 227 + return ops->get_sgtable(dev, sgt, cpu_addr, dma_addr, size, 228 + attrs); 229 + return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size); 230 + } 231 + 232 + #define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, NULL) 233 + 179 234 #endif
+2
include/linux/dma-attrs.h
··· 15 15 DMA_ATTR_WEAK_ORDERING, 16 16 DMA_ATTR_WRITE_COMBINE, 17 17 DMA_ATTR_NON_CONSISTENT, 18 + DMA_ATTR_NO_KERNEL_MAPPING, 19 + DMA_ATTR_SKIP_CPU_SYNC, 18 20 DMA_ATTR_MAX, 19 21 }; 20 22
+3
include/linux/dma-mapping.h
··· 18 18 int (*mmap)(struct device *, struct vm_area_struct *, 19 19 void *, dma_addr_t, size_t, struct dma_attrs *attrs); 20 20 21 + int (*get_sgtable)(struct device *dev, struct sg_table *sgt, void *, 22 + dma_addr_t, size_t, struct dma_attrs *attrs); 23 + 21 24 dma_addr_t (*map_page)(struct device *dev, struct page *page, 22 25 unsigned long offset, size_t size, 23 26 enum dma_data_direction dir,
+4
include/linux/scatterlist.h
··· 214 214 int __sg_alloc_table(struct sg_table *, unsigned int, unsigned int, gfp_t, 215 215 sg_alloc_fn *); 216 216 int sg_alloc_table(struct sg_table *, unsigned int, gfp_t); 217 + int sg_alloc_table_from_pages(struct sg_table *sgt, 218 + struct page **pages, unsigned int n_pages, 219 + unsigned long offset, unsigned long size, 220 + gfp_t gfp_mask); 217 221 218 222 size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents, 219 223 void *buf, size_t buflen);
+5 -4
include/linux/vmalloc.h
··· 32 32 struct page **pages; 33 33 unsigned int nr_pages; 34 34 phys_addr_t phys_addr; 35 - void *caller; 35 + const void *caller; 36 36 }; 37 37 38 38 /* ··· 62 62 extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot); 63 63 extern void *__vmalloc_node_range(unsigned long size, unsigned long align, 64 64 unsigned long start, unsigned long end, gfp_t gfp_mask, 65 - pgprot_t prot, int node, void *caller); 65 + pgprot_t prot, int node, const void *caller); 66 66 extern void vfree(const void *addr); 67 67 68 68 extern void *vmap(struct page **pages, unsigned int count, ··· 85 85 86 86 extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags); 87 87 extern struct vm_struct *get_vm_area_caller(unsigned long size, 88 - unsigned long flags, void *caller); 88 + unsigned long flags, const void *caller); 89 89 extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, 90 90 unsigned long start, unsigned long end); 91 91 extern struct vm_struct *__get_vm_area_caller(unsigned long size, 92 92 unsigned long flags, 93 93 unsigned long start, unsigned long end, 94 - void *caller); 94 + const void *caller); 95 95 extern struct vm_struct *remove_vm_area(const void *addr); 96 + extern struct vm_struct *find_vm_area(const void *addr); 96 97 97 98 extern int map_vm_area(struct vm_struct *area, pgprot_t prot, 98 99 struct page ***pages);
+64
lib/scatterlist.c
··· 319 319 EXPORT_SYMBOL(sg_alloc_table); 320 320 321 321 /** 322 + * sg_alloc_table_from_pages - Allocate and initialize an sg table from 323 + * an array of pages 324 + * @sgt: The sg table header to use 325 + * @pages: Pointer to an array of page pointers 326 + * @n_pages: Number of pages in the pages array 327 + * @offset: Offset from start of the first page to the start of a buffer 328 + * @size: Number of valid bytes in the buffer (after offset) 329 + * @gfp_mask: GFP allocation mask 330 + * 331 + * Description: 332 + * Allocate and initialize an sg table from a list of pages. Contiguous 333 + * ranges of the pages are squashed into a single scatterlist node. A user 334 + * may provide an offset at a start and a size of valid data in a buffer 335 + * specified by the page array. The returned sg table is released by 336 + * sg_free_table. 337 + * 338 + * Returns: 339 + * 0 on success, negative error on failure 340 + */ 341 + int sg_alloc_table_from_pages(struct sg_table *sgt, 342 + struct page **pages, unsigned int n_pages, 343 + unsigned long offset, unsigned long size, 344 + gfp_t gfp_mask) 345 + { 346 + unsigned int chunks; 347 + unsigned int i; 348 + unsigned int cur_page; 349 + int ret; 350 + struct scatterlist *s; 351 + 352 + /* compute number of contiguous chunks */ 353 + chunks = 1; 354 + for (i = 1; i < n_pages; ++i) 355 + if (page_to_pfn(pages[i]) != page_to_pfn(pages[i - 1]) + 1) 356 + ++chunks; 357 + 358 + ret = sg_alloc_table(sgt, chunks, gfp_mask); 359 + if (unlikely(ret)) 360 + return ret; 361 + 362 + /* merging chunks and putting them into the scatterlist */ 363 + cur_page = 0; 364 + for_each_sg(sgt->sgl, s, sgt->orig_nents, i) { 365 + unsigned long chunk_size; 366 + unsigned int j; 367 + 368 + /* look for the end of the current chunk */ 369 + for (j = cur_page + 1; j < n_pages; ++j) 370 + if (page_to_pfn(pages[j]) != 371 + page_to_pfn(pages[j - 1]) + 1) 372 + break; 373 + 374 + chunk_size = ((j - cur_page) << PAGE_SHIFT) - offset; 375 + sg_set_page(s, pages[cur_page], min(size, chunk_size), offset); 376 + size -= chunk_size; 377 + offset = 0; 378 + cur_page = j; 379 + } 380 + 381 + return 0; 382 + } 383 + EXPORT_SYMBOL(sg_alloc_table_from_pages); 384 + 385 + /** 322 386 * sg_miter_start - start mapping iteration over a sg list 323 387 * @miter: sg mapping iter to be started 324 388 * @sgl: sg list to iterate over
+18 -10
mm/vmalloc.c
··· 1280 1280 struct vm_struct *vmlist; 1281 1281 1282 1282 static void setup_vmalloc_vm(struct vm_struct *vm, struct vmap_area *va, 1283 - unsigned long flags, void *caller) 1283 + unsigned long flags, const void *caller) 1284 1284 { 1285 1285 vm->flags = flags; 1286 1286 vm->addr = (void *)va->va_start; ··· 1306 1306 } 1307 1307 1308 1308 static void insert_vmalloc_vm(struct vm_struct *vm, struct vmap_area *va, 1309 - unsigned long flags, void *caller) 1309 + unsigned long flags, const void *caller) 1310 1310 { 1311 1311 setup_vmalloc_vm(vm, va, flags, caller); 1312 1312 insert_vmalloc_vmlist(vm); ··· 1314 1314 1315 1315 static struct vm_struct *__get_vm_area_node(unsigned long size, 1316 1316 unsigned long align, unsigned long flags, unsigned long start, 1317 - unsigned long end, int node, gfp_t gfp_mask, void *caller) 1317 + unsigned long end, int node, gfp_t gfp_mask, const void *caller) 1318 1318 { 1319 1319 struct vmap_area *va; 1320 1320 struct vm_struct *area; ··· 1375 1375 1376 1376 struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags, 1377 1377 unsigned long start, unsigned long end, 1378 - void *caller) 1378 + const void *caller) 1379 1379 { 1380 1380 return __get_vm_area_node(size, 1, flags, start, end, -1, GFP_KERNEL, 1381 1381 caller); ··· 1397 1397 } 1398 1398 1399 1399 struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags, 1400 - void *caller) 1400 + const void *caller) 1401 1401 { 1402 1402 return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END, 1403 1403 -1, GFP_KERNEL, caller); 1404 1404 } 1405 1405 1406 - static struct vm_struct *find_vm_area(const void *addr) 1406 + /** 1407 + * find_vm_area - find a continuous kernel virtual area 1408 + * @addr: base address 1409 + * 1410 + * Search for the kernel VM area starting at @addr, and return it. 1411 + * It is up to the caller to do all required locking to keep the returned 1412 + * pointer valid. 1413 + */ 1414 + struct vm_struct *find_vm_area(const void *addr) 1407 1415 { 1408 1416 struct vmap_area *va; 1409 1417 ··· 1576 1568 1577 1569 static void *__vmalloc_node(unsigned long size, unsigned long align, 1578 1570 gfp_t gfp_mask, pgprot_t prot, 1579 - int node, void *caller); 1571 + int node, const void *caller); 1580 1572 static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, 1581 - pgprot_t prot, int node, void *caller) 1573 + pgprot_t prot, int node, const void *caller) 1582 1574 { 1583 1575 const int order = 0; 1584 1576 struct page **pages; ··· 1651 1643 */ 1652 1644 void *__vmalloc_node_range(unsigned long size, unsigned long align, 1653 1645 unsigned long start, unsigned long end, gfp_t gfp_mask, 1654 - pgprot_t prot, int node, void *caller) 1646 + pgprot_t prot, int node, const void *caller) 1655 1647 { 1656 1648 struct vm_struct *area; 1657 1649 void *addr; ··· 1707 1699 */ 1708 1700 static void *__vmalloc_node(unsigned long size, unsigned long align, 1709 1701 gfp_t gfp_mask, pgprot_t prot, 1710 - int node, void *caller) 1702 + int node, const void *caller) 1711 1703 { 1712 1704 return __vmalloc_node_range(size, align, VMALLOC_START, VMALLOC_END, 1713 1705 gfp_mask, prot, node, caller);