target/riscv: UPDATE xATP write CSR
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.ryapolova@syntacore.com> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20240109145923.37893-2-irina.ryapolova@syntacore.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
57020a464c
commit
1349f96952
@ -1299,6 +1299,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)
|
||||
{
|
||||
@ -3021,31 +3047,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;
|
||||
}
|
||||
|
||||
@ -3532,7 +3538,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;
|
||||
}
|
||||
|
||||
@ -3809,7 +3815,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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user