* [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups
@ 2023-04-12 11:43 Richard Henderson
2023-04-12 11:43 ` [PATCH v7 01/25] target/riscv: Extract virt enabled state from tb flags Richard Henderson
` (25 more replies)
0 siblings, 26 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel; +Cc: alistair23, qemu-riscv
v6: 20230325105429.1142530-1-richard.henderson@linaro.org
Changes for v7:
* Rebase on Alistair's riscv-to-apply.next.
* Replace priv_level() with ctx->priv in trans_xthead.c.inc (Zhiwei).
r~
Fei Wu (2):
target/riscv: Separate priv from mmu_idx
target/riscv: Reduce overhead of MSTATUS_SUM change
LIU Zhiwei (4):
target/riscv: Extract virt enabled state from tb flags
target/riscv: Add a general status enum for extensions
target/riscv: Encode the FS and VS on a normal way for tb flags
target/riscv: Add a tb flags field for vstart
Richard Henderson (19):
target/riscv: Remove mstatus_hs_{fs, vs} from tb_flags
accel/tcg: Add cpu_ld*_code_mmu
target/riscv: Use cpu_ld*_code_mmu for HLVX
target/riscv: Handle HLV, HSV via helpers
target/riscv: Rename MMU_HYP_ACCESS_BIT to MMU_2STAGE_BIT
target/riscv: Introduce mmuidx_sum
target/riscv: Introduce mmuidx_priv
target/riscv: Introduce mmuidx_2stage
target/riscv: Move hstatus.spvp check to check_access_hlsv
target/riscv: Set MMU_2STAGE_BIT in riscv_cpu_mmu_index
target/riscv: Check SUM in the correct register
target/riscv: Hoist second stage mode change to callers
target/riscv: Hoist pbmte and hade out of the level loop
target/riscv: Move leaf pte processing out of level loop
target/riscv: Suppress pte update with is_debug
target/riscv: Don't modify SUM with is_debug
target/riscv: Merge checks for reserved pte flags
target/riscv: Reorg access check in get_physical_address
target/riscv: Reorg sum check in get_physical_address
include/exec/cpu_ldst.h | 9 +
target/riscv/cpu.h | 47 +-
target/riscv/cpu_bits.h | 12 +-
target/riscv/helper.h | 12 +-
target/riscv/internals.h | 35 ++
accel/tcg/cputlb.c | 48 +++
accel/tcg/user-exec.c | 58 +++
target/riscv/cpu.c | 2 +-
target/riscv/cpu_helper.c | 403 +++++++++---------
target/riscv/csr.c | 21 +-
target/riscv/op_helper.c | 113 ++++-
target/riscv/translate.c | 70 +--
.../riscv/insn_trans/trans_privileged.c.inc | 2 +-
target/riscv/insn_trans/trans_rvf.c.inc | 2 +-
target/riscv/insn_trans/trans_rvh.c.inc | 137 +++---
target/riscv/insn_trans/trans_rvv.c.inc | 22 +-
target/riscv/insn_trans/trans_xthead.c.inc | 14 +-
17 files changed, 591 insertions(+), 416 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v7 01/25] target/riscv: Extract virt enabled state from tb flags
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 02/25] target/riscv: Add a general status enum for extensions Richard Henderson
` (24 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, LIU Zhiwei, Weiwei Li, Alistair Francis,
Daniel Henrique Barboza
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Virt enabled state is not a constant, so we should put it into tb flags.
Thus we can use it like a constant condition at translation phase.
Reported-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Message-Id: <20230324143031.1093-2-zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-2-richard.henderson@linaro.org>
---
target/riscv/cpu.h | 2 ++
target/riscv/cpu_helper.c | 1 +
target/riscv/translate.c | 10 +---------
3 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 86e08d10da..aa53d0e256 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -648,6 +648,8 @@ FIELD(TB_FLAGS, VTA, 24, 1)
FIELD(TB_FLAGS, VMA, 25, 1)
/* Native debug itrigger */
FIELD(TB_FLAGS, ITRIGGER, 26, 1)
+/* Virtual mode enabled */
+FIELD(TB_FLAGS, VIRT_ENABLED, 27, 1)
#ifdef TARGET_RISCV32
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 433ea529b0..1d90977d46 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -104,6 +104,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS,
get_field(env->mstatus_hs, MSTATUS_VS));
+ flags = FIELD_DP32(flags, TB_FLAGS, VIRT_ENABLED, env->virt_enabled);
}
if (cpu->cfg.debug && !icount_enabled()) {
flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index d0094922b6..ebd00529ff 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1171,15 +1171,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
ctx->mstatus_fs = tb_flags & TB_FLAGS_MSTATUS_FS;
ctx->mstatus_vs = tb_flags & TB_FLAGS_MSTATUS_VS;
ctx->priv_ver = env->priv_ver;
-#if !defined(CONFIG_USER_ONLY)
- if (riscv_has_ext(env, RVH)) {
- ctx->virt_enabled = env->virt_enabled;
- } else {
- ctx->virt_enabled = false;
- }
-#else
- ctx->virt_enabled = false;
-#endif
+ ctx->virt_enabled = FIELD_EX32(tb_flags, TB_FLAGS, VIRT_ENABLED);
ctx->misa_ext = env->misa_ext;
ctx->frm = -1; /* unknown rounding mode */
ctx->cfg_ptr = &(cpu->cfg);
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 02/25] target/riscv: Add a general status enum for extensions
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
2023-04-12 11:43 ` [PATCH v7 01/25] target/riscv: Extract virt enabled state from tb flags Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 03/25] target/riscv: Encode the FS and VS on a normal way for tb flags Richard Henderson
` (23 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, LIU Zhiwei, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
The pointer masking is the only extension that directly use status.
The vector or float extension uses the status in an indirect way.
Replace the pointer masking extension special status fields with
the general status.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Message-Id: <20230324143031.1093-3-zhiwei_liu@linux.alibaba.com>
[rth: Add a typedef for the enum]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-3-richard.henderson@linaro.org>
---
target/riscv/cpu.h | 8 ++++++++
target/riscv/cpu_bits.h | 12 ++++--------
target/riscv/cpu.c | 2 +-
target/riscv/csr.c | 14 +++++++-------
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index aa53d0e256..ba11279716 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -97,6 +97,14 @@ enum {
TRANSLATE_G_STAGE_FAIL
};
+/* Extension context status */
+typedef enum {
+ EXT_STATUS_DISABLED = 0,
+ EXT_STATUS_INITIAL,
+ EXT_STATUS_CLEAN,
+ EXT_STATUS_DIRTY,
+} RISCVExtStatus;
+
#define MMU_USER_IDX 3
#define MAX_RISCV_PMPS (16)
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index a16bfaf43f..fb63b8e125 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -9,6 +9,9 @@
(((uint64_t)(val) * ((mask) & ~((mask) << 1))) & \
(uint64_t)(mask)))
+/* Extension context status mask */
+#define EXT_STATUS_MASK 0x3ULL
+
/* Floating point round mode */
#define FSR_RD_SHIFT 5
#define FSR_RD (0x7 << FSR_RD_SHIFT)
@@ -735,13 +738,6 @@ typedef enum RISCVException {
#define PM_ENABLE 0x00000001ULL
#define PM_CURRENT 0x00000002ULL
#define PM_INSN 0x00000004ULL
-#define PM_XS_MASK 0x00000003ULL
-
-/* PointerMasking XS bits values */
-#define PM_EXT_DISABLE 0x00000000ULL
-#define PM_EXT_INITIAL 0x00000001ULL
-#define PM_EXT_CLEAN 0x00000002ULL
-#define PM_EXT_DIRTY 0x00000003ULL
/* Execution enviornment configuration bits */
#define MENVCFG_FIOM BIT(0)
@@ -781,7 +777,7 @@ typedef enum RISCVException {
#define S_OFFSET 5ULL
#define M_OFFSET 8ULL
-#define PM_XS_BITS (PM_XS_MASK << XS_OFFSET)
+#define PM_XS_BITS (EXT_STATUS_MASK << XS_OFFSET)
#define U_PM_ENABLE (PM_ENABLE << U_OFFSET)
#define U_PM_CURRENT (PM_CURRENT << U_OFFSET)
#define U_PM_INSN (PM_INSN << U_OFFSET)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index fab38859ec..32c04214a1 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -759,7 +759,7 @@ static void riscv_cpu_reset_hold(Object *obj)
i++;
}
/* mmte is supposed to have pm.current hardwired to 1 */
- env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
+ env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT);
#endif
env->xl = riscv_cpu_mxl(env);
riscv_cpu_update_mask(env);
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index f4d2dcfdc8..4268828dc4 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3534,7 +3534,7 @@ static RISCVException write_mmte(CPURISCVState *env, int csrno,
/* hardwiring pm.instruction bit to 0, since it's not supported yet */
wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
- env->mmte = wpri_val | PM_EXT_DIRTY;
+ env->mmte = wpri_val | EXT_STATUS_DIRTY;
riscv_cpu_update_mask(env);
/* Set XS and SD bits, since PM CSRs are dirty */
@@ -3614,7 +3614,7 @@ static RISCVException write_mpmmask(CPURISCVState *env, int csrno,
if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
env->cur_pmmask = val;
}
- env->mmte |= PM_EXT_DIRTY;
+ env->mmte |= EXT_STATUS_DIRTY;
/* Set XS and SD bits, since PM CSRs are dirty */
mstatus = env->mstatus | MSTATUS_XS;
@@ -3642,7 +3642,7 @@ static RISCVException write_spmmask(CPURISCVState *env, int csrno,
if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
env->cur_pmmask = val;
}
- env->mmte |= PM_EXT_DIRTY;
+ env->mmte |= EXT_STATUS_DIRTY;
/* Set XS and SD bits, since PM CSRs are dirty */
mstatus = env->mstatus | MSTATUS_XS;
@@ -3670,7 +3670,7 @@ static RISCVException write_upmmask(CPURISCVState *env, int csrno,
if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
env->cur_pmmask = val;
}
- env->mmte |= PM_EXT_DIRTY;
+ env->mmte |= EXT_STATUS_DIRTY;
/* Set XS and SD bits, since PM CSRs are dirty */
mstatus = env->mstatus | MSTATUS_XS;
@@ -3694,7 +3694,7 @@ static RISCVException write_mpmbase(CPURISCVState *env, int csrno,
if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
env->cur_pmbase = val;
}
- env->mmte |= PM_EXT_DIRTY;
+ env->mmte |= EXT_STATUS_DIRTY;
/* Set XS and SD bits, since PM CSRs are dirty */
mstatus = env->mstatus | MSTATUS_XS;
@@ -3722,7 +3722,7 @@ static RISCVException write_spmbase(CPURISCVState *env, int csrno,
if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
env->cur_pmbase = val;
}
- env->mmte |= PM_EXT_DIRTY;
+ env->mmte |= EXT_STATUS_DIRTY;
/* Set XS and SD bits, since PM CSRs are dirty */
mstatus = env->mstatus | MSTATUS_XS;
@@ -3750,7 +3750,7 @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
env->cur_pmbase = val;
}
- env->mmte |= PM_EXT_DIRTY;
+ env->mmte |= EXT_STATUS_DIRTY;
/* Set XS and SD bits, since PM CSRs are dirty */
mstatus = env->mstatus | MSTATUS_XS;
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 03/25] target/riscv: Encode the FS and VS on a normal way for tb flags
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
2023-04-12 11:43 ` [PATCH v7 01/25] target/riscv: Extract virt enabled state from tb flags Richard Henderson
2023-04-12 11:43 ` [PATCH v7 02/25] target/riscv: Add a general status enum for extensions Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 04/25] target/riscv: Remove mstatus_hs_{fs, vs} from tb_flags Richard Henderson
` (22 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, LIU Zhiwei, Weiwei Li, Alistair Francis,
Daniel Henrique Barboza
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reuse the MSTATUS_FS and MSTATUS_VS for the tb flags positions is not a
normal way.
It will make it hard to change the tb flags layout. And even worse, if we
want to keep tb flags for a same extension togather without a hole.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Message-Id: <20230324143031.1093-4-zhiwei_liu@linux.alibaba.com>
[rth: Adjust trans_rvf.c.inc as well; use the typedef]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-4-richard.henderson@linaro.org>
---
target/riscv/cpu.h | 15 ++++++------
target/riscv/cpu_helper.c | 11 +++++----
target/riscv/translate.c | 32 +++++++++++--------------
target/riscv/insn_trans/trans_rvf.c.inc | 2 +-
target/riscv/insn_trans/trans_rvv.c.inc | 8 +++----
5 files changed, 32 insertions(+), 36 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index ba11279716..51d39687fe 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -631,18 +631,17 @@ void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
#define TB_FLAGS_PRIV_MMU_MASK 3
#define TB_FLAGS_PRIV_HYP_ACCESS_MASK (1 << 2)
-#define TB_FLAGS_MSTATUS_FS MSTATUS_FS
-#define TB_FLAGS_MSTATUS_VS MSTATUS_VS
#include "exec/cpu-all.h"
FIELD(TB_FLAGS, MEM_IDX, 0, 3)
-FIELD(TB_FLAGS, LMUL, 3, 3)
-FIELD(TB_FLAGS, SEW, 6, 3)
-/* Skip MSTATUS_VS (0x600) bits */
-FIELD(TB_FLAGS, VL_EQ_VLMAX, 11, 1)
-FIELD(TB_FLAGS, VILL, 12, 1)
-/* Skip MSTATUS_FS (0x6000) bits */
+FIELD(TB_FLAGS, FS, 3, 2)
+/* Vector flags */
+FIELD(TB_FLAGS, VS, 5, 2)
+FIELD(TB_FLAGS, LMUL, 7, 3)
+FIELD(TB_FLAGS, SEW, 10, 3)
+FIELD(TB_FLAGS, VL_EQ_VLMAX, 13, 1)
+FIELD(TB_FLAGS, VILL, 14, 1)
/* Is a Hypervisor instruction load/store allowed? */
FIELD(TB_FLAGS, HLSX, 15, 1)
FIELD(TB_FLAGS, MSTATUS_HS_FS, 16, 2)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 1d90977d46..8412ef26ee 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -79,16 +79,17 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
}
#ifdef CONFIG_USER_ONLY
- flags |= TB_FLAGS_MSTATUS_FS;
- flags |= TB_FLAGS_MSTATUS_VS;
+ flags = FIELD_DP32(flags, TB_FLAGS, FS, EXT_STATUS_DIRTY);
+ flags = FIELD_DP32(flags, TB_FLAGS, VS, EXT_STATUS_DIRTY);
#else
flags |= cpu_mmu_index(env, 0);
if (riscv_cpu_fp_enabled(env)) {
- flags |= env->mstatus & MSTATUS_FS;
+ flags = FIELD_DP32(flags, TB_FLAGS, FS,
+ get_field(env->mstatus, MSTATUS_FS));
}
-
if (riscv_cpu_vector_enabled(env)) {
- flags |= env->mstatus & MSTATUS_VS;
+ flags = FIELD_DP32(flags, TB_FLAGS, VS,
+ get_field(env->mstatus, MSTATUS_VS));
}
if (riscv_has_ext(env, RVH)) {
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index ebd00529ff..411e771e6f 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -64,10 +64,10 @@ typedef struct DisasContext {
RISCVMXL xl;
uint32_t misa_ext;
uint32_t opcode;
- uint32_t mstatus_fs;
- uint32_t mstatus_vs;
- uint32_t mstatus_hs_fs;
- uint32_t mstatus_hs_vs;
+ RISCVExtStatus mstatus_fs;
+ RISCVExtStatus mstatus_vs;
+ RISCVExtStatus mstatus_hs_fs;
+ RISCVExtStatus mstatus_hs_vs;
uint32_t mem_idx;
/*
* Remember the rounding mode encoded in the previous fp instruction,
@@ -601,8 +601,6 @@ static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs)
#ifndef CONFIG_USER_ONLY
/*
- * The states of mstatus_fs are:
- * 0 = disabled, 1 = initial, 2 = clean, 3 = dirty
* We will have already diagnosed disabled state,
* and need to turn initial/clean into dirty.
*/
@@ -614,9 +612,9 @@ static void mark_fs_dirty(DisasContext *ctx)
return;
}
- if (ctx->mstatus_fs != MSTATUS_FS) {
+ if (ctx->mstatus_fs != EXT_STATUS_DIRTY) {
/* Remember the state change for the rest of the TB. */
- ctx->mstatus_fs = MSTATUS_FS;
+ ctx->mstatus_fs = EXT_STATUS_DIRTY;
tmp = tcg_temp_new();
tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
@@ -624,9 +622,9 @@ static void mark_fs_dirty(DisasContext *ctx)
tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
}
- if (ctx->virt_enabled && ctx->mstatus_hs_fs != MSTATUS_FS) {
+ if (ctx->virt_enabled && ctx->mstatus_hs_fs != EXT_STATUS_DIRTY) {
/* Remember the stage change for the rest of the TB. */
- ctx->mstatus_hs_fs = MSTATUS_FS;
+ ctx->mstatus_hs_fs = EXT_STATUS_DIRTY;
tmp = tcg_temp_new();
tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
@@ -640,8 +638,6 @@ static inline void mark_fs_dirty(DisasContext *ctx) { }
#ifndef CONFIG_USER_ONLY
/*
- * The states of mstatus_vs are:
- * 0 = disabled, 1 = initial, 2 = clean, 3 = dirty
* We will have already diagnosed disabled state,
* and need to turn initial/clean into dirty.
*/
@@ -649,9 +645,9 @@ static void mark_vs_dirty(DisasContext *ctx)
{
TCGv tmp;
- if (ctx->mstatus_vs != MSTATUS_VS) {
+ if (ctx->mstatus_vs != EXT_STATUS_DIRTY) {
/* Remember the state change for the rest of the TB. */
- ctx->mstatus_vs = MSTATUS_VS;
+ ctx->mstatus_vs = EXT_STATUS_DIRTY;
tmp = tcg_temp_new();
tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
@@ -659,9 +655,9 @@ static void mark_vs_dirty(DisasContext *ctx)
tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
}
- if (ctx->virt_enabled && ctx->mstatus_hs_vs != MSTATUS_VS) {
+ if (ctx->virt_enabled && ctx->mstatus_hs_vs != EXT_STATUS_DIRTY) {
/* Remember the stage change for the rest of the TB. */
- ctx->mstatus_hs_vs = MSTATUS_VS;
+ ctx->mstatus_hs_vs = EXT_STATUS_DIRTY;
tmp = tcg_temp_new();
tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
@@ -1168,8 +1164,8 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
ctx->pc_succ_insn = ctx->base.pc_first;
ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
- ctx->mstatus_fs = tb_flags & TB_FLAGS_MSTATUS_FS;
- ctx->mstatus_vs = tb_flags & TB_FLAGS_MSTATUS_VS;
+ ctx->mstatus_fs = FIELD_EX32(tb_flags, TB_FLAGS, FS);
+ ctx->mstatus_vs = FIELD_EX32(tb_flags, TB_FLAGS, VS);
ctx->priv_ver = env->priv_ver;
ctx->virt_enabled = FIELD_EX32(tb_flags, TB_FLAGS, VIRT_ENABLED);
ctx->misa_ext = env->misa_ext;
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
index 9e9fa2087a..b2de4fcf3f 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -19,7 +19,7 @@
*/
#define REQUIRE_FPU do {\
- if (ctx->mstatus_fs == 0) \
+ if (ctx->mstatus_fs == EXT_STATUS_DISABLED) \
if (!ctx->cfg_ptr->ext_zfinx) \
return false; \
} while (0)
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index ca3c4c1a3d..ecbdf1b3d7 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -29,12 +29,12 @@ static inline bool is_overlapped(const int8_t astart, int8_t asize,
static bool require_rvv(DisasContext *s)
{
- return s->mstatus_vs != 0;
+ return s->mstatus_vs != EXT_STATUS_DISABLED;
}
static bool require_rvf(DisasContext *s)
{
- if (s->mstatus_fs == 0) {
+ if (s->mstatus_fs == EXT_STATUS_DISABLED) {
return false;
}
@@ -52,7 +52,7 @@ static bool require_rvf(DisasContext *s)
static bool require_scale_rvf(DisasContext *s)
{
- if (s->mstatus_fs == 0) {
+ if (s->mstatus_fs == EXT_STATUS_DISABLED) {
return false;
}
@@ -70,7 +70,7 @@ static bool require_scale_rvf(DisasContext *s)
static bool require_scale_rvfmin(DisasContext *s)
{
- if (s->mstatus_fs == 0) {
+ if (s->mstatus_fs == EXT_STATUS_DISABLED) {
return false;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 04/25] target/riscv: Remove mstatus_hs_{fs, vs} from tb_flags
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (2 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 03/25] target/riscv: Encode the FS and VS on a normal way for tb flags Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 05/25] target/riscv: Add a tb flags field for vstart Richard Henderson
` (21 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, LIU Zhiwei, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
Merge with mstatus_{fs,vs}. We might perform a redundant
assignment to one or the other field, but it's a trivial
and saves 4 bits from TB_FLAGS.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-5-richard.henderson@linaro.org>
---
target/riscv/cpu.h | 16 +++++++---------
target/riscv/cpu_helper.c | 33 ++++++++++++++++-----------------
target/riscv/translate.c | 32 ++++++++++----------------------
3 files changed, 33 insertions(+), 48 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 51d39687fe..ab64d5f92d 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -644,19 +644,17 @@ FIELD(TB_FLAGS, VL_EQ_VLMAX, 13, 1)
FIELD(TB_FLAGS, VILL, 14, 1)
/* Is a Hypervisor instruction load/store allowed? */
FIELD(TB_FLAGS, HLSX, 15, 1)
-FIELD(TB_FLAGS, MSTATUS_HS_FS, 16, 2)
-FIELD(TB_FLAGS, MSTATUS_HS_VS, 18, 2)
/* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
-FIELD(TB_FLAGS, XL, 20, 2)
+FIELD(TB_FLAGS, XL, 16, 2)
/* If PointerMasking should be applied */
-FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
-FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
-FIELD(TB_FLAGS, VTA, 24, 1)
-FIELD(TB_FLAGS, VMA, 25, 1)
+FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1)
+FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1)
+FIELD(TB_FLAGS, VTA, 20, 1)
+FIELD(TB_FLAGS, VMA, 21, 1)
/* Native debug itrigger */
-FIELD(TB_FLAGS, ITRIGGER, 26, 1)
+FIELD(TB_FLAGS, ITRIGGER, 22, 1)
/* Virtual mode enabled */
-FIELD(TB_FLAGS, VIRT_ENABLED, 27, 1)
+FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1)
#ifdef TARGET_RISCV32
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 8412ef26ee..e3e620137b 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -45,7 +45,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
{
CPUState *cs = env_cpu(env);
RISCVCPU *cpu = RISCV_CPU(cs);
-
+ RISCVExtStatus fs, vs;
uint32_t flags = 0;
*pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
@@ -79,18 +79,12 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
}
#ifdef CONFIG_USER_ONLY
- flags = FIELD_DP32(flags, TB_FLAGS, FS, EXT_STATUS_DIRTY);
- flags = FIELD_DP32(flags, TB_FLAGS, VS, EXT_STATUS_DIRTY);
+ fs = EXT_STATUS_DIRTY;
+ vs = EXT_STATUS_DIRTY;
#else
flags |= cpu_mmu_index(env, 0);
- if (riscv_cpu_fp_enabled(env)) {
- flags = FIELD_DP32(flags, TB_FLAGS, FS,
- get_field(env->mstatus, MSTATUS_FS));
- }
- if (riscv_cpu_vector_enabled(env)) {
- flags = FIELD_DP32(flags, TB_FLAGS, VS,
- get_field(env->mstatus, MSTATUS_VS));
- }
+ fs = get_field(env->mstatus, MSTATUS_FS);
+ vs = get_field(env->mstatus, MSTATUS_VS);
if (riscv_has_ext(env, RVH)) {
if (env->priv == PRV_M ||
@@ -100,18 +94,23 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
flags = FIELD_DP32(flags, TB_FLAGS, HLSX, 1);
}
- flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_FS,
- get_field(env->mstatus_hs, MSTATUS_FS));
-
- flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS,
- get_field(env->mstatus_hs, MSTATUS_VS));
- flags = FIELD_DP32(flags, TB_FLAGS, VIRT_ENABLED, env->virt_enabled);
+ if (env->virt_enabled) {
+ flags = FIELD_DP32(flags, TB_FLAGS, VIRT_ENABLED, 1);
+ /*
+ * Merge DISABLED and !DIRTY states using MIN.
+ * We will set both fields when dirtying.
+ */
+ fs = MIN(fs, get_field(env->mstatus_hs, MSTATUS_FS));
+ vs = MIN(vs, get_field(env->mstatus_hs, MSTATUS_VS));
+ }
}
if (cpu->cfg.debug && !icount_enabled()) {
flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
}
#endif
+ flags = FIELD_DP32(flags, TB_FLAGS, FS, fs);
+ flags = FIELD_DP32(flags, TB_FLAGS, VS, vs);
flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
if (env->cur_pmmask < (env->xl == MXL_RV32 ? UINT32_MAX : UINT64_MAX)) {
flags = FIELD_DP32(flags, TB_FLAGS, PM_MASK_ENABLED, 1);
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 411e771e6f..3092c942ab 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -66,8 +66,6 @@ typedef struct DisasContext {
uint32_t opcode;
RISCVExtStatus mstatus_fs;
RISCVExtStatus mstatus_vs;
- RISCVExtStatus mstatus_hs_fs;
- RISCVExtStatus mstatus_hs_vs;
uint32_t mem_idx;
/*
* Remember the rounding mode encoded in the previous fp instruction,
@@ -620,16 +618,12 @@ static void mark_fs_dirty(DisasContext *ctx)
tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS);
tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
- }
- if (ctx->virt_enabled && ctx->mstatus_hs_fs != EXT_STATUS_DIRTY) {
- /* Remember the stage change for the rest of the TB. */
- ctx->mstatus_hs_fs = EXT_STATUS_DIRTY;
-
- tmp = tcg_temp_new();
- tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
- tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS);
- tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
+ if (ctx->virt_enabled) {
+ tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
+ tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS);
+ tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
+ }
}
}
#else
@@ -653,16 +647,12 @@ static void mark_vs_dirty(DisasContext *ctx)
tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS);
tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
- }
- if (ctx->virt_enabled && ctx->mstatus_hs_vs != EXT_STATUS_DIRTY) {
- /* Remember the stage change for the rest of the TB. */
- ctx->mstatus_hs_vs = EXT_STATUS_DIRTY;
-
- tmp = tcg_temp_new();
- tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
- tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS);
- tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
+ if (ctx->virt_enabled) {
+ tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
+ tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS);
+ tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
+ }
}
}
#else
@@ -1171,8 +1161,6 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
ctx->misa_ext = env->misa_ext;
ctx->frm = -1; /* unknown rounding mode */
ctx->cfg_ptr = &(cpu->cfg);
- ctx->mstatus_hs_fs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_FS);
- ctx->mstatus_hs_vs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_VS);
ctx->hlsx = FIELD_EX32(tb_flags, TB_FLAGS, HLSX);
ctx->vill = FIELD_EX32(tb_flags, TB_FLAGS, VILL);
ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW);
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 05/25] target/riscv: Add a tb flags field for vstart
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (3 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 04/25] target/riscv: Remove mstatus_hs_{fs, vs} from tb_flags Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 06/25] target/riscv: Separate priv from mmu_idx Richard Henderson
` (20 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, LIU Zhiwei, Weiwei Li, Alistair Francis,
Daniel Henrique Barboza
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Once we mistook the vstart directly from the env->vstart. As env->vstart is not
a constant, we should record it in the tb flags if we want to use
it in translation.
Reported-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Message-Id: <20230324143031.1093-5-zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-6-richard.henderson@linaro.org>
---
target/riscv/cpu.h | 1 +
target/riscv/cpu_helper.c | 1 +
target/riscv/translate.c | 4 ++--
target/riscv/insn_trans/trans_rvv.c.inc | 14 +++++++-------
4 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index ab64d5f92d..786ad047ee 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -655,6 +655,7 @@ FIELD(TB_FLAGS, VMA, 21, 1)
FIELD(TB_FLAGS, ITRIGGER, 22, 1)
/* Virtual mode enabled */
FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1)
+FIELD(TB_FLAGS, VSTART_EQ_ZERO, 24, 1)
#ifdef TARGET_RISCV32
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index e3e620137b..7579e83c3d 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -74,6 +74,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
FIELD_EX64(env->vtype, VTYPE, VTA));
flags = FIELD_DP32(flags, TB_FLAGS, VMA,
FIELD_EX64(env->vtype, VTYPE, VMA));
+ flags = FIELD_DP32(flags, TB_FLAGS, VSTART_EQ_ZERO, env->vstart == 0);
} else {
flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 3092c942ab..3ab8a9999e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -99,7 +99,7 @@ typedef struct DisasContext {
uint8_t vta;
uint8_t vma;
bool cfg_vta_all_1s;
- target_ulong vstart;
+ bool vstart_eq_zero;
bool vl_eq_vlmax;
CPUState *cs;
TCGv zero;
@@ -1168,7 +1168,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
ctx->vta = FIELD_EX32(tb_flags, TB_FLAGS, VTA) && cpu->cfg.rvv_ta_all_1s;
ctx->vma = FIELD_EX32(tb_flags, TB_FLAGS, VMA) && cpu->cfg.rvv_ma_all_1s;
ctx->cfg_vta_all_1s = cpu->cfg.rvv_ta_all_1s;
- ctx->vstart = env->vstart;
+ ctx->vstart_eq_zero = FIELD_EX32(tb_flags, TB_FLAGS, VSTART_EQ_ZERO);
ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
ctx->misa_mxl_max = env->misa_mxl_max;
ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index ecbdf1b3d7..6c07eebc52 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -547,7 +547,7 @@ static bool vext_check_sds(DisasContext *s, int vd, int vs1, int vs2, int vm)
*/
static bool vext_check_reduction(DisasContext *s, int vs2)
{
- return require_align(vs2, s->lmul) && (s->vstart == 0);
+ return require_align(vs2, s->lmul) && s->vstart_eq_zero;
}
/*
@@ -3083,7 +3083,7 @@ static bool trans_vcpop_m(DisasContext *s, arg_rmr *a)
{
if (require_rvv(s) &&
vext_check_isa_ill(s) &&
- s->vstart == 0) {
+ s->vstart_eq_zero) {
TCGv_ptr src2, mask;
TCGv dst;
TCGv_i32 desc;
@@ -3112,7 +3112,7 @@ static bool trans_vfirst_m(DisasContext *s, arg_rmr *a)
{
if (require_rvv(s) &&
vext_check_isa_ill(s) &&
- s->vstart == 0) {
+ s->vstart_eq_zero) {
TCGv_ptr src2, mask;
TCGv dst;
TCGv_i32 desc;
@@ -3148,7 +3148,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
vext_check_isa_ill(s) && \
require_vm(a->vm, a->rd) && \
(a->rd != a->rs2) && \
- (s->vstart == 0)) { \
+ s->vstart_eq_zero) { \
uint32_t data = 0; \
gen_helper_gvec_3_ptr *fn = gen_helper_##NAME; \
TCGLabel *over = gen_new_label(); \
@@ -3189,7 +3189,7 @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
!is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) &&
require_vm(a->vm, a->rd) &&
require_align(a->rd, s->lmul) &&
- (s->vstart == 0)) {
+ s->vstart_eq_zero) {
uint32_t data = 0;
TCGLabel *over = gen_new_label();
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
@@ -3638,7 +3638,7 @@ static bool vcompress_vm_check(DisasContext *s, arg_r *a)
require_align(a->rs2, s->lmul) &&
(a->rd != a->rs2) &&
!is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs1, 1) &&
- (s->vstart == 0);
+ s->vstart_eq_zero;
}
static bool trans_vcompress_vm(DisasContext *s, arg_r *a)
@@ -3677,7 +3677,7 @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
QEMU_IS_ALIGNED(a->rd, LEN) && \
QEMU_IS_ALIGNED(a->rs2, LEN)) { \
uint32_t maxsz = (s->cfg_ptr->vlen >> 3) * LEN; \
- if (s->vstart == 0) { \
+ if (s->vstart_eq_zero) { \
/* EEW = 8 */ \
tcg_gen_gvec_mov(MO_8, vreg_ofs(s, a->rd), \
vreg_ofs(s, a->rs2), maxsz, maxsz); \
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 06/25] target/riscv: Separate priv from mmu_idx
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (4 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 05/25] target/riscv: Add a tb flags field for vstart Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 07/25] target/riscv: Reduce overhead of MSTATUS_SUM change Richard Henderson
` (19 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Fei Wu, LIU Zhiwei, Alistair Francis,
Weiwei Li, Daniel Henrique Barboza
From: Fei Wu <fei2.wu@intel.com>
Currently it's assumed the 2 low bits of mmu_idx map to privilege mode,
this assumption won't last as we are about to add more mmu_idx. Here an
individual priv field is added into TB_FLAGS.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Fei Wu <fei2.wu@intel.com>
Message-Id: <20230324054154.414846-2-fei2.wu@intel.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-7-richard.henderson@linaro.org>
---
target/riscv/cpu.h | 2 +-
target/riscv/cpu_helper.c | 4 +++-
target/riscv/translate.c | 2 ++
target/riscv/insn_trans/trans_privileged.c.inc | 2 +-
target/riscv/insn_trans/trans_xthead.c.inc | 14 +-------------
5 files changed, 8 insertions(+), 16 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 786ad047ee..9b971ee1b0 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -629,7 +629,6 @@ G_NORETURN void riscv_raise_exception(CPURISCVState *env,
target_ulong riscv_cpu_get_fflags(CPURISCVState *env);
void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
-#define TB_FLAGS_PRIV_MMU_MASK 3
#define TB_FLAGS_PRIV_HYP_ACCESS_MASK (1 << 2)
#include "exec/cpu-all.h"
@@ -656,6 +655,7 @@ FIELD(TB_FLAGS, ITRIGGER, 22, 1)
/* Virtual mode enabled */
FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1)
FIELD(TB_FLAGS, VSTART_EQ_ZERO, 24, 1)
+FIELD(TB_FLAGS, PRIV, 25, 2)
#ifdef TARGET_RISCV32
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 7579e83c3d..36d6e422d7 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -83,6 +83,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
fs = EXT_STATUS_DIRTY;
vs = EXT_STATUS_DIRTY;
#else
+ flags = FIELD_DP32(flags, TB_FLAGS, PRIV, env->priv);
+
flags |= cpu_mmu_index(env, 0);
fs = get_field(env->mstatus, MSTATUS_FS);
vs = get_field(env->mstatus, MSTATUS_VS);
@@ -751,7 +753,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
*/
MemTxResult res;
MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
- int mode = mmu_idx & TB_FLAGS_PRIV_MMU_MASK;
+ int mode = env->priv;
bool use_background = false;
hwaddr ppn;
int napot_bits = 0;
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 3ab8a9999e..6d59348f0c 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -67,6 +67,7 @@ typedef struct DisasContext {
RISCVExtStatus mstatus_fs;
RISCVExtStatus mstatus_vs;
uint32_t mem_idx;
+ uint32_t priv;
/*
* Remember the rounding mode encoded in the previous fp instruction,
* which we have already installed into env->fp_status. Or -1 for
@@ -1153,6 +1154,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
uint32_t tb_flags = ctx->base.tb->flags;
ctx->pc_succ_insn = ctx->base.pc_first;
+ ctx->priv = FIELD_EX32(tb_flags, TB_FLAGS, PRIV);
ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
ctx->mstatus_fs = FIELD_EX32(tb_flags, TB_FLAGS, FS);
ctx->mstatus_vs = FIELD_EX32(tb_flags, TB_FLAGS, VS);
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
index e3bee971c6..7c2837194c 100644
--- a/target/riscv/insn_trans/trans_privileged.c.inc
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
@@ -52,7 +52,7 @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a)
* that no exception will be raised when fetching them.
*/
- if (semihosting_enabled(ctx->mem_idx < PRV_S) &&
+ if (semihosting_enabled(ctx->priv == PRV_U) &&
(pre_addr & TARGET_PAGE_MASK) == (post_addr & TARGET_PAGE_MASK)) {
pre = opcode_at(&ctx->base, pre_addr);
ebreak = opcode_at(&ctx->base, ebreak_addr);
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
index df504c3f2c..3e13b1d74d 100644
--- a/target/riscv/insn_trans/trans_xthead.c.inc
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
@@ -263,25 +263,13 @@ static bool trans_th_tst(DisasContext *ctx, arg_th_tst *a)
/* XTheadCmo */
-static inline int priv_level(DisasContext *ctx)
-{
-#ifdef CONFIG_USER_ONLY
- return PRV_U;
-#else
- /* Priv level is part of mem_idx. */
- return ctx->mem_idx & TB_FLAGS_PRIV_MMU_MASK;
-#endif
-}
-
/* Test if priv level is M, S, or U (cannot fail). */
#define REQUIRE_PRIV_MSU(ctx)
/* Test if priv level is M or S. */
#define REQUIRE_PRIV_MS(ctx) \
do { \
- int priv = priv_level(ctx); \
- if (!(priv == PRV_M || \
- priv == PRV_S)) { \
+ if (ctx->priv == PRV_U) { \
return false; \
} \
} while (0)
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 07/25] target/riscv: Reduce overhead of MSTATUS_SUM change
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (5 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 06/25] target/riscv: Separate priv from mmu_idx Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 08/25] accel/tcg: Add cpu_ld*_code_mmu Richard Henderson
` (18 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Fei Wu, LIU Zhiwei, Alistair Francis,
Weiwei Li, Daniel Henrique Barboza
From: Fei Wu <fei2.wu@intel.com>
Kernel needs to access user mode memory e.g. during syscalls, the window
is usually opened up for a very limited time through MSTATUS.SUM, the
overhead is too much if tlb_flush() gets called for every SUM change.
This patch creates a separate MMU index for S+SUM, so that it's not
necessary to flush tlb anymore when SUM changes. This is similar to how
ARM handles Privileged Access Never (PAN).
Result of 'pipe 10' from unixbench boosts from 223656 to 1705006. Many
other syscalls benefit a lot from this too.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Fei Wu <fei2.wu@intel.com>
Message-Id: <20230324054154.414846-3-fei2.wu@intel.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-8-richard.henderson@linaro.org>
---
target/riscv/cpu.h | 2 --
target/riscv/internals.h | 14 ++++++++++++++
target/riscv/cpu_helper.c | 17 +++++++++++++++--
target/riscv/csr.c | 3 +--
target/riscv/op_helper.c | 5 +++--
target/riscv/insn_trans/trans_rvh.c.inc | 4 ++--
6 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 9b971ee1b0..6239c99f4c 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -629,8 +629,6 @@ G_NORETURN void riscv_raise_exception(CPURISCVState *env,
target_ulong riscv_cpu_get_fflags(CPURISCVState *env);
void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
-#define TB_FLAGS_PRIV_HYP_ACCESS_MASK (1 << 2)
-
#include "exec/cpu-all.h"
FIELD(TB_FLAGS, MEM_IDX, 0, 3)
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 5620fbffb6..b55152a7dc 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -21,6 +21,20 @@
#include "hw/registerfields.h"
+/*
+ * The current MMU Modes are:
+ * - U 0b000
+ * - S 0b001
+ * - S+SUM 0b010
+ * - M 0b011
+ * - HLV/HLVX/HSV adds 0b100
+ */
+#define MMUIdx_U 0
+#define MMUIdx_S 1
+#define MMUIdx_S_SUM 2
+#define MMUIdx_M 3
+#define MMU_HYP_ACCESS_BIT (1 << 2)
+
/* share data between vector helpers and decode code */
FIELD(VDATA, VM, 0, 1)
FIELD(VDATA, LMUL, 1, 3)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 36d6e422d7..174a77706b 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -21,6 +21,7 @@
#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "cpu.h"
+#include "internals.h"
#include "pmu.h"
#include "exec/exec-all.h"
#include "instmap.h"
@@ -36,7 +37,19 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
#ifdef CONFIG_USER_ONLY
return 0;
#else
- return env->priv;
+ if (ifetch) {
+ return env->priv;
+ }
+
+ /* All priv -> mmu_idx mapping are here */
+ int mode = env->priv;
+ if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) {
+ mode = get_field(env->mstatus, MSTATUS_MPP);
+ }
+ if (mode == PRV_S && get_field(env->mstatus, MSTATUS_SUM)) {
+ return MMUIdx_S_SUM;
+ }
+ return mode;
#endif
}
@@ -588,7 +601,7 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable)
bool riscv_cpu_two_stage_lookup(int mmu_idx)
{
- return mmu_idx & TB_FLAGS_PRIV_HYP_ACCESS_MASK;
+ return mmu_idx & MMU_HYP_ACCESS_BIT;
}
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 4268828dc4..124be448dc 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1270,8 +1270,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
val = legalize_mpp(env, get_field(mstatus, MSTATUS_MPP), val);
/* flush tlb on mstatus fields that affect VM */
- if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
- MSTATUS_MPRV | MSTATUS_SUM)) {
+ if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPV)) {
tlb_flush(env_cpu(env));
}
mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index bd21c6eeef..00bdf77f32 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -20,6 +20,7 @@
#include "qemu/osdep.h"
#include "cpu.h"
+#include "internals.h"
#include "qemu/main-loop.h"
#include "exec/exec-all.h"
#include "exec/helper-proto.h"
@@ -428,14 +429,14 @@ void helper_hyp_gvma_tlb_flush(CPURISCVState *env)
target_ulong helper_hyp_hlvx_hu(CPURISCVState *env, target_ulong address)
{
- int mmu_idx = cpu_mmu_index(env, true) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
+ int mmu_idx = cpu_mmu_index(env, true) | MMU_HYP_ACCESS_BIT;
return cpu_lduw_mmuidx_ra(env, address, mmu_idx, GETPC());
}
target_ulong helper_hyp_hlvx_wu(CPURISCVState *env, target_ulong address)
{
- int mmu_idx = cpu_mmu_index(env, true) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
+ int mmu_idx = cpu_mmu_index(env, true) | MMU_HYP_ACCESS_BIT;
return cpu_ldl_mmuidx_ra(env, address, mmu_idx, GETPC());
}
diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc
index 4b730cd492..ae98b45e5e 100644
--- a/target/riscv/insn_trans/trans_rvh.c.inc
+++ b/target/riscv/insn_trans/trans_rvh.c.inc
@@ -42,7 +42,7 @@ static bool do_hlv(DisasContext *ctx, arg_r2 *a, MemOp mop)
if (check_access(ctx)) {
TCGv dest = dest_gpr(ctx, a->rd);
TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
- int mem_idx = ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
+ int mem_idx = ctx->mem_idx | MMU_HYP_ACCESS_BIT;
tcg_gen_qemu_ld_tl(dest, addr, mem_idx, mop);
gen_set_gpr(ctx, a->rd, dest);
}
@@ -89,7 +89,7 @@ static bool do_hsv(DisasContext *ctx, arg_r2_s *a, MemOp mop)
if (check_access(ctx)) {
TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
TCGv data = get_gpr(ctx, a->rs2, EXT_NONE);
- int mem_idx = ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
+ int mem_idx = ctx->mem_idx | MMU_HYP_ACCESS_BIT;
tcg_gen_qemu_st_tl(data, addr, mem_idx, mop);
}
return true;
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 08/25] accel/tcg: Add cpu_ld*_code_mmu
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (6 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 07/25] target/riscv: Reduce overhead of MSTATUS_SUM change Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 09/25] target/riscv: Use cpu_ld*_code_mmu for HLVX Richard Henderson
` (17 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
At least RISC-V has the need to be able to perform a read
using execute permissions, outside of translation.
Add helpers to facilitate this.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-9-richard.henderson@linaro.org>
---
include/exec/cpu_ldst.h | 9 +++++++
accel/tcg/cputlb.c | 48 ++++++++++++++++++++++++++++++++++
accel/tcg/user-exec.c | 58 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 115 insertions(+)
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index 09b55cc0ee..c141f0394f 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -445,6 +445,15 @@ static inline CPUTLBEntry *tlb_entry(CPUArchState *env, uintptr_t mmu_idx,
# define cpu_stq_mmu cpu_stq_le_mmu
#endif
+uint8_t cpu_ldb_code_mmu(CPUArchState *env, abi_ptr addr,
+ MemOpIdx oi, uintptr_t ra);
+uint16_t cpu_ldw_code_mmu(CPUArchState *env, abi_ptr addr,
+ MemOpIdx oi, uintptr_t ra);
+uint32_t cpu_ldl_code_mmu(CPUArchState *env, abi_ptr addr,
+ MemOpIdx oi, uintptr_t ra);
+uint64_t cpu_ldq_code_mmu(CPUArchState *env, abi_ptr addr,
+ MemOpIdx oi, uintptr_t ra);
+
uint32_t cpu_ldub_code(CPUArchState *env, abi_ptr addr);
uint32_t cpu_lduw_code(CPUArchState *env, abi_ptr addr);
uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr addr);
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index e984a98dc4..e62c8f3c3f 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -2768,3 +2768,51 @@ uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr addr)
MemOpIdx oi = make_memop_idx(MO_TEUQ, cpu_mmu_index(env, true));
return full_ldq_code(env, addr, oi, 0);
}
+
+uint8_t cpu_ldb_code_mmu(CPUArchState *env, abi_ptr addr,
+ MemOpIdx oi, uintptr_t retaddr)
+{
+ return full_ldub_code(env, addr, oi, retaddr);
+}
+
+uint16_t cpu_ldw_code_mmu(CPUArchState *env, abi_ptr addr,
+ MemOpIdx oi, uintptr_t retaddr)
+{
+ MemOp mop = get_memop(oi);
+ int idx = get_mmuidx(oi);
+ uint16_t ret;
+
+ ret = full_lduw_code(env, addr, make_memop_idx(MO_TEUW, idx), retaddr);
+ if ((mop & MO_BSWAP) != MO_TE) {
+ ret = bswap16(ret);
+ }
+ return ret;
+}
+
+uint32_t cpu_ldl_code_mmu(CPUArchState *env, abi_ptr addr,
+ MemOpIdx oi, uintptr_t retaddr)
+{
+ MemOp mop = get_memop(oi);
+ int idx = get_mmuidx(oi);
+ uint32_t ret;
+
+ ret = full_ldl_code(env, addr, make_memop_idx(MO_TEUL, idx), retaddr);
+ if ((mop & MO_BSWAP) != MO_TE) {
+ ret = bswap32(ret);
+ }
+ return ret;
+}
+
+uint64_t cpu_ldq_code_mmu(CPUArchState *env, abi_ptr addr,
+ MemOpIdx oi, uintptr_t retaddr)
+{
+ MemOp mop = get_memop(oi);
+ int idx = get_mmuidx(oi);
+ uint64_t ret;
+
+ ret = full_ldq_code(env, addr, make_memop_idx(MO_TEUQ, idx), retaddr);
+ if ((mop & MO_BSWAP) != MO_TE) {
+ ret = bswap64(ret);
+ }
+ return ret;
+}
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index a7e0c3e2f4..fc597a010d 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -1219,6 +1219,64 @@ uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr ptr)
return ret;
}
+uint8_t cpu_ldb_code_mmu(CPUArchState *env, abi_ptr addr,
+ MemOpIdx oi, uintptr_t ra)
+{
+ void *haddr;
+ uint8_t ret;
+
+ haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_INST_FETCH);
+ ret = ldub_p(haddr);
+ clear_helper_retaddr();
+ return ret;
+}
+
+uint16_t cpu_ldw_code_mmu(CPUArchState *env, abi_ptr addr,
+ MemOpIdx oi, uintptr_t ra)
+{
+ void *haddr;
+ uint16_t ret;
+
+ haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_INST_FETCH);
+ ret = lduw_p(haddr);
+ clear_helper_retaddr();
+ if (get_memop(oi) & MO_BSWAP) {
+ ret = bswap16(ret);
+ }
+ return ret;
+}
+
+uint32_t cpu_ldl_code_mmu(CPUArchState *env, abi_ptr addr,
+ MemOpIdx oi, uintptr_t ra)
+{
+ void *haddr;
+ uint32_t ret;
+
+ haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_INST_FETCH);
+ ret = ldl_p(haddr);
+ clear_helper_retaddr();
+ if (get_memop(oi) & MO_BSWAP) {
+ ret = bswap32(ret);
+ }
+ return ret;
+}
+
+uint64_t cpu_ldq_code_mmu(CPUArchState *env, abi_ptr addr,
+ MemOpIdx oi, uintptr_t ra)
+{
+ void *haddr;
+ uint64_t ret;
+
+ validate_memop(oi, MO_BEUQ);
+ haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_LOAD);
+ ret = ldq_p(haddr);
+ clear_helper_retaddr();
+ if (get_memop(oi) & MO_BSWAP) {
+ ret = bswap64(ret);
+ }
+ return ret;
+}
+
#include "ldst_common.c.inc"
/*
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 09/25] target/riscv: Use cpu_ld*_code_mmu for HLVX
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (7 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 08/25] accel/tcg: Add cpu_ld*_code_mmu Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 10/25] target/riscv: Handle HLV, HSV via helpers Richard Henderson
` (16 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
Use the new functions to properly check execute permission
for the read rather than read permission.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-10-richard.henderson@linaro.org>
---
target/riscv/op_helper.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 00bdf77f32..4a0bb5b11a 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -427,18 +427,27 @@ void helper_hyp_gvma_tlb_flush(CPURISCVState *env)
helper_hyp_tlb_flush(env);
}
+/*
+ * TODO: These implementations are not quite correct. They perform the
+ * access using execute permission just fine, but the final PMP check
+ * is supposed to have read permission as well. Without replicating
+ * a fair fraction of cputlb.c, fixing this requires adding new mmu_idx
+ * which would imply that exact check in tlb_fill.
+ */
target_ulong helper_hyp_hlvx_hu(CPURISCVState *env, target_ulong address)
{
int mmu_idx = cpu_mmu_index(env, true) | MMU_HYP_ACCESS_BIT;
+ MemOpIdx oi = make_memop_idx(MO_TEUW, mmu_idx);
- return cpu_lduw_mmuidx_ra(env, address, mmu_idx, GETPC());
+ return cpu_ldw_code_mmu(env, address, oi, GETPC());
}
target_ulong helper_hyp_hlvx_wu(CPURISCVState *env, target_ulong address)
{
int mmu_idx = cpu_mmu_index(env, true) | MMU_HYP_ACCESS_BIT;
+ MemOpIdx oi = make_memop_idx(MO_TEUL, mmu_idx);
- return cpu_ldl_mmuidx_ra(env, address, mmu_idx, GETPC());
+ return cpu_ldl_code_mmu(env, address, oi, GETPC());
}
#endif /* !CONFIG_USER_ONLY */
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 10/25] target/riscv: Handle HLV, HSV via helpers
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (8 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 09/25] target/riscv: Use cpu_ld*_code_mmu for HLVX Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 11/25] target/riscv: Rename MMU_HYP_ACCESS_BIT to MMU_2STAGE_BIT Richard Henderson
` (15 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
Implement these instructions via helpers, in expectation
of determining the mmu_idx to use at runtime. This allows
the permission check to also be moved out of line, which
allows HLSX to be removed from TB_FLAGS.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-11-richard.henderson@linaro.org>
---
target/riscv/cpu.h | 6 +-
target/riscv/helper.h | 12 ++-
target/riscv/cpu_helper.c | 26 ++---
target/riscv/op_helper.c | 99 +++++++++++++++--
target/riscv/translate.c | 2 -
target/riscv/insn_trans/trans_rvh.c.inc | 137 ++++++++++--------------
6 files changed, 169 insertions(+), 113 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6239c99f4c..35cf2e2691 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -639,8 +639,7 @@ FIELD(TB_FLAGS, LMUL, 7, 3)
FIELD(TB_FLAGS, SEW, 10, 3)
FIELD(TB_FLAGS, VL_EQ_VLMAX, 13, 1)
FIELD(TB_FLAGS, VILL, 14, 1)
-/* Is a Hypervisor instruction load/store allowed? */
-FIELD(TB_FLAGS, HLSX, 15, 1)
+FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1)
/* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
FIELD(TB_FLAGS, XL, 16, 2)
/* If PointerMasking should be applied */
@@ -652,8 +651,7 @@ FIELD(TB_FLAGS, VMA, 21, 1)
FIELD(TB_FLAGS, ITRIGGER, 22, 1)
/* Virtual mode enabled */
FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1)
-FIELD(TB_FLAGS, VSTART_EQ_ZERO, 24, 1)
-FIELD(TB_FLAGS, PRIV, 25, 2)
+FIELD(TB_FLAGS, PRIV, 24, 2)
#ifdef TARGET_RISCV32
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 1880e95c50..98e97810fd 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -123,8 +123,16 @@ DEF_HELPER_1(itrigger_match, void, env)
#ifndef CONFIG_USER_ONLY
DEF_HELPER_1(hyp_tlb_flush, void, env)
DEF_HELPER_1(hyp_gvma_tlb_flush, void, env)
-DEF_HELPER_2(hyp_hlvx_hu, tl, env, tl)
-DEF_HELPER_2(hyp_hlvx_wu, tl, env, tl)
+DEF_HELPER_FLAGS_2(hyp_hlv_bu, TCG_CALL_NO_WG, tl, env, tl)
+DEF_HELPER_FLAGS_2(hyp_hlv_hu, TCG_CALL_NO_WG, tl, env, tl)
+DEF_HELPER_FLAGS_2(hyp_hlv_wu, TCG_CALL_NO_WG, tl, env, tl)
+DEF_HELPER_FLAGS_2(hyp_hlv_d, TCG_CALL_NO_WG, tl, env, tl)
+DEF_HELPER_FLAGS_2(hyp_hlvx_hu, TCG_CALL_NO_WG, tl, env, tl)
+DEF_HELPER_FLAGS_2(hyp_hlvx_wu, TCG_CALL_NO_WG, tl, env, tl)
+DEF_HELPER_FLAGS_3(hyp_hsv_b, TCG_CALL_NO_WG, void, env, tl, tl)
+DEF_HELPER_FLAGS_3(hyp_hsv_h, TCG_CALL_NO_WG, void, env, tl, tl)
+DEF_HELPER_FLAGS_3(hyp_hsv_w, TCG_CALL_NO_WG, void, env, tl, tl)
+DEF_HELPER_FLAGS_3(hyp_hsv_d, TCG_CALL_NO_WG, void, env, tl, tl)
#endif
/* Vector functions */
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 174a77706b..abf275d2c6 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -102,24 +102,16 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
fs = get_field(env->mstatus, MSTATUS_FS);
vs = get_field(env->mstatus, MSTATUS_VS);
- if (riscv_has_ext(env, RVH)) {
- if (env->priv == PRV_M ||
- (env->priv == PRV_S && !env->virt_enabled) ||
- (env->priv == PRV_U && !env->virt_enabled &&
- get_field(env->hstatus, HSTATUS_HU))) {
- flags = FIELD_DP32(flags, TB_FLAGS, HLSX, 1);
- }
-
- if (env->virt_enabled) {
- flags = FIELD_DP32(flags, TB_FLAGS, VIRT_ENABLED, 1);
- /*
- * Merge DISABLED and !DIRTY states using MIN.
- * We will set both fields when dirtying.
- */
- fs = MIN(fs, get_field(env->mstatus_hs, MSTATUS_FS));
- vs = MIN(vs, get_field(env->mstatus_hs, MSTATUS_VS));
- }
+ if (env->virt_enabled) {
+ flags = FIELD_DP32(flags, TB_FLAGS, VIRT_ENABLED, 1);
+ /*
+ * Merge DISABLED and !DIRTY states using MIN.
+ * We will set both fields when dirtying.
+ */
+ fs = MIN(fs, get_field(env->mstatus_hs, MSTATUS_FS));
+ vs = MIN(vs, get_field(env->mstatus_hs, MSTATUS_VS));
}
+
if (cpu->cfg.debug && !icount_enabled()) {
flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
}
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 4a0bb5b11a..663382785e 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -427,6 +427,91 @@ void helper_hyp_gvma_tlb_flush(CPURISCVState *env)
helper_hyp_tlb_flush(env);
}
+static int check_access_hlsv(CPURISCVState *env, bool x, uintptr_t ra)
+{
+ if (env->priv == PRV_M) {
+ /* always allowed */
+ } else if (env->virt_enabled) {
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, ra);
+ } else if (env->priv == PRV_U && !get_field(env->hstatus, HSTATUS_HU)) {
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, ra);
+ }
+
+ return cpu_mmu_index(env, x) | MMU_HYP_ACCESS_BIT;
+}
+
+target_ulong helper_hyp_hlv_bu(CPURISCVState *env, target_ulong addr)
+{
+ uintptr_t ra = GETPC();
+ int mmu_idx = check_access_hlsv(env, false, ra);
+ MemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
+
+ return cpu_ldb_mmu(env, addr, oi, ra);
+}
+
+target_ulong helper_hyp_hlv_hu(CPURISCVState *env, target_ulong addr)
+{
+ uintptr_t ra = GETPC();
+ int mmu_idx = check_access_hlsv(env, false, ra);
+ MemOpIdx oi = make_memop_idx(MO_TEUW, mmu_idx);
+
+ return cpu_ldw_mmu(env, addr, oi, ra);
+}
+
+target_ulong helper_hyp_hlv_wu(CPURISCVState *env, target_ulong addr)
+{
+ uintptr_t ra = GETPC();
+ int mmu_idx = check_access_hlsv(env, false, ra);
+ MemOpIdx oi = make_memop_idx(MO_TEUL, mmu_idx);
+
+ return cpu_ldl_mmu(env, addr, oi, ra);
+}
+
+target_ulong helper_hyp_hlv_d(CPURISCVState *env, target_ulong addr)
+{
+ uintptr_t ra = GETPC();
+ int mmu_idx = check_access_hlsv(env, false, ra);
+ MemOpIdx oi = make_memop_idx(MO_TEUQ, mmu_idx);
+
+ return cpu_ldq_mmu(env, addr, oi, ra);
+}
+
+void helper_hyp_hsv_b(CPURISCVState *env, target_ulong addr, target_ulong val)
+{
+ uintptr_t ra = GETPC();
+ int mmu_idx = check_access_hlsv(env, false, ra);
+ MemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
+
+ cpu_stb_mmu(env, addr, val, oi, ra);
+}
+
+void helper_hyp_hsv_h(CPURISCVState *env, target_ulong addr, target_ulong val)
+{
+ uintptr_t ra = GETPC();
+ int mmu_idx = check_access_hlsv(env, false, ra);
+ MemOpIdx oi = make_memop_idx(MO_TEUW, mmu_idx);
+
+ cpu_stw_mmu(env, addr, val, oi, ra);
+}
+
+void helper_hyp_hsv_w(CPURISCVState *env, target_ulong addr, target_ulong val)
+{
+ uintptr_t ra = GETPC();
+ int mmu_idx = check_access_hlsv(env, false, ra);
+ MemOpIdx oi = make_memop_idx(MO_TEUL, mmu_idx);
+
+ cpu_stl_mmu(env, addr, val, oi, ra);
+}
+
+void helper_hyp_hsv_d(CPURISCVState *env, target_ulong addr, target_ulong val)
+{
+ uintptr_t ra = GETPC();
+ int mmu_idx = check_access_hlsv(env, false, ra);
+ MemOpIdx oi = make_memop_idx(MO_TEUQ, mmu_idx);
+
+ cpu_stq_mmu(env, addr, val, oi, ra);
+}
+
/*
* TODO: These implementations are not quite correct. They perform the
* access using execute permission just fine, but the final PMP check
@@ -434,20 +519,22 @@ void helper_hyp_gvma_tlb_flush(CPURISCVState *env)
* a fair fraction of cputlb.c, fixing this requires adding new mmu_idx
* which would imply that exact check in tlb_fill.
*/
-target_ulong helper_hyp_hlvx_hu(CPURISCVState *env, target_ulong address)
+target_ulong helper_hyp_hlvx_hu(CPURISCVState *env, target_ulong addr)
{
- int mmu_idx = cpu_mmu_index(env, true) | MMU_HYP_ACCESS_BIT;
+ uintptr_t ra = GETPC();
+ int mmu_idx = check_access_hlsv(env, true, ra);
MemOpIdx oi = make_memop_idx(MO_TEUW, mmu_idx);
- return cpu_ldw_code_mmu(env, address, oi, GETPC());
+ return cpu_ldw_code_mmu(env, addr, oi, GETPC());
}
-target_ulong helper_hyp_hlvx_wu(CPURISCVState *env, target_ulong address)
+target_ulong helper_hyp_hlvx_wu(CPURISCVState *env, target_ulong addr)
{
- int mmu_idx = cpu_mmu_index(env, true) | MMU_HYP_ACCESS_BIT;
+ uintptr_t ra = GETPC();
+ int mmu_idx = check_access_hlsv(env, true, ra);
MemOpIdx oi = make_memop_idx(MO_TEUL, mmu_idx);
- return cpu_ldl_code_mmu(env, address, oi, GETPC());
+ return cpu_ldl_code_mmu(env, addr, oi, ra);
}
#endif /* !CONFIG_USER_ONLY */
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 6d59348f0c..928da0d3f0 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -80,7 +80,6 @@ typedef struct DisasContext {
bool virt_inst_excp;
bool virt_enabled;
const RISCVCPUConfig *cfg_ptr;
- bool hlsx;
/* vector extension */
bool vill;
/*
@@ -1163,7 +1162,6 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
ctx->misa_ext = env->misa_ext;
ctx->frm = -1; /* unknown rounding mode */
ctx->cfg_ptr = &(cpu->cfg);
- ctx->hlsx = FIELD_EX32(tb_flags, TB_FLAGS, HLSX);
ctx->vill = FIELD_EX32(tb_flags, TB_FLAGS, VILL);
ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW);
ctx->lmul = sextract32(FIELD_EX32(tb_flags, TB_FLAGS, LMUL), 0, 3);
diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc
index ae98b45e5e..3e9322130f 100644
--- a/target/riscv/insn_trans/trans_rvh.c.inc
+++ b/target/riscv/insn_trans/trans_rvh.c.inc
@@ -16,158 +16,131 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef CONFIG_USER_ONLY
-static bool check_access(DisasContext *ctx)
-{
- if (!ctx->hlsx) {
- tcg_gen_st_i32(tcg_constant_i32(ctx->opcode), cpu_env,
- offsetof(CPURISCVState, bins));
- if (ctx->virt_enabled) {
- generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
- } else {
- generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
- }
- return false;
- }
- return true;
-}
-#endif
-
-static bool do_hlv(DisasContext *ctx, arg_r2 *a, MemOp mop)
-{
#ifdef CONFIG_USER_ONLY
- return false;
+#define do_hlv(ctx, a, func) false
+#define do_hsv(ctx, a, func) false
#else
- decode_save_opc(ctx);
- if (check_access(ctx)) {
- TCGv dest = dest_gpr(ctx, a->rd);
- TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
- int mem_idx = ctx->mem_idx | MMU_HYP_ACCESS_BIT;
- tcg_gen_qemu_ld_tl(dest, addr, mem_idx, mop);
- gen_set_gpr(ctx, a->rd, dest);
- }
- return true;
-#endif
+static void gen_helper_hyp_hlv_b(TCGv r, TCGv_env e, TCGv a)
+{
+ gen_helper_hyp_hlv_bu(r, e, a);
+ tcg_gen_ext8s_tl(r, r);
}
+static void gen_helper_hyp_hlv_h(TCGv r, TCGv_env e, TCGv a)
+{
+ gen_helper_hyp_hlv_hu(r, e, a);
+ tcg_gen_ext16s_tl(r, r);
+}
+
+static void gen_helper_hyp_hlv_w(TCGv r, TCGv_env e, TCGv a)
+{
+ gen_helper_hyp_hlv_wu(r, e, a);
+ tcg_gen_ext32s_tl(r, r);
+}
+
+static bool do_hlv(DisasContext *ctx, arg_r2 *a,
+ void (*func)(TCGv, TCGv_env, TCGv))
+{
+ TCGv dest = dest_gpr(ctx, a->rd);
+ TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
+
+ decode_save_opc(ctx);
+ func(dest, cpu_env, addr);
+ gen_set_gpr(ctx, a->rd, dest);
+ return true;
+}
+
+static bool do_hsv(DisasContext *ctx, arg_r2_s *a,
+ void (*func)(TCGv_env, TCGv, TCGv))
+{
+ TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
+ TCGv data = get_gpr(ctx, a->rs2, EXT_NONE);
+
+ decode_save_opc(ctx);
+ func(cpu_env, addr, data);
+ return true;
+}
+#endif /* CONFIG_USER_ONLY */
+
static bool trans_hlv_b(DisasContext *ctx, arg_hlv_b *a)
{
REQUIRE_EXT(ctx, RVH);
- return do_hlv(ctx, a, MO_SB);
+ return do_hlv(ctx, a, gen_helper_hyp_hlv_b);
}
static bool trans_hlv_h(DisasContext *ctx, arg_hlv_h *a)
{
REQUIRE_EXT(ctx, RVH);
- return do_hlv(ctx, a, MO_TESW);
+ return do_hlv(ctx, a, gen_helper_hyp_hlv_h);
}
static bool trans_hlv_w(DisasContext *ctx, arg_hlv_w *a)
{
REQUIRE_EXT(ctx, RVH);
- return do_hlv(ctx, a, MO_TESL);
+ return do_hlv(ctx, a, gen_helper_hyp_hlv_w);
}
static bool trans_hlv_bu(DisasContext *ctx, arg_hlv_bu *a)
{
REQUIRE_EXT(ctx, RVH);
- return do_hlv(ctx, a, MO_UB);
+ return do_hlv(ctx, a, gen_helper_hyp_hlv_bu);
}
static bool trans_hlv_hu(DisasContext *ctx, arg_hlv_hu *a)
{
REQUIRE_EXT(ctx, RVH);
- return do_hlv(ctx, a, MO_TEUW);
-}
-
-static bool do_hsv(DisasContext *ctx, arg_r2_s *a, MemOp mop)
-{
-#ifdef CONFIG_USER_ONLY
- return false;
-#else
- decode_save_opc(ctx);
- if (check_access(ctx)) {
- TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
- TCGv data = get_gpr(ctx, a->rs2, EXT_NONE);
- int mem_idx = ctx->mem_idx | MMU_HYP_ACCESS_BIT;
- tcg_gen_qemu_st_tl(data, addr, mem_idx, mop);
- }
- return true;
-#endif
+ return do_hlv(ctx, a, gen_helper_hyp_hlv_hu);
}
static bool trans_hsv_b(DisasContext *ctx, arg_hsv_b *a)
{
REQUIRE_EXT(ctx, RVH);
- return do_hsv(ctx, a, MO_SB);
+ return do_hsv(ctx, a, gen_helper_hyp_hsv_b);
}
static bool trans_hsv_h(DisasContext *ctx, arg_hsv_h *a)
{
REQUIRE_EXT(ctx, RVH);
- return do_hsv(ctx, a, MO_TESW);
+ return do_hsv(ctx, a, gen_helper_hyp_hsv_h);
}
static bool trans_hsv_w(DisasContext *ctx, arg_hsv_w *a)
{
REQUIRE_EXT(ctx, RVH);
- return do_hsv(ctx, a, MO_TESL);
+ return do_hsv(ctx, a, gen_helper_hyp_hsv_w);
}
static bool trans_hlv_wu(DisasContext *ctx, arg_hlv_wu *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_EXT(ctx, RVH);
- return do_hlv(ctx, a, MO_TEUL);
+ return do_hlv(ctx, a, gen_helper_hyp_hlv_wu);
}
static bool trans_hlv_d(DisasContext *ctx, arg_hlv_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_EXT(ctx, RVH);
- return do_hlv(ctx, a, MO_TEUQ);
+ return do_hlv(ctx, a, gen_helper_hyp_hlv_d);
}
static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a)
{
REQUIRE_64BIT(ctx);
REQUIRE_EXT(ctx, RVH);
- return do_hsv(ctx, a, MO_TEUQ);
+ return do_hsv(ctx, a, gen_helper_hyp_hsv_d);
}
-#ifndef CONFIG_USER_ONLY
-static bool do_hlvx(DisasContext *ctx, arg_r2 *a,
- void (*func)(TCGv, TCGv_env, TCGv))
-{
- decode_save_opc(ctx);
- if (check_access(ctx)) {
- TCGv dest = dest_gpr(ctx, a->rd);
- TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
- func(dest, cpu_env, addr);
- gen_set_gpr(ctx, a->rd, dest);
- }
- return true;
-}
-#endif
-
static bool trans_hlvx_hu(DisasContext *ctx, arg_hlvx_hu *a)
{
REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
- return do_hlvx(ctx, a, gen_helper_hyp_hlvx_hu);
-#else
- return false;
-#endif
+ return do_hlv(ctx, a, gen_helper_hyp_hlvx_hu);
}
static bool trans_hlvx_wu(DisasContext *ctx, arg_hlvx_wu *a)
{
REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
- return do_hlvx(ctx, a, gen_helper_hyp_hlvx_wu);
-#else
- return false;
-#endif
+ return do_hlv(ctx, a, gen_helper_hyp_hlvx_wu);
}
static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 11/25] target/riscv: Rename MMU_HYP_ACCESS_BIT to MMU_2STAGE_BIT
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (9 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 10/25] target/riscv: Handle HLV, HSV via helpers Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 12/25] target/riscv: Introduce mmuidx_sum Richard Henderson
` (14 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
We will enable more uses of this bit in the future.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-12-richard.henderson@linaro.org>
---
target/riscv/internals.h | 6 ++++--
target/riscv/cpu_helper.c | 2 +-
target/riscv/op_helper.c | 2 +-
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index b55152a7dc..7b63c0f1b6 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -27,13 +27,15 @@
* - S 0b001
* - S+SUM 0b010
* - M 0b011
- * - HLV/HLVX/HSV adds 0b100
+ * - U+2STAGE 0b100
+ * - S+2STAGE 0b101
+ * - S+SUM+2STAGE 0b110
*/
#define MMUIdx_U 0
#define MMUIdx_S 1
#define MMUIdx_S_SUM 2
#define MMUIdx_M 3
-#define MMU_HYP_ACCESS_BIT (1 << 2)
+#define MMU_2STAGE_BIT (1 << 2)
/* share data between vector helpers and decode code */
FIELD(VDATA, VM, 0, 1)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index abf275d2c6..291a1acbf7 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -593,7 +593,7 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable)
bool riscv_cpu_two_stage_lookup(int mmu_idx)
{
- return mmu_idx & MMU_HYP_ACCESS_BIT;
+ return mmu_idx & MMU_2STAGE_BIT;
}
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts)
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 663382785e..a5de3daee7 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -437,7 +437,7 @@ static int check_access_hlsv(CPURISCVState *env, bool x, uintptr_t ra)
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, ra);
}
- return cpu_mmu_index(env, x) | MMU_HYP_ACCESS_BIT;
+ return cpu_mmu_index(env, x) | MMU_2STAGE_BIT;
}
target_ulong helper_hyp_hlv_bu(CPURISCVState *env, target_ulong addr)
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 12/25] target/riscv: Introduce mmuidx_sum
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (10 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 11/25] target/riscv: Rename MMU_HYP_ACCESS_BIT to MMU_2STAGE_BIT Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 13/25] target/riscv: Introduce mmuidx_priv Richard Henderson
` (13 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
In get_physical_address, we should use the setting passed
via mmu_idx rather than checking env->mstatus directly.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-13-richard.henderson@linaro.org>
---
target/riscv/internals.h | 5 +++++
target/riscv/cpu_helper.c | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 7b63c0f1b6..0b61f337dd 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -37,6 +37,11 @@
#define MMUIdx_M 3
#define MMU_2STAGE_BIT (1 << 2)
+static inline bool mmuidx_sum(int mmu_idx)
+{
+ return (mmu_idx & 3) == MMUIdx_S_SUM;
+}
+
/* share data between vector helpers and decode code */
FIELD(VDATA, VM, 0, 1)
FIELD(VDATA, LMUL, 1, 3)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 291a1acbf7..29ee9b1b42 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -842,7 +842,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
widened = 2;
}
/* status.SUM will be ignored if execute on background */
- sum = get_field(env->mstatus, MSTATUS_SUM) || use_background || is_debug;
+ sum = mmuidx_sum(mmu_idx) || use_background || is_debug;
switch (vm) {
case VM_1_10_SV32:
levels = 2; ptidxbits = 10; ptesize = 4; break;
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 13/25] target/riscv: Introduce mmuidx_priv
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (11 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 12/25] target/riscv: Introduce mmuidx_sum Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 14/25] target/riscv: Introduce mmuidx_2stage Richard Henderson
` (12 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
Use the priv level encoded into the mmu_idx, rather than
starting from env->priv. We have already checked MPRV+MPP
in riscv_cpu_mmu_index -- no need to repeat that.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-14-richard.henderson@linaro.org>
---
target/riscv/internals.h | 9 +++++++++
target/riscv/cpu_helper.c | 6 +-----
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 0b61f337dd..4aa1cb409f 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -37,6 +37,15 @@
#define MMUIdx_M 3
#define MMU_2STAGE_BIT (1 << 2)
+static inline int mmuidx_priv(int mmu_idx)
+{
+ int ret = mmu_idx & 3;
+ if (ret == MMUIdx_S_SUM) {
+ ret = PRV_S;
+ }
+ return ret;
+}
+
static inline bool mmuidx_sum(int mmu_idx)
{
return (mmu_idx & 3) == MMUIdx_S_SUM;
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 29ee9b1b42..57bb19c76e 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -758,7 +758,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
*/
MemTxResult res;
MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
- int mode = env->priv;
+ int mode = mmuidx_priv(mmu_idx);
bool use_background = false;
hwaddr ppn;
int napot_bits = 0;
@@ -781,10 +781,6 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
*/
if (riscv_cpu_two_stage_lookup(mmu_idx)) {
mode = get_field(env->hstatus, HSTATUS_SPVP);
- } else if (mode == PRV_M && access_type != MMU_INST_FETCH) {
- if (get_field(env->mstatus, MSTATUS_MPRV)) {
- mode = get_field(env->mstatus, MSTATUS_MPP);
- }
}
if (first_stage == false) {
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 14/25] target/riscv: Introduce mmuidx_2stage
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (12 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 13/25] target/riscv: Introduce mmuidx_priv Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 15/25] target/riscv: Move hstatus.spvp check to check_access_hlsv Richard Henderson
` (11 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
Move and rename riscv_cpu_two_stage_lookup, to match
the other mmuidx_* functions.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-15-richard.henderson@linaro.org>
---
target/riscv/cpu.h | 1 -
target/riscv/internals.h | 5 +++++
target/riscv/cpu_helper.c | 20 ++++++--------------
3 files changed, 11 insertions(+), 15 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 35cf2e2691..d1f888a790 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -581,7 +581,6 @@ target_ulong riscv_cpu_get_geilen(CPURISCVState *env);
void riscv_cpu_set_geilen(CPURISCVState *env, target_ulong geilen);
bool riscv_cpu_vector_enabled(CPURISCVState *env);
void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
-bool riscv_cpu_two_stage_lookup(int mmu_idx);
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
G_NORETURN void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
MMUAccessType access_type,
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 4aa1cb409f..b5f823c7ec 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -51,6 +51,11 @@ static inline bool mmuidx_sum(int mmu_idx)
return (mmu_idx & 3) == MMUIdx_S_SUM;
}
+static inline bool mmuidx_2stage(int mmu_idx)
+{
+ return mmu_idx & MMU_2STAGE_BIT;
+}
+
/* share data between vector helpers and decode code */
FIELD(VDATA, VM, 0, 1)
FIELD(VDATA, LMUL, 1, 3)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 57bb19c76e..9dfd1d739b 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -591,11 +591,6 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable)
}
}
-bool riscv_cpu_two_stage_lookup(int mmu_idx)
-{
- return mmu_idx & MMU_2STAGE_BIT;
-}
-
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts)
{
CPURISCVState *env = &cpu->env;
@@ -779,7 +774,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
* MPRV does not affect the virtual-machine load/store
* instructions, HLV, HLVX, and HSV.
*/
- if (riscv_cpu_two_stage_lookup(mmu_idx)) {
+ if (mmuidx_2stage(mmu_idx)) {
mode = get_field(env->hstatus, HSTATUS_SPVP);
}
@@ -1175,8 +1170,7 @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
}
env->badaddr = addr;
- env->two_stage_lookup = env->virt_enabled ||
- riscv_cpu_two_stage_lookup(mmu_idx);
+ env->two_stage_lookup = env->virt_enabled || mmuidx_2stage(mmu_idx);
env->two_stage_indirect_lookup = false;
cpu_loop_exit_restore(cs, retaddr);
}
@@ -1201,8 +1195,7 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
g_assert_not_reached();
}
env->badaddr = addr;
- env->two_stage_lookup = env->virt_enabled ||
- riscv_cpu_two_stage_lookup(mmu_idx);
+ env->two_stage_lookup = env->virt_enabled || mmuidx_2stage(mmu_idx);
env->two_stage_indirect_lookup = false;
cpu_loop_exit_restore(cs, retaddr);
}
@@ -1256,7 +1249,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
* MPRV does not affect the virtual-machine load/store
* instructions, HLV, HLVX, and HSV.
*/
- if (riscv_cpu_two_stage_lookup(mmu_idx)) {
+ if (mmuidx_2stage(mmu_idx)) {
mode = get_field(env->hstatus, HSTATUS_SPVP);
} else if (mode == PRV_M && access_type != MMU_INST_FETCH &&
get_field(env->mstatus, MSTATUS_MPRV)) {
@@ -1268,7 +1261,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
pmu_tlb_fill_incr_ctr(cpu, access_type);
if (env->virt_enabled ||
- ((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
+ ((mmuidx_2stage(mmu_idx) || two_stage_lookup) &&
access_type != MMU_INST_FETCH)) {
/* Two stage lookup */
ret = get_physical_address(env, &pa, &prot, address,
@@ -1366,8 +1359,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
} else {
raise_mmu_exception(env, address, access_type, pmp_violation,
first_stage_error,
- env->virt_enabled ||
- riscv_cpu_two_stage_lookup(mmu_idx),
+ env->virt_enabled || mmuidx_2stage(mmu_idx),
two_stage_indirect_error);
cpu_loop_exit_restore(cs, retaddr);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 15/25] target/riscv: Move hstatus.spvp check to check_access_hlsv
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (13 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 14/25] target/riscv: Introduce mmuidx_2stage Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 16/25] target/riscv: Set MMU_2STAGE_BIT in riscv_cpu_mmu_index Richard Henderson
` (10 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
The current cpu_mmu_index value is really irrelevant to
the HLV/HSV lookup. Provide the correct priv level directly.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-16-richard.henderson@linaro.org>
---
target/riscv/cpu_helper.c | 10 +---------
target/riscv/op_helper.c | 2 +-
2 files changed, 2 insertions(+), 10 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 9dfd1d739b..ccba3c45e7 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -770,14 +770,6 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
use_background = true;
}
- /*
- * MPRV does not affect the virtual-machine load/store
- * instructions, HLV, HLVX, and HSV.
- */
- if (mmuidx_2stage(mmu_idx)) {
- mode = get_field(env->hstatus, HSTATUS_SPVP);
- }
-
if (first_stage == false) {
/*
* We are in stage 2 translation, this is similar to stage 1.
@@ -1250,7 +1242,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
* instructions, HLV, HLVX, and HSV.
*/
if (mmuidx_2stage(mmu_idx)) {
- mode = get_field(env->hstatus, HSTATUS_SPVP);
+ ;
} else if (mode == PRV_M && access_type != MMU_INST_FETCH &&
get_field(env->mstatus, MSTATUS_MPRV)) {
mode = get_field(env->mstatus, MSTATUS_MPP);
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index a5de3daee7..49c19d971d 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -437,7 +437,7 @@ static int check_access_hlsv(CPURISCVState *env, bool x, uintptr_t ra)
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, ra);
}
- return cpu_mmu_index(env, x) | MMU_2STAGE_BIT;
+ return get_field(env->hstatus, HSTATUS_SPVP) | MMU_2STAGE_BIT;
}
target_ulong helper_hyp_hlv_bu(CPURISCVState *env, target_ulong addr)
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 16/25] target/riscv: Set MMU_2STAGE_BIT in riscv_cpu_mmu_index
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (14 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 15/25] target/riscv: Move hstatus.spvp check to check_access_hlsv Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 17/25] target/riscv: Check SUM in the correct register Richard Henderson
` (9 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
Incorporate the virt_enabled and MPV checks into the cpu_mmu_index
function, so we don't have to keep doing it within tlb_fill and
subroutines. This also elides a flush on changes to MPV.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-17-richard.henderson@linaro.org>
---
target/riscv/cpu_helper.c | 49 ++++++++++++++-------------------------
target/riscv/csr.c | 6 +----
2 files changed, 18 insertions(+), 37 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index ccba3c45e7..baa4b3a1d2 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -37,19 +37,21 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
#ifdef CONFIG_USER_ONLY
return 0;
#else
- if (ifetch) {
- return env->priv;
- }
+ bool virt = env->virt_enabled;
+ int mode = env->priv;
/* All priv -> mmu_idx mapping are here */
- int mode = env->priv;
- if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) {
- mode = get_field(env->mstatus, MSTATUS_MPP);
+ if (!ifetch) {
+ if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) {
+ mode = get_field(env->mstatus, MSTATUS_MPP);
+ virt = get_field(env->mstatus, MSTATUS_MPV);
+ }
+ if (mode == PRV_S && get_field(env->mstatus, MSTATUS_SUM)) {
+ mode = MMUIdx_S_SUM;
+ }
}
- if (mode == PRV_S && get_field(env->mstatus, MSTATUS_SUM)) {
- return MMUIdx_S_SUM;
- }
- return mode;
+
+ return mode | (virt ? MMU_2STAGE_BIT : 0);
#endif
}
@@ -1162,7 +1164,7 @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
}
env->badaddr = addr;
- env->two_stage_lookup = env->virt_enabled || mmuidx_2stage(mmu_idx);
+ env->two_stage_lookup = mmuidx_2stage(mmu_idx);
env->two_stage_indirect_lookup = false;
cpu_loop_exit_restore(cs, retaddr);
}
@@ -1187,7 +1189,7 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
g_assert_not_reached();
}
env->badaddr = addr;
- env->two_stage_lookup = env->virt_enabled || mmuidx_2stage(mmu_idx);
+ env->two_stage_lookup = mmuidx_2stage(mmu_idx);
env->two_stage_indirect_lookup = false;
cpu_loop_exit_restore(cs, retaddr);
}
@@ -1225,7 +1227,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
int prot, prot2, prot_pmp;
bool pmp_violation = false;
bool first_stage_error = true;
- bool two_stage_lookup = false;
+ bool two_stage_lookup = mmuidx_2stage(mmu_idx);
bool two_stage_indirect_error = false;
int ret = TRANSLATE_FAIL;
int mode = mmu_idx;
@@ -1237,24 +1239,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
__func__, address, access_type, mmu_idx);
- /*
- * MPRV does not affect the virtual-machine load/store
- * instructions, HLV, HLVX, and HSV.
- */
- if (mmuidx_2stage(mmu_idx)) {
- ;
- } else if (mode == PRV_M && access_type != MMU_INST_FETCH &&
- get_field(env->mstatus, MSTATUS_MPRV)) {
- mode = get_field(env->mstatus, MSTATUS_MPP);
- if (riscv_has_ext(env, RVH) && get_field(env->mstatus, MSTATUS_MPV)) {
- two_stage_lookup = true;
- }
- }
-
pmu_tlb_fill_incr_ctr(cpu, access_type);
- if (env->virt_enabled ||
- ((mmuidx_2stage(mmu_idx) || two_stage_lookup) &&
- access_type != MMU_INST_FETCH)) {
+ if (two_stage_lookup) {
/* Two stage lookup */
ret = get_physical_address(env, &pa, &prot, address,
&env->guest_phys_fault_addr, access_type,
@@ -1350,8 +1336,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
return false;
} else {
raise_mmu_exception(env, address, access_type, pmp_violation,
- first_stage_error,
- env->virt_enabled || mmuidx_2stage(mmu_idx),
+ first_stage_error, two_stage_lookup,
two_stage_indirect_error);
cpu_loop_exit_restore(cs, retaddr);
}
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 124be448dc..211acad5ae 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1270,7 +1270,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
val = legalize_mpp(env, get_field(mstatus, MSTATUS_MPP), val);
/* flush tlb on mstatus fields that affect VM */
- if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPV)) {
+ if ((val ^ mstatus) & MSTATUS_MXR) {
tlb_flush(env_cpu(env));
}
mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
@@ -1318,10 +1318,6 @@ static RISCVException write_mstatush(CPURISCVState *env, int csrno,
uint64_t valh = (uint64_t)val << 32;
uint64_t mask = MSTATUS_MPV | MSTATUS_GVA;
- if ((valh ^ env->mstatus) & (MSTATUS_MPV)) {
- tlb_flush(env_cpu(env));
- }
-
env->mstatus = (env->mstatus & ~mask) | (valh & mask);
return RISCV_EXCP_NONE;
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 17/25] target/riscv: Check SUM in the correct register
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (15 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 16/25] target/riscv: Set MMU_2STAGE_BIT in riscv_cpu_mmu_index Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 18/25] target/riscv: Hoist second stage mode change to callers Richard Henderson
` (8 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
Table 9.5 "Effect of MPRV..." specifies that MPV=1 uses VS-level
vsstatus.SUM instead of HS-level sstatus.SUM.
For HLV/HSV instructions, the HS-level register does not apply, but
the VS-level register presumably does, though this is not mentioned
explicitly in the manual. However, it matches the behavior for MPV.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-18-richard.henderson@linaro.org>
---
target/riscv/cpu_helper.c | 12 ++++++++----
target/riscv/op_helper.c | 6 +++++-
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index baa4b3a1d2..38bd83f66d 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -42,11 +42,16 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
/* All priv -> mmu_idx mapping are here */
if (!ifetch) {
- if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) {
+ uint64_t status = env->mstatus;
+
+ if (mode == PRV_M && get_field(status, MSTATUS_MPRV)) {
mode = get_field(env->mstatus, MSTATUS_MPP);
virt = get_field(env->mstatus, MSTATUS_MPV);
+ if (virt) {
+ status = env->vsstatus;
+ }
}
- if (mode == PRV_S && get_field(env->mstatus, MSTATUS_SUM)) {
+ if (mode == PRV_S && get_field(status, MSTATUS_SUM)) {
mode = MMUIdx_S_SUM;
}
}
@@ -826,8 +831,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
}
widened = 2;
}
- /* status.SUM will be ignored if execute on background */
- sum = mmuidx_sum(mmu_idx) || use_background || is_debug;
+ sum = mmuidx_sum(mmu_idx) || is_debug;
switch (vm) {
case VM_1_10_SV32:
levels = 2; ptidxbits = 10; ptesize = 4; break;
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 49c19d971d..66a9065a5d 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -437,7 +437,11 @@ static int check_access_hlsv(CPURISCVState *env, bool x, uintptr_t ra)
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, ra);
}
- return get_field(env->hstatus, HSTATUS_SPVP) | MMU_2STAGE_BIT;
+ int mode = get_field(env->hstatus, HSTATUS_SPVP);
+ if (!x && mode == PRV_S && get_field(env->vsstatus, MSTATUS_SUM)) {
+ mode = MMUIdx_S_SUM;
+ }
+ return mode | MMU_2STAGE_BIT;
}
target_ulong helper_hyp_hlv_bu(CPURISCVState *env, target_ulong addr)
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 18/25] target/riscv: Hoist second stage mode change to callers
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (16 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 17/25] target/riscv: Check SUM in the correct register Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 19/25] target/riscv: Hoist pbmte and hade out of the level loop Richard Henderson
` (7 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
Move the check from the top of get_physical_address to
the two callers, where passing mmu_idx makes no sense.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-19-richard.henderson@linaro.org>
---
target/riscv/cpu_helper.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 38bd83f66d..5753e4e612 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -777,14 +777,6 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
use_background = true;
}
- if (first_stage == false) {
- /*
- * We are in stage 2 translation, this is similar to stage 1.
- * Stage 2 is always taken as U-mode
- */
- mode = PRV_U;
- }
-
if (mode == PRV_M || !riscv_cpu_cfg(env)->mmu) {
*physical = addr;
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
@@ -890,7 +882,7 @@ restart:
/* Do the second stage translation on the base PTE address. */
int vbase_ret = get_physical_address(env, &vbase, &vbase_prot,
base, NULL, MMU_DATA_LOAD,
- mmu_idx, false, true,
+ MMUIdx_U, false, true,
is_debug);
if (vbase_ret != TRANSLATE_SUCCESS) {
@@ -1271,7 +1263,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
im_address = pa;
ret = get_physical_address(env, &pa, &prot2, im_address, NULL,
- access_type, mmu_idx, false, true,
+ access_type, MMUIdx_U, false, true,
false);
qemu_log_mask(CPU_LOG_MMU,
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 19/25] target/riscv: Hoist pbmte and hade out of the level loop
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (17 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 18/25] target/riscv: Hoist second stage mode change to callers Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 20/25] target/riscv: Move leaf pte processing out of " Richard Henderson
` (6 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
These values are constant for every level of pte lookup.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-20-richard.henderson@linaro.org>
---
target/riscv/cpu_helper.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 5753e4e612..7c9f89d4d3 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -856,6 +856,14 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
return TRANSLATE_FAIL;
}
+ bool pbmte = env->menvcfg & MENVCFG_PBMTE;
+ bool hade = env->menvcfg & MENVCFG_HADE;
+
+ if (first_stage && two_stage && env->virt_enabled) {
+ pbmte = pbmte && (env->henvcfg & HENVCFG_PBMTE);
+ hade = hade && (env->henvcfg & HENVCFG_HADE);
+ }
+
int ptshift = (levels - 1) * ptidxbits;
int i;
@@ -916,14 +924,6 @@ restart:
return TRANSLATE_FAIL;
}
- bool pbmte = env->menvcfg & MENVCFG_PBMTE;
- bool hade = env->menvcfg & MENVCFG_HADE;
-
- if (first_stage && two_stage && env->virt_enabled) {
- pbmte = pbmte && (env->henvcfg & HENVCFG_PBMTE);
- hade = hade && (env->henvcfg & HENVCFG_HADE);
- }
-
if (riscv_cpu_sxl(env) == MXL_RV32) {
ppn = pte >> PTE_PPN_SHIFT;
} else if (pbmte || riscv_cpu_cfg(env)->ext_svnapot) {
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 20/25] target/riscv: Move leaf pte processing out of level loop
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (18 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 19/25] target/riscv: Hoist pbmte and hade out of the level loop Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 21/25] target/riscv: Suppress pte update with is_debug Richard Henderson
` (5 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
Move the code that never loops outside of the loop.
Unchain the if-return-else statements.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-21-richard.henderson@linaro.org>
---
target/riscv/cpu_helper.c | 238 ++++++++++++++++++++------------------
1 file changed, 125 insertions(+), 113 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 7c9f89d4d3..c2d083f029 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -865,6 +865,8 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
}
int ptshift = (levels - 1) * ptidxbits;
+ target_ulong pte;
+ hwaddr pte_addr;
int i;
#if !TCG_OVERSIZED_GUEST
@@ -881,7 +883,6 @@ restart:
}
/* check that physical address of PTE is legal */
- hwaddr pte_addr;
if (two_stage && first_stage) {
int vbase_prot;
@@ -913,7 +914,6 @@ restart:
return TRANSLATE_PMP_FAIL;
}
- target_ulong pte;
if (riscv_cpu_mxl(env) == MXL_RV32) {
pte = address_space_ldl(cs->as, pte_addr, attrs, &res);
} else {
@@ -938,128 +938,140 @@ restart:
if (!(pte & PTE_V)) {
/* Invalid PTE */
return TRANSLATE_FAIL;
- } else if (!pbmte && (pte & PTE_PBMT)) {
+ }
+ if (pte & (PTE_R | PTE_W | PTE_X)) {
+ goto leaf;
+ }
+
+ /* Inner PTE, continue walking */
+ if (pte & (PTE_D | PTE_A | PTE_U | PTE_ATTR)) {
return TRANSLATE_FAIL;
- } else if (!(pte & (PTE_R | PTE_W | PTE_X))) {
- /* Inner PTE, continue walking */
- if (pte & (PTE_D | PTE_A | PTE_U | PTE_ATTR)) {
- return TRANSLATE_FAIL;
- }
- base = ppn << PGSHIFT;
- } else if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
- /* Reserved leaf PTE flags: PTE_W */
- return TRANSLATE_FAIL;
- } else if ((pte & (PTE_R | PTE_W | PTE_X)) == (PTE_W | PTE_X)) {
- /* Reserved leaf PTE flags: PTE_W + PTE_X */
- return TRANSLATE_FAIL;
- } else if ((pte & PTE_U) && ((mode != PRV_U) &&
- (!sum || access_type == MMU_INST_FETCH))) {
- /* User PTE flags when not U mode and mstatus.SUM is not set,
- or the access type is an instruction fetch */
- return TRANSLATE_FAIL;
- } else if (!(pte & PTE_U) && (mode != PRV_S)) {
- /* Supervisor PTE flags when not S mode */
- return TRANSLATE_FAIL;
- } else if (ppn & ((1ULL << ptshift) - 1)) {
- /* Misaligned PPN */
- return TRANSLATE_FAIL;
- } else if (access_type == MMU_DATA_LOAD && !((pte & PTE_R) ||
- ((pte & PTE_X) && mxr))) {
- /* Read access check failed */
- return TRANSLATE_FAIL;
- } else if (access_type == MMU_DATA_STORE && !(pte & PTE_W)) {
- /* Write access check failed */
- return TRANSLATE_FAIL;
- } else if (access_type == MMU_INST_FETCH && !(pte & PTE_X)) {
- /* Fetch access check failed */
- return TRANSLATE_FAIL;
- } else {
- /* if necessary, set accessed and dirty bits. */
- target_ulong updated_pte = pte | PTE_A |
+ }
+ base = ppn << PGSHIFT;
+ }
+
+ /* No leaf pte at any translation level. */
+ return TRANSLATE_FAIL;
+
+ leaf:
+ if (ppn & ((1ULL << ptshift) - 1)) {
+ /* Misaligned PPN */
+ return TRANSLATE_FAIL;
+ }
+ if (!pbmte && (pte & PTE_PBMT)) {
+ /* Reserved without Svpbmt. */
+ return TRANSLATE_FAIL;
+ }
+ if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
+ /* Reserved leaf PTE flags: PTE_W */
+ return TRANSLATE_FAIL;
+ }
+ if ((pte & (PTE_R | PTE_W | PTE_X)) == (PTE_W | PTE_X)) {
+ /* Reserved leaf PTE flags: PTE_W + PTE_X */
+ return TRANSLATE_FAIL;
+ }
+ if ((pte & PTE_U) &&
+ ((mode != PRV_U) && (!sum || access_type == MMU_INST_FETCH))) {
+ /*
+ * User PTE flags when not U mode and mstatus.SUM is not set,
+ * or the access type is an instruction fetch.
+ */
+ return TRANSLATE_FAIL;
+ }
+ if (!(pte & PTE_U) && (mode != PRV_S)) {
+ /* Supervisor PTE flags when not S mode */
+ return TRANSLATE_FAIL;
+ }
+ if (access_type == MMU_DATA_LOAD &&
+ !((pte & PTE_R) || ((pte & PTE_X) && mxr))) {
+ /* Read access check failed */
+ return TRANSLATE_FAIL;
+ }
+ if (access_type == MMU_DATA_STORE && !(pte & PTE_W)) {
+ /* Write access check failed */
+ return TRANSLATE_FAIL;
+ }
+ if (access_type == MMU_INST_FETCH && !(pte & PTE_X)) {
+ /* Fetch access check failed */
+ return TRANSLATE_FAIL;
+ }
+
+ /* If necessary, set accessed and dirty bits. */
+ target_ulong updated_pte = pte | PTE_A |
(access_type == MMU_DATA_STORE ? PTE_D : 0);
- /* Page table updates need to be atomic with MTTCG enabled */
- if (updated_pte != pte) {
- if (!hade) {
- return TRANSLATE_FAIL;
- }
+ /* Page table updates need to be atomic with MTTCG enabled */
+ if (updated_pte != pte) {
+ if (!hade) {
+ return TRANSLATE_FAIL;
+ }
- /*
- * - if accessed or dirty bits need updating, and the PTE is
- * in RAM, then we do so atomically with a compare and swap.
- * - if the PTE is in IO space or ROM, then it can't be updated
- * and we return TRANSLATE_FAIL.
- * - if the PTE changed by the time we went to update it, then
- * it is no longer valid and we must re-walk the page table.
- */
- MemoryRegion *mr;
- hwaddr l = sizeof(target_ulong), addr1;
- mr = address_space_translate(cs->as, pte_addr, &addr1, &l,
- false, MEMTXATTRS_UNSPECIFIED);
- if (memory_region_is_ram(mr)) {
- target_ulong *pte_pa =
- qemu_map_ram_ptr(mr->ram_block, addr1);
+ /*
+ * - if accessed or dirty bits need updating, and the PTE is
+ * in RAM, then we do so atomically with a compare and swap.
+ * - if the PTE is in IO space or ROM, then it can't be updated
+ * and we return TRANSLATE_FAIL.
+ * - if the PTE changed by the time we went to update it, then
+ * it is no longer valid and we must re-walk the page table.
+ */
+ MemoryRegion *mr;
+ hwaddr l = sizeof(target_ulong), addr1;
+ mr = address_space_translate(cs->as, pte_addr, &addr1, &l,
+ false, MEMTXATTRS_UNSPECIFIED);
+ if (memory_region_is_ram(mr)) {
+ target_ulong *pte_pa = qemu_map_ram_ptr(mr->ram_block, addr1);
#if TCG_OVERSIZED_GUEST
- /*
- * MTTCG is not enabled on oversized TCG guests so
- * page table updates do not need to be atomic
- */
- *pte_pa = pte = updated_pte;
+ /*
+ * MTTCG is not enabled on oversized TCG guests so
+ * page table updates do not need to be atomic
+ */
+ *pte_pa = pte = updated_pte;
#else
- target_ulong old_pte =
- qatomic_cmpxchg(pte_pa, pte, updated_pte);
- if (old_pte != pte) {
- goto restart;
- } else {
- pte = updated_pte;
- }
+ target_ulong old_pte = qatomic_cmpxchg(pte_pa, pte, updated_pte);
+ if (old_pte != pte) {
+ goto restart;
+ }
+ pte = updated_pte;
#endif
- } else {
- /*
- * misconfigured PTE in ROM (AD bits are not preset) or
- * PTE is in IO space and can't be updated atomically
- */
- return TRANSLATE_FAIL;
- }
- }
-
+ } else {
/*
- * for superpage mappings, make a fake leaf PTE for the TLB's
- * benefit.
+ * Misconfigured PTE in ROM (AD bits are not preset) or
+ * PTE is in IO space and can't be updated atomically.
*/
- target_ulong vpn = addr >> PGSHIFT;
-
- if (riscv_cpu_cfg(env)->ext_svnapot && (pte & PTE_N)) {
- napot_bits = ctzl(ppn) + 1;
- if ((i != (levels - 1)) || (napot_bits != 4)) {
- return TRANSLATE_FAIL;
- }
- }
-
- napot_mask = (1 << napot_bits) - 1;
- *physical = (((ppn & ~napot_mask) | (vpn & napot_mask) |
- (vpn & (((target_ulong)1 << ptshift) - 1))
- ) << PGSHIFT) | (addr & ~TARGET_PAGE_MASK);
-
- /* set permissions on the TLB entry */
- if ((pte & PTE_R) || ((pte & PTE_X) && mxr)) {
- *prot |= PAGE_READ;
- }
- if (pte & PTE_X) {
- *prot |= PAGE_EXEC;
- }
- /*
- * add write permission on stores or if the page is already dirty,
- * so that we TLB miss on later writes to update the dirty bit
- */
- if ((pte & PTE_W) &&
- (access_type == MMU_DATA_STORE || (pte & PTE_D))) {
- *prot |= PAGE_WRITE;
- }
- return TRANSLATE_SUCCESS;
+ return TRANSLATE_FAIL;
}
}
- return TRANSLATE_FAIL;
+
+ /* For superpage mappings, make a fake leaf PTE for the TLB's benefit. */
+ target_ulong vpn = addr >> PGSHIFT;
+
+ if (riscv_cpu_cfg(env)->ext_svnapot && (pte & PTE_N)) {
+ napot_bits = ctzl(ppn) + 1;
+ if ((i != (levels - 1)) || (napot_bits != 4)) {
+ return TRANSLATE_FAIL;
+ }
+ }
+
+ napot_mask = (1 << napot_bits) - 1;
+ *physical = (((ppn & ~napot_mask) | (vpn & napot_mask) |
+ (vpn & (((target_ulong)1 << ptshift) - 1))
+ ) << PGSHIFT) | (addr & ~TARGET_PAGE_MASK);
+
+ /* set permissions on the TLB entry */
+ if ((pte & PTE_R) || ((pte & PTE_X) && mxr)) {
+ *prot |= PAGE_READ;
+ }
+ if (pte & PTE_X) {
+ *prot |= PAGE_EXEC;
+ }
+ /*
+ * Add write permission on stores or if the page is already dirty,
+ * so that we TLB miss on later writes to update the dirty bit.
+ */
+ if ((pte & PTE_W) && (access_type == MMU_DATA_STORE || (pte & PTE_D))) {
+ *prot |= PAGE_WRITE;
+ }
+ return TRANSLATE_SUCCESS;
}
static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 21/25] target/riscv: Suppress pte update with is_debug
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (19 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 20/25] target/riscv: Move leaf pte processing out of " Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 22/25] target/riscv: Don't modify SUM " Richard Henderson
` (4 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
The debugger should not modify PTE_A or PTE_D.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-22-richard.henderson@linaro.org>
---
target/riscv/cpu_helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index c2d083f029..6dc3fdf594 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -1001,7 +1001,7 @@ restart:
(access_type == MMU_DATA_STORE ? PTE_D : 0);
/* Page table updates need to be atomic with MTTCG enabled */
- if (updated_pte != pte) {
+ if (updated_pte != pte && !is_debug) {
if (!hade) {
return TRANSLATE_FAIL;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 22/25] target/riscv: Don't modify SUM with is_debug
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (20 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 21/25] target/riscv: Suppress pte update with is_debug Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 23/25] target/riscv: Merge checks for reserved pte flags Richard Henderson
` (3 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
If we want to give the debugger a greater view of memory than
the cpu, we should simply disable the access check entirely,
not simply for this one corner case.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-23-richard.henderson@linaro.org>
---
target/riscv/cpu_helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 6dc3fdf594..9a2b944990 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -823,7 +823,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
}
widened = 2;
}
- sum = mmuidx_sum(mmu_idx) || is_debug;
+ sum = mmuidx_sum(mmu_idx);
switch (vm) {
case VM_1_10_SV32:
levels = 2; ptidxbits = 10; ptesize = 4; break;
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 23/25] target/riscv: Merge checks for reserved pte flags
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (21 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 22/25] target/riscv: Don't modify SUM " Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 24/25] target/riscv: Reorg access check in get_physical_address Richard Henderson
` (2 subsequent siblings)
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-24-richard.henderson@linaro.org>
---
target/riscv/cpu_helper.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 9a2b944990..c7c384bae3 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -962,14 +962,14 @@ restart:
/* Reserved without Svpbmt. */
return TRANSLATE_FAIL;
}
- if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
- /* Reserved leaf PTE flags: PTE_W */
- return TRANSLATE_FAIL;
- }
- if ((pte & (PTE_R | PTE_W | PTE_X)) == (PTE_W | PTE_X)) {
- /* Reserved leaf PTE flags: PTE_W + PTE_X */
+
+ /* Check for reserved combinations of RWX flags. */
+ switch (pte & (PTE_R | PTE_W | PTE_X)) {
+ case PTE_W:
+ case PTE_W | PTE_X:
return TRANSLATE_FAIL;
}
+
if ((pte & PTE_U) &&
((mode != PRV_U) && (!sum || access_type == MMU_INST_FETCH))) {
/*
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 24/25] target/riscv: Reorg access check in get_physical_address
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (22 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 23/25] target/riscv: Merge checks for reserved pte flags Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-12 11:43 ` [PATCH v7 25/25] target/riscv: Reorg sum " Richard Henderson
2023-04-17 2:11 ` [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Alistair Francis
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
We were effectively computing the protection bits twice,
once while performing access checks and once while returning
the valid bits to the caller. Reorg so we do this once.
Move the computation of mxr close to its single use.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-25-richard.henderson@linaro.org>
---
target/riscv/cpu_helper.c | 69 ++++++++++++++++++++-------------------
1 file changed, 36 insertions(+), 33 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index c7c384bae3..7849e18554 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -747,7 +747,7 @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot,
* @is_debug: Is this access from a debugger or the monitor?
*/
static int get_physical_address(CPURISCVState *env, hwaddr *physical,
- int *prot, vaddr addr,
+ int *ret_prot, vaddr addr,
target_ulong *fault_pte_addr,
int access_type, int mmu_idx,
bool first_stage, bool two_stage,
@@ -779,20 +779,14 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
if (mode == PRV_M || !riscv_cpu_cfg(env)->mmu) {
*physical = addr;
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ *ret_prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
return TRANSLATE_SUCCESS;
}
- *prot = 0;
+ *ret_prot = 0;
hwaddr base;
- int levels, ptidxbits, ptesize, vm, sum, mxr, widened;
-
- if (first_stage == true) {
- mxr = get_field(env->mstatus, MSTATUS_MXR);
- } else {
- mxr = get_field(env->vsstatus, MSTATUS_MXR);
- }
+ int levels, ptidxbits, ptesize, vm, sum, widened;
if (first_stage == true) {
if (use_background) {
@@ -835,7 +829,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
levels = 5; ptidxbits = 9; ptesize = 8; break;
case VM_1_10_MBARE:
*physical = addr;
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ *ret_prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
return TRANSLATE_SUCCESS;
default:
g_assert_not_reached();
@@ -970,6 +964,27 @@ restart:
return TRANSLATE_FAIL;
}
+ int prot = 0;
+ if (pte & PTE_R) {
+ prot |= PAGE_READ;
+ }
+ if (pte & PTE_W) {
+ prot |= PAGE_WRITE;
+ }
+ if (pte & PTE_X) {
+ bool mxr;
+
+ if (first_stage == true) {
+ mxr = get_field(env->mstatus, MSTATUS_MXR);
+ } else {
+ mxr = get_field(env->vsstatus, MSTATUS_MXR);
+ }
+ if (mxr) {
+ prot |= PAGE_READ;
+ }
+ prot |= PAGE_EXEC;
+ }
+
if ((pte & PTE_U) &&
((mode != PRV_U) && (!sum || access_type == MMU_INST_FETCH))) {
/*
@@ -982,17 +997,9 @@ restart:
/* Supervisor PTE flags when not S mode */
return TRANSLATE_FAIL;
}
- if (access_type == MMU_DATA_LOAD &&
- !((pte & PTE_R) || ((pte & PTE_X) && mxr))) {
- /* Read access check failed */
- return TRANSLATE_FAIL;
- }
- if (access_type == MMU_DATA_STORE && !(pte & PTE_W)) {
- /* Write access check failed */
- return TRANSLATE_FAIL;
- }
- if (access_type == MMU_INST_FETCH && !(pte & PTE_X)) {
- /* Fetch access check failed */
+
+ if (!((prot >> access_type) & 1)) {
+ /* Access check failed */
return TRANSLATE_FAIL;
}
@@ -1057,20 +1064,16 @@ restart:
(vpn & (((target_ulong)1 << ptshift) - 1))
) << PGSHIFT) | (addr & ~TARGET_PAGE_MASK);
- /* set permissions on the TLB entry */
- if ((pte & PTE_R) || ((pte & PTE_X) && mxr)) {
- *prot |= PAGE_READ;
- }
- if (pte & PTE_X) {
- *prot |= PAGE_EXEC;
- }
/*
- * Add write permission on stores or if the page is already dirty,
- * so that we TLB miss on later writes to update the dirty bit.
+ * Remove write permission unless this is a store, or the page is
+ * already dirty, so that we TLB miss on later writes to update
+ * the dirty bit.
*/
- if ((pte & PTE_W) && (access_type == MMU_DATA_STORE || (pte & PTE_D))) {
- *prot |= PAGE_WRITE;
+ if (access_type != MMU_DATA_STORE && !(pte & PTE_D)) {
+ prot &= ~PAGE_WRITE;
}
+ *ret_prot = prot;
+
return TRANSLATE_SUCCESS;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v7 25/25] target/riscv: Reorg sum check in get_physical_address
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (23 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 24/25] target/riscv: Reorg access check in get_physical_address Richard Henderson
@ 2023-04-12 11:43 ` Richard Henderson
2023-04-17 2:11 ` [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Alistair Francis
25 siblings, 0 replies; 27+ messages in thread
From: Richard Henderson @ 2023-04-12 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: alistair23, qemu-riscv, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza
Implement this by adjusting prot, which reduces the set of
checks required. This prevents exec to be set for U pages
in MMUIdx_S_SUM. While it had been technically incorrect,
it did not manifest as a bug, because we will never attempt
to execute from MMUIdx_S_SUM.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-26-richard.henderson@linaro.org>
---
target/riscv/cpu_helper.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 7849e18554..32a65f8007 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -786,7 +786,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
*ret_prot = 0;
hwaddr base;
- int levels, ptidxbits, ptesize, vm, sum, widened;
+ int levels, ptidxbits, ptesize, vm, widened;
if (first_stage == true) {
if (use_background) {
@@ -817,7 +817,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
}
widened = 2;
}
- sum = mmuidx_sum(mmu_idx);
+
switch (vm) {
case VM_1_10_SV32:
levels = 2; ptidxbits = 10; ptesize = 4; break;
@@ -985,15 +985,15 @@ restart:
prot |= PAGE_EXEC;
}
- if ((pte & PTE_U) &&
- ((mode != PRV_U) && (!sum || access_type == MMU_INST_FETCH))) {
- /*
- * User PTE flags when not U mode and mstatus.SUM is not set,
- * or the access type is an instruction fetch.
- */
- return TRANSLATE_FAIL;
- }
- if (!(pte & PTE_U) && (mode != PRV_S)) {
+ if (pte & PTE_U) {
+ if (mode != PRV_U) {
+ if (!mmuidx_sum(mmu_idx)) {
+ return TRANSLATE_FAIL;
+ }
+ /* SUM allows only read+write, not execute. */
+ prot &= PAGE_READ | PAGE_WRITE;
+ }
+ } else if (mode != PRV_S) {
/* Supervisor PTE flags when not S mode */
return TRANSLATE_FAIL;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
` (24 preceding siblings ...)
2023-04-12 11:43 ` [PATCH v7 25/25] target/riscv: Reorg sum " Richard Henderson
@ 2023-04-17 2:11 ` Alistair Francis
25 siblings, 0 replies; 27+ messages in thread
From: Alistair Francis @ 2023-04-17 2:11 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, qemu-riscv
On Wed, Apr 12, 2023 at 9:43 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> v6: 20230325105429.1142530-1-richard.henderson@linaro.org
>
> Changes for v7:
> * Rebase on Alistair's riscv-to-apply.next.
> * Replace priv_level() with ctx->priv in trans_xthead.c.inc (Zhiwei).
>
>
> r~
>
>
> Fei Wu (2):
> target/riscv: Separate priv from mmu_idx
> target/riscv: Reduce overhead of MSTATUS_SUM change
>
> LIU Zhiwei (4):
> target/riscv: Extract virt enabled state from tb flags
> target/riscv: Add a general status enum for extensions
> target/riscv: Encode the FS and VS on a normal way for tb flags
> target/riscv: Add a tb flags field for vstart
>
> Richard Henderson (19):
> target/riscv: Remove mstatus_hs_{fs, vs} from tb_flags
> accel/tcg: Add cpu_ld*_code_mmu
> target/riscv: Use cpu_ld*_code_mmu for HLVX
> target/riscv: Handle HLV, HSV via helpers
> target/riscv: Rename MMU_HYP_ACCESS_BIT to MMU_2STAGE_BIT
> target/riscv: Introduce mmuidx_sum
> target/riscv: Introduce mmuidx_priv
> target/riscv: Introduce mmuidx_2stage
> target/riscv: Move hstatus.spvp check to check_access_hlsv
> target/riscv: Set MMU_2STAGE_BIT in riscv_cpu_mmu_index
> target/riscv: Check SUM in the correct register
> target/riscv: Hoist second stage mode change to callers
> target/riscv: Hoist pbmte and hade out of the level loop
> target/riscv: Move leaf pte processing out of level loop
> target/riscv: Suppress pte update with is_debug
> target/riscv: Don't modify SUM with is_debug
> target/riscv: Merge checks for reserved pte flags
> target/riscv: Reorg access check in get_physical_address
> target/riscv: Reorg sum check in get_physical_address
Thanks!
Applied to riscv-to-apply.next
Alistair
>
> include/exec/cpu_ldst.h | 9 +
> target/riscv/cpu.h | 47 +-
> target/riscv/cpu_bits.h | 12 +-
> target/riscv/helper.h | 12 +-
> target/riscv/internals.h | 35 ++
> accel/tcg/cputlb.c | 48 +++
> accel/tcg/user-exec.c | 58 +++
> target/riscv/cpu.c | 2 +-
> target/riscv/cpu_helper.c | 403 +++++++++---------
> target/riscv/csr.c | 21 +-
> target/riscv/op_helper.c | 113 ++++-
> target/riscv/translate.c | 70 +--
> .../riscv/insn_trans/trans_privileged.c.inc | 2 +-
> target/riscv/insn_trans/trans_rvf.c.inc | 2 +-
> target/riscv/insn_trans/trans_rvh.c.inc | 137 +++---
> target/riscv/insn_trans/trans_rvv.c.inc | 22 +-
> target/riscv/insn_trans/trans_xthead.c.inc | 14 +-
> 17 files changed, 591 insertions(+), 416 deletions(-)
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2023-04-17 2:13 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-12 11:43 [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Richard Henderson
2023-04-12 11:43 ` [PATCH v7 01/25] target/riscv: Extract virt enabled state from tb flags Richard Henderson
2023-04-12 11:43 ` [PATCH v7 02/25] target/riscv: Add a general status enum for extensions Richard Henderson
2023-04-12 11:43 ` [PATCH v7 03/25] target/riscv: Encode the FS and VS on a normal way for tb flags Richard Henderson
2023-04-12 11:43 ` [PATCH v7 04/25] target/riscv: Remove mstatus_hs_{fs, vs} from tb_flags Richard Henderson
2023-04-12 11:43 ` [PATCH v7 05/25] target/riscv: Add a tb flags field for vstart Richard Henderson
2023-04-12 11:43 ` [PATCH v7 06/25] target/riscv: Separate priv from mmu_idx Richard Henderson
2023-04-12 11:43 ` [PATCH v7 07/25] target/riscv: Reduce overhead of MSTATUS_SUM change Richard Henderson
2023-04-12 11:43 ` [PATCH v7 08/25] accel/tcg: Add cpu_ld*_code_mmu Richard Henderson
2023-04-12 11:43 ` [PATCH v7 09/25] target/riscv: Use cpu_ld*_code_mmu for HLVX Richard Henderson
2023-04-12 11:43 ` [PATCH v7 10/25] target/riscv: Handle HLV, HSV via helpers Richard Henderson
2023-04-12 11:43 ` [PATCH v7 11/25] target/riscv: Rename MMU_HYP_ACCESS_BIT to MMU_2STAGE_BIT Richard Henderson
2023-04-12 11:43 ` [PATCH v7 12/25] target/riscv: Introduce mmuidx_sum Richard Henderson
2023-04-12 11:43 ` [PATCH v7 13/25] target/riscv: Introduce mmuidx_priv Richard Henderson
2023-04-12 11:43 ` [PATCH v7 14/25] target/riscv: Introduce mmuidx_2stage Richard Henderson
2023-04-12 11:43 ` [PATCH v7 15/25] target/riscv: Move hstatus.spvp check to check_access_hlsv Richard Henderson
2023-04-12 11:43 ` [PATCH v7 16/25] target/riscv: Set MMU_2STAGE_BIT in riscv_cpu_mmu_index Richard Henderson
2023-04-12 11:43 ` [PATCH v7 17/25] target/riscv: Check SUM in the correct register Richard Henderson
2023-04-12 11:43 ` [PATCH v7 18/25] target/riscv: Hoist second stage mode change to callers Richard Henderson
2023-04-12 11:43 ` [PATCH v7 19/25] target/riscv: Hoist pbmte and hade out of the level loop Richard Henderson
2023-04-12 11:43 ` [PATCH v7 20/25] target/riscv: Move leaf pte processing out of " Richard Henderson
2023-04-12 11:43 ` [PATCH v7 21/25] target/riscv: Suppress pte update with is_debug Richard Henderson
2023-04-12 11:43 ` [PATCH v7 22/25] target/riscv: Don't modify SUM " Richard Henderson
2023-04-12 11:43 ` [PATCH v7 23/25] target/riscv: Merge checks for reserved pte flags Richard Henderson
2023-04-12 11:43 ` [PATCH v7 24/25] target/riscv: Reorg access check in get_physical_address Richard Henderson
2023-04-12 11:43 ` [PATCH v7 25/25] target/riscv: Reorg sum " Richard Henderson
2023-04-17 2:11 ` [PATCH v7 00/25] target/riscv: MSTATUS_SUM + cleanups Alistair Francis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).