On Mon, Feb 2, 2026 at 3:34 PM Peter Maydell <peter.maydell@linaro.org> 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: qemu-stable@nongnu.org
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> 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
>