Skip to content

Commit b681604

Browse files
committed
LoongArch: mm: Fix huge page entry update for virtual machine
In virtual machine (guest mode), the tlbwr instruction can not write the last entry of MTLB, so we need to make it non-present by invtlb and then write it by tlbfill. This also simplify the whole logic. Signed-off-by: Rui Wang <[email protected]> Signed-off-by: Huacai Chen <[email protected]>
1 parent 143d64b commit b681604

File tree

1 file changed

+16
-14
lines changed

1 file changed

+16
-14
lines changed

arch/loongarch/mm/tlbex.S

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include <asm/regdef.h>
1111
#include <asm/stackframe.h>
1212

13+
#define INVTLB_ADDR_GFALSE_AND_ASID 5
14+
1315
#define PTRS_PER_PGD_BITS (PAGE_SHIFT - 3)
1416
#define PTRS_PER_PUD_BITS (PAGE_SHIFT - 3)
1517
#define PTRS_PER_PMD_BITS (PAGE_SHIFT - 3)
@@ -136,13 +138,10 @@ tlb_huge_update_load:
136138
ori t0, ra, _PAGE_VALID
137139
st.d t0, t1, 0
138140
#endif
139-
tlbsrch
140-
addu16i.d t1, zero, -(CSR_TLBIDX_EHINV >> 16)
141-
addi.d ra, t1, 0
142-
csrxchg ra, t1, LOONGARCH_CSR_TLBIDX
143-
tlbwr
144-
145-
csrxchg zero, t1, LOONGARCH_CSR_TLBIDX
141+
csrrd ra, LOONGARCH_CSR_ASID
142+
csrrd t1, LOONGARCH_CSR_BADV
143+
andi ra, ra, CSR_ASID_ASID
144+
invtlb INVTLB_ADDR_GFALSE_AND_ASID, ra, t1
146145

147146
/*
148147
* A huge PTE describes an area the size of the
@@ -287,13 +286,11 @@ tlb_huge_update_store:
287286
ori t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
288287
st.d t0, t1, 0
289288
#endif
290-
tlbsrch
291-
addu16i.d t1, zero, -(CSR_TLBIDX_EHINV >> 16)
292-
addi.d ra, t1, 0
293-
csrxchg ra, t1, LOONGARCH_CSR_TLBIDX
294-
tlbwr
289+
csrrd ra, LOONGARCH_CSR_ASID
290+
csrrd t1, LOONGARCH_CSR_BADV
291+
andi ra, ra, CSR_ASID_ASID
292+
invtlb INVTLB_ADDR_GFALSE_AND_ASID, ra, t1
295293

296-
csrxchg zero, t1, LOONGARCH_CSR_TLBIDX
297294
/*
298295
* A huge PTE describes an area the size of the
299296
* configured huge page size. This is twice the
@@ -436,6 +433,11 @@ tlb_huge_update_modify:
436433
ori t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
437434
st.d t0, t1, 0
438435
#endif
436+
csrrd ra, LOONGARCH_CSR_ASID
437+
csrrd t1, LOONGARCH_CSR_BADV
438+
andi ra, ra, CSR_ASID_ASID
439+
invtlb INVTLB_ADDR_GFALSE_AND_ASID, ra, t1
440+
439441
/*
440442
* A huge PTE describes an area the size of the
441443
* configured huge page size. This is twice the
@@ -466,7 +468,7 @@ tlb_huge_update_modify:
466468
addu16i.d t1, zero, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
467469
csrxchg t1, t0, LOONGARCH_CSR_TLBIDX
468470

469-
tlbwr
471+
tlbfill
470472

471473
/* Reset default page size */
472474
addu16i.d t0, zero, (CSR_TLBIDX_PS >> 16)

0 commit comments

Comments
 (0)