If the host supports KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES and KVM_ARM_GET_REG_WRITABLE_MASKS ioctl successfully retrieved the mask of writable fields for all ID regs, expose uint64 SYSREG properties for all the writable ID reg fields exposed by the host kernel which can be matched in target/arm/cpu-idregs.h.inc.
Properties are named SYSREG_<REG>_<FIELD> with REG and FIELD being those used ARCHMRS Registers.json. When such properties are set, they override the default field value retrieved from the host and reinjected into KVM. Then the actual value being applied at KVM depends on the register, ie. it can be sanitized. In case the field value is rejected by KVM, the vpcu init fails. Anyway there is a first attempt to write back this value into KVM. Then legacy CPU options (virtualization, secure, ...) can still override the previous value. So low level IDREG field properties apply before the legacy ones. An example of invocation is: -cpu host,SYSREG_ID_AA64MMFR0_EL1_ECV=0x0 which sets ECV field of ID_AA64MMFR0_EL1 to 0 (enhanced counter virtualization). Signed-off-by: Eric Auger <[email protected]> Signed-off-by: Cornelia Huck <[email protected]> --- v4 -> v5: - get rid of ret local variable, dynamically allocate and free writable_map here --- target/arm/cpu64.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index f2edbfc437..e0e1ff6cfb 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -37,6 +37,7 @@ #include "hw/core/qdev-properties.h" #include "internals.h" #include "cpu-features.h" +#include "cpu-idregs.h" /* convert between <register>_IDX and SYS_<register> */ #define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \ @@ -851,7 +852,6 @@ static void kvm_arm_set_cpreg_mig_tolerances(ARMCPU *cpu) static void aarch64_host_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); - int ret; #if defined(CONFIG_NITRO) if (nitro_enabled()) { @@ -865,13 +865,18 @@ static void aarch64_host_initfn(Object *obj) cpu->writable_map = g_new(uint64_t, KVM_ARM_FEATURE_ID_RANGE_SIZE); - ret = kvm_arm_get_writable_id_regs(cpu->writable_map); - if (ret) { + if (kvm_arm_get_writable_id_regs(cpu->writable_map)) { g_free(cpu->writable_map); cpu->writable_map = NULL; } kvm_arm_set_cpu_features_from_host(cpu); aarch64_add_sve_properties(obj); + + if (cpu->writable_map) { + /* generate SYSREG properties according to writable masks */ + kvm_arm_expose_idreg_properties(cpu, arm64_id_regs); + } + #elif defined(CONFIG_HVF) hvf_arm_set_cpu_features_from_host(cpu); #elif defined(CONFIG_WHPX) -- 2.53.0
