qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] target/mips: Fix PageMask with variable page size
@ 2020-06-16  7:30 Jiaxun Yang
  2020-06-20 17:24 ` Aleksandar Markovic
  0 siblings, 1 reply; 2+ messages in thread
From: Jiaxun Yang @ 2020-06-16  7:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: chenhc, aleksandar.qemu.devel, aurelien

Our current code assumed the target page size is always 4k
when handling PageMask and VPN2, however, variable page size
was just added to mips target and that's nolonger true.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
v2: Remove Big Page support from this patch
---
 target/mips/cp0_helper.c | 41 ++++++++++++++++++++++++++++------------
 target/mips/cpu.h        |  1 +
 2 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/target/mips/cp0_helper.c b/target/mips/cp0_helper.c
index bbf12e4a97..f6dc590315 100644
--- a/target/mips/cp0_helper.c
+++ b/target/mips/cp0_helper.c
@@ -872,20 +872,37 @@ void helper_mtc0_memorymapid(CPUMIPSState *env, target_ulong arg1)
     }
 }
 
-void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask)
+void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1)
 {
-    uint64_t mask = arg1 >> (TARGET_PAGE_BITS + 1);
-    if (!(env->insn_flags & ISA_MIPS32R6) || (arg1 == ~0) ||
-        (mask == 0x0000 || mask == 0x0003 || mask == 0x000F ||
-         mask == 0x003F || mask == 0x00FF || mask == 0x03FF ||
-         mask == 0x0FFF || mask == 0x3FFF || mask == 0xFFFF)) {
-        env->CP0_PageMask = arg1 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
+    unsigned long mask;
+    int maskbits;
+
+    if (env->insn_flags & ISA_MIPS32R6) {
+        return;
     }
-}
+    /* Don't care MASKX as we don't support 1KB page */
+    mask = extract32((uint32_t)arg1, CP0PM_MASK, 16);
+    maskbits = find_first_zero_bit(&mask, 32);
 
-void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1)
-{
-    update_pagemask(env, arg1, &env->CP0_PageMask);
+    /* Ensure no more set bit after first zero */
+    if (mask >> maskbits) {
+        goto invalid;
+    }
+    /* We don't support VTLB entry smaller than target page */
+    if ((maskbits + 12) < TARGET_PAGE_BITS) {
+        goto invalid;
+    }
+    env->CP0_PageMask = mask << CP0PM_MASK;
+
+    return;
+
+invalid:
+    /*
+     * When invalid, ensure the value is bigger tan or equel to
+     * the minimal but smaller than or equel to the maxium.
+     */
+    maskbits = MIN(16, MAX(maskbits, TARGET_PAGE_BITS - 12));
+    env->CP0_PageMask = ((1 << (16 + 1)) - 1) << CP0PM_MASK;
 }
 
 void helper_mtc0_pagegrain(CPUMIPSState *env, target_ulong arg1)
@@ -1111,7 +1128,7 @@ void helper_mthc0_saar(CPUMIPSState *env, target_ulong arg1)
 void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1)
 {
     target_ulong old, val, mask;
-    mask = (TARGET_PAGE_MASK << 1) | env->CP0_EntryHi_ASID_mask;
+    mask = ~((1 << 14) - 1) | env->CP0_EntryHi_ASID_mask;
     if (((env->CP0_Config4 >> CP0C4_IE) & 0x3) >= 2) {
         mask |= 1 << CP0EnHi_EHINV;
     }
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 7cf7f5239f..9c8bb23807 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -618,6 +618,7 @@ struct CPUMIPSState {
  * CP0 Register 5
  */
     int32_t CP0_PageMask;
+#define CP0PM_MASK 13
     int32_t CP0_PageGrain_rw_bitmask;
     int32_t CP0_PageGrain;
 #define CP0PG_RIE 31
-- 
2.27.0.rc2



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

* Re: [PATCH v2] target/mips: Fix PageMask with variable page size
  2020-06-16  7:30 [PATCH v2] target/mips: Fix PageMask with variable page size Jiaxun Yang
@ 2020-06-20 17:24 ` Aleksandar Markovic
  0 siblings, 0 replies; 2+ messages in thread
From: Aleksandar Markovic @ 2020-06-20 17:24 UTC (permalink / raw)
  To: Jiaxun Yang
  Cc: chenhc@lemote.com, qemu-devel@nongnu.org, aurelien@aurel32.net

[-- Attachment #1: Type: text/plain, Size: 3600 bytes --]

уторак, 16. јун 2020., Jiaxun Yang <jiaxun.yang@flygoat.com> је написао/ла:

> Our current code assumed the target page size is always 4k
> when handling PageMask and VPN2, however, variable page size
> was just added to mips target and that's nolonger true.
>
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> ---
> v2: Remove Big Page support from this patch
> ---
>  target/mips/cp0_helper.c | 41 ++++++++++++++++++++++++++++------------


Please do not use harcoded numbers, if possibe.

Yours,
Aleksandar



>  target/mips/cpu.h        |  1 +
>  2 files changed, 30 insertions(+), 12 deletions(-)
>
> diff --git a/target/mips/cp0_helper.c b/target/mips/cp0_helper.c
> index bbf12e4a97..f6dc590315 100644
> --- a/target/mips/cp0_helper.c
> +++ b/target/mips/cp0_helper.c
> @@ -872,20 +872,37 @@ void helper_mtc0_memorymapid(CPUMIPSState *env,
> target_ulong arg1)
>      }
>  }
>
> -void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t
> *pagemask)
> +void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1)
>  {
> -    uint64_t mask = arg1 >> (TARGET_PAGE_BITS + 1);
> -    if (!(env->insn_flags & ISA_MIPS32R6) || (arg1 == ~0) ||
> -        (mask == 0x0000 || mask == 0x0003 || mask == 0x000F ||
> -         mask == 0x003F || mask == 0x00FF || mask == 0x03FF ||
> -         mask == 0x0FFF || mask == 0x3FFF || mask == 0xFFFF)) {
> -        env->CP0_PageMask = arg1 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
> +    unsigned long mask;
> +    int maskbits;
> +
> +    if (env->insn_flags & ISA_MIPS32R6) {
> +        return;
>      }
> -}
> +    /* Don't care MASKX as we don't support 1KB page */
> +    mask = extract32((uint32_t)arg1, CP0PM_MASK, 16);
> +    maskbits = find_first_zero_bit(&mask, 32);
>
> -void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1)
> -{
> -    update_pagemask(env, arg1, &env->CP0_PageMask);
> +    /* Ensure no more set bit after first zero */
> +    if (mask >> maskbits) {
> +        goto invalid;
> +    }
> +    /* We don't support VTLB entry smaller than target page */
> +    if ((maskbits + 12) < TARGET_PAGE_BITS) {
> +        goto invalid;
> +    }


12.


> +    env->CP0_PageMask = mask << CP0PM_MASK;
> +
> +    return;
> +
> +invalid:
> +    /*
> +     * When invalid, ensure the value is bigger tan or equel to


than or equal


> +     * the minimal but smaller than or equel to the maxium.


equal


> +     */
> +    maskbits = MIN(16, MAX(maskbits, TARGET_PAGE_BITS - 12));
> +    env->CP0_PageMask = ((1 << (16 + 1)) - 1) << CP0PM_MASK;


16, 12, 16 + 1 ?


>  }
>
>  void helper_mtc0_pagegrain(CPUMIPSState *env, target_ulong arg1)
> @@ -1111,7 +1128,7 @@ void helper_mthc0_saar(CPUMIPSState *env,
> target_ulong arg1)
>  void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1)
>  {
>      target_ulong old, val, mask;
> -    mask = (TARGET_PAGE_MASK << 1) | env->CP0_EntryHi_ASID_mask;
> +    mask = ~((1 << 14) - 1) | env->CP0_EntryHi_ASID_mask;


14.


>      if (((env->CP0_Config4 >> CP0C4_IE) & 0x3) >= 2) {
>          mask |= 1 << CP0EnHi_EHINV;
>      }
> diff --git a/target/mips/cpu.h b/target/mips/cpu.h
> index 7cf7f5239f..9c8bb23807 100644
> --- a/target/mips/cpu.h
> +++ b/target/mips/cpu.h
> @@ -618,6 +618,7 @@ struct CPUMIPSState {
>   * CP0 Register 5
>   */
>      int32_t CP0_PageMask;
> +#define CP0PM_MASK 13
>      int32_t CP0_PageGrain_rw_bitmask;
>      int32_t CP0_PageGrain;
>  #define CP0PG_RIE 31
> --
> 2.27.0.rc2
>
>

[-- Attachment #2: Type: text/html, Size: 5180 bytes --]

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

end of thread, other threads:[~2020-06-20 17:24 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-06-16  7:30 [PATCH v2] target/mips: Fix PageMask with variable page size Jiaxun Yang
2020-06-20 17:24 ` Aleksandar Markovic

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).