Re: [RFC PATCH v3 07/19] target/arm/kvm: handle special ID registers cases when reading from KVM
Khushit Shah <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
> 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. >> + 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