> On 10 Oct 2026, at 7:06 PM, Eric Auger <[email protected]> wrote:
> 
> !-------------------------------------------------------------------|
>  CAUTION: External Email
> 
> |-------------------------------------------------------------------!
> 
> 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) {
Hi Eric,

We should ignore ENOENT errors here.

Also, When we read the full register set, we need to take care of
some special cases, like I do in (target/arm/kvm: handle special ID
registers when reading from KVM) (I can handle this in my series
if you like).

Anyway, for now, using a local commit for the first point.

Thanks,
Khushit

> +            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
> 

Reply via email to