On 8/3/26 5:52 PM, Khushit Shah wrote:
>
>> On 22 Jul 2026, at 6:02 PM, Eric Auger <[email protected]> wrote:
>>
>> !-------------------------------------------------------------------|
>>  CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> Hi Khushit,
>>
>> On 7/16/26 11:38 PM, Khushit Shah wrote:
>>> The generic KVM_GET_ONE_REG loop cannot correctly read a handful of
>>> ID registers, so specially handle those:
>>>
>>> - DCZID_EL0: No fine grain trap exists, hence not tracked by KVM.
>>>  It is EL0-readable and untrapped, so read it directly with MRS.
>>>
>>> - CCSIDR_EL1/CCSIDR2_EL1: not plain ID registers, their value is
>>>  selected by CSSELR_EL1. KVM only exposes them via the DEMUX API
>>>  (KVM_REG_ARM_DEMUX_ID_CCSIDR), so there is no single value to read
>>>  here. Skip them.
>>>
>>> - SMIDR_EL1: KVM does not support SME, so there is no meaningful host
>>>  value. Skip it.
>>>
>>> - GMID_EL1: not in KVM's sys_reg_descs[] and, being an EL1 register,
>>>  cannot be read from userspace via MRS either. The guest reads the
>>>  raw host value; this is a genuine miss when MTE is enabled.
>>>
>>> Signed-off-by: Khushit Shah <[email protected]>
>>> ---
>>> target/arm/kvm.c | 53 ++++++++++++++++++++++++++++++++++++++++--------
>>> 1 file changed, 44 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/target/arm/kvm.c b/target/arm/kvm.c
>>> index 42ff731f6e..6974e5c551 100644
>>> --- a/target/arm/kvm.c
>>> +++ b/target/arm/kvm.c
>>> @@ -311,15 +311,50 @@ static int get_host_cpu_idregs(int fd, 
>>> ARMHostCPUFeatures *ahcf)
>>>         int ret;
>>>
>>>         reg = &ahcf->isar.idregs[i];
>>> -        ret = read_sys_reg64(fd, reg, idregs_sysreg_to_kvm_reg(sysreg));
>>> -        if (ret) {
>>> -            if (errno == ENOENT) {
>>> -                warn_report("%s error reading value of host %s register "
>>> -                                "(ENOENT)", __func__, sysregdesc->name);
>>> -            } else {
>>> -                error_report("%s error reading value of host %s register"
>>> -                            " (%m)", __func__, sysregdesc->name);
>>> -                err = ret;
>>> +        switch (i) {
>>> +        case DCZID_EL0_IDX:
>>> +            /*
>>> +             * DCZID_EL0 is not in KVM's sys_reg_descs[], so
>>> +             * KVM_GET_ONE_REG will fail. Read it directly from
>>> +             * hardware since KVM doesn't trap guest reads of it.
>>> +             */
>>> +            asm volatile("mrs %0, DCZID_EL0" : "=r" (*reg));
>>> +            break;
>>> +        case CCSIDR_EL1_IDX:
>>> +        case CCSIDR2_EL1_IDX:
>>> +            /*
>>> +             * CCSIDR_EL1 is not a plain ID register: the value it
>>> +             * returns is selected by CSSELR_EL1, so there is no single
>>> +             * value to capture here. It is exposed to userspace only via
>>> +             * the DEMUX API (KVM_REG_ARM_DEMUX_ID_CCSIDR), indexed by
>>> +             * CSSELR. Skip reading it here as there is no meaningful host
>>> +             * value to read.
>>> +             */
>> I think you should rely on prerequisite
>> [PATCH v4 3/3] arm/kvm: get demuxed ID registers from kvm
> Currently I am just skipping those as anyway KVM exposes a very
> barebone Cache topology.
>
> Agreed on using DEMUX regs, in case we want to support exopsing some other
> “config”.
>
> Also on this point, I don’t know if CCSIDR_EL1/CCSIDR2_EL1 should
> be part of idregs[], we already have a ccsidr[], maybe this can be fixed
> in your series.

OK i will investigate this.

Thanks

Eric
>
>>> +            break;
>>> +        case SMIDR_EL1_IDX:
>>> +            /*
>>> +             * As SME is not yet supported by KVM, ignore reading SMIDR_EL1
>>> +             */
>>> +             break;
>>> +        case GMID_EL1_IDX:
>>> +            /*
>>> +             * GMID_EL1 is not in KVM's sys_reg_descs[] and guest reads
>>> +             * the raw host value. But as it is an EL1 register, we cannot
>>> +             * read it directly. This is a genuine miss when MTE is
>>> +             * enabled for the guest.
>>> +             */
>>> +            break;
>>> +        default:
>>> +            ret = read_sys_reg64(fd, reg, 
>>> idregs_sysreg_to_kvm_reg(sysreg));
>>> +            if (ret) {
>>> +                if (errno == ENOENT) {
>>> +                    warn_report("%s error reading value of host %s 
>>> register "
>>> +                                    "(ENOENT)", __func__, 
>>> sysregdesc->name);
>> trace point
> Noted.
>
> Warm Regards,
> Khushit
>>> +                } else {
>>> +                    error_report("%s error reading value of host %s 
>>> register"
>>> +                                " (%m)", __func__, sysregdesc->name);
>>> +                    err = ret;
>>> +                }
>>>             }
>>>         }
>>>         trace_get_host_cpu_idregs(sysregdesc->name, *reg);
>> Thanks
>>
>> Eric
>


Reply via email to