On 8 November 2018 at 17:52, Richard Henderson
wrote:
> Signed-off-by: Richard Henderson
> ---
> 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], , ARM_CP15_REG32(0, 0, 0, 0));
> err |= read_sys_reg32(fdarray[2], _pfr0, ARM_CP15_REG32(0, 0, 1, 0));
> -err |= read_sys_reg32(fdarray[2], ,
> +
> +err |= read_sys_reg32(fdarray[2], >isar.id_isar0,
> + ARM_CP15_REG32(0, 0, 2, 0));
> +err |= read_sys_reg32(fdarray[2], >isar.id_isar1,
> + ARM_CP15_REG32(0, 0, 2, 1));
> +err |= read_sys_reg32(fdarray[2], >isar.id_isar2,
> + ARM_CP15_REG32(0, 0, 2, 2));
> +err |= read_sys_reg32(fdarray[2], >isar.id_isar3,
> + ARM_CP15_REG32(0, 0, 2, 3));
> +err |= read_sys_reg32(fdarray[2], >isar.id_isar4,
> + ARM_CP15_REG32(0, 0, 2, 4));
> +err |= read_sys_reg32(fdarray[2], >isar.id_isar5,
> + ARM_CP15_REG32(0, 0, 2, 5));
> +err |= read_sys_reg32(fdarray[2], >isar.id_isar6,
> + ARM_CP15_REG32(0, 0, 2, 7));
> +
> +err |= read_sys_reg32(fdarray[2], >isar.mvfr0,
> + KVM_REG_ARM | KVM_REG_SIZE_U32 |
> + KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR0);
> +err |= read_sys_reg32(fdarray[2], >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], >isar.id_isar5,
ARM_CP15_REG32(0, 0, 2, 5));
-err |= read_sys_reg32(fdarray[2], >isar.id_isar6,
- ARM_CP15_REG32(0, 0, 2, 7));
-
+if (read_sys_reg32(fdarray[2], >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], >isar.mvfr0,
KVM_REG_ARM | KVM_REG_SIZE_U32 |
KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR0);
thanks
-- PMM