qemu-riscv
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v3] target/riscv: raise an exception when CSRRS/CSRRC writes


From: Alistair Francis
Subject: Re: [PATCH v3] target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR
Date: Tue, 4 Jun 2024 13:41:30 +1000

On Mon, Jun 3, 2024 at 4:00 PM Yuming Yu-Ming Chang(張育銘)
<yumin686@andestech.com> wrote:
>
> Hi Alistair,
>
> I think we need the following patch to fix this issue:

I have dropped the original patch from my tree. Please fix the issue
and send a new patch with the fix incorporated.

Alistair

>
> From 6175c9aee103e40b5a5da587f659563de93b3d85 Mon Sep 17 00:00:00 2001
> From: Alvin Chang <alvinga@andestech.com>
> Date: Thu, 18 Apr 2024 14:52:36 +0800
> Subject: [PATCH] target/riscv: Fix GDB can not read the read-only CSR
>
> From commit 563581cb60, use riscv_csrrw() to read a read-only CSR will
> lead to exception. Fix it by calling riscv_csrr() when GDB wants to read
> a read-only CSR.
>
> Signed-off-by: Alvin Chang <alvinga@andestech.com>
> ---
>  target/riscv/csr.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 7aab267916..96accc1549 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -4625,7 +4625,11 @@ RISCVException riscv_csrrw_debug(CPURISCVState *env, 
> int csrno,
>  #if !defined(CONFIG_USER_ONLY)
>      env->debugger = true;
>  #endif
> -    ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
> +    if (!write_mask) {
> +        ret = riscv_csrr(env, csrno, ret_value);
> +    } else {
> +        ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
> +    }
>  #if !defined(CONFIG_USER_ONLY)
>      env->debugger = false;
>  #endif
> --
> 2.34.1
>
> Best regards,
> Yuming
>
> -----Original Message-----
> From: Alistair Francis <alistair23@gmail.com>
> Sent: Monday, June 3, 2024 1:39 PM
> To: Yuming Yu-Ming Chang(張育銘) <yumin686@andestech.com>
> Cc: qemu-riscv@nongnu.org; qemu-devel@nongnu.org; palmer@dabbelt.com; 
> alistair.francis@wdc.com; bin.meng@windriver.com; liwei1518@gmail.com; 
> dbarboza@ventanamicro.com; zhiwei_liu@linux.alibaba.com
> Subject: Re: [PATCH v3] target/riscv: raise an exception when CSRRS/CSRRC 
> writes a read-only CSR
>
> [EXTERNAL MAIL]
>
> On Wed, Apr 3, 2024 at 5:10 PM Yu-Ming Chang via <qemu-devel@nongnu.org> 
> wrote:
> >
> > Both CSRRS and CSRRC always read the addressed CSR and cause any read side
> > effects regardless of rs1 and rd fields. Note that if rs1 specifies a 
> > register
> > holding a zero value other than x0, the instruction will still attempt to 
> > write
> > the unmodified value back to the CSR and will cause any attendant side 
> > effects.
> >
> > So if CSRRS or CSRRC tries to write a read-only CSR with rs1 which specifies
> > a register holding a zero value, an illegal instruction exception should be
> > raised.
> >
> > Signed-off-by: Yu-Ming Chang <yumin686@andestech.com>
>
> This fails the GitLab CI tests
>
> https://gitlab.com/qemu-project/qemu/-/jobs/6953349448
>
> ERROR:../tests/plugin/insn.c:58:vcpu_init: assertion failed: (count > 0)
> timeout: the monitored command dumped core
> Aborted
> make[1]: *** [Makefile:178: run-plugin-catch-syscalls-with-libinsn.so] Error 
> 134
> make: *** [/builds/qemu-project/qemu/tests/Makefile.include:56:
> run-tcg-tests-riscv64-linux-user] Error 2
>
> #0  riscv_gdb_get_csr (cs=<optimized out>, buf=0x5555558e7f50, n=3072)
>      at ../src/target/riscv/gdbstub.c:183
> #1  0x00007ffff7fb7841 in vcpu_init (id=<optimized out>,
>      vcpu_index=<optimized out>) at ../src/tests/plugin/insn.c:57
> #2  0x000055555569ef1a in plugin_vcpu_cb__simple (cpu=0x5555558fb820,
>      ev=<optimized out>) at ../src/plugins/core.c:111
>
>
> After
>
> 182             result = riscv_csrrw_debug(env, n, &val, 0, 0);
>
> result == 2.
>
> I haven't had much luck reproducing this locally, so I don't have a
> great idea of why it isn't working. I suspect you need to ignore the
> checks for debug accesses
>
> Alistair
>
> > ---
> > Hi maintainers,
> >     Do I need to make any further improvements to this patch?
> >
> > Best regards,
> > Yuming
> >
> >  target/riscv/cpu.h       |  4 ++++
> >  target/riscv/csr.c       | 51 ++++++++++++++++++++++++++++++++++++----
> >  target/riscv/op_helper.c |  6 ++---
> >  3 files changed, 53 insertions(+), 8 deletions(-)
> >
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 3b1a02b944..99006bdb45 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -710,6 +710,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
> >  void riscv_cpu_update_mask(CPURISCVState *env);
> >  bool riscv_cpu_is_32bit(RISCVCPU *cpu);
> >
> > +RISCVException riscv_csrr(CPURISCVState *env, int csrno,
> > +                          target_ulong *ret_value);
> >  RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> >                             target_ulong *ret_value,
> >                             target_ulong new_value, target_ulong 
> > write_mask);
> > @@ -742,6 +744,8 @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState 
> > *env, int csrno,
> >                                            target_ulong new_value,
> >                                            target_ulong write_mask);
> >
> > +RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
> > +                               Int128 *ret_value);
> >  RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
> >                                  Int128 *ret_value,
> >                                  Int128 new_value, Int128 write_mask);
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 726096444f..35662e1777 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -4312,7 +4312,7 @@ static RISCVException rmw_seed(CPURISCVState *env, 
> > int csrno,
> >
> >  static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
> >                                                 int csrno,
> > -                                               bool write_mask)
> > +                                               bool write)
> >  {
> >      /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails 
> > */
> >      bool read_only = get_field(csrno, 0xC00) == 3;
> > @@ -4334,7 +4334,7 @@ static inline RISCVException 
> > riscv_csrrw_check(CPURISCVState *env,
> >      }
> >
> >      /* read / write check */
> > -    if (write_mask && read_only) {
> > +    if (write && read_only) {
> >          return RISCV_EXCP_ILLEGAL_INST;
> >      }
> >
> > @@ -4421,11 +4421,22 @@ static RISCVException 
> > riscv_csrrw_do64(CPURISCVState *env, int csrno,
> >      return RISCV_EXCP_NONE;
> >  }
> >
> > +RISCVException riscv_csrr(CPURISCVState *env, int csrno,
> > +                           target_ulong *ret_value)
> > +{
> > +    RISCVException ret = riscv_csrrw_check(env, csrno, false);
> > +    if (ret != RISCV_EXCP_NONE) {
> > +        return ret;
> > +    }
> > +
> > +    return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
> > +}
> > +
> >  RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> >                             target_ulong *ret_value,
> >                             target_ulong new_value, target_ulong write_mask)
> >  {
> > -    RISCVException ret = riscv_csrrw_check(env, csrno, write_mask);
> > +    RISCVException ret = riscv_csrrw_check(env, csrno, true);
> >      if (ret != RISCV_EXCP_NONE) {
> >          return ret;
> >      }
> > @@ -4473,13 +4484,45 @@ static RISCVException 
> > riscv_csrrw_do128(CPURISCVState *env, int csrno,
> >      return RISCV_EXCP_NONE;
> >  }
> >
> > +RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
> > +                               Int128 *ret_value)
> > +{
> > +    RISCVException ret;
> > +
> > +    ret = riscv_csrrw_check(env, csrno, false);
> > +    if (ret != RISCV_EXCP_NONE) {
> > +        return ret;
> > +    }
> > +
> > +    if (csr_ops[csrno].read128) {
> > +        return riscv_csrrw_do128(env, csrno, ret_value,
> > +                                 int128_zero(), int128_zero());
> > +    }
> > +
> > +    /*
> > +     * Fall back to 64-bit version for now, if the 128-bit alternative 
> > isn't
> > +     * at all defined.
> > +     * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
> > +     * significant), for those, this fallback is correctly handling the
> > +     * accesses
> > +     */
> > +    target_ulong old_value;
> > +    ret = riscv_csrrw_do64(env, csrno, &old_value,
> > +                           (target_ulong)0,
> > +                           (target_ulong)0);
> > +    if (ret == RISCV_EXCP_NONE && ret_value) {
> > +        *ret_value = int128_make64(old_value);
> > +    }
> > +    return ret;
> > +}
> > +
> >  RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
> >                                  Int128 *ret_value,
> >                                  Int128 new_value, Int128 write_mask)
> >  {
> >      RISCVException ret;
> >
> > -    ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask));
> > +    ret = riscv_csrrw_check(env, csrno, true);
> >      if (ret != RISCV_EXCP_NONE) {
> >          return ret;
> >      }
> > diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
> > index f414aaebdb..b95d47e9ac 100644
> > --- a/target/riscv/op_helper.c
> > +++ b/target/riscv/op_helper.c
> > @@ -51,7 +51,7 @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
> >      }
> >
> >      target_ulong val = 0;
> > -    RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0);
> > +    RISCVException ret = riscv_csrr(env, csr, &val);
> >
> >      if (ret != RISCV_EXCP_NONE) {
> >          riscv_raise_exception(env, ret, GETPC());
> > @@ -84,9 +84,7 @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
> >  target_ulong helper_csrr_i128(CPURISCVState *env, int csr)
> >  {
> >      Int128 rv = int128_zero();
> > -    RISCVException ret = riscv_csrrw_i128(env, csr, &rv,
> > -                                          int128_zero(),
> > -                                          int128_zero());
> > +    RISCVException ret = riscv_csrr_i128(env, csr, &rv);
> >
> >      if (ret != RISCV_EXCP_NONE) {
> >          riscv_raise_exception(env, ret, GETPC());
> > --
> > 2.34.1
> >
> >
> CONFIDENTIALITY NOTICE:
>
> This e-mail (and its attachments) may contain confidential and legally 
> privileged information or information protected from disclosure. If you are 
> not the intended recipient, you are hereby notified that any disclosure, 
> copying, distribution, or use of the information contained herein is strictly 
> prohibited. In this case, please immediately notify the sender by return 
> e-mail, delete the message (and any accompanying documents) and destroy all 
> printed hard copies. Thank you for your cooperation.
>
> Copyright ANDES TECHNOLOGY CORPORATION - All Rights Reserved.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]