diff options
author | Rusty Russell <rusty.russell@linaro.org> | 2012-09-11 15:40:21 +0930 |
---|---|---|
committer | Rusty Russell <rusty.russell@linaro.org> | 2012-09-11 15:40:21 +0930 |
commit | bee93045fb94a93ef0708cb9e293c5eeb1203e6e (patch) | |
tree | 193ba5c5f942c8864614bf1c90c09aa383e9a0ea | |
parent | 6db30e0609fef90a083e2ef05beee0eb6072333a (diff) | |
download | linux-kvm-arm-testing-wip.tar.gz |
patch kvmtest-test-vfp.patchtesting-wip
-rw-r--r-- | tools/testing/selftests/kvm/arm/vfp-guest.c | 15 | ||||
-rw-r--r-- | tools/testing/selftests/kvm/arm/vfp-host.c | 101 | ||||
-rw-r--r-- | tools/testing/selftests/kvm/arm/vfp_test.h | 5 |
3 files changed, 86 insertions, 35 deletions
diff --git a/tools/testing/selftests/kvm/arm/vfp-guest.c b/tools/testing/selftests/kvm/arm/vfp-guest.c index b5bffe3f79f0d..075d4f7142b37 100644 --- a/tools/testing/selftests/kvm/arm/vfp-guest.c +++ b/tools/testing/selftests/kvm/arm/vfp-guest.c @@ -64,5 +64,20 @@ int test(void) asm volatile("ldr %0, [%1]" : "=r"(val) : "r"(VFP_USE_REG + 16)); assert(d16 == 2.0); + /* Now check host ioctl sees register correctly. */ + d0 = 2.0; + asm volatile("ldr %0, [%1]" : "=r"(val) : "r"(VFP_CHECK_REG)); + + d0 = 2.0; + asm volatile("ldr %0, [%1]" : "=r"(val) : "r"(VFP_SET_REG)); + assert(d0 == 3.0); + + d16 = 2.0; + asm volatile("ldr %0, [%1]" : "=r"(val) : "r"(VFP_CHECK_REG+16)); + + d16 = 2.0; + asm volatile("ldr %0, [%1]" : "=r"(val) : "r"(VFP_SET_REG+16)); + assert(d16 == 3.0); + return 0; } diff --git a/tools/testing/selftests/kvm/arm/vfp-host.c b/tools/testing/selftests/kvm/arm/vfp-host.c index bf8f03ba097e5..7761f4d1cd753 100644 --- a/tools/testing/selftests/kvm/arm/vfp-host.c +++ b/tools/testing/selftests/kvm/arm/vfp-host.c @@ -18,6 +18,9 @@ #include <stdbool.h> #include <string.h> #include <linux/kvm.h> +#include <sys/ioctl.h> +#include <err.h> +#include <stdlib.h> #include "guest-driver.h" #include "vfp_test.h" @@ -27,6 +30,8 @@ static bool vfp_test(struct kvm_run *kvm_run, int vcpu_fd) { unsigned long phys_addr; bool is_write; + struct kvm_one_reg r; + double d; phys_addr = (unsigned long)kvm_run->mmio.phys_addr; is_write = kvm_run->mmio.is_write; @@ -37,104 +42,130 @@ static bool vfp_test(struct kvm_run *kvm_run, int vcpu_fd) switch (phys_addr) { case VFP_USE_REG: asm volatile("fconstd d0, #112"); - break; + return true; case VFP_USE_REG+1: asm volatile("fconstd d1, #112"); - break; + return true; case VFP_USE_REG+2: asm volatile("fconstd d2, #112"); - break; + return true; case VFP_USE_REG+3: asm volatile("fconstd d3, #112"); - break; + return true; case VFP_USE_REG+4: asm volatile("fconstd d4, #112"); - break; + return true; case VFP_USE_REG+5: asm volatile("fconstd d5, #112"); - break; + return true; case VFP_USE_REG+6: asm volatile("fconstd d6, #112"); - break; + return true; case VFP_USE_REG+7: asm volatile("fconstd d7, #112"); - break; + return true; case VFP_USE_REG+8: asm volatile("fconstd d8, #112"); - break; + return true; case VFP_USE_REG+9: asm volatile("fconstd d9, #112"); - break; + return true; case VFP_USE_REG+10: asm volatile("fconstd d10, #112"); - break; + return true; case VFP_USE_REG+11: asm volatile("fconstd d11, #112"); - break; + return true; case VFP_USE_REG+12: asm volatile("fconstd d12, #112"); - break; + return true; case VFP_USE_REG+13: asm volatile("fconstd d13, #112"); - break; + return true; case VFP_USE_REG+14: asm volatile("fconstd d14, #112"); - break; + return true; case VFP_USE_REG+15: asm volatile("fconstd d15, #112"); - break; + return true; case VFP_USE_REG+16: asm volatile("fconstd d16, #112"); - break; + return true; case VFP_USE_REG+17: asm volatile("fconstd d17, #112"); - break; + return true; case VFP_USE_REG+18: asm volatile("fconstd d18, #112"); - break; + return true; case VFP_USE_REG+19: asm volatile("fconstd d19, #112"); - break; + return true; case VFP_USE_REG+20: asm volatile("fconstd d20, #112"); - break; + return true; case VFP_USE_REG+21: asm volatile("fconstd d21, #112"); - break; + return true; case VFP_USE_REG+22: asm volatile("fconstd d22, #112"); - break; + return true; case VFP_USE_REG+23: asm volatile("fconstd d23, #112"); - break; + return true; case VFP_USE_REG+24: asm volatile("fconstd d24, #112"); - break; + return true; case VFP_USE_REG+25: asm volatile("fconstd d25, #112"); - break; + return true; case VFP_USE_REG+26: asm volatile("fconstd d26, #112"); - break; + return true; case VFP_USE_REG+27: asm volatile("fconstd d27, #112"); - break; + return true; case VFP_USE_REG+28: asm volatile("fconstd d28, #112"); - break; + return true; case VFP_USE_REG+29: asm volatile("fconstd d29, #112"); - break; + return true; case VFP_USE_REG+30: asm volatile("fconstd d30, #112"); - break; + return true; case VFP_USE_REG+31: asm volatile("fconstd d31, #112"); - break; - default: - return false; + return true; + } + + /* Check reg is a particular value. */ + if (phys_addr >= VFP_CHECK_REG && phys_addr < VFP_CHECK_REG + 32) { + r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 + | KVM_REG_ARM_VFP + | (phys_addr - VFP_CHECK_REG); + r.addr = (long)&d; + if (ioctl(vcpu_fd, KVM_GET_ONE_REG, &r) != 0) + err(EXIT_FAILURE, "KVM_GET_ONE_REG(VFP %li) failed", + phys_addr - VFP_CHECK_REG); + if (d != 2.0) + errx(EXIT_FAILURE, "KVM_GET_ONE_REG(VFP %li) == %.lf", + phys_addr - VFP_CHECK_REG, d); + return true; } - return true; + + if (phys_addr >= VFP_SET_REG && phys_addr < VFP_SET_REG + 32) { + r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 + | KVM_REG_ARM_VFP + | (phys_addr - VFP_SET_REG); + r.addr = (long)&d; + d = 3.0; + if (ioctl(vcpu_fd, KVM_SET_ONE_REG, &r) != 0) + err(EXIT_FAILURE, "KVM_SET_ONE_REG(VFP %li) failed", + phys_addr - VFP_CHECK_REG); + return true; + } + + return false; } GUEST_TEST(vfp, vfp_test); diff --git a/tools/testing/selftests/kvm/arm/vfp_test.h b/tools/testing/selftests/kvm/arm/vfp_test.h index eedc953b230b4..8a56a80f90d32 100644 --- a/tools/testing/selftests/kvm/arm/vfp_test.h +++ b/tools/testing/selftests/kvm/arm/vfp_test.h @@ -1,6 +1,11 @@ #ifndef VFP_TEST_H #define VFP_TEST_H +/* This uses reg in host, to check for interference. */ #define VFP_USE_REG (0xc0000000) /* + offset of register number */ +/* This uses ioctl to check register is 2.0. */ +#define VFP_CHECK_REG (0xc0000020) /* + offset of register number */ +/* This uses ioctl to set register to 3.0. */ +#define VFP_SET_REG (0xc0000040) /* + offset of register number */ #endif /* VFP_TEST_H */ |