Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
target/riscv: Flush TLB only when pmpcfg/pmpaddr really changes
TLB needn't be flushed when pmpcfg/pmpaddr don't changes.

Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Message-Id: <20230517091519.34439-11-liweiwei@iscas.ac.cn>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
  • Loading branch information
Weiwei Li authored and alistair23 committed Jun 13, 2023
1 parent 7c4c31f commit e924074
Showing 1 changed file with 18 additions and 10 deletions.
28 changes: 18 additions & 10 deletions target/riscv/pmp.c
Expand Up @@ -26,7 +26,7 @@
#include "trace.h"
#include "exec/exec-all.h"

static void pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
static bool pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
uint8_t val);
static uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t addr_index);
static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index);
Expand Down Expand Up @@ -83,7 +83,7 @@ static inline uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t pmp_index)
* Accessor to set the cfg reg for a specific PMP/HART
* Bounds checks and relevant lock bit.
*/
static void pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
static bool pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
{
if (pmp_index < MAX_RISCV_PMPS) {
bool locked = true;
Expand Down Expand Up @@ -119,14 +119,17 @@ static void pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)

if (locked) {
qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - locked\n");
} else {
} else if (env->pmp_state.pmp[pmp_index].cfg_reg != val) {
env->pmp_state.pmp[pmp_index].cfg_reg = val;
pmp_update_rule(env, pmp_index);
return true;
}
} else {
qemu_log_mask(LOG_GUEST_ERROR,
"ignoring pmpcfg write - out of bounds\n");
}

return false;
}

static void pmp_decode_napot(target_ulong a, target_ulong *sa,
Expand Down Expand Up @@ -467,16 +470,19 @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
int i;
uint8_t cfg_val;
int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
bool modified = false;

trace_pmpcfg_csr_write(env->mhartid, reg_index, val);

for (i = 0; i < pmpcfg_nums; i++) {
cfg_val = (val >> 8 * i) & 0xff;
pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
modified |= pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
}

/* If PMP permission of any addr has been changed, flush TLB pages. */
tlb_flush(env_cpu(env));
if (modified) {
tlb_flush(env_cpu(env));
}
}


Expand Down Expand Up @@ -526,12 +532,14 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
}

if (!pmp_is_locked(env, addr_index)) {
env->pmp_state.pmp[addr_index].addr_reg = val;
pmp_update_rule_addr(env, addr_index);
if (is_next_cfg_tor) {
pmp_update_rule_addr(env, addr_index + 1);
if (env->pmp_state.pmp[addr_index].addr_reg != val) {
env->pmp_state.pmp[addr_index].addr_reg = val;
pmp_update_rule_addr(env, addr_index);
if (is_next_cfg_tor) {
pmp_update_rule_addr(env, addr_index + 1);
}
tlb_flush(env_cpu(env));
}
tlb_flush(env_cpu(env));
} else {
qemu_log_mask(LOG_GUEST_ERROR,
"ignoring pmpaddr write - locked\n");
Expand Down

0 comments on commit e924074

Please sign in to comment.