Re: [RFC PATCH v3 07/19] target/arm/kvm: handle special ID registers cases when reading from KVM

Eric Auger <[email protected]>
Newsgroups gmane.comp.emulators.qemu
Message-ID <[email protected]>

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
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.