diff mbox series

[v3,4/5] target/arm: Fill in ARMISARegisters for kvm32

Message ID 20181108175246.13416-5-richard.henderson@linaro.org
State Superseded
Headers show
Series target/arm: KVM vs ARMISARegisters | expand

Commit Message

Richard Henderson Nov. 8, 2018, 5:52 p.m. UTC
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 target/arm/kvm32.c | 33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)

-- 
2.17.2

Comments

Peter Maydell Nov. 12, 2018, 11:39 a.m. UTC | #1
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
Peter Maydell Nov. 12, 2018, 12:42 p.m. UTC | #2
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
Richard Henderson Nov. 12, 2018, 2:10 p.m. UTC | #3
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 mbox series

Patch

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);
     }