Hi Connie, On 4/14/25 6:38 PM, Cornelia Huck wrote: > Add an helper to retrieve the writable id reg bitmask. The > status of the query is stored in the CPU struct so that an > an error, if any, can be reported on vcpu realize(). > > Signed-off-by: Eric Auger <eric.au...@redhat.com> > Signed-off-by: Cornelia Huck <coh...@redhat.com> > --- > target/arm/cpu.h | 26 ++++++++++++++++++++++++++ > target/arm/kvm.c | 32 ++++++++++++++++++++++++++++++++ > target/arm/kvm_arm.h | 7 +++++++ > 3 files changed, 65 insertions(+) > > diff --git a/target/arm/cpu.h b/target/arm/cpu.h > index d27134f4a025..bbee7ff2414a 100644 > --- a/target/arm/cpu.h > +++ b/target/arm/cpu.h > @@ -856,6 +856,26 @@ typedef struct { > uint32_t map, init, supported; > } ARMVQMap; > > +typedef enum ARMIdRegsState { > + WRITABLE_ID_REGS_UNKNOWN, > + WRITABLE_ID_REGS_NOT_DISCOVERABLE, > + WRITABLE_ID_REGS_FAILED, > + WRITABLE_ID_REGS_AVAIL, > +} ARMIdRegsState; > + > +/* > + * The following structures are for the purpose of mapping the output of > + * KVM_ARM_GET_REG_WRITABLE_MASKS that also may cover id registers we do > + * not support in QEMU > + * ID registers in op0==3, op1=={0,1,3}, crn=0, crm=={0-7}, op2=={0-7}, > + * as used by the KVM_ARM_GET_REG_WRITABLE_MASKS ioctl call. > + */ > +#define NR_ID_REGS (3 * 8 * 8) We may rename this define to better associate to the KVM API. I tend to mix it with NUM_ID_IDX now ;-) maybe something like KVM_NR_EXPOSED_ID_REGS > + > +typedef struct IdRegMap { > + uint64_t regs[NR_ID_REGS]; > +} IdRegMap; I would add a comment saying this is the mask array, just to prevent the reading from thinking it is the actual reg content. > + > /* REG is ID_XXX */ > #define FIELD_DP64_IDREG(ISAR, REG, FIELD, VALUE) \ > ({ \ > @@ -1044,6 +1064,12 @@ struct ArchCPU { > */ > bool host_cpu_probe_failed; > > + /* > + * state of writable id regs query used to report an error, if any, > + * on KVM custom vcpu model realize > + */ > + ARMIdRegsState writable_id_regs; maybe rename into writable_id_reg_status that would better reflect what it is. > + > /* QOM property to indicate we should use the back-compat CNTFRQ default > */ > bool backcompat_cntfrq; > > diff --git a/target/arm/kvm.c b/target/arm/kvm.c > index 8491f42a18d2..6e3cd06e9bc5 100644 > --- a/target/arm/kvm.c > +++ b/target/arm/kvm.c > @@ -50,6 +50,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = { > static bool cap_has_mp_state; > static bool cap_has_inject_serror_esr; > static bool cap_has_inject_ext_dabt; > +static int cap_writable_id_regs; > > /** > * ARMHostCPUFeatures: information about the host CPU (identified > @@ -488,6 +489,37 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu) > env->features = arm_host_cpu_features.features; > } > > +int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap) > +{ > + struct reg_mask_range range = { > + .range = 0, /* up to now only a single range is supported */ > + .addr = (uint64_t)idregmap, > + }; > + int ret; > + > + if (!kvm_enabled()) { > + cpu->writable_id_regs = WRITABLE_ID_REGS_NOT_DISCOVERABLE; > + return -ENOSYS; > + } > + > + cap_writable_id_regs = > + kvm_check_extension(kvm_state, > KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES); > + > + if (!cap_writable_id_regs || > + !(cap_writable_id_regs & (1 << KVM_ARM_FEATURE_ID_RANGE))) { > + cpu->writable_id_regs = WRITABLE_ID_REGS_NOT_DISCOVERABLE; > + return -ENOSYS; > + } > + > + ret = kvm_vm_ioctl(kvm_state, KVM_ARM_GET_REG_WRITABLE_MASKS, &range); > + if (ret) { > + cpu->writable_id_regs = WRITABLE_ID_REGS_FAILED; > + return ret; > + } > + cpu->writable_id_regs = WRITABLE_ID_REGS_AVAIL; > + return ret; > +} > + > static bool kvm_no_adjvtime_get(Object *obj, Error **errp) > { > return !ARM_CPU(obj)->kvm_adjvtime; > diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h > index 05c3de8cd46e..8d1f20ca8d89 100644 > --- a/target/arm/kvm_arm.h > +++ b/target/arm/kvm_arm.h > @@ -221,6 +221,8 @@ int kvm_arm_set_irq(int cpu, int irqtype, int irq, int > level); > > void kvm_arm_enable_mte(Object *cpuobj, Error **errp); > > +int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap); > + > #else > > /* > @@ -247,6 +249,11 @@ static inline bool kvm_arm_mte_supported(void) > return false; > } > > +static inline int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap > *idregmap) > +{ > + return -ENOSYS; > +} > + > /* > * These functions should never actually be called without KVM support. > */ Cheers
Eric