target/riscv/insn_trans/trans_svinval.c.inc | 12 ++++++++++++ 1 file changed, 12 insertions(+)
From: Portia Stephens <portias@oss.tenstorrent.com>
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 <portias@oss.tenstorrent.com>
---
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;
+ }
/* 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;
}
--
2.43.0
Hi,
On 6/22/2026 7:45 PM, stephensportia@gmail.com wrote:
> From: Portia Stephens <portias@oss.tenstorrent.com>
>
> 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 <portias@oss.tenstorrent.com>
> ---
> 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 <fritchleybohrer@gmail.com>
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;
> }
On 6/22/26 15:45, stephensportia@gmail.com wrote:
> From: Portia Stephens <portias@oss.tenstorrent.com>
>
> 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 <portias@oss.tenstorrent.com>
> ---
> 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;
> + }
If you generate code, such as raising an exception, never return false.
False means "this is not the instruction you are looking for, continue matching".
True means "this is the correct instruction", regardless if that instruction is illegal to
be executed in the current context.
r~
© 2016 - 2026 Red Hat, Inc.