diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c index d53742e10b..5e93d27d8f 100644 --- a/linux-user/aarch64/cpu_loop.c +++ b/linux-user/aarch64/cpu_loop.c @@ -96,7 +96,6 @@ void cpu_loop(CPUARMState *env) aarch64_set_svcr(env, 0, R_SVCR_SM_MASK); if (FIELD_EX64(env->svcr, SVCR, SM)) { arm_rebuild_hflags(env); - arm_reset_sve_state(env); } ret = do_syscall(env, env->xregs[8], diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c index b6e4dcb494..a326a6def5 100644 --- a/linux-user/aarch64/signal.c +++ b/linux-user/aarch64/signal.c @@ -665,14 +665,8 @@ static void target_setup_frame(int usig, struct target_sigaction *ka, env->btype = 2; } - /* - * Invoke the signal handler with both SM and ZA disabled. - * When clearing SM, ResetSVEState, per SMSTOP. - */ + /* Invoke the signal handler with both SM and ZA disabled. */ aarch64_set_svcr(env, 0, R_SVCR_SM_MASK | R_SVCR_ZA_MASK); - if (FIELD_EX64(env->svcr, SVCR, SM)) { - arm_reset_sve_state(env); - } if (env->svcr) { arm_rebuild_hflags(env); } diff --git a/target/arm/cpu.h b/target/arm/cpu.h index ef61849eb1..f3ddc3b779 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1124,7 +1124,6 @@ void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq); void aarch64_sve_change_el(CPUARMState *env, int old_el, int new_el, bool el0_a64); void aarch64_set_svcr(CPUARMState *env, uint64_t new, uint64_t mask); -void arm_reset_sve_state(CPUARMState *env); /* * SVE registers are encoded in KVM's memory in an endianness-invariant format. diff --git a/target/arm/helper.c b/target/arm/helper.c index 24c069b8ac..0ac867c411 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6725,11 +6725,24 @@ static CPAccessResult access_esm(CPUARMState *env, const ARMCPRegInfo *ri, return CP_ACCESS_OK; } +/* ResetSVEState */ +static void arm_reset_sve_state(CPUARMState *env) +{ + memset(env->vfp.zregs, 0, sizeof(env->vfp.zregs)); + /* Recall that FFR is stored as pregs[16]. */ + memset(env->vfp.pregs, 0, sizeof(env->vfp.pregs)); + vfp_set_fpcr(env, 0x0800009f); +} + void aarch64_set_svcr(CPUARMState *env, uint64_t new, uint64_t mask) { uint64_t change = (env->svcr ^ new) & mask; env->svcr ^= change; + + if (change & R_SVCR_SM_MASK) { + arm_reset_sve_state(env); + } } static void svcr_write(CPUARMState *env, const ARMCPRegInfo *ri, diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c index 94dc084135..f73bf4d285 100644 --- a/target/arm/sme_helper.c +++ b/target/arm/sme_helper.c @@ -29,22 +29,12 @@ #include "vec_internal.h" #include "sve_ldst_internal.h" -/* ResetSVEState */ -void arm_reset_sve_state(CPUARMState *env) -{ - memset(env->vfp.zregs, 0, sizeof(env->vfp.zregs)); - /* Recall that FFR is stored as pregs[16]. */ - memset(env->vfp.pregs, 0, sizeof(env->vfp.pregs)); - vfp_set_fpcr(env, 0x0800009f); -} - void helper_set_pstate_sm(CPUARMState *env, uint32_t i) { if (i == FIELD_EX64(env->svcr, SVCR, SM)) { return; } aarch64_set_svcr(env, 0, R_SVCR_SM_MASK); - arm_reset_sve_state(env); arm_rebuild_hflags(env); }