On LoongArch system, there are two pages with one TLB entry. If the
whole TLB entry is flushed, two pages will be flushed. Otherwise if
tlb is flushed one by one, page size is one page at a time.

Also virtual address of odd page is fixed here.

Signed-off-by: Bibo Mao <maob...@loongson.cn>
---
 target/loongarch/tcg/tlb_helper.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/target/loongarch/tcg/tlb_helper.c 
b/target/loongarch/tcg/tlb_helper.c
index 76ec469341..47eb3ee318 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -112,20 +112,19 @@ static void invalidate_tlb_entry(CPULoongArchState *env, 
int index)
     }
 
     tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
-    pagesize = MAKE_64BIT_MASK(tlb_ps, 1);
-    mask = MAKE_64BIT_MASK(0, tlb_ps + 1);
+    pagesize = BIT_ULL(tlb_ps);
+    mask = ~((pagesize << 1) - 1) & TARGET_VIRT_MASK;
+    addr = (tlb_vppn << R_TLB_MISC_VPPN_SHIFT) & mask;
 
     if (tlb_v0) {
-        addr = (tlb_vppn << R_TLB_MISC_VPPN_SHIFT) & ~mask;    /* even */
         mmu_idx = BIT(FIELD_EX64(tlb->tlb_entry0, TLBENTRY, PLV));
         tlb_flush_range_by_mmuidx(env_cpu(env), addr, pagesize,
                                   mmu_idx, TARGET_LONG_BITS);
     }
 
     if (tlb_v1) {
-        addr = (tlb_vppn << R_TLB_MISC_VPPN_SHIFT) & pagesize;    /* odd */
         mmu_idx = BIT(FIELD_EX64(tlb->tlb_entry1, TLBENTRY, PLV));
-        tlb_flush_range_by_mmuidx(env_cpu(env), addr, pagesize,
+        tlb_flush_range_by_mmuidx(env_cpu(env), addr + pagesize, pagesize,
                                   mmu_idx, TARGET_LONG_BITS);
     }
 }
-- 
2.39.3


Reply via email to