target/riscv: Add a helper to return the current effective priv mode
This helper returns the current effective privilege mode. Signed-off-by: Frank Chang <frank.chang@sifive.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20260421093715.2995067-3-frank.chang@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Frank Chang committed
Apr 21, 2026 at 17:37 UTC
f359e463015c2f22388eeb4743e93e1176f93abe
2 files changed
+42
-10
target/riscv/cpu.h
+37
@@ -806,6 +806,43 @@ static inline RISCVMXL riscv_cpu_sxl(CPURISCVState *env)
806
}
807
#endif
808
809
+/*
810
+ * Returns the current effective privilege mode.
811
+ *
812
+ * @env: CPURISCVState
813
+ * @priv: The returned effective privilege mode.
814
+ * @virt: The returned effective virtualization mode.
815
+ *
816
+ * Returns true if the effective privilege mode is modified.
817
+ */
818
+static inline QEMU_ALWAYS_INLINE
819
+bool riscv_cpu_eff_priv(CPURISCVState *env, int *priv, bool *virt)
820
+{
821
+ int mode = env->priv;
822
+ bool virt_enabled = false;
823
+ bool mode_modified = false;
824
+
825
+#ifndef CONFIG_USER_ONLY
826
+ if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) {
827
+ mode = get_field(env->mstatus, MSTATUS_MPP);
828
+ virt_enabled = get_field(env->mstatus, MSTATUS_MPV) && (mode != PRV_M);
829
+ mode_modified = true;
830
+ } else {
831
+ virt_enabled = env->virt_enabled;
832
+ }
833
+#endif
834
+
835
+ if (priv) {
836
+ *priv = mode;
837
+ }
838
+
839
+ if (virt) {
840
+ *virt = virt_enabled;
841
+ }
842
+
843
+ return mode_modified;
844
+}
845
+
846
static inline bool riscv_cpu_allow_16bit_insn(const RISCVCPUConfig *cfg,
847
target_long priv_ver,
848
uint32_t misa_ext)
target/riscv/cpu_helper.c
+5
-10
@@ -45,19 +45,14 @@ int riscv_env_mmu_index(CPURISCVState *env, bool ifetch)
45
#else
46
bool virt = env->virt_enabled;
47
int mode = env->priv;
48
+ bool mode_modified = false;
49
50
/* All priv -> mmu_idx mapping are here */
51
if (!ifetch) {
51
- uint64_t status = env->mstatus;
52
-
53
- if (mode == PRV_M && get_field(status, MSTATUS_MPRV)) {
54
- mode = get_field(env->mstatus, MSTATUS_MPP);
55
- virt = get_field(env->mstatus, MSTATUS_MPV) &&
56
- (mode != PRV_M);
57
- if (virt) {
58
- status = env->vsstatus;
59
- }
60
- }
52
+ mode_modified = riscv_cpu_eff_priv(env, &mode, &virt);
53
+ uint64_t status = (mode_modified && virt) ? env->vsstatus :
54
+ env->mstatus;
55
+
56
if (mode == PRV_S && get_field(status, MSTATUS_SUM)) {
57
mode = MMUIdx_S_SUM;
58
}