On Wed, Jan 10, 2024 at 2:07 AM Irina Ryapolova <irina.ryapol...@syntacore.com> wrote: > > Added xATP_MODE validation for vsatp/hgatp CSRs. > The xATP register is an SXLEN-bit read/write WARL register, so > the legal value must be returned (See riscv-privileged-20211203, > SATP/VSATP/HGATP CSRs). > > Signed-off-by: Irina Ryapolova <irina.ryapol...@syntacore.com> > Reviewed-by: Daniel Henrique Barboza <dbarb...@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > target/riscv/csr.c | 52 ++++++++++++++++++++++++++-------------------- > 1 file changed, 29 insertions(+), 23 deletions(-) > > diff --git a/target/riscv/csr.c b/target/riscv/csr.c > index 735fb27be7..6d7a3dd9aa 100644 > --- a/target/riscv/csr.c > +++ b/target/riscv/csr.c > @@ -1282,6 +1282,32 @@ static bool validate_vm(CPURISCVState *env, > target_ulong vm) > return get_field(mode_supported, (1 << vm)); > } > > +static target_ulong legalize_xatp(CPURISCVState *env, target_ulong old_xatp, > + target_ulong val) > +{ > + target_ulong mask; > + bool vm; > + if (riscv_cpu_mxl(env) == MXL_RV32) { > + vm = validate_vm(env, get_field(val, SATP32_MODE)); > + mask = (val ^ old_xatp) & (SATP32_MODE | SATP32_ASID | SATP32_PPN); > + } else { > + vm = validate_vm(env, get_field(val, SATP64_MODE)); > + mask = (val ^ old_xatp) & (SATP64_MODE | SATP64_ASID | SATP64_PPN); > + } > + > + if (vm && mask) { > + /* > + * The ISA defines SATP.MODE=Bare as "no translation", but we still > + * pass these through QEMU's TLB emulation as it improves > + * performance. Flushing the TLB on SATP writes with paging > + * enabled avoids leaking those invalid cached mappings. > + */ > + tlb_flush(env_cpu(env)); > + return val; > + } > + return old_xatp; > +} > + > static target_ulong legalize_mpp(CPURISCVState *env, target_ulong old_mpp, > target_ulong val) > { > @@ -2997,31 +3023,11 @@ static RISCVException read_satp(CPURISCVState *env, > int csrno, > static RISCVException write_satp(CPURISCVState *env, int csrno, > target_ulong val) > { > - target_ulong mask; > - bool vm; > - > if (!riscv_cpu_cfg(env)->mmu) { > return RISCV_EXCP_NONE; > } > > - if (riscv_cpu_mxl(env) == MXL_RV32) { > - vm = validate_vm(env, get_field(val, SATP32_MODE)); > - mask = (val ^ env->satp) & (SATP32_MODE | SATP32_ASID | SATP32_PPN); > - } else { > - vm = validate_vm(env, get_field(val, SATP64_MODE)); > - mask = (val ^ env->satp) & (SATP64_MODE | SATP64_ASID | SATP64_PPN); > - } > - > - if (vm && mask) { > - /* > - * The ISA defines SATP.MODE=Bare as "no translation", but we still > - * pass these through QEMU's TLB emulation as it improves > - * performance. Flushing the TLB on SATP writes with paging > - * enabled avoids leaking those invalid cached mappings. > - */ > - tlb_flush(env_cpu(env)); > - env->satp = val; > - } > + env->satp = legalize_xatp(env, env->satp, val); > return RISCV_EXCP_NONE; > } > > @@ -3506,7 +3512,7 @@ static RISCVException read_hgatp(CPURISCVState *env, > int csrno, > static RISCVException write_hgatp(CPURISCVState *env, int csrno, > target_ulong val) > { > - env->hgatp = val; > + env->hgatp = legalize_xatp(env, env->hgatp, val); > return RISCV_EXCP_NONE; > } > > @@ -3772,7 +3778,7 @@ static RISCVException read_vsatp(CPURISCVState *env, > int csrno, > static RISCVException write_vsatp(CPURISCVState *env, int csrno, > target_ulong val) > { > - env->vsatp = val; > + env->vsatp = legalize_xatp(env, env->vsatp, val); > return RISCV_EXCP_NONE; > } > > -- > 2.25.1 > >