mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/
synced 2026-11-10 20:48:12 +00:00
modify_prot_start_ptes() performs the break-before-make TLB invalidation
required by erratum 2645198 with __flush_tlb_range(), whose third
argument is the end address of the range. It passes nr * PAGE_SIZE
instead of addr + nr * PAGE_SIZE, so __do_flush_tlb_range() computes the
page count as (nr * PAGE_SIZE - addr) >> PAGE_SHIFT.
For addr > nr * PAGE_SIZE that subtraction underflows, the page count
exceeds the batching limit and the flush degenerates to flush_tlb_mm(),
so a single-page mprotect broadcasts an ASID-wide invalidation and a
full-range mmu notifier call.
For addr <= nr * PAGE_SIZE only [addr, nr * PAGE_SIZE) is invalidated,
and when the cleared batch starts below nr * PAGE_SIZE the tail is left
in the TLB. The workaround then no longer covers the whole batch, and
for addr == nr * PAGE_SIZE the flush is empty.
On affected Cortex-A715 CPUs, this can corrupt ESR_ELx and FAR_ELx on the
next instruction abort caused by a permission fault.
Pass addr + nr * PAGE_SIZE as the end address.
Fixes:
|
History
|
|
|---|---|---|
| .. | ||
| cache.S | ||
| context.c | ||
| contpte.c | ||
| copypage.c | ||
| dma-mapping.c | ||
| extable.c | ||
| fault.c | ||
| fixmap.c | ||
| flush.c | ||
| gcs.c | ||
| hugetlbpage.c | ||
| init.c | ||
| ioremap.c | ||
| kasan_init.c | ||
| Makefile | ||
| mem_encrypt.c | ||
| mmap.c | ||
| mmu.c | ||
| mteswap.c | ||
| pageattr.c | ||
| pgd.c | ||
| physaddr.c | ||
| proc.S | ||
| ptdump.c | ||
| ptdump_debugfs.c | ||
| trans_pgd-asm.S | ||
| trans_pgd.c | ||