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.

avoid endless loops in lib/swiotlb.c

Commit 681cc5cd3efbeafca6386114070e0bfb5012e249 ("iommu sg merging:
swiotlb: respect the segment boundary limits") introduced two
possibilities for entering an endless loop in lib/swiotlb.c:

- if max_slots is zero (possible if mask is ~0UL)
- if the number of slots requested fits into a swiotlb segment, but is
too large for the part of a segment which remains after considering
offset_slots

This fixes them

Signed-off-by: Jan Beulich <jbeulich@novell.com>
Cc: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Jan Beulich and committed by
Linus Torvalds
b15a3891 96e31022

+16 -14
+16 -14
lib/swiotlb.c
··· 310 310 start_dma_addr = virt_to_bus(io_tlb_start) & mask; 311 311 312 312 offset_slots = ALIGN(start_dma_addr, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; 313 - max_slots = ALIGN(mask + 1, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; 313 + max_slots = mask + 1 314 + ? ALIGN(mask + 1, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT 315 + : 1UL << (BITS_PER_LONG - IO_TLB_SHIFT); 314 316 315 317 /* 316 318 * For mappings greater than a page, we limit the stride (and ··· 335 333 index = ALIGN(io_tlb_index, stride); 336 334 if (index >= io_tlb_nslabs) 337 335 index = 0; 338 - 339 - while (is_span_boundary(index, nslots, offset_slots, 340 - max_slots)) { 341 - index += stride; 342 - if (index >= io_tlb_nslabs) 343 - index = 0; 344 - } 345 336 wrap = index; 346 337 347 338 do { 339 + while (is_span_boundary(index, nslots, offset_slots, 340 + max_slots)) { 341 + index += stride; 342 + if (index >= io_tlb_nslabs) 343 + index = 0; 344 + if (index == wrap) 345 + goto not_found; 346 + } 347 + 348 348 /* 349 349 * If we find a slot that indicates we have 'nslots' 350 350 * number of contiguous buffers, we allocate the ··· 371 367 372 368 goto found; 373 369 } 374 - do { 375 - index += stride; 376 - if (index >= io_tlb_nslabs) 377 - index = 0; 378 - } while (is_span_boundary(index, nslots, offset_slots, 379 - max_slots)); 370 + index += stride; 371 + if (index >= io_tlb_nslabs) 372 + index = 0; 380 373 } while (index != wrap); 381 374 375 + not_found: 382 376 spin_unlock_irqrestore(&io_tlb_lock, flags); 383 377 return NULL; 384 378 }