diff mbox series

[PULL,v3,36/42] target/riscv: Remove the hardcoded MSTATUS_SD macro

Message ID 20210511101951.165287-37-alistair.francis@wdc.com
State New
Headers show
Series [PULL,v3,01/42] target/riscv: Remove privilege v1.9 specific CSR related code | expand

Commit Message

Alistair Francis May 11, 2021, 10:19 a.m. UTC
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: fcc125d96da941b56c817c9dd6068dc36478fc53.1619234854.git.alistair.francis@wdc.com
---
 target/riscv/cpu_bits.h  | 10 ----------
 target/riscv/csr.c       | 12 ++++++++++--
 target/riscv/translate.c | 19 +++++++++++++++++--
 3 files changed, 27 insertions(+), 14 deletions(-)

Comments

Peter Maydell May 20, 2021, 1:55 p.m. UTC | #1
On Tue, 11 May 2021 at 11:22, Alistair Francis <alistair.francis@wdc.com> wrote:
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> Message-id: fcc125d96da941b56c817c9dd6068dc36478fc53.1619234854.git.alistair.francis@wdc.com
> ---
>  target/riscv/cpu_bits.h  | 10 ----------
>  target/riscv/csr.c       | 12 ++++++++++--
>  target/riscv/translate.c | 19 +++++++++++++++++--
>  3 files changed, 27 insertions(+), 14 deletions(-)

> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 26eccc5eb1..a596f80f20 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -78,6 +78,17 @@ static inline bool has_ext(DisasContext *ctx, uint32_t ext)
>      return ctx->misa & ext;
>  }
>
> +#ifdef TARGET_RISCV32
> +# define is_32bit(ctx)  true
> +#elif defined(CONFIG_USER_ONLY)
> +# define is_32bit(ctx)  false
> +#else
> +static inline bool is_32bit(DisasContext *ctx)
> +{
> +    return (ctx->misa & RV32) == RV32;
> +}
> +#endif

Hi; Coverity points out (CID 1453107) that this is_32bit() function
can never return true for at least some build configs, because RV32
is defined as ((target_ulong)1 << (TARGET_LONG_BITS - 2))
but ctx->misa is a uint32_t field, which (if TARGET_LONG_BITS is
64) is not big enough for the RV32 bit.

Bug, or false positive ?

thanks
-- PMM
Alistair Francis May 20, 2021, 10:55 p.m. UTC | #2
On Thu, May 20, 2021 at 11:55 PM Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Tue, 11 May 2021 at 11:22, Alistair Francis <alistair.francis@wdc.com> wrote:
> >
> > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> > Message-id: fcc125d96da941b56c817c9dd6068dc36478fc53.1619234854.git.alistair.francis@wdc.com
> > ---
> >  target/riscv/cpu_bits.h  | 10 ----------
> >  target/riscv/csr.c       | 12 ++++++++++--
> >  target/riscv/translate.c | 19 +++++++++++++++++--
> >  3 files changed, 27 insertions(+), 14 deletions(-)
>
> > diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> > index 26eccc5eb1..a596f80f20 100644
> > --- a/target/riscv/translate.c
> > +++ b/target/riscv/translate.c
> > @@ -78,6 +78,17 @@ static inline bool has_ext(DisasContext *ctx, uint32_t ext)
> >      return ctx->misa & ext;
> >  }
> >
> > +#ifdef TARGET_RISCV32
> > +# define is_32bit(ctx)  true
> > +#elif defined(CONFIG_USER_ONLY)
> > +# define is_32bit(ctx)  false
> > +#else
> > +static inline bool is_32bit(DisasContext *ctx)
> > +{
> > +    return (ctx->misa & RV32) == RV32;
> > +}
> > +#endif
>
> Hi; Coverity points out (CID 1453107) that this is_32bit() function
> can never return true for at least some build configs, because RV32
> is defined as ((target_ulong)1 << (TARGET_LONG_BITS - 2))
> but ctx->misa is a uint32_t field, which (if TARGET_LONG_BITS is
> 64) is not big enough for the RV32 bit.

This seems like a false positive as RV32 is defined as:

((target_ulong)1 << (TARGET_LONG_BITS - 2))

while ctx->misa is a target_ulong.

So it should always be able to return true.

Alistair

>
> Bug, or false positive ?
>
> thanks
> -- PMM
LIU Zhiwei May 21, 2021, 2:07 a.m. UTC | #3
On 5/21/21 6:55 AM, Alistair Francis wrote:
> On Thu, May 20, 2021 at 11:55 PM Peter Maydell <peter.maydell@linaro.org> wrote:
>> On Tue, 11 May 2021 at 11:22, Alistair Francis <alistair.francis@wdc.com> wrote:
>>> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
>>> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>>> Message-id: fcc125d96da941b56c817c9dd6068dc36478fc53.1619234854.git.alistair.francis@wdc.com
>>> ---
>>>   target/riscv/cpu_bits.h  | 10 ----------
>>>   target/riscv/csr.c       | 12 ++++++++++--
>>>   target/riscv/translate.c | 19 +++++++++++++++++--
>>>   3 files changed, 27 insertions(+), 14 deletions(-)
>>> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
>>> index 26eccc5eb1..a596f80f20 100644
>>> --- a/target/riscv/translate.c
>>> +++ b/target/riscv/translate.c
>>> @@ -78,6 +78,17 @@ static inline bool has_ext(DisasContext *ctx, uint32_t ext)
>>>       return ctx->misa & ext;
>>>   }
>>>
>>> +#ifdef TARGET_RISCV32
>>> +# define is_32bit(ctx)  true
>>> +#elif defined(CONFIG_USER_ONLY)
>>> +# define is_32bit(ctx)  false
>>> +#else
>>> +static inline bool is_32bit(DisasContext *ctx)
>>> +{
>>> +    return (ctx->misa & RV32) == RV32;
>>> +}
>>> +#endif
>> Hi; Coverity points out (CID 1453107) that this is_32bit() function
>> can never return true for at least some build configs, because RV32
>> is defined as ((target_ulong)1 << (TARGET_LONG_BITS - 2))
>> but ctx->misa is a uint32_t field, which (if TARGET_LONG_BITS is
>> 64) is not big enough for the RV32 bit.
> This seems like a false positive as RV32 is defined as:
>
> ((target_ulong)1 << (TARGET_LONG_BITS - 2))
>
> while ctx->misa is a target_ulong.

Although the misa in RISCVCPUState is target_ulong, the misa in 
DisasContext is uint32_t.

I think we should  fix up the misa in DisasContext.

Zhiwei

>
> So it should always be able to return true.
>
> Alistair
>
>> Bug, or false positive ?
>>
>> thanks
>> -- PMM
Alistair Francis May 25, 2021, 9:47 p.m. UTC | #4
On Fri, May 21, 2021 at 12:09 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
>
> On 5/21/21 6:55 AM, Alistair Francis wrote:
> > On Thu, May 20, 2021 at 11:55 PM Peter Maydell <peter.maydell@linaro.org> wrote:
> >> On Tue, 11 May 2021 at 11:22, Alistair Francis <alistair.francis@wdc.com> wrote:
> >>> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> >>> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> >>> Message-id: fcc125d96da941b56c817c9dd6068dc36478fc53.1619234854.git.alistair.francis@wdc.com
> >>> ---
> >>>   target/riscv/cpu_bits.h  | 10 ----------
> >>>   target/riscv/csr.c       | 12 ++++++++++--
> >>>   target/riscv/translate.c | 19 +++++++++++++++++--
> >>>   3 files changed, 27 insertions(+), 14 deletions(-)
> >>> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> >>> index 26eccc5eb1..a596f80f20 100644
> >>> --- a/target/riscv/translate.c
> >>> +++ b/target/riscv/translate.c
> >>> @@ -78,6 +78,17 @@ static inline bool has_ext(DisasContext *ctx, uint32_t ext)
> >>>       return ctx->misa & ext;
> >>>   }
> >>>
> >>> +#ifdef TARGET_RISCV32
> >>> +# define is_32bit(ctx)  true
> >>> +#elif defined(CONFIG_USER_ONLY)
> >>> +# define is_32bit(ctx)  false
> >>> +#else
> >>> +static inline bool is_32bit(DisasContext *ctx)
> >>> +{
> >>> +    return (ctx->misa & RV32) == RV32;
> >>> +}
> >>> +#endif
> >> Hi; Coverity points out (CID 1453107) that this is_32bit() function
> >> can never return true for at least some build configs, because RV32
> >> is defined as ((target_ulong)1 << (TARGET_LONG_BITS - 2))
> >> but ctx->misa is a uint32_t field, which (if TARGET_LONG_BITS is
> >> 64) is not big enough for the RV32 bit.
> > This seems like a false positive as RV32 is defined as:
> >
> > ((target_ulong)1 << (TARGET_LONG_BITS - 2))
> >
> > while ctx->misa is a target_ulong.
>
> Although the misa in RISCVCPUState is target_ulong, the misa in
> DisasContext is uint32_t.
>
> I think we should  fix up the misa in DisasContext.

Good catch, I'll send a patch.

Alistair

>
> Zhiwei
>
> >
> > So it should always be able to return true.
> >
> > Alistair
> >
> >> Bug, or false positive ?
> >>
> >> thanks
> >> -- PMM
diff mbox series

Patch

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index d738e2fdbd..6e30b312f0 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -368,16 +368,6 @@ 
 #define MXL_RV64            2
 #define MXL_RV128           3
 
-#if defined(TARGET_RISCV32)
-#define MSTATUS_SD MSTATUS32_SD
-#define MISA_MXL MISA32_MXL
-#define MXL_VAL MXL_RV32
-#elif defined(TARGET_RISCV64)
-#define MSTATUS_SD MSTATUS64_SD
-#define MISA_MXL MISA64_MXL
-#define MXL_VAL MXL_RV64
-#endif
-
 /* sstatus CSR bits */
 #define SSTATUS_UIE         0x00000001
 #define SSTATUS_SIE         0x00000002
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 41951a0a84..e955753441 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -538,7 +538,11 @@  static RISCVException write_mstatus(CPURISCVState *env, int csrno,
 
     dirty = ((mstatus & MSTATUS_FS) == MSTATUS_FS) |
             ((mstatus & MSTATUS_XS) == MSTATUS_XS);
-    mstatus = set_field(mstatus, MSTATUS_SD, dirty);
+    if (riscv_cpu_is_32bit(env)) {
+        mstatus = set_field(mstatus, MSTATUS32_SD, dirty);
+    } else {
+        mstatus = set_field(mstatus, MSTATUS64_SD, dirty);
+    }
     env->mstatus = mstatus;
 
     return RISCV_EXCP_NONE;
@@ -614,7 +618,11 @@  static RISCVException write_misa(CPURISCVState *env, int csrno,
     }
 
     /* misa.MXL writes are not supported by QEMU */
-    val = (env->misa & MISA_MXL) | (val & ~MISA_MXL);
+    if (riscv_cpu_is_32bit(env)) {
+        val = (env->misa & MISA32_MXL) | (val & ~MISA32_MXL);
+    } else {
+        val = (env->misa & MISA64_MXL) | (val & ~MISA64_MXL);
+    }
 
     /* flush translation cache */
     if (val != env->misa) {
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 26eccc5eb1..a596f80f20 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -78,6 +78,17 @@  static inline bool has_ext(DisasContext *ctx, uint32_t ext)
     return ctx->misa & ext;
 }
 
+#ifdef TARGET_RISCV32
+# define is_32bit(ctx)  true
+#elif defined(CONFIG_USER_ONLY)
+# define is_32bit(ctx)  false
+#else
+static inline bool is_32bit(DisasContext *ctx)
+{
+    return (ctx->misa & RV32) == RV32;
+}
+#endif
+
 /*
  * RISC-V requires NaN-boxing of narrower width floating point values.
  * This applies when a 32-bit value is assigned to a 64-bit FP register.
@@ -369,6 +380,8 @@  static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
 static void mark_fs_dirty(DisasContext *ctx)
 {
     TCGv tmp;
+    target_ulong sd;
+
     if (ctx->mstatus_fs == MSTATUS_FS) {
         return;
     }
@@ -376,13 +389,15 @@  static void mark_fs_dirty(DisasContext *ctx)
     ctx->mstatus_fs = MSTATUS_FS;
 
     tmp = tcg_temp_new();
+    sd = is_32bit(ctx) ? MSTATUS32_SD : MSTATUS64_SD;
+
     tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
-    tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS | MSTATUS_SD);
+    tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS | sd);
     tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
 
     if (ctx->virt_enabled) {
         tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
-        tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS | MSTATUS_SD);
+        tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS | sd);
         tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
     }
     tcg_temp_free(tmp);