target/riscv: smstateen check for h/s/envcfg
Accesses to henvcfg, henvcfgh and senvcfg are allowed only if the corresponding bit in mstateen0/hstateen0 is enabled. Otherwise an illegal instruction trap is generated. Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com> Reviewed-by: Weiwei Li<liweiwei@iscas.ac.cn> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-Id: <20221016124726.102129-3-mchitale@ventanamicro.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
3bee0e4010
commit
252b06f638
@ -41,6 +41,42 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
|
||||
}
|
||||
|
||||
/* Predicates */
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
|
||||
uint64_t bit)
|
||||
{
|
||||
bool virt = riscv_cpu_virt_enabled(env);
|
||||
CPUState *cs = env_cpu(env);
|
||||
RISCVCPU *cpu = RISCV_CPU(cs);
|
||||
|
||||
if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
if (!(env->mstateen[index] & bit)) {
|
||||
return RISCV_EXCP_ILLEGAL_INST;
|
||||
}
|
||||
|
||||
if (virt) {
|
||||
if (!(env->hstateen[index] & bit)) {
|
||||
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
|
||||
}
|
||||
|
||||
if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
|
||||
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
|
||||
}
|
||||
}
|
||||
|
||||
if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
|
||||
if (!(env->sstateen[index] & bit)) {
|
||||
return RISCV_EXCP_ILLEGAL_INST;
|
||||
}
|
||||
}
|
||||
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static RISCVException fs(CPURISCVState *env, int csrno)
|
||||
{
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
@ -1874,6 +1910,13 @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
|
||||
static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
|
||||
target_ulong *val)
|
||||
{
|
||||
RISCVException ret;
|
||||
|
||||
ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
|
||||
if (ret != RISCV_EXCP_NONE) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
*val = env->senvcfg;
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
@ -1882,15 +1925,27 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
|
||||
target_ulong val)
|
||||
{
|
||||
uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
|
||||
RISCVException ret;
|
||||
|
||||
ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
|
||||
if (ret != RISCV_EXCP_NONE) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
|
||||
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
|
||||
target_ulong *val)
|
||||
{
|
||||
RISCVException ret;
|
||||
|
||||
ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
|
||||
if (ret != RISCV_EXCP_NONE) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
*val = env->henvcfg;
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
@ -1899,6 +1954,12 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
|
||||
target_ulong val)
|
||||
{
|
||||
uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
|
||||
RISCVException ret;
|
||||
|
||||
ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
|
||||
if (ret != RISCV_EXCP_NONE) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (riscv_cpu_mxl(env) == MXL_RV64) {
|
||||
mask |= HENVCFG_PBMTE | HENVCFG_STCE;
|
||||
@ -1912,6 +1973,13 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
|
||||
static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
|
||||
target_ulong *val)
|
||||
{
|
||||
RISCVException ret;
|
||||
|
||||
ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
|
||||
if (ret != RISCV_EXCP_NONE) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
*val = env->henvcfg >> 32;
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
@ -1921,9 +1989,14 @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
|
||||
{
|
||||
uint64_t mask = HENVCFG_PBMTE | HENVCFG_STCE;
|
||||
uint64_t valh = (uint64_t)val << 32;
|
||||
RISCVException ret;
|
||||
|
||||
ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
|
||||
if (ret != RISCV_EXCP_NONE) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
|
||||
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
@ -1949,7 +2022,7 @@ static RISCVException write_mstateen(CPURISCVState *env, int csrno,
|
||||
static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
|
||||
target_ulong new_val)
|
||||
{
|
||||
uint64_t wr_mask = SMSTATEEN_STATEEN;
|
||||
uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
|
||||
|
||||
return write_mstateen(env, csrno, wr_mask, new_val);
|
||||
}
|
||||
@ -1984,7 +2057,7 @@ static RISCVException write_mstateenh(CPURISCVState *env, int csrno,
|
||||
static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
|
||||
target_ulong new_val)
|
||||
{
|
||||
uint64_t wr_mask = SMSTATEEN_STATEEN;
|
||||
uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
|
||||
|
||||
return write_mstateenh(env, csrno, wr_mask, new_val);
|
||||
}
|
||||
@ -2021,7 +2094,7 @@ static RISCVException write_hstateen(CPURISCVState *env, int csrno,
|
||||
static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
|
||||
target_ulong new_val)
|
||||
{
|
||||
uint64_t wr_mask = SMSTATEEN_STATEEN;
|
||||
uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
|
||||
|
||||
return write_hstateen(env, csrno, wr_mask, new_val);
|
||||
}
|
||||
@ -2060,7 +2133,7 @@ static RISCVException write_hstateenh(CPURISCVState *env, int csrno,
|
||||
static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
|
||||
target_ulong new_val)
|
||||
{
|
||||
uint64_t wr_mask = SMSTATEEN_STATEEN;
|
||||
uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
|
||||
|
||||
return write_hstateenh(env, csrno, wr_mask, new_val);
|
||||
}
|
||||
@ -2107,7 +2180,7 @@ static RISCVException write_sstateen(CPURISCVState *env, int csrno,
|
||||
static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
|
||||
target_ulong new_val)
|
||||
{
|
||||
uint64_t wr_mask = SMSTATEEN_STATEEN;
|
||||
uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
|
||||
|
||||
return write_sstateen(env, csrno, wr_mask, new_val);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user