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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'stable/for-linus-3.16-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb

Pull swiotlb bugfix from Konrad Rzeszutek Wilk:
"One bug-fix that had been in tree for quite some time. We had assumed
that the physical address zero was invalid and would fail it. But
that is not true and on some architectures it is not reserved and
valid. This fixes it"

* tag 'stable/for-linus-3.16-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb:
swiotlb: don't assume PA 0 is invalid

+18 -10
+18 -10
lib/swiotlb.c
··· 86 86 * We need to save away the original address corresponding to a mapped entry 87 87 * for the sync operations. 88 88 */ 89 + #define INVALID_PHYS_ADDR (~(phys_addr_t)0) 89 90 static phys_addr_t *io_tlb_orig_addr; 90 91 91 92 /* ··· 189 188 io_tlb_list = memblock_virt_alloc( 190 189 PAGE_ALIGN(io_tlb_nslabs * sizeof(int)), 191 190 PAGE_SIZE); 192 - for (i = 0; i < io_tlb_nslabs; i++) 193 - io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); 194 - io_tlb_index = 0; 195 191 io_tlb_orig_addr = memblock_virt_alloc( 196 192 PAGE_ALIGN(io_tlb_nslabs * sizeof(phys_addr_t)), 197 193 PAGE_SIZE); 194 + for (i = 0; i < io_tlb_nslabs; i++) { 195 + io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); 196 + io_tlb_orig_addr[i] = INVALID_PHYS_ADDR; 197 + } 198 + io_tlb_index = 0; 198 199 199 200 if (verbose) 200 201 swiotlb_print_info(); ··· 316 313 if (!io_tlb_list) 317 314 goto cleanup3; 318 315 319 - for (i = 0; i < io_tlb_nslabs; i++) 320 - io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); 321 - io_tlb_index = 0; 322 - 323 316 io_tlb_orig_addr = (phys_addr_t *) 324 317 __get_free_pages(GFP_KERNEL, 325 318 get_order(io_tlb_nslabs * ··· 323 324 if (!io_tlb_orig_addr) 324 325 goto cleanup4; 325 326 326 - memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(phys_addr_t)); 327 + for (i = 0; i < io_tlb_nslabs; i++) { 328 + io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); 329 + io_tlb_orig_addr[i] = INVALID_PHYS_ADDR; 330 + } 331 + io_tlb_index = 0; 327 332 328 333 swiotlb_print_info(); 329 334 ··· 559 556 /* 560 557 * First, sync the memory before unmapping the entry 561 558 */ 562 - if (orig_addr && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) 559 + if (orig_addr != INVALID_PHYS_ADDR && 560 + ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) 563 561 swiotlb_bounce(orig_addr, tlb_addr, size, DMA_FROM_DEVICE); 564 562 565 563 /* ··· 577 573 * Step 1: return the slots to the free list, merging the 578 574 * slots with superceeding slots 579 575 */ 580 - for (i = index + nslots - 1; i >= index; i--) 576 + for (i = index + nslots - 1; i >= index; i--) { 581 577 io_tlb_list[i] = ++count; 578 + io_tlb_orig_addr[i] = INVALID_PHYS_ADDR; 579 + } 582 580 /* 583 581 * Step 2: merge the returned slots with the preceding slots, 584 582 * if available (non zero) ··· 599 593 int index = (tlb_addr - io_tlb_start) >> IO_TLB_SHIFT; 600 594 phys_addr_t orig_addr = io_tlb_orig_addr[index]; 601 595 596 + if (orig_addr == INVALID_PHYS_ADDR) 597 + return; 602 598 orig_addr += (unsigned long)tlb_addr & ((1 << IO_TLB_SHIFT) - 1); 603 599 604 600 switch (target) {