On Mon, Feb 2, 2026 at 3:34 PM Peter Maydell <[email protected]> wrote:
>
> In our handling of the boolean 'sme' CPU property, we write this 0/1
> value directly to ID_AA64PFR1_EL1.SME.  This worked when the only
> valid values in that field were 0 (for no SME) and 1 (for SME1).
> However, with the addition of SME2 the SME field can now also read 2.
> This means that "-cpu max,sme=on" will result in an inconsistent set
> of ID registers, where ID_AA64PFR1_EL1.SME claims SME1 but
> ID_AA64SMFR0_EL1.SMEver claims SME2p1.  This isn't a valid thing to
> report, and confuses Linux into reporting SME2 to userspace but not
> actually enabling userspace access for it.
>
> Fix this bug by having arm_cpu_sme_finalize() fix up the
> ID_AA64PFR1_EL1.SME field to match ID_AA64SMFR0.SMEver.  This means
> the "sme" property's semantics are "off" for "no SME" and "on" for
> "enable at whatever the default SME version this CPU provides is".
>
> Update the documentation to clarify what 'sve=on' and 'sme=on' do.
> (We don't have the equivalent bug for 'sve=on' because
> ID_AA64PFR0_EL1.SVE only has 0 and 1 as valid values, but the
> semantics of the property are the same.)
>
> Cc: [email protected]
> Signed-off-by: Peter Maydell <[email protected]>
> ---

Reviewed-by: Manos Pitsidianakis <[email protected]>

>  docs/system/arm/cpu-features.rst | 10 ++++++++++
>  target/arm/cpu64.c               | 15 +++++++++++++++
>  2 files changed, 25 insertions(+)
>
> diff --git a/docs/system/arm/cpu-features.rst 
> b/docs/system/arm/cpu-features.rst
> index 37d5dfd15b..024119449c 100644
> --- a/docs/system/arm/cpu-features.rst
> +++ b/docs/system/arm/cpu-features.rst
> @@ -318,6 +318,11 @@ SVE CPU Property Parsing Semantics
>       provided an error will be generated.  To avoid this error, one must
>       enable at least one vector length prior to enabling SVE.
>
> +  10) Enabling SVE (with ``sve=on`` or by default) enables all the SVE
> +      sub-features that the CPU supports (for example, it may also
> +      enable SVE2). There are not generally any lower-level controls
> +      for disabling specific SVE sub-features.
> +
>  SVE CPU Property Examples
>  -------------------------
>
> @@ -430,6 +435,11 @@ and all vector lengths must be powers of 2.  The maximum 
> vector
>  length supported by qemu is 2048 bits.  Otherwise, there are no
>  additional constraints on the set of vector lengths supported by SME.
>
> +As with SVE, ``sme=on`` enables all the SME sub-features the CPU
> +supports (for example, it may also enable SME2), and there are
> +no lower-level controls for fine-grained disabling of specific
> +SME sub-features.
> +
>  SME User-mode Default Vector Length Property
>  --------------------------------------------
>
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index 4dfc03973e..26873a39b4 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -363,6 +363,16 @@ void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp)
>
>      cpu->sme_vq.map = vq_map;
>      cpu->sme_max_vq = 32 - clz32(vq_map);
> +
> +    /*
> +     * The "sme" property setter writes a bool value into ID_AA64PFR1_EL1.SME
> +     * (and at this point we know it's not 0). Correct that value to report
> +     * the same SME version as ID_AA64SMFR0_EL1.SMEver.
> +     */
> +    if (FIELD_EX64_IDREG(&cpu->isar, ID_AA64SMFR0, SMEVER) != 0) {
> +        /* SME2 or better */
> +        FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR1, SME, 2);
> +    }
>  }
>
>  static bool cpu_arm_get_sme(Object *obj, Error **errp)
> @@ -375,6 +385,11 @@ static void cpu_arm_set_sme(Object *obj, bool value, 
> Error **errp)
>  {
>      ARMCPU *cpu = ARM_CPU(obj);
>
> +    /*
> +     * For now, write 0 for "off" and 1 for "on" into the PFR1 field.
> +     * We will correct this value to report the right SME
> +     * level (SME vs SME2) in arm_cpu_sme_finalize() later.
> +     */
>      FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR1, SME, value);
>  }
>
> --
> 2.43.0
>

Reply via email to