qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Fixed tlb huge page loading issue
@ 2024-02-28  6:55 Xianglai Li
  2024-03-04  6:39 ` maobibo
  2024-03-04  8:33 ` gaosong
  0 siblings, 2 replies; 4+ messages in thread
From: Xianglai Li @ 2024-02-28  6:55 UTC (permalink / raw)
  To: qemu-devel

The lddir and ldpte instruction emulation has
a problem with the use of large page processing above level 2.
The page size is not correctly calculated,
resulting in the wrong page size of the table entry found by tlb.

Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
---
 target/loongarch/cpu.h            |  1 +
 target/loongarch/tcg/tlb_helper.c | 21 ++++++++++++---------
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index ec37579fd6..eab3e41c71 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -292,6 +292,7 @@ typedef struct CPUArchState {
     uint32_t fcsr0_mask;
 
     uint32_t cpucfg[21];
+    uint32_t lddir_ps;
 
     uint64_t lladdr; /* LL virtual address compared against SC */
     uint64_t llval;
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index a08c08b05a..3594c800b3 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -38,6 +38,7 @@ static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
             cs->exception_index = EXCCODE_PIF;
         }
         env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 1);
+        env->lddir_ps = 0;
         break;
     case TLBRET_INVALID:
         /* TLB match with no valid bit */
@@ -488,13 +489,6 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base,
     uint64_t dir_base, dir_width;
     bool huge = (base >> LOONGARCH_PAGE_HUGE_SHIFT) & 0x1;
 
-    badvaddr = env->CSR_TLBRBADV;
-    base = base & TARGET_PHYS_MASK;
-
-    /* 0:64bit, 1:128bit, 2:192bit, 3:256bit */
-    shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH);
-    shift = (shift + 1) * 3;
-
     if (huge) {
         return base;
     }
@@ -519,9 +513,18 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base,
         do_raise_exception(env, EXCCODE_INE, GETPC());
         return 0;
     }
+
+    /* 0:64bit, 1:128bit, 2:192bit, 3:256bit */
+    shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH);
+    shift = (shift + 1) * 3;
+    badvaddr = env->CSR_TLBRBADV;
+    base = base & TARGET_PHYS_MASK;
     index = (badvaddr >> dir_base) & ((1 << dir_width) - 1);
     phys = base | index << shift;
     ret = ldq_phys(cs->as, phys) & TARGET_PHYS_MASK;
+    if (ret & BIT_ULL(LOONGARCH_PAGE_HUGE_SHIFT)) {
+        env->lddir_ps = dir_base;
+    }
     return ret;
 }
 
@@ -538,13 +541,13 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd,
     base = base & TARGET_PHYS_MASK;
 
     if (huge) {
-        /* Huge Page. base is paddr */
         tmp0 = base ^ (1 << LOONGARCH_PAGE_HUGE_SHIFT);
         /* Move Global bit */
         tmp0 = ((tmp0 & (1 << LOONGARCH_HGLOBAL_SHIFT))  >>
                 LOONGARCH_HGLOBAL_SHIFT) << R_TLBENTRY_G_SHIFT |
                 (tmp0 & (~(1 << LOONGARCH_HGLOBAL_SHIFT)));
-        ps = ptbase + ptwidth - 1;
+
+        ps = env->lddir_ps - 1;
         if (odd) {
             tmp0 += MAKE_64BIT_MASK(ps, 1);
         }
-- 
2.39.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] Fixed tlb huge page loading issue
  2024-02-28  6:55 [PATCH] Fixed tlb huge page loading issue Xianglai Li
@ 2024-03-04  6:39 ` maobibo
  2024-03-04  8:33 ` gaosong
  1 sibling, 0 replies; 4+ messages in thread
From: maobibo @ 2024-03-04  6:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: Song Gao

Xianglai,

Thanks for your patch.

On 2024/2/28 下午2:55, Xianglai Li wrote:
> The lddir and ldpte instruction emulation has
> a problem with the use of large page processing above level 2.
> The page size is not correctly calculated,
> resulting in the wrong page size of the table entry found by tlb.
Could you describe the actual problem in detail?

> 
> Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
> ---
>   target/loongarch/cpu.h            |  1 +
>   target/loongarch/tcg/tlb_helper.c | 21 ++++++++++++---------
>   2 files changed, 13 insertions(+), 9 deletions(-)
> 
> diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
> index ec37579fd6..eab3e41c71 100644
> --- a/target/loongarch/cpu.h
> +++ b/target/loongarch/cpu.h
> @@ -292,6 +292,7 @@ typedef struct CPUArchState {
>       uint32_t fcsr0_mask;
>   
>       uint32_t cpucfg[21];
> +    uint32_t lddir_ps;
>   
>       uint64_t lladdr; /* LL virtual address compared against SC */
>       uint64_t llval;
> diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
> index a08c08b05a..3594c800b3 100644
> --- a/target/loongarch/tcg/tlb_helper.c
> +++ b/target/loongarch/tcg/tlb_helper.c
> @@ -38,6 +38,7 @@ static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
>               cs->exception_index = EXCCODE_PIF;
>           }
>           env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 1);
> +        env->lddir_ps = 0;
>           break;
>       case TLBRET_INVALID:
>           /* TLB match with no valid bit */
> @@ -488,13 +489,6 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base,
>       uint64_t dir_base, dir_width;
>       bool huge = (base >> LOONGARCH_PAGE_HUGE_SHIFT) & 0x1;
>   
> -    badvaddr = env->CSR_TLBRBADV;
> -    base = base & TARGET_PHYS_MASK;
> -
> -    /* 0:64bit, 1:128bit, 2:192bit, 3:256bit */
> -    shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH);
> -    shift = (shift + 1) * 3;
> -
>       if (huge) {
>           return base;
>       }
> @@ -519,9 +513,18 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base,
>           do_raise_exception(env, EXCCODE_INE, GETPC());
>           return 0;
>       }
> +
> +    /* 0:64bit, 1:128bit, 2:192bit, 3:256bit */
> +    shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH);
> +    shift = (shift + 1) * 3;
> +    badvaddr = env->CSR_TLBRBADV;
> +    base = base & TARGET_PHYS_MASK;
>       index = (badvaddr >> dir_base) & ((1 << dir_width) - 1);
>       phys = base | index << shift;
>       ret = ldq_phys(cs->as, phys) & TARGET_PHYS_MASK;
> +    if (ret & BIT_ULL(LOONGARCH_PAGE_HUGE_SHIFT)) {
> +        env->lddir_ps = dir_base;
> +    }
>       return ret;
>   }
>   
> @@ -538,13 +541,13 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd,
>       base = base & TARGET_PHYS_MASK;
>   
>       if (huge) {
> -        /* Huge Page. base is paddr */
>           tmp0 = base ^ (1 << LOONGARCH_PAGE_HUGE_SHIFT);
>           /* Move Global bit */
>           tmp0 = ((tmp0 & (1 << LOONGARCH_HGLOBAL_SHIFT))  >>
>                   LOONGARCH_HGLOBAL_SHIFT) << R_TLBENTRY_G_SHIFT |
>                   (tmp0 & (~(1 << LOONGARCH_HGLOBAL_SHIFT)));
> -        ps = ptbase + ptwidth - 1;
> +
empty line is not necessary.

Regards
Bibo Mao
> +        ps = env->lddir_ps - 1;
>           if (odd) {
>               tmp0 += MAKE_64BIT_MASK(ps, 1);
>           }
> 



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Fixed tlb huge page loading issue
  2024-02-28  6:55 [PATCH] Fixed tlb huge page loading issue Xianglai Li
  2024-03-04  6:39 ` maobibo
@ 2024-03-04  8:33 ` gaosong
  2024-03-05  1:49   ` lixianglai
  1 sibling, 1 reply; 4+ messages in thread
From: gaosong @ 2024-03-04  8:33 UTC (permalink / raw)
  To: Xianglai Li, qemu-devel

Hi,

Title 'target/loongarch: xxxx' ...

Thanks.
Song Gao
在 2024/2/28 14:55, Xianglai Li 写道:
> The lddir and ldpte instruction emulation has
> a problem with the use of large page processing above level 2.
> The page size is not correctly calculated,
> resulting in the wrong page size of the table entry found by tlb.
>
> Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
> ---
>   target/loongarch/cpu.h            |  1 +
>   target/loongarch/tcg/tlb_helper.c | 21 ++++++++++++---------
>   2 files changed, 13 insertions(+), 9 deletions(-)
>
> diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
> index ec37579fd6..eab3e41c71 100644
> --- a/target/loongarch/cpu.h
> +++ b/target/loongarch/cpu.h
> @@ -292,6 +292,7 @@ typedef struct CPUArchState {
>       uint32_t fcsr0_mask;
>   
>       uint32_t cpucfg[21];
> +    uint32_t lddir_ps;
>   
>       uint64_t lladdr; /* LL virtual address compared against SC */
>       uint64_t llval;
> diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
> index a08c08b05a..3594c800b3 100644
> --- a/target/loongarch/tcg/tlb_helper.c
> +++ b/target/loongarch/tcg/tlb_helper.c
> @@ -38,6 +38,7 @@ static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
>               cs->exception_index = EXCCODE_PIF;
>           }
>           env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 1);
> +        env->lddir_ps = 0;
>           break;
>       case TLBRET_INVALID:
>           /* TLB match with no valid bit */
> @@ -488,13 +489,6 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base,
>       uint64_t dir_base, dir_width;
>       bool huge = (base >> LOONGARCH_PAGE_HUGE_SHIFT) & 0x1;
>   
> -    badvaddr = env->CSR_TLBRBADV;
> -    base = base & TARGET_PHYS_MASK;
> -
> -    /* 0:64bit, 1:128bit, 2:192bit, 3:256bit */
> -    shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH);
> -    shift = (shift + 1) * 3;
> -
>       if (huge) {
>           return base;
>       }
> @@ -519,9 +513,18 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base,
>           do_raise_exception(env, EXCCODE_INE, GETPC());
>           return 0;
>       }
> +
> +    /* 0:64bit, 1:128bit, 2:192bit, 3:256bit */
> +    shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH);
> +    shift = (shift + 1) * 3;
> +    badvaddr = env->CSR_TLBRBADV;
> +    base = base & TARGET_PHYS_MASK;
>       index = (badvaddr >> dir_base) & ((1 << dir_width) - 1);
>       phys = base | index << shift;
>       ret = ldq_phys(cs->as, phys) & TARGET_PHYS_MASK;
> +    if (ret & BIT_ULL(LOONGARCH_PAGE_HUGE_SHIFT)) {
> +        env->lddir_ps = dir_base;
> +    }
>       return ret;
>   }
>   
> @@ -538,13 +541,13 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd,
>       base = base & TARGET_PHYS_MASK;
>   
>       if (huge) {
> -        /* Huge Page. base is paddr */
>           tmp0 = base ^ (1 << LOONGARCH_PAGE_HUGE_SHIFT);
>           /* Move Global bit */
>           tmp0 = ((tmp0 & (1 << LOONGARCH_HGLOBAL_SHIFT))  >>
>                   LOONGARCH_HGLOBAL_SHIFT) << R_TLBENTRY_G_SHIFT |
>                   (tmp0 & (~(1 << LOONGARCH_HGLOBAL_SHIFT)));
> -        ps = ptbase + ptwidth - 1;
> +
> +        ps = env->lddir_ps - 1;
>           if (odd) {
>               tmp0 += MAKE_64BIT_MASK(ps, 1);
>           }



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Fixed tlb huge page loading issue
  2024-03-04  8:33 ` gaosong
@ 2024-03-05  1:49   ` lixianglai
  0 siblings, 0 replies; 4+ messages in thread
From: lixianglai @ 2024-03-05  1:49 UTC (permalink / raw)
  To: gaosong, qemu-devel


Hi gaosong:
> Hi,
>
> Title 'target/loongarch: xxxx' ...
>
OK! I will fix it in next version.

Thanks,

Xianglai.




> Thanks.
> Song Gao
> 在 2024/2/28 14:55, Xianglai Li 写道:
>> The lddir and ldpte instruction emulation has
>> a problem with the use of large page processing above level 2.
>> The page size is not correctly calculated,
>> resulting in the wrong page size of the table entry found by tlb.
>>
>> Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
>> ---
>>   target/loongarch/cpu.h            |  1 +
>>   target/loongarch/tcg/tlb_helper.c | 21 ++++++++++++---------
>>   2 files changed, 13 insertions(+), 9 deletions(-)
>>
>> diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
>> index ec37579fd6..eab3e41c71 100644
>> --- a/target/loongarch/cpu.h
>> +++ b/target/loongarch/cpu.h
>> @@ -292,6 +292,7 @@ typedef struct CPUArchState {
>>       uint32_t fcsr0_mask;
>>         uint32_t cpucfg[21];
>> +    uint32_t lddir_ps;
>>         uint64_t lladdr; /* LL virtual address compared against SC */
>>       uint64_t llval;
>> diff --git a/target/loongarch/tcg/tlb_helper.c 
>> b/target/loongarch/tcg/tlb_helper.c
>> index a08c08b05a..3594c800b3 100644
>> --- a/target/loongarch/tcg/tlb_helper.c
>> +++ b/target/loongarch/tcg/tlb_helper.c
>> @@ -38,6 +38,7 @@ static void raise_mmu_exception(CPULoongArchState 
>> *env, target_ulong address,
>>               cs->exception_index = EXCCODE_PIF;
>>           }
>>           env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, 
>> CSR_TLBRERA, ISTLBR, 1);
>> +        env->lddir_ps = 0;
>>           break;
>>       case TLBRET_INVALID:
>>           /* TLB match with no valid bit */
>> @@ -488,13 +489,6 @@ target_ulong helper_lddir(CPULoongArchState 
>> *env, target_ulong base,
>>       uint64_t dir_base, dir_width;
>>       bool huge = (base >> LOONGARCH_PAGE_HUGE_SHIFT) & 0x1;
>>   -    badvaddr = env->CSR_TLBRBADV;
>> -    base = base & TARGET_PHYS_MASK;
>> -
>> -    /* 0:64bit, 1:128bit, 2:192bit, 3:256bit */
>> -    shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH);
>> -    shift = (shift + 1) * 3;
>> -
>>       if (huge) {
>>           return base;
>>       }
>> @@ -519,9 +513,18 @@ target_ulong helper_lddir(CPULoongArchState 
>> *env, target_ulong base,
>>           do_raise_exception(env, EXCCODE_INE, GETPC());
>>           return 0;
>>       }
>> +
>> +    /* 0:64bit, 1:128bit, 2:192bit, 3:256bit */
>> +    shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH);
>> +    shift = (shift + 1) * 3;
>> +    badvaddr = env->CSR_TLBRBADV;
>> +    base = base & TARGET_PHYS_MASK;
>>       index = (badvaddr >> dir_base) & ((1 << dir_width) - 1);
>>       phys = base | index << shift;
>>       ret = ldq_phys(cs->as, phys) & TARGET_PHYS_MASK;
>> +    if (ret & BIT_ULL(LOONGARCH_PAGE_HUGE_SHIFT)) {
>> +        env->lddir_ps = dir_base;
>> +    }
>>       return ret;
>>   }
>>   @@ -538,13 +541,13 @@ void helper_ldpte(CPULoongArchState *env, 
>> target_ulong base, target_ulong odd,
>>       base = base & TARGET_PHYS_MASK;
>>         if (huge) {
>> -        /* Huge Page. base is paddr */
>>           tmp0 = base ^ (1 << LOONGARCH_PAGE_HUGE_SHIFT);
>>           /* Move Global bit */
>>           tmp0 = ((tmp0 & (1 << LOONGARCH_HGLOBAL_SHIFT))  >>
>>                   LOONGARCH_HGLOBAL_SHIFT) << R_TLBENTRY_G_SHIFT |
>>                   (tmp0 & (~(1 << LOONGARCH_HGLOBAL_SHIFT)));
>> -        ps = ptbase + ptwidth - 1;
>> +
>> +        ps = env->lddir_ps - 1;
>>           if (odd) {
>>               tmp0 += MAKE_64BIT_MASK(ps, 1);
>>           }



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-03-05  1:50 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-28  6:55 [PATCH] Fixed tlb huge page loading issue Xianglai Li
2024-03-04  6:39 ` maobibo
2024-03-04  8:33 ` gaosong
2024-03-05  1:49   ` lixianglai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).