Skip to content

Commit 379791a

Browse files
authored
Merge pull request #1995 from apparentlymart/f-qemu-backport-wfi-umode
[QEMU backport] riscv: fix wfi exception behavior
2 parents 87610ba + 58f1a61 commit 379791a

File tree

2 files changed

+9
-4
lines changed

2 files changed

+9
-4
lines changed

qemu/target/riscv/cpu_bits.h

+1
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@
427427
#define HSTATUS_SP2P 0x00000100
428428
#define HSTATUS_SP2V 0x00000200
429429
#define HSTATUS_VTVM 0x00100000
430+
#define HSTATUS_VTW 0x00200000
430431
#define HSTATUS_VTSR 0x00400000
431432

432433
#define HSTATUS32_WPRI 0xFF8FF87E

qemu/target/riscv/op_helper.c

+8-4
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,15 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
172172
void helper_wfi(CPURISCVState *env)
173173
{
174174
CPUState *cs = env_cpu(env);
175+
bool rvs = riscv_has_ext(env, RVS);
176+
bool prv_u = env->priv == PRV_U;
177+
bool prv_s = env->priv == PRV_S;
175178

176-
if ((env->priv == PRV_S &&
177-
env->priv_ver >= PRIV_VERSION_1_10_0 &&
178-
get_field(env->mstatus, MSTATUS_TW)) ||
179-
riscv_cpu_virt_enabled(env)) {
179+
if (((prv_s || (!rvs && prv_u)) && get_field(env->mstatus, MSTATUS_TW)) ||
180+
(rvs && prv_u && !riscv_cpu_virt_enabled(env))) {
181+
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
182+
} else if (riscv_cpu_virt_enabled(env) && (prv_u ||
183+
(prv_s && get_field(env->hstatus, HSTATUS_VTW)))) {
180184
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
181185
} else {
182186
cs->halted = 1;

0 commit comments

Comments
 (0)