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 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fixes from Will Deacon:
"The main one is a horrible macro fix for our TLB flushing code which
resulted in over-invalidation on the MMU notifier path.

Summary:

- Fix population of the vmemmap for regions of memory that are
smaller than a section (128 MiB)

- Fix range-based TLB over-invalidation when invoked via a MMU
notifier"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
Fix mmu notifiers for range-based invalidates
arm64: mm: Populate vmemmap at the page level if not section aligned

+16 -11
+12 -10
arch/arm64/include/asm/tlbflush.h
··· 396 396 #define __flush_tlb_range_op(op, start, pages, stride, \ 397 397 asid, tlb_level, tlbi_user, lpa2) \ 398 398 do { \ 399 + typeof(start) __flush_start = start; \ 400 + typeof(pages) __flush_pages = pages; \ 399 401 int num = 0; \ 400 402 int scale = 3; \ 401 403 int shift = lpa2 ? 16 : PAGE_SHIFT; \ 402 404 unsigned long addr; \ 403 405 \ 404 - while (pages > 0) { \ 406 + while (__flush_pages > 0) { \ 405 407 if (!system_supports_tlb_range() || \ 406 - pages == 1 || \ 407 - (lpa2 && start != ALIGN(start, SZ_64K))) { \ 408 - addr = __TLBI_VADDR(start, asid); \ 408 + __flush_pages == 1 || \ 409 + (lpa2 && __flush_start != ALIGN(__flush_start, SZ_64K))) { \ 410 + addr = __TLBI_VADDR(__flush_start, asid); \ 409 411 __tlbi_level(op, addr, tlb_level); \ 410 412 if (tlbi_user) \ 411 413 __tlbi_user_level(op, addr, tlb_level); \ 412 - start += stride; \ 413 - pages -= stride >> PAGE_SHIFT; \ 414 + __flush_start += stride; \ 415 + __flush_pages -= stride >> PAGE_SHIFT; \ 414 416 continue; \ 415 417 } \ 416 418 \ 417 - num = __TLBI_RANGE_NUM(pages, scale); \ 419 + num = __TLBI_RANGE_NUM(__flush_pages, scale); \ 418 420 if (num >= 0) { \ 419 - addr = __TLBI_VADDR_RANGE(start >> shift, asid, \ 421 + addr = __TLBI_VADDR_RANGE(__flush_start >> shift, asid, \ 420 422 scale, num, tlb_level); \ 421 423 __tlbi(r##op, addr); \ 422 424 if (tlbi_user) \ 423 425 __tlbi_user(r##op, addr); \ 424 - start += __TLBI_RANGE_PAGES(num, scale) << PAGE_SHIFT; \ 425 - pages -= __TLBI_RANGE_PAGES(num, scale); \ 426 + __flush_start += __TLBI_RANGE_PAGES(num, scale) << PAGE_SHIFT; \ 427 + __flush_pages -= __TLBI_RANGE_PAGES(num, scale);\ 426 428 } \ 427 429 scale--; \ 428 430 } \
+4 -1
arch/arm64/mm/mmu.c
··· 1177 1177 struct vmem_altmap *altmap) 1178 1178 { 1179 1179 WARN_ON((start < VMEMMAP_START) || (end > VMEMMAP_END)); 1180 + /* [start, end] should be within one section */ 1181 + WARN_ON_ONCE(end - start > PAGES_PER_SECTION * sizeof(struct page)); 1180 1182 1181 - if (!IS_ENABLED(CONFIG_ARM64_4K_PAGES)) 1183 + if (!IS_ENABLED(CONFIG_ARM64_4K_PAGES) || 1184 + (end - start < PAGES_PER_SECTION * sizeof(struct page))) 1182 1185 return vmemmap_populate_basepages(start, end, node, altmap); 1183 1186 else 1184 1187 return vmemmap_populate_hugepages(start, end, node, altmap);