Starting from M4 cores and MacOS 15.2 SDK, HVF can virtualise FEAT_SME2.
Reviewed-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
---
target/arm/cpu.c | 4 +++-
target/arm/cpu64.c | 13 ++++++++++++-
target/arm/hvf/hvf.c | 25 +++++++++++++------------
3 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index caf7980b1fc5244c5c2f130e79ba869456c20c88..7f4ebfdf61217db6075495119c1b642bc2abf295 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1577,7 +1577,9 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
* assumes it, so if the user asked for sve=off then turn off SME also.
* (KVM doesn't currently support SME at all.)
*/
- if (cpu_isar_feature(aa64_sme, cpu) && !cpu_isar_feature(aa64_sve, cpu)) {
+ if (!hvf_enabled()
+ && cpu_isar_feature(aa64_sme, cpu)
+ && !cpu_isar_feature(aa64_sve, cpu)) {
object_property_set_bool(OBJECT(cpu), "sme", false, &error_abort);
}
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index bf303813701972648fa6751ffe352ba074ca6442..8dd9eb46c783a799a53891a6ddad40b930e95eb4 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -329,9 +329,20 @@ void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp)
{
uint32_t vq_map = cpu->sme_vq.map;
uint32_t vq_init = cpu->sme_vq.init;
- uint32_t vq_supported = cpu->sme_vq.supported;
+ uint32_t vq_supported;
uint32_t vq;
+ if (hvf_enabled()) {
+ if (hvf_arm_sme2_supported()) {
+ vq_supported = hvf_arm_sme2_get_svl();
+ } else {
+ assert(!cpu_isar_feature(aa64_sme, cpu));
+ vq_supported = 0;
+ }
+ } else {
+ vq_supported = cpu->sme_vq.supported;
+ }
+
if (vq_map == 0) {
if (!cpu_isar_feature(aa64_sme, cpu)) {
SET_IDREG(&cpu->isar, ID_AA64SMFR0, 0);
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 6c5061742862635ae394f764188114f939259703..01bbb90b962156885021da75a0d62ae3c39ff5b0 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -1043,18 +1043,18 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
clamp_id_aa64mmfr0_parange_to_ipa_size(&host_isar);
- /*
- * Disable SME, which is not properly handled by QEMU hvf yet.
- * To allow this through we would need to:
- * - make sure that the SME state is correctly handled in the
- * get_registers/put_registers functions
- * - get the SME-specific CPU properties to work with accelerators
- * other than TCG
- * - fix any assumptions we made that SME implies SVE (since
- * on the M4 there is SME but not SVE)
- */
- SET_IDREG(&host_isar, ID_AA64PFR1,
- GET_IDREG(&host_isar, ID_AA64PFR1) & ~R_ID_AA64PFR1_SME_MASK);
+ if (hvf_arm_sme2_supported()) {
+ t = GET_IDREG(&host_isar, ID_AA64PFR1);
+ t = FIELD_DP64(t, ID_AA64PFR1, SME, 2); /* FEAT_SME2 */
+ SET_IDREG(&host_isar, ID_AA64PFR1, t);
+
+ t = GET_IDREG(&host_isar, ID_AA64SMFR0);
+ t = FIELD_DP64(t, ID_AA64SMFR0, SMEVER, 1); /* FEAT_SME2 */
+ SET_IDREG(&host_isar, ID_AA64SMFR0, t);
+ } else {
+ SET_IDREG(&host_isar, ID_AA64PFR1,
+ GET_IDREG(&host_isar, ID_AA64PFR1) & ~R_ID_AA64PFR1_SME_MASK);
+ }
ahcf->isar = host_isar;
@@ -1252,6 +1252,7 @@ int hvf_arch_init_vcpu(CPUState *cpu)
arm_cpu->isar.idregs[ID_AA64MMFR0_EL1_IDX]);
assert_hvf_ok(ret);
+ aarch64_add_sme_properties(OBJECT(cpu));
return 0;
}
--
2.47.3
On 1/15/26 22:20, Manos Pitsidianakis wrote:
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index bf303813701972648fa6751ffe352ba074ca6442..8dd9eb46c783a799a53891a6ddad40b930e95eb4 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -329,9 +329,20 @@ void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp)
> {
> uint32_t vq_map = cpu->sme_vq.map;
> uint32_t vq_init = cpu->sme_vq.init;
> - uint32_t vq_supported = cpu->sme_vq.supported;
> + uint32_t vq_supported;
> uint32_t vq;
>
> + if (hvf_enabled()) {
> + if (hvf_arm_sme2_supported()) {
> + vq_supported = hvf_arm_sme2_get_svl();
> + } else {
> + assert(!cpu_isar_feature(aa64_sme, cpu));
> + vq_supported = 0;
> + }
> + } else {
> + vq_supported = cpu->sme_vq.supported;
> + }
While this mirrors what we do for kvm and sve, I don't think this is sustainable. I think
cpu->sme_vq should be initialized in hvf_arm_set_cpu_features_from_host.
r~
On 15/1/26 12:20, Manos Pitsidianakis wrote:
> Starting from M4 cores and MacOS 15.2 SDK, HVF can virtualise FEAT_SME2.
>
> Reviewed-by: Mohamed Mediouni <mohamed@unpredictable.fr>
> Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> ---
> target/arm/cpu.c | 4 +++-
> target/arm/cpu64.c | 13 ++++++++++++-
> target/arm/hvf/hvf.c | 25 +++++++++++++------------
> 3 files changed, 28 insertions(+), 14 deletions(-)
>
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index caf7980b1fc5244c5c2f130e79ba869456c20c88..7f4ebfdf61217db6075495119c1b642bc2abf295 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -1577,7 +1577,9 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
> * assumes it, so if the user asked for sve=off then turn off SME also.
> * (KVM doesn't currently support SME at all.)
> */
> - if (cpu_isar_feature(aa64_sme, cpu) && !cpu_isar_feature(aa64_sve, cpu)) {
> + if (!hvf_enabled()
In my experience "if(!accel)" is bug prone, maybe change to explicit "if
(tcg_enabled() || kvm_enabled()"?
> + && cpu_isar_feature(aa64_sme, cpu)
> + && !cpu_isar_feature(aa64_sve, cpu)) {
> object_property_set_bool(OBJECT(cpu), "sme", false, &error_abort);
> }
>
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index bf303813701972648fa6751ffe352ba074ca6442..8dd9eb46c783a799a53891a6ddad40b930e95eb4 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -329,9 +329,20 @@ void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp)
> {
> uint32_t vq_map = cpu->sme_vq.map;
> uint32_t vq_init = cpu->sme_vq.init;
> - uint32_t vq_supported = cpu->sme_vq.supported;
> + uint32_t vq_supported;
> uint32_t vq;
>
> + if (hvf_enabled()) {
> + if (hvf_arm_sme2_supported()) {
> + vq_supported = hvf_arm_sme2_get_svl();
> + } else {
> + assert(!cpu_isar_feature(aa64_sme, cpu));
> + vq_supported = 0;
> + }
> + } else {
> + vq_supported = cpu->sme_vq.supported;
> + }
> +
> if (vq_map == 0) {
> if (!cpu_isar_feature(aa64_sme, cpu)) {
> SET_IDREG(&cpu->isar, ID_AA64SMFR0, 0);
> diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
> index 6c5061742862635ae394f764188114f939259703..01bbb90b962156885021da75a0d62ae3c39ff5b0 100644
> --- a/target/arm/hvf/hvf.c
> +++ b/target/arm/hvf/hvf.c
> @@ -1043,18 +1043,18 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
>
> clamp_id_aa64mmfr0_parange_to_ipa_size(&host_isar);
>
> - /*
> - * Disable SME, which is not properly handled by QEMU hvf yet.
> - * To allow this through we would need to:
> - * - make sure that the SME state is correctly handled in the
> - * get_registers/put_registers functions
> - * - get the SME-specific CPU properties to work with accelerators
> - * other than TCG
> - * - fix any assumptions we made that SME implies SVE (since
> - * on the M4 there is SME but not SVE)
> - */
> - SET_IDREG(&host_isar, ID_AA64PFR1,
> - GET_IDREG(&host_isar, ID_AA64PFR1) & ~R_ID_AA64PFR1_SME_MASK);
> + if (hvf_arm_sme2_supported()) {
> + t = GET_IDREG(&host_isar, ID_AA64PFR1);
> + t = FIELD_DP64(t, ID_AA64PFR1, SME, 2); /* FEAT_SME2 */
> + SET_IDREG(&host_isar, ID_AA64PFR1, t);
> +
> + t = GET_IDREG(&host_isar, ID_AA64SMFR0);
> + t = FIELD_DP64(t, ID_AA64SMFR0, SMEVER, 1); /* FEAT_SME2 */
> + SET_IDREG(&host_isar, ID_AA64SMFR0, t);
> + } else {
> + SET_IDREG(&host_isar, ID_AA64PFR1,
> + GET_IDREG(&host_isar, ID_AA64PFR1) & ~R_ID_AA64PFR1_SME_MASK);
> + }
>
> ahcf->isar = host_isar;
>
> @@ -1252,6 +1252,7 @@ int hvf_arch_init_vcpu(CPUState *cpu)
> arm_cpu->isar.idregs[ID_AA64MMFR0_EL1_IDX]);
> assert_hvf_ok(ret);
>
> + aarch64_add_sme_properties(OBJECT(cpu));
Out of scope, those aarch64_add_FEAT_properties() should really take a
ARMCPU *cpu argument IMHO.
> return 0;
> }
>
>
On Tue, Jan 20, 2026 at 11:50 AM Philippe Mathieu-Daudé
<philmd@linaro.org> wrote:
>
> On 15/1/26 12:20, Manos Pitsidianakis wrote:
> > Starting from M4 cores and MacOS 15.2 SDK, HVF can virtualise FEAT_SME2.
> >
> > Reviewed-by: Mohamed Mediouni <mohamed@unpredictable.fr>
> > Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> > ---
> > target/arm/cpu.c | 4 +++-
> > target/arm/cpu64.c | 13 ++++++++++++-
> > target/arm/hvf/hvf.c | 25 +++++++++++++------------
> > 3 files changed, 28 insertions(+), 14 deletions(-)
> >
> > diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> > index caf7980b1fc5244c5c2f130e79ba869456c20c88..7f4ebfdf61217db6075495119c1b642bc2abf295 100644
> > --- a/target/arm/cpu.c
> > +++ b/target/arm/cpu.c
> > @@ -1577,7 +1577,9 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
> > * assumes it, so if the user asked for sve=off then turn off SME also.
> > * (KVM doesn't currently support SME at all.)
> > */
> > - if (cpu_isar_feature(aa64_sme, cpu) && !cpu_isar_feature(aa64_sve, cpu)) {
> > + if (!hvf_enabled()
>
> In my experience "if(!accel)" is bug prone, maybe change to explicit "if
> (tcg_enabled() || kvm_enabled()"?
Shouldn't we list all accelerators instead of just tcg/kvm then?
And why is if(!accel) bug prone?
>
> > + && cpu_isar_feature(aa64_sme, cpu)
> > + && !cpu_isar_feature(aa64_sve, cpu)) {
> > object_property_set_bool(OBJECT(cpu), "sme", false, &error_abort);
> > }
> >
> > diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> > index bf303813701972648fa6751ffe352ba074ca6442..8dd9eb46c783a799a53891a6ddad40b930e95eb4 100644
> > --- a/target/arm/cpu64.c
> > +++ b/target/arm/cpu64.c
> > @@ -329,9 +329,20 @@ void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp)
> > {
> > uint32_t vq_map = cpu->sme_vq.map;
> > uint32_t vq_init = cpu->sme_vq.init;
> > - uint32_t vq_supported = cpu->sme_vq.supported;
> > + uint32_t vq_supported;
> > uint32_t vq;
> >
> > + if (hvf_enabled()) {
> > + if (hvf_arm_sme2_supported()) {
> > + vq_supported = hvf_arm_sme2_get_svl();
> > + } else {
> > + assert(!cpu_isar_feature(aa64_sme, cpu));
> > + vq_supported = 0;
> > + }
> > + } else {
> > + vq_supported = cpu->sme_vq.supported;
> > + }
> > +
> > if (vq_map == 0) {
> > if (!cpu_isar_feature(aa64_sme, cpu)) {
> > SET_IDREG(&cpu->isar, ID_AA64SMFR0, 0);
> > diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
> > index 6c5061742862635ae394f764188114f939259703..01bbb90b962156885021da75a0d62ae3c39ff5b0 100644
> > --- a/target/arm/hvf/hvf.c
> > +++ b/target/arm/hvf/hvf.c
> > @@ -1043,18 +1043,18 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
> >
> > clamp_id_aa64mmfr0_parange_to_ipa_size(&host_isar);
> >
> > - /*
> > - * Disable SME, which is not properly handled by QEMU hvf yet.
> > - * To allow this through we would need to:
> > - * - make sure that the SME state is correctly handled in the
> > - * get_registers/put_registers functions
> > - * - get the SME-specific CPU properties to work with accelerators
> > - * other than TCG
> > - * - fix any assumptions we made that SME implies SVE (since
> > - * on the M4 there is SME but not SVE)
> > - */
> > - SET_IDREG(&host_isar, ID_AA64PFR1,
> > - GET_IDREG(&host_isar, ID_AA64PFR1) & ~R_ID_AA64PFR1_SME_MASK);
> > + if (hvf_arm_sme2_supported()) {
> > + t = GET_IDREG(&host_isar, ID_AA64PFR1);
> > + t = FIELD_DP64(t, ID_AA64PFR1, SME, 2); /* FEAT_SME2 */
> > + SET_IDREG(&host_isar, ID_AA64PFR1, t);
> > +
> > + t = GET_IDREG(&host_isar, ID_AA64SMFR0);
> > + t = FIELD_DP64(t, ID_AA64SMFR0, SMEVER, 1); /* FEAT_SME2 */
> > + SET_IDREG(&host_isar, ID_AA64SMFR0, t);
> > + } else {
> > + SET_IDREG(&host_isar, ID_AA64PFR1,
> > + GET_IDREG(&host_isar, ID_AA64PFR1) & ~R_ID_AA64PFR1_SME_MASK);
> > + }
> >
> > ahcf->isar = host_isar;
> >
> > @@ -1252,6 +1252,7 @@ int hvf_arch_init_vcpu(CPUState *cpu)
> > arm_cpu->isar.idregs[ID_AA64MMFR0_EL1_IDX]);
> > assert_hvf_ok(ret);
> >
> > + aarch64_add_sme_properties(OBJECT(cpu));
>
> Out of scope, those aarch64_add_FEAT_properties() should really take a
> ARMCPU *cpu argument IMHO.
You're just looking for new things to fix :D
>
> > return 0;
> > }
> >
> >
>
--
Manos Pitsidianakis
Emulation and Virtualization Engineer at Linaro Ltd
On Tue, 20 Jan 2026 at 10:02, Manos Pitsidianakis
<manos.pitsidianakis@linaro.org> wrote:
>
> On Tue, Jan 20, 2026 at 11:50 AM Philippe Mathieu-Daudé
> <philmd@linaro.org> wrote:
> >
> > On 15/1/26 12:20, Manos Pitsidianakis wrote:
> > > Starting from M4 cores and MacOS 15.2 SDK, HVF can virtualise FEAT_SME2.
> > >
> > > Reviewed-by: Mohamed Mediouni <mohamed@unpredictable.fr>
> > > Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> > > ---
> > > target/arm/cpu.c | 4 +++-
> > > target/arm/cpu64.c | 13 ++++++++++++-
> > > target/arm/hvf/hvf.c | 25 +++++++++++++------------
> > > 3 files changed, 28 insertions(+), 14 deletions(-)
> > >
> > > diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> > > index caf7980b1fc5244c5c2f130e79ba869456c20c88..7f4ebfdf61217db6075495119c1b642bc2abf295 100644
> > > --- a/target/arm/cpu.c
> > > +++ b/target/arm/cpu.c
> > > @@ -1577,7 +1577,9 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
> > > * assumes it, so if the user asked for sve=off then turn off SME also.
> > > * (KVM doesn't currently support SME at all.)
> > > */
> > > - if (cpu_isar_feature(aa64_sme, cpu) && !cpu_isar_feature(aa64_sve, cpu)) {
> > > + if (!hvf_enabled()
> >
> > In my experience "if(!accel)" is bug prone, maybe change to explicit "if
> > (tcg_enabled() || kvm_enabled()"?
>
> Shouldn't we list all accelerators instead of just tcg/kvm then?
This "turn off SME if no SVE" check is principally trying to
avoid users hitting a bug / missing feature in TCG where
it will assert on startup when the guest tries to write to
SMCR_EL1 (see the backtrace in f7767ca3017's commit message),
because we accidentally coded in assumptions that any guest
with SME also has SVE. We turned it off for all accelerators
because (a) at the time there weren't any others which had
SME support and (b) we didn't do the investigation to figure
out if any of those bogus assumptions were in code that's
not TCG-specific. (In our defence, it was just prior to
a QEMU release :-))
To the extent that those accidental assumptions are in code
that you can hit with HVF, we need to fix them before we
can enable SME-no-SVE in HVF. To the extent that they're TCG
specific, the only accelerator we really need to turn
this off for is TCG. As the comment notes, right now
KVM doesn't support SME so it's impossible to get here
with SME in the feature registers.
If the core code is OK for hvf to enable SME-no-SVE,
then it should also be OK for any other accelerator
except TCG.
I don't think hvf can get to the smcr_write() function
which is the specific failure we saw with TCG, but
I think that it ought to be possible to end up calling
sve_vqm1_for_el() if you use the gdbstub with hvf
accel, get the guest into streaming SME mode (PSTATE.SM
set), and then read the "svg" register that gdb uses to
expose the vector granule.
If giving the SME registers a good workout with the
gdbstub interface all seems to work fine, then I think
we can adjust this condition to be "if tcg_enabled && ...".
thanks
-- PMM
On Thu, Jan 22, 2026 at 6:52 PM Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Tue, 20 Jan 2026 at 10:02, Manos Pitsidianakis
> <manos.pitsidianakis@linaro.org> wrote:
> >
> > On Tue, Jan 20, 2026 at 11:50 AM Philippe Mathieu-Daudé
> > <philmd@linaro.org> wrote:
> > >
> > > On 15/1/26 12:20, Manos Pitsidianakis wrote:
> > > > Starting from M4 cores and MacOS 15.2 SDK, HVF can virtualise FEAT_SME2.
> > > >
> > > > Reviewed-by: Mohamed Mediouni <mohamed@unpredictable.fr>
> > > > Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> > > > ---
> > > > target/arm/cpu.c | 4 +++-
> > > > target/arm/cpu64.c | 13 ++++++++++++-
> > > > target/arm/hvf/hvf.c | 25 +++++++++++++------------
> > > > 3 files changed, 28 insertions(+), 14 deletions(-)
> > > >
> > > > diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> > > > index caf7980b1fc5244c5c2f130e79ba869456c20c88..7f4ebfdf61217db6075495119c1b642bc2abf295 100644
> > > > --- a/target/arm/cpu.c
> > > > +++ b/target/arm/cpu.c
> > > > @@ -1577,7 +1577,9 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
> > > > * assumes it, so if the user asked for sve=off then turn off SME also.
> > > > * (KVM doesn't currently support SME at all.)
> > > > */
> > > > - if (cpu_isar_feature(aa64_sme, cpu) && !cpu_isar_feature(aa64_sve, cpu)) {
> > > > + if (!hvf_enabled()
> > >
> > > In my experience "if(!accel)" is bug prone, maybe change to explicit "if
> > > (tcg_enabled() || kvm_enabled()"?
> >
> > Shouldn't we list all accelerators instead of just tcg/kvm then?
>
> This "turn off SME if no SVE" check is principally trying to
> avoid users hitting a bug / missing feature in TCG where
> it will assert on startup when the guest tries to write to
> SMCR_EL1 (see the backtrace in f7767ca3017's commit message),
> because we accidentally coded in assumptions that any guest
> with SME also has SVE. We turned it off for all accelerators
> because (a) at the time there weren't any others which had
> SME support and (b) we didn't do the investigation to figure
> out if any of those bogus assumptions were in code that's
> not TCG-specific. (In our defence, it was just prior to
> a QEMU release :-))
>
> To the extent that those accidental assumptions are in code
> that you can hit with HVF, we need to fix them before we
> can enable SME-no-SVE in HVF. To the extent that they're TCG
> specific, the only accelerator we really need to turn
> this off for is TCG. As the comment notes, right now
> KVM doesn't support SME so it's impossible to get here
> with SME in the feature registers.
>
> If the core code is OK for hvf to enable SME-no-SVE,
> then it should also be OK for any other accelerator
> except TCG.
>
> I don't think hvf can get to the smcr_write() function
> which is the specific failure we saw with TCG, but
> I think that it ought to be possible to end up calling
> sve_vqm1_for_el() if you use the gdbstub with hvf
> accel, get the guest into streaming SME mode (PSTATE.SM
> set), and then read the "svg" register that gdb uses to
> expose the vector granule.
>
> If giving the SME registers a good workout with the
> gdbstub interface all seems to work fine, then I think
> we can adjust this condition to be "if tcg_enabled && ...".
gdb had a disastrous workout, because it turns out it also assumes SME
must have SVE:
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
../../gdb/aarch64-tdep.c:3068: internal-error:
aarch64_pseudo_register_type: bad register number 160
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Fatal signal: Abort trap: 6
"register number 160" corresponds to pseudoregister regnum
AARCH64_SVE_V0_REGNUM. Looking at gdb/aarch64-tdep.c, it seems they
are only supported by checking against `tdep->has_sve ()` [0]
Peter: So what do we do on the QEMU side? Merge it and wait till
upstream gdb fixes it to check for bugs?
[0]: https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdb/aarch64-tdep.c;h=f1bdce453db27dffeb42f10fcd44a408f706afb2;hb=HEAD#l3116
--
Manos Pitsidianakis
Emulation and Virtualization Engineer at Linaro Ltd
On Mon, 26 Jan 2026 at 08:34, Manos Pitsidianakis <manos.pitsidianakis@linaro.org> wrote: > > On Thu, Jan 22, 2026 at 6:52 PM Peter Maydell <peter.maydell@linaro.org> wrote: > > If giving the SME registers a good workout with the > > gdbstub interface all seems to work fine, then I think > > we can adjust this condition to be "if tcg_enabled && ...". > > gdb had a disastrous workout, because it turns out it also assumes SME > must have SVE: > > > (gdb) target remote localhost:1234 > Remote debugging using localhost:1234 > ../../gdb/aarch64-tdep.c:3068: internal-error: > aarch64_pseudo_register_type: bad register number 160 > A problem internal to GDB has been detected, > further debugging may prove unreliable. > Fatal signal: Abort trap: 6 I think that if we rebase this series on top of the patchset I just sent out: https://patchew.org/QEMU/20260129113455.1283266-1-peter.maydell@linaro.org/ that should avoid this GDB internal error (which happened because we were reporting the Z registers as zero width, so GDB got confused about whether they existed or not). The GDB and LLDB changes to handle SME-only CPUs seem to mostly be related to the ptrace API, because of choices made in the Linux kernel API about how to handle SME-only, so I'm optimistic we don't need to wait for anything to land on the debugger side. thanks -- PMM
> On 26. Jan 2026, at 09:34, Manos Pitsidianakis <manos.pitsidianakis@linaro.org> wrote:
>
> On Thu, Jan 22, 2026 at 6:52 PM Peter Maydell <peter.maydell@linaro.org> wrote:
>>
>> On Tue, 20 Jan 2026 at 10:02, Manos Pitsidianakis
>> <manos.pitsidianakis@linaro.org> wrote:
>>>
>>> On Tue, Jan 20, 2026 at 11:50 AM Philippe Mathieu-Daudé
>>> <philmd@linaro.org> wrote:
>>>>
>>>> On 15/1/26 12:20, Manos Pitsidianakis wrote:
>>>>> Starting from M4 cores and MacOS 15.2 SDK, HVF can virtualise FEAT_SME2.
>>>>>
>>>>> Reviewed-by: Mohamed Mediouni <mohamed@unpredictable.fr>
>>>>> Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
>>>>> ---
>>>>> target/arm/cpu.c | 4 +++-
>>>>> target/arm/cpu64.c | 13 ++++++++++++-
>>>>> target/arm/hvf/hvf.c | 25 +++++++++++++------------
>>>>> 3 files changed, 28 insertions(+), 14 deletions(-)
>>>>>
>>>>> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
>>>>> index caf7980b1fc5244c5c2f130e79ba869456c20c88..7f4ebfdf61217db6075495119c1b642bc2abf295 100644
>>>>> --- a/target/arm/cpu.c
>>>>> +++ b/target/arm/cpu.c
>>>>> @@ -1577,7 +1577,9 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
>>>>> * assumes it, so if the user asked for sve=off then turn off SME also.
>>>>> * (KVM doesn't currently support SME at all.)
>>>>> */
>>>>> - if (cpu_isar_feature(aa64_sme, cpu) && !cpu_isar_feature(aa64_sve, cpu)) {
>>>>> + if (!hvf_enabled()
>>>>
>>>> In my experience "if(!accel)" is bug prone, maybe change to explicit "if
>>>> (tcg_enabled() || kvm_enabled()"?
>>>
>>> Shouldn't we list all accelerators instead of just tcg/kvm then?
>>
>> This "turn off SME if no SVE" check is principally trying to
>> avoid users hitting a bug / missing feature in TCG where
>> it will assert on startup when the guest tries to write to
>> SMCR_EL1 (see the backtrace in f7767ca3017's commit message),
>> because we accidentally coded in assumptions that any guest
>> with SME also has SVE. We turned it off for all accelerators
>> because (a) at the time there weren't any others which had
>> SME support and (b) we didn't do the investigation to figure
>> out if any of those bogus assumptions were in code that's
>> not TCG-specific. (In our defence, it was just prior to
>> a QEMU release :-))
>>
>> To the extent that those accidental assumptions are in code
>> that you can hit with HVF, we need to fix them before we
>> can enable SME-no-SVE in HVF. To the extent that they're TCG
>> specific, the only accelerator we really need to turn
>> this off for is TCG. As the comment notes, right now
>> KVM doesn't support SME so it's impossible to get here
>> with SME in the feature registers.
>>
>> If the core code is OK for hvf to enable SME-no-SVE,
>> then it should also be OK for any other accelerator
>> except TCG.
>>
>> I don't think hvf can get to the smcr_write() function
>> which is the specific failure we saw with TCG, but
>> I think that it ought to be possible to end up calling
>> sve_vqm1_for_el() if you use the gdbstub with hvf
>> accel, get the guest into streaming SME mode (PSTATE.SM
>> set), and then read the "svg" register that gdb uses to
>> expose the vector granule.
>>
>> If giving the SME registers a good workout with the
>> gdbstub interface all seems to work fine, then I think
>> we can adjust this condition to be "if tcg_enabled && ...".
>
> gdb had a disastrous workout, because it turns out it also assumes SME
> must have SVE:
>
>
> (gdb) target remote localhost:1234
> Remote debugging using localhost:1234
> ../../gdb/aarch64-tdep.c:3068: internal-error:
> aarch64_pseudo_register_type: bad register number 160
> A problem internal to GDB has been detected,
> further debugging may prove unreliable.
> Fatal signal: Abort trap: 6
>
Hello,
Meanwhile the LLVM side looks un-merged: https://github.com/llvm/llvm-project/pull/165413
Maybe having a way to mask SME via “-cpu host,sme=off” and documenting it would be enough?
> "register number 160" corresponds to pseudoregister regnum
> AARCH64_SVE_V0_REGNUM. Looking at gdb/aarch64-tdep.c, it seems they
> are only supported by checking against `tdep->has_sve ()` [0]
>
> Peter: So what do we do on the QEMU side? Merge it and wait till
> upstream gdb fixes it to check for bugs?
>
> [0]: https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdb/aarch64-tdep.c;h=f1bdce453db27dffeb42f10fcd44a408f706afb2;hb=HEAD#l3116
>
>
>
> --
> Manos Pitsidianakis
> Emulation and Virtualization Engineer at Linaro Ltd
>
On 20/1/26 11:01, Manos Pitsidianakis wrote:
> On Tue, Jan 20, 2026 at 11:50 AM Philippe Mathieu-Daudé
> <philmd@linaro.org> wrote:
>>
>> On 15/1/26 12:20, Manos Pitsidianakis wrote:
>>> Starting from M4 cores and MacOS 15.2 SDK, HVF can virtualise FEAT_SME2.
>>>
>>> Reviewed-by: Mohamed Mediouni <mohamed@unpredictable.fr>
>>> Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
>>> ---
>>> target/arm/cpu.c | 4 +++-
>>> target/arm/cpu64.c | 13 ++++++++++++-
>>> target/arm/hvf/hvf.c | 25 +++++++++++++------------
>>> 3 files changed, 28 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
>>> index caf7980b1fc5244c5c2f130e79ba869456c20c88..7f4ebfdf61217db6075495119c1b642bc2abf295 100644
>>> --- a/target/arm/cpu.c
>>> +++ b/target/arm/cpu.c
>>> @@ -1577,7 +1577,9 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
>>> * assumes it, so if the user asked for sve=off then turn off SME also.
>>> * (KVM doesn't currently support SME at all.)
>>> */
>>> - if (cpu_isar_feature(aa64_sme, cpu) && !cpu_isar_feature(aa64_sve, cpu)) {
>>> + if (!hvf_enabled()
>>
>> In my experience "if(!accel)" is bug prone, maybe change to explicit "if
>> (tcg_enabled() || kvm_enabled()"?
>
> Shouldn't we list all accelerators instead of just tcg/kvm then?
Correct.
>
> And why is if(!accel) bug prone?
I was thinking of f46f05b6d88 ("target/arm: Only allow disabling NEON
when using TCG").
>
>>
>>> + && cpu_isar_feature(aa64_sme, cpu)
>>> + && !cpu_isar_feature(aa64_sve, cpu)) {
>>> object_property_set_bool(OBJECT(cpu), "sme", false, &error_abort);
>>> }
>>>
>>> @@ -1252,6 +1252,7 @@ int hvf_arch_init_vcpu(CPUState *cpu)
>>> arm_cpu->isar.idregs[ID_AA64MMFR0_EL1_IDX]);
>>> assert_hvf_ok(ret);
>>>
>>> + aarch64_add_sme_properties(OBJECT(cpu));
>>
>> Out of scope, those aarch64_add_FEAT_properties() should really take a
>> ARMCPU *cpu argument IMHO.
>
> You're just looking for new things to fix :D
Correct!
>
>>
>>> return 0;
>>> }
>>>
>>>
>>
>
© 2016 - 2026 Red Hat, Inc.