> On 18 Jun 2026, at 2:56 PM, Eric Auger <[email protected]> wrote: > > !-------------------------------------------------------------------| > CAUTION: External Email > > |-------------------------------------------------------------------! > > Hi Khushit, > > On 6/16/26 3:17 PM, Eric Auger wrote: >> From: Cornelia Huck <[email protected]> >> >> Implement the capability to query available ID register values by >> adding SYSREG_* options and values to the cpu model expansion for the >> host model, if available. >> >> Excerpt: >> (QEMU) query-cpu-model-expansion type=full model={"name":"host"} >> {"return": {"model": {"name": "host", "props": >> {"SYSREG_ID_AA64PFR0_EL1_EL3": 1, >> "SYSREG_ID_AA64ISAR2_EL1_CLRBHB": 0, "SYSREG_CTR_EL0_L1Ip": 3, >> "SYSREG_MIDR_EL1_PartNum": 3407, "SYSREG_CTR_EL0_DminLine": 4, >> "SYSREG_ID_AA64MMFR0_EL1_PARange": 5, "SYSREG_ID_AA64MMFR1_EL1_ECBHB": 0 >> ../.. >> >> So this allows the upper stack to detect available writable ID >> regs and the "host passthrough model" values. >> >> It also allows to test some ID reg field values: >> (QEMU) query-cpu-model-expansion type=full >> model={"name":"host","props":{"SYSREG_ID_AA64ISAR0_EL1_DP":0x13}} >> {"error": {"class": "GenericError", "desc": "idreg >> SYSREG_ID_AA64ISAR0_EL1_DP set value (0x13) exceeds length of field (4)!"}} >> >> (QEMU) query-cpu-model-expansion type=full >> model={"name":"host","props":{"SYSREG_ID_AA64ISAR0_EL1_DP":0x2}} >> {"error": {"class": "GenericError", "desc": "idreg >> SYSREG_ID_AA64ISAR0_EL1_DP set value (0x2) does not match any arch valid >> enum value!"}} > > for your info I am currently exploring ways to test set field values > against KVM. Current check only test against field size and enum values > if any. > > I have a POC instantiating a scratch vcpu and it is totally feasible to > set the id reg with the modified value. What is more tricky is to build > an incremental scratch vcpu with all the set values accumulating But I > guess it should be feasible too. > > If we manage to do that, I don't think you need safe rules/values > anymore because using query-cpu-model-expansion you could directly check > the enhanced cpu model can safely apply on host. I will share as soon as > I get something clean enough. Thanks Eric
This seems like it is definitely doable. But, I think it is inefficient and does not scale with the number of cpu models. It will essentially require 1 (vcpu create) + x (number of id register) ioctl calls per Named CPU model or a configuration that management software wants to test. In v3, I will change how we handle safe_rules. As the analysis in mail to Marc almost all of the writeable ID register fields supports writing a lower value. There are only few exceptions. Another point I want to raise is without safe_rules, we will not have QMP feature parity with x86 where cpu-definitions reports model blocker properties. This in-parity means some management software can not be easily ported to work with arm64 named cpu models. Warm Regards, Khushit > >> >> Signed-off-by: Eric Auger <[email protected]> >> Signed-off-by: Cornelia Huck <[email protected]> >> >> --- >> >> v5 -> v6: >> - add the write capability >> --- >> target/arm/arm-qmp-cmds.c | 29 +++++++++++++++++++++++++++++ >> 1 file changed, 29 insertions(+) >> >> diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c >> index 83ec95c290..edcfc82a25 100644 >> --- a/target/arm/arm-qmp-cmds.c >> +++ b/target/arm/arm-qmp-cmds.c >> @@ -21,6 +21,7 @@ >> */ >> >> #include "qemu/osdep.h" >> +#include "qemu/error-report.h" >> #include "qemu/target-info.h" >> #include "hw/core/boards.h" >> #include "kvm_arm.h" >> @@ -84,6 +85,8 @@ CpuModelExpansionInfo >> *qmp_query_cpu_model_expansion(CpuModelExpansionType type, >> Error **errp) >> { >> CpuModelExpansionInfo *expansion_info; >> + ObjectPropertyIterator iter; >> + ObjectProperty *idregprop; >> const QDict *qdict_in; >> QDict *qdict_out; >> ObjectClass *oc; >> @@ -145,6 +148,20 @@ CpuModelExpansionInfo >> *qmp_query_cpu_model_expansion(CpuModelExpansionType type, >> } >> >> qdict_in = qobject_to(QDict, model->props); >> + >> + object_property_iter_init(&iter, obj); >> + >> + while ((idregprop = object_property_iter_next(&iter))) { >> + if (!g_str_has_prefix(idregprop->name, "SYSREG_")) { >> + continue; >> + } >> + if (qdict_get(qdict_in, idregprop->name)) { >> + if (!object_property_set(obj, idregprop->name, visitor, >> &err)) { >> + break; >> + } >> + } >> + } >> + >> i = 0; >> while ((name = cpu_model_advertised_features[i++]) != NULL) { >> if (qdict_get(qdict_in, name)) { >> @@ -190,6 +207,18 @@ CpuModelExpansionInfo >> *qmp_query_cpu_model_expansion(CpuModelExpansionType type, >> } >> } >> >> + object_property_iter_init(&iter, obj); >> + >> + while ((idregprop = object_property_iter_next(&iter))) { >> + QObject *value; >> + >> + if (!g_str_has_prefix(idregprop->name, "SYSREG_")) { >> + continue; >> + } >> + value = object_property_get_qobject(obj, idregprop->name, >> &error_abort); >> + qdict_put_obj(qdict_out, idregprop->name, value); >> + } >> + >> if (!qdict_size(qdict_out)) { >> qobject_unref(qdict_out); >> } else {
