Message ID | 20241206112213.88394-2-cohuck@redhat.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | kvm/arm: Introduce a customizable aarch64 KVM host model | expand |
On 12/6/24 05:21, Cornelia Huck wrote: > +#define NR_ID_REGS (3 * 8 * 8) > + > +typedef struct IdRegMap { > + uint64_t regs[NR_ID_REGS]; > +} IdRegMap; > + Where does the NR_ID_REGS come from? In particular the * 3? IIRC, all of the id registers are in op0=3, op1=0, crn=0, crm={0-7}, op2={0-7}. Whatever the actual answer, some comments would be good. r~
Hi Richard, On 12/12/24 14:59, Richard Henderson wrote: > On 12/6/24 05:21, Cornelia Huck wrote: >> +#define NR_ID_REGS (3 * 8 * 8) >> + >> +typedef struct IdRegMap { >> + uint64_t regs[NR_ID_REGS]; >> +} IdRegMap; >> + > > Where does the NR_ID_REGS come from? In particular the * 3? > IIRC, all of the id registers are in op0=3, op1=0, crn=0, crm={0-7}, > op2={0-7}. According to the KVM API and code, "The Feature ID space is defined as the AArch64 System register space with +op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, op2=={0-7}." hence that choice See: https://lore.kernel.org/all/20230919175017.538312-3-jingzhangos@google.com/ Definitively we can add a comment Thanks Eric > > Whatever the actual answer, some comments would be good. > > > r~ >
On Thu, Dec 12 2024, Eric Auger <eric.auger@redhat.com> wrote: > Hi Richard, > > On 12/12/24 14:59, Richard Henderson wrote: >> On 12/6/24 05:21, Cornelia Huck wrote: >>> +#define NR_ID_REGS (3 * 8 * 8) >>> + >>> +typedef struct IdRegMap { >>> + uint64_t regs[NR_ID_REGS]; >>> +} IdRegMap; >>> + >> >> Where does the NR_ID_REGS come from? In particular the * 3? >> IIRC, all of the id registers are in op0=3, op1=0, crn=0, crm={0-7}, >> op2={0-7}. > > According to the KVM API and code, > > "The Feature ID space is defined as the AArch64 System register space > with +op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, op2=={0-7}." > > > hence that choice > > See: > https://lore.kernel.org/all/20230919175017.538312-3-jingzhangos@google.com/ > > Definitively we can add a comment I've added /* * 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. */
diff --git a/target/arm/cpu.h b/target/arm/cpu.h index d86e641280d4..e359152a4dbc 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -828,6 +828,19 @@ 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; + +#define NR_ID_REGS (3 * 8 * 8) + +typedef struct IdRegMap { + uint64_t regs[NR_ID_REGS]; +} IdRegMap; + /** * ARMCPU: * @env: #CPUARMState @@ -969,6 +982,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; + /* 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 7b6812c0de2e..8577d6f520ba 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -49,6 +49,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 @@ -495,6 +496,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 2e6b49bf1376..426816ad3a74 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. */