Hi,
On 6/22/2026 7:45 PM, [email protected] wrote:
From: Portia Stephens <[email protected]>
According to the priv spec "Attempting to execute SFENCE.W.INVAL or
SFENCE.INVAL.IR in U-mode raises an illegal-instruction exception." Fix
the current implementation to generate exception.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3543
Signed-off-by: Portia Stephens <[email protected]>
---
target/riscv/insn_trans/trans_svinval.c.inc | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/target/riscv/insn_trans/trans_svinval.c.inc
b/target/riscv/insn_trans/trans_svinval.c.inc
index a06c3b214f..10cb9e32b6 100644
--- a/target/riscv/insn_trans/trans_svinval.c.inc
+++ b/target/riscv/insn_trans/trans_svinval.c.inc
@@ -39,6 +39,12 @@ static bool trans_sfence_w_inval(DisasContext *ctx,
arg_sfence_w_inval *a)
{
REQUIRE_SVINVAL(ctx);
REQUIRE_EXT(ctx, RVS);
+ if (ctx->priv == PRV_U) {
+ /* Set the virtual exception if virt enabled */
+ ctx->virt_inst_excp = ctx->virt_enabled;
+ gen_exception_illegal(ctx);
+ return false;
+ }
I am afraid that the bug is already fixed in master by:
commit a4a35544e43220657f718a5d0be5ab49c6129000
Author: Zephyr Li <[email protected]>
Date: Fri May 22 11:31:44 2026 +0800
target/riscv: Reject Svinval instructions in U-mode
We now have this macro that is called in all those insns:
/* Test if priv level is M or S. */
#define REQUIRE_PRIV_MS(ctx) do { \
if (ctx->priv == PRV_U) { \
return false; \
} \
} while (0)
That said, your code is setting virtual exceptions too. Feel free to re-send
this patch enhancing the REQUIRE_PRIV_MS() macro to do the same.
I'll close the gitlab bug as dup/already fixed. Thanks,
Daniel
/* Do nothing currently */
return true;
}
@@ -47,6 +53,12 @@ static bool trans_sfence_inval_ir(DisasContext *ctx,
arg_sfence_inval_ir *a)
{
REQUIRE_SVINVAL(ctx);
REQUIRE_EXT(ctx, RVS);
+ if (ctx->priv == PRV_U) {
+ /* Set the virtual exception if virt enabled */
+ ctx->virt_inst_excp = ctx->virt_enabled;
+ gen_exception_illegal(ctx);
+ return false;
+ }
/* Do nothing currently */
return true;
}