* [PATCH 0/2] target/arm: SME vs FP enable fixes
@ 2025-03-07 19:04 Richard Henderson
2025-03-07 19:04 ` [PATCH 1/2] target/arm: Make DisasContext.{fp, sve}_access_checked tristate Richard Henderson
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Richard Henderson @ 2025-03-07 19:04 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-arm
If SME Streaming Mode is enabled, but FP is disabled, we get two
assertion failures within the translator. Beyond the assertions,
this combination should succeed because we're executing on the
SME co-processor's registers, not the core cpu's AdvSIMD registers.
r~
Richard Henderson (2):
target/arm: Make DisasContext.{fp,sve}_access_checked tristate
target/arm: Simplify pstate_sm check in sve_access_check
target/arm/tcg/translate-a64.h | 2 +-
target/arm/tcg/translate.h | 10 +++++++---
target/arm/tcg/translate-a64.c | 35 +++++++++++++++++-----------------
3 files changed, 25 insertions(+), 22 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] target/arm: Make DisasContext.{fp, sve}_access_checked tristate
2025-03-07 19:04 [PATCH 0/2] target/arm: SME vs FP enable fixes Richard Henderson
@ 2025-03-07 19:04 ` Richard Henderson
2025-03-07 19:04 ` [PATCH 2/2] target/arm: Simplify pstate_sm check in sve_access_check Richard Henderson
2025-03-12 14:39 ` [PATCH 0/2] target/arm: SME vs FP enable fixes Peter Maydell
2 siblings, 0 replies; 4+ messages in thread
From: Richard Henderson @ 2025-03-07 19:04 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-arm, qemu-stable
The check for fp_excp_el in assert_fp_access_checked is
incorrect. For SME, with StreamingMode enabled, the access
is really against the streaming mode vectors, and access
to the normal fp registers is allowed to be disabled.
C.f. sme_enabled_check.
Convert sve_access_checked to match, even though we don't
currently check the exception state.
Cc: qemu-stable@nongnu.org
Fixes: 3d74825f4d6 ("target/arm: Add SME enablement checks")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/tcg/translate-a64.h | 2 +-
target/arm/tcg/translate.h | 10 +++++++---
target/arm/tcg/translate-a64.c | 17 +++++++++--------
3 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
index 7d3b59ccd9..b2420f59eb 100644
--- a/target/arm/tcg/translate-a64.h
+++ b/target/arm/tcg/translate-a64.h
@@ -65,7 +65,7 @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
static inline void assert_fp_access_checked(DisasContext *s)
{
#ifdef CONFIG_DEBUG_TCG
- if (unlikely(!s->fp_access_checked || s->fp_excp_el)) {
+ if (unlikely(s->fp_access_checked <= 0)) {
fprintf(stderr, "target-arm: FP access check missing for "
"instruction 0x%08x\n", s->insn);
abort();
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index f8dc2f0d4b..53e485d28a 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -92,15 +92,19 @@ typedef struct DisasContext {
bool aarch64;
bool thumb;
bool lse2;
- /* Because unallocated encodings generate different exception syndrome
+ /*
+ * Because unallocated encodings generate different exception syndrome
* information from traps due to FP being disabled, we can't do a single
* "is fp access disabled" check at a high level in the decode tree.
* To help in catching bugs where the access check was forgotten in some
* code path, we set this flag when the access check is done, and assert
* that it is set at the point where we actually touch the FP regs.
+ * 0: not checked,
+ * 1: checked, access ok
+ * -1: checked, access denied
*/
- bool fp_access_checked;
- bool sve_access_checked;
+ int8_t fp_access_checked;
+ int8_t sve_access_checked;
/* ARMv8 single-step state (this is distinct from the QEMU gdbstub
* single-step support).
*/
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 8bef391bb0..48e0ac75b1 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -1381,14 +1381,14 @@ static bool fp_access_check_only(DisasContext *s)
{
if (s->fp_excp_el) {
assert(!s->fp_access_checked);
- s->fp_access_checked = true;
+ s->fp_access_checked = -1;
gen_exception_insn_el(s, 0, EXCP_UDEF,
syn_fp_access_trap(1, 0xe, false, 0),
s->fp_excp_el);
return false;
}
- s->fp_access_checked = true;
+ s->fp_access_checked = 1;
return true;
}
@@ -1465,13 +1465,13 @@ bool sve_access_check(DisasContext *s)
syn_sve_access_trap(), s->sve_excp_el);
goto fail_exit;
}
- s->sve_access_checked = true;
+ s->sve_access_checked = 1;
return fp_access_check(s);
fail_exit:
/* Assert that we only raise one exception per instruction. */
assert(!s->sve_access_checked);
- s->sve_access_checked = true;
+ s->sve_access_checked = -1;
return false;
}
@@ -1500,8 +1500,9 @@ bool sme_enabled_check(DisasContext *s)
* sme_excp_el by itself for cpregs access checks.
*/
if (!s->fp_excp_el || s->sme_excp_el < s->fp_excp_el) {
- s->fp_access_checked = true;
- return sme_access_check(s);
+ bool ret = sme_access_check(s);
+ s->fp_access_checked = (ret ? 1 : -1);
+ return ret;
}
return fp_access_check_only(s);
}
@@ -10257,8 +10258,8 @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
s->insn = insn;
s->base.pc_next = pc + 4;
- s->fp_access_checked = false;
- s->sve_access_checked = false;
+ s->fp_access_checked = 0;
+ s->sve_access_checked = 0;
if (s->pstate_il) {
/*
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] target/arm: Simplify pstate_sm check in sve_access_check
2025-03-07 19:04 [PATCH 0/2] target/arm: SME vs FP enable fixes Richard Henderson
2025-03-07 19:04 ` [PATCH 1/2] target/arm: Make DisasContext.{fp, sve}_access_checked tristate Richard Henderson
@ 2025-03-07 19:04 ` Richard Henderson
2025-03-12 14:39 ` [PATCH 0/2] target/arm: SME vs FP enable fixes Peter Maydell
2 siblings, 0 replies; 4+ messages in thread
From: Richard Henderson @ 2025-03-07 19:04 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-arm, qemu-stable
In StreamingMode, fp_access_checked is handled already.
We cannot fall through to fp_access_check lest we fall
foul of the double-check assertion.
Cc: qemu-stable@nongnu.org
Fixes: 285b1d5fcef ("target/arm: Handle SME in sve_access_check")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/tcg/translate-a64.c | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 48e0ac75b1..723cb3f24a 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -1457,22 +1457,20 @@ bool sve_access_check(DisasContext *s)
{
if (s->pstate_sm || !dc_isar_feature(aa64_sve, s)) {
assert(dc_isar_feature(aa64_sme, s));
- if (!sme_sm_enabled_check(s)) {
- goto fail_exit;
- }
- } else if (s->sve_excp_el) {
+ bool ret = sme_sm_enabled_check(s);
+ s->sve_access_checked = (ret ? 1 : -1);
+ return ret;
+ }
+ if (s->sve_excp_el) {
+ /* Assert that we only raise one exception per instruction. */
+ assert(!s->sve_access_checked);
gen_exception_insn_el(s, 0, EXCP_UDEF,
syn_sve_access_trap(), s->sve_excp_el);
- goto fail_exit;
+ s->sve_access_checked = -1;
+ return false;
}
s->sve_access_checked = 1;
return fp_access_check(s);
-
- fail_exit:
- /* Assert that we only raise one exception per instruction. */
- assert(!s->sve_access_checked);
- s->sve_access_checked = -1;
- return false;
}
/*
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 0/2] target/arm: SME vs FP enable fixes
2025-03-07 19:04 [PATCH 0/2] target/arm: SME vs FP enable fixes Richard Henderson
2025-03-07 19:04 ` [PATCH 1/2] target/arm: Make DisasContext.{fp, sve}_access_checked tristate Richard Henderson
2025-03-07 19:04 ` [PATCH 2/2] target/arm: Simplify pstate_sm check in sve_access_check Richard Henderson
@ 2025-03-12 14:39 ` Peter Maydell
2 siblings, 0 replies; 4+ messages in thread
From: Peter Maydell @ 2025-03-12 14:39 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, qemu-arm
On Fri, 7 Mar 2025 at 19:05, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> If SME Streaming Mode is enabled, but FP is disabled, we get two
> assertion failures within the translator. Beyond the assertions,
> this combination should succeed because we're executing on the
> SME co-processor's registers, not the core cpu's AdvSIMD registers.
Patch 2 has a 'bool ret' declaration that needs to move to
the top of its block. Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
and applied to target-arm.next with that minor tweak.
thanks
-- PMM
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-03-12 14:40 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-07 19:04 [PATCH 0/2] target/arm: SME vs FP enable fixes Richard Henderson
2025-03-07 19:04 ` [PATCH 1/2] target/arm: Make DisasContext.{fp, sve}_access_checked tristate Richard Henderson
2025-03-07 19:04 ` [PATCH 2/2] target/arm: Simplify pstate_sm check in sve_access_check Richard Henderson
2025-03-12 14:39 ` [PATCH 0/2] target/arm: SME vs FP enable fixes Peter Maydell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).