Message ID | 20181108175246.13416-5-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | target/arm: KVM vs ARMISARegisters | expand |
On 8 November 2018 at 17:52, Richard Henderson <richard.henderson@linaro.org> wrote: > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > target/arm/kvm32.c | 33 ++++++++++++++++++++++++++++----- > 1 file changed, 28 insertions(+), 5 deletions(-) > Reviewed-by: Peter Maydell <peter.maydell@linaro.org> thanks -- PMM
On 8 November 2018 at 17:52, Richard Henderson <richard.henderson@linaro.org> wrote: > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > target/arm/kvm32.c | 33 ++++++++++++++++++++++++++++----- > 1 file changed, 28 insertions(+), 5 deletions(-) > > diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c > index de573f9aa8..9ededa3c73 100644 > --- a/target/arm/kvm32.c > +++ b/target/arm/kvm32.c > @@ -44,7 +44,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) > * and then query that CPU for the relevant ID registers. > */ > int err = 0, fdarray[3]; > - uint32_t midr, id_pfr0, mvfr1; > + uint32_t midr, id_pfr0; > uint64_t features = 0; > > /* Old kernels may not know about the PREFERRED_TARGET ioctl: however > @@ -71,9 +71,32 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) > > err |= read_sys_reg32(fdarray[2], &midr, ARM_CP15_REG32(0, 0, 0, 0)); > err |= read_sys_reg32(fdarray[2], &id_pfr0, ARM_CP15_REG32(0, 0, 1, 0)); > - err |= read_sys_reg32(fdarray[2], &mvfr1, > + > + err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar0, > + ARM_CP15_REG32(0, 0, 2, 0)); > + err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar1, > + ARM_CP15_REG32(0, 0, 2, 1)); > + err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar2, > + ARM_CP15_REG32(0, 0, 2, 2)); > + err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar3, > + ARM_CP15_REG32(0, 0, 2, 3)); > + err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar4, > + ARM_CP15_REG32(0, 0, 2, 4)); > + err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar5, > + ARM_CP15_REG32(0, 0, 2, 5)); > + err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar6, > + ARM_CP15_REG32(0, 0, 2, 7)); > + > + err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr0, > + KVM_REG_ARM | KVM_REG_SIZE_U32 | > + KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR0); > + err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr1, > KVM_REG_ARM | KVM_REG_SIZE_U32 | > KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR1); Testing this on my aarch32 system (a cubieboard running 4.0.0-rc4) this fails with qemu-system-arm: Failed to retrieve host CPU features strace says: ioctl(14, KVM_CREATE_VM, 0) = 15 ioctl(15, KVM_CREATE_VCPU, 0) = 16 ioctl(15, 0x8020aeaf, 0xbea1bc74) = 0 ioctl(16, KVM_ARM_VCPU_INIT, 0xbea1bc74) = 0 ioctl(16, KVM_ARM_SET_DEVICE_ADDR or KVM_GET_ONE_REG, 0xbea1bc30) = 0 ioctl(16, KVM_ARM_SET_DEVICE_ADDR or KVM_GET_ONE_REG, 0xbea1bc30) = 0 ioctl(16, KVM_ARM_SET_DEVICE_ADDR or KVM_GET_ONE_REG, 0xbea1bc30) = 0 ioctl(16, KVM_ARM_SET_DEVICE_ADDR or KVM_GET_ONE_REG, 0xbea1bc30) = 0 ioctl(16, KVM_ARM_SET_DEVICE_ADDR or KVM_GET_ONE_REG, 0xbea1bc30) = 0 ioctl(16, KVM_ARM_SET_DEVICE_ADDR or KVM_GET_ONE_REG, 0xbea1bc30) = 0 ioctl(16, KVM_ARM_SET_DEVICE_ADDR or KVM_GET_ONE_REG, 0xbea1bc30) = 0 ioctl(16, KVM_ARM_SET_DEVICE_ADDR or KVM_GET_ONE_REG, 0xbea1bc30) = 0 ioctl(16, KVM_ARM_SET_DEVICE_ADDR or KVM_GET_ONE_REG, 0xbea1bc30) = -1 ENOENT (No such file or directory) ioctl(16, KVM_ARM_SET_DEVICE_ADDR or KVM_GET_ONE_REG, 0xbea1bc30) = 0 ioctl(16, KVM_ARM_SET_DEVICE_ADDR or KVM_GET_ONE_REG, 0xbea1bc30) = 0 so I deduce that this is because the kernel doesn't support reading ID_ISAR6. Adding the following change allowed me to boot: diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c index 8b2c9b3..2f7df81 100644 --- a/target/arm/kvm32.c +++ b/target/arm/kvm32.c @@ -84,9 +84,15 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) ARM_CP15_REG32(0, 0, 2, 4)); err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar5, ARM_CP15_REG32(0, 0, 2, 5)); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar6, - ARM_CP15_REG32(0, 0, 2, 7)); - + if (read_sys_reg32(fdarray[2], &ahcf->isar.id_isar6, + ARM_CP15_REG32(0, 0, 2, 7))) { + /* + * Older kernels don't support reading ID_ISAR6. This register was + * only introduced in ARMv8, so we can assume that it is zero on a + * CPU that a kernel this old is running on. + */ + ahcf->isar.id_isar6 = 0; + } err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr0, KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR0); thanks -- PMM
On 11/12/18 1:42 PM, Peter Maydell wrote: > Adding the following change allowed me to boot: > > diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c > index 8b2c9b3..2f7df81 100644 > --- a/target/arm/kvm32.c > +++ b/target/arm/kvm32.c > @@ -84,9 +84,15 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) > ARM_CP15_REG32(0, 0, 2, 4)); > err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar5, > ARM_CP15_REG32(0, 0, 2, 5)); > - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar6, > - ARM_CP15_REG32(0, 0, 2, 7)); > - > + if (read_sys_reg32(fdarray[2], &ahcf->isar.id_isar6, > + ARM_CP15_REG32(0, 0, 2, 7))) { > + /* > + * Older kernels don't support reading ID_ISAR6. This register was > + * only introduced in ARMv8, so we can assume that it is zero on a > + * CPU that a kernel this old is running on. > + */ > + ahcf->isar.id_isar6 = 0; > + } Ah, right, thanks. r~
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c index de573f9aa8..9ededa3c73 100644 --- a/target/arm/kvm32.c +++ b/target/arm/kvm32.c @@ -44,7 +44,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) * and then query that CPU for the relevant ID registers. */ int err = 0, fdarray[3]; - uint32_t midr, id_pfr0, mvfr1; + uint32_t midr, id_pfr0; uint64_t features = 0; /* Old kernels may not know about the PREFERRED_TARGET ioctl: however @@ -71,9 +71,32 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) err |= read_sys_reg32(fdarray[2], &midr, ARM_CP15_REG32(0, 0, 0, 0)); err |= read_sys_reg32(fdarray[2], &id_pfr0, ARM_CP15_REG32(0, 0, 1, 0)); - err |= read_sys_reg32(fdarray[2], &mvfr1, + + err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar0, + ARM_CP15_REG32(0, 0, 2, 0)); + err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar1, + ARM_CP15_REG32(0, 0, 2, 1)); + err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar2, + ARM_CP15_REG32(0, 0, 2, 2)); + err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar3, + ARM_CP15_REG32(0, 0, 2, 3)); + err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar4, + ARM_CP15_REG32(0, 0, 2, 4)); + err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar5, + ARM_CP15_REG32(0, 0, 2, 5)); + err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar6, + ARM_CP15_REG32(0, 0, 2, 7)); + + err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr0, + KVM_REG_ARM | KVM_REG_SIZE_U32 | + KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR0); + err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr1, KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR1); + /* + * FIXME: There is not yet a way to read MVFR2. + * Fortunately there is not yet anything in there that affects migration. + */ kvm_arm_destroy_scratch_host_vcpu(fdarray); @@ -95,13 +118,13 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) if (extract32(id_pfr0, 12, 4) == 1) { set_feature(&features, ARM_FEATURE_THUMB2EE); } - if (extract32(mvfr1, 20, 4) == 1) { + if (extract32(ahcf->isar.mvfr1, 20, 4) == 1) { set_feature(&features, ARM_FEATURE_VFP_FP16); } - if (extract32(mvfr1, 12, 4) == 1) { + if (extract32(ahcf->isar.mvfr1, 12, 4) == 1) { set_feature(&features, ARM_FEATURE_NEON); } - if (extract32(mvfr1, 28, 4) == 1) { + if (extract32(ahcf->isar.mvfr1, 28, 4) == 1) { /* FMAC support implies VFPv4 */ set_feature(&features, ARM_FEATURE_VFP4); }
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/arm/kvm32.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) -- 2.17.2