If asid is changed in function helper_csrwr_asid(), qemu TLB is flushed,
however loongArch TLB is still valid. So loongArch TLB need be invalidated
in function invalidate_tlb() with different asid and bit effective need
be cleared.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/tcg/tlb_helper.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 8cfce48a29..f8fada5b9a 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -117,13 +117,7 @@ static void invalidate_tlb_entry(CPULoongArchState *env, int index)
uint8_t tlb_v0 = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, V);
uint8_t tlb_v1 = FIELD_EX64(tlb->tlb_entry1, TLBENTRY, V);
uint64_t tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
- uint8_t tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
- if (!tlb_e) {
- return;
- }
-
- tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 0);
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);
@@ -145,11 +139,19 @@ static void invalidate_tlb(CPULoongArchState *env, int index)
{
LoongArchTLB *tlb;
uint16_t csr_asid, tlb_asid, tlb_g;
+ uint8_t tlb_e;
csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID);
tlb = &env->tlb[index];
+ tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
+ if (!tlb_e) {
+ return;
+ }
+
+ tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 0);
tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
+ /* QEMU TLB is flushed when asid is changed */
if (tlb_g == 0 && tlb_asid != csr_asid) {
return;
}
--
2.39.3
在 2025/10/9 上午10:59, Bibo Mao 写道:
> If asid is changed in function helper_csrwr_asid(), qemu TLB is flushed,
> however loongArch TLB is still valid. So loongArch TLB need be invalidated
> in function invalidate_tlb() with different asid and bit effective need
> be cleared.
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> ---
> target/loongarch/tcg/tlb_helper.c | 14 ++++++++------
> 1 file changed, 8 insertions(+), 6 deletions(-)
Signed-off-by: Song Gao <gaosong@loongson.cn>
Thanks.
Song Gao
> diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
> index 8cfce48a29..f8fada5b9a 100644
> --- a/target/loongarch/tcg/tlb_helper.c
> +++ b/target/loongarch/tcg/tlb_helper.c
> @@ -117,13 +117,7 @@ static void invalidate_tlb_entry(CPULoongArchState *env, int index)
> uint8_t tlb_v0 = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, V);
> uint8_t tlb_v1 = FIELD_EX64(tlb->tlb_entry1, TLBENTRY, V);
> uint64_t tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
> - uint8_t tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
>
> - if (!tlb_e) {
> - return;
> - }
> -
> - tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 0);
> 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);
> @@ -145,11 +139,19 @@ static void invalidate_tlb(CPULoongArchState *env, int index)
> {
> LoongArchTLB *tlb;
> uint16_t csr_asid, tlb_asid, tlb_g;
> + uint8_t tlb_e;
>
> csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID);
> tlb = &env->tlb[index];
> + tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
> + if (!tlb_e) {
> + return;
> + }
> +
> + tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 0);
> tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
> tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
> + /* QEMU TLB is flushed when asid is changed */
> if (tlb_g == 0 && tlb_asid != csr_asid) {
> return;
> }
© 2016 - 2025 Red Hat, Inc.