kvm_arm_get_host_cpu_features() already retrieves the values of some host id registers to analyze the available vcpu features.
Eventually we want to be able to allow the user to change the value of writable ID reg fields. So we need to store the initial value of all writable ID regs into isar.idregs[]. Introduce a new get_host_cpu_idregs() helper that populates isar.idregs[] and call it from kvm_arm_get_host_cpu_features. This patch has no impact on cpreg values. isar.idregs[] is only used as a temporary storage for register values to be updated in place later. Also it does not handle the writeback of isar.idregs[] into cpreg value list after user update. This will be handled separately. Note the host values are retrieved from the scratch vcpu initialized with all the available capabilities exposed by KVM, independently on the final vcpu features made by the user through the legacy composite options such as sve, pauth, virtualization, ... At the moment, the only caller sets writable to true. Named vcpu models will use the writable=false mode. Note this will require some extra handling for ID regs that cannot be read from KVM. Signed-off-by: Eric Auger <[email protected]> Signed-off-by: Cornelia Huck <[email protected]> --- v9 -> v10: - get rid of spurious kvm_arm_writable_idregs_to_cpreg_list trace point - add a writable parameter to get_host_cpu_idregs - some code cleanup v8 -> v9: - improve the commit msg. Only initialize in this patch and move the write back to cpreg value list in a different patch. - Do not hack CLIDR here. The correct way to fix that temporarily is to do that in the machine instead. v7 -> v8 - fix indent and added Khushit's R-b v6 -> v7 - remove vcpu from prototypes (Khushit) v5 -> v6 - do not check writable_map anymore --- target/arm/kvm.c | 44 ++++++++++++++++++++++++++++++++++++++++- target/arm/trace-events | 1 + 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 2e68130611..ac4f307276 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -43,6 +43,7 @@ #include "hw/acpi/ghes.h" #include "target/arm/gtimer.h" #include "migration/blocker.h" +#include "cpu-idregs.h" const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_INFO(DEVICE_CTRL), @@ -329,7 +330,45 @@ static int kvm_feature_idx_to_idregs_idx(int kidx) return get_sysreg_idx(sysreg); } -static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) +/* + * get_host_cpu_idregs: Read all the ID register values from KVM + * vcpu fd and populate @ahcf->isar.idregs[] with those values + * + * Need to be called once the writable mask has been populated + * if @writable is set + * + * @fd: vcpu fd + * @ahcf: ARMHostCPUFeatures whose @ahcf->isar.idregs[] will be + * populated + * @writable: if set, only writable ID regs are read + */ +static int get_host_cpu_idregs(int fd, ARMHostCPUFeatures *ahcf, bool writable) +{ + for (int i = 0; i < NUM_ID_IDX; i++) { + ARM64SysReg *sysregdesc = &arm64_id_regs[i]; + ARMSysRegs sysreg = id_register_sysreg[i]; + uint64_t *reg; + int ret; + + if (writable && !sysregdesc->writable_mask) { + continue; + } + + reg = &ahcf->isar.idregs[i]; + ret = read_sys_reg64(fd, reg, idregs_sysreg_to_kvm_reg(sysreg)); + if (ret) { + error_report("%s error reading value of host %s register (%m)", + __func__, sysregdesc->name); + + return ret; + } + trace_get_host_cpu_idregs(sysregdesc->name, *reg); + } + return 0; +} + +static void +kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) { /* Identify the feature bits corresponding to the host CPU, and * fill out the ARMHostCPUClass fields accordingly. To do this @@ -415,6 +454,9 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) SET_IDREG(&ahcf->isar, ID_AA64PFR0, 0x00000011); /* EL1&0, AArch64 only */ err = 0; } else { + /* Make sure all writable ID reg values are initialized */ + err |= get_host_cpu_idregs(fd, ahcf, true); + err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR1_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR2_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_AA64SMFR0_EL1_IDX); diff --git a/target/arm/trace-events b/target/arm/trace-events index 8502fb3265..8c7faf57c7 100644 --- a/target/arm/trace-events +++ b/target/arm/trace-events @@ -13,6 +13,7 @@ arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d" # kvm.c kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64 +get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu host value for %s is 0x%"PRIx64 # cpu.c arm_cpu_reset(uint64_t mp_aff) "cpu %" PRIu64 -- 2.53.0
