Thread (6 messages) 6 messages, 3 authors, 2021-06-24

Re: [PATCH v1] arm64: tlb: fix the TTL value of tlb_get_level

From: Will Deacon <will@kernel.org>
Date: 2021-06-23 11:04:20
Also in: linux-arm-kernel, linux-mm, lkml

On Wed, Jun 23, 2021 at 03:05:22PM +0800, Zhenyu Ye wrote:
quoted hunk ↗ jump to hunk
The TTL field indicates the level of page table walk holding the *leaf*
entry for the address being invalidated. But currently, the TTL field
may be set to an incorrent value in the following stack:

pte_free_tlb
    __pte_free_tlb
        tlb_remove_table
            tlb_table_invalidate
                tlb_flush_mmu_tlbonly
                    tlb_flush

In this case, we just want to flush a PTE page, but the tlb->cleared_pmds
is set and we get tlb_level = 2 in the tlb_get_level() function. This may
cause some unexpected problems.

This patch set the TTL field to 0 if tlb->freed_tables is set. The
tlb->freed_tables indicates page table pages are freed, not the leaf
entry.

Fixes: c4ab2cbc1d87 ("arm64: tlb: Set the TTL field in flush_tlb_range")
Reported-by: ZhuRui <redacted>
Signed-off-by: Zhenyu Ye <redacted>
---
 arch/arm64/include/asm/tlb.h | 4 ++++
 1 file changed, 4 insertions(+)
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index 61c97d3b58c7..c995d1f4594f 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -28,6 +28,10 @@ static void tlb_flush(struct mmu_gather *tlb);
  */
 static inline int tlb_get_level(struct mmu_gather *tlb)
 {
+	/* The TTL field is only valid for the leaf entry. */
+	if (tlb->freed_tables)
+		return 0;
+
 	if (tlb->cleared_ptes && !(tlb->cleared_pmds ||
 				   tlb->cleared_puds ||
 				   tlb->cleared_p4ds))
Thanks. I can't see a better way around this, so I'll queue the patch.
The stage-2 page-table code looks ok afaict, but please can you check it
too?

Cheers,

Will
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help