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 >
