diff mbox series

target/arm: Fix SME vs AdvSIMD exception priority

Message ID 20250622175052.180728-1-richard.henderson@linaro.org
State Superseded
Headers show
Series target/arm: Fix SME vs AdvSIMD exception priority | expand

Commit Message

Richard Henderson June 22, 2025, 5:50 p.m. UTC
We failed to raise an exception when
sme_excp_el == 0 and fp_excp_el == 1.

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.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Richard Henderson June 22, 2025, 6:30 p.m. UTC | #1
On 6/22/25 10:50, Richard Henderson wrote:
> We failed to raise an exception when
> sme_excp_el == 0 and fp_excp_el == 1.
> 
> 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.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
> index 297064806e..427f029e28 100644
> --- a/target/arm/tcg/translate-a64.c
> +++ b/target/arm/tcg/translate-a64.c
> @@ -1494,7 +1494,8 @@ bool sme_enabled_check(DisasContext *s)
>        * to be zero when fp_excp_el has priority.  This is because we need
>        * sme_excp_el by itself for cpregs access checks.
>        */
> -    if (!s->fp_excp_el || s->sme_excp_el < s->fp_excp_el) {
> +    if (s->sme_excp_el
> +        && (!s->fp_excp_el || s->sme_excp_el < s->fp_excp_el)) {

One more fix: <=
SMEN is checked before FPEN in each block of CheckSMEEnabled().


r~
diff mbox series

Patch

diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 297064806e..427f029e28 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -1494,7 +1494,8 @@  bool sme_enabled_check(DisasContext *s)
      * to be zero when fp_excp_el has priority.  This is because we need
      * sme_excp_el by itself for cpregs access checks.
      */
-    if (!s->fp_excp_el || s->sme_excp_el < s->fp_excp_el) {
+    if (s->sme_excp_el
+        && (!s->fp_excp_el || s->sme_excp_el < s->fp_excp_el)) {
         bool ret = sme_access_check(s);
         s->fp_access_checked = (ret ? 1 : -1);
         return ret;