diff --git a/qemu/target/riscv/cpu_bits.h b/qemu/target/riscv/cpu_bits.h
index f40ea2617e..ffa73864a9 100644
--- a/qemu/target/riscv/cpu_bits.h
+++ b/qemu/target/riscv/cpu_bits.h
@@ -427,6 +427,7 @@
 #define HSTATUS_SP2P         0x00000100
 #define HSTATUS_SP2V         0x00000200
 #define HSTATUS_VTVM         0x00100000
+#define HSTATUS_VTW          0x00200000
 #define HSTATUS_VTSR         0x00400000
 
 #define HSTATUS32_WPRI       0xFF8FF87E
diff --git a/qemu/target/riscv/op_helper.c b/qemu/target/riscv/op_helper.c
index 05dd67aeae..5afb2ce881 100644
--- a/qemu/target/riscv/op_helper.c
+++ b/qemu/target/riscv/op_helper.c
@@ -172,11 +172,15 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
 void helper_wfi(CPURISCVState *env)
 {
     CPUState *cs = env_cpu(env);
+    bool rvs = riscv_has_ext(env, RVS);
+    bool prv_u = env->priv == PRV_U;
+    bool prv_s = env->priv == PRV_S;
 
-    if ((env->priv == PRV_S &&
-        env->priv_ver >= PRIV_VERSION_1_10_0 &&
-        get_field(env->mstatus, MSTATUS_TW)) ||
-        riscv_cpu_virt_enabled(env)) {
+    if (((prv_s || (!rvs && prv_u)) && get_field(env->mstatus, MSTATUS_TW)) ||
+        (rvs && prv_u && !riscv_cpu_virt_enabled(env))) {
+        riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
+    } else if (riscv_cpu_virt_enabled(env) && (prv_u ||
+        (prv_s && get_field(env->hstatus, HSTATUS_VTW)))) {
         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
     } else {
         cs->halted = 1;