diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-08-16 17:21:39 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-08-16 17:21:40 +0100 |
commit | afd760539308a5524accf964107cdb1d54a059e3 (patch) | |
tree | 010ff88dcad4835f0d863e38515119ff0de1a550 /target/arm/kvm64.c | |
parent | e018ccb3fbfa1d446ca7b49266c8a80dce40612d (diff) | |
parent | 664b7e3b97d6376f3329986c465b3782458b0f8b (diff) | |
download | qemu-afd760539308a5524accf964107cdb1d54a059e3.zip qemu-afd760539308a5524accf964107cdb1d54a059e3.tar.gz qemu-afd760539308a5524accf964107cdb1d54a059e3.tar.bz2 |
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20190816' into staging
target-arm queue:
* target/arm: generate a custom MIDR for -cpu max
* hw/misc/zynq_slcr: refactor to use standard register definition
* Set ENET_BD_BDU in I.MX FEC controller
* target/arm: Fix routing of singlestep exceptions
* refactor a32/t32 decoder handling of PC
* minor optimisations/cleanups of some a32/t32 codegen
* target/arm/cpu64: Ensure kvm really supports aarch64=off
* target/arm/cpu: Ensure we can use the pmu with kvm
* target/arm: Minor cleanups preparatory to KVM SVE support
# gpg: Signature made Fri 16 Aug 2019 14:15:55 BST
# gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg: issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE
* remotes/pmaydell/tags/pull-target-arm-20190816: (29 commits)
target/arm: Use tcg_gen_extrh_i64_i32 to extract the high word
target/arm: Simplify SMMLA, SMMLAR, SMMLS, SMMLSR
target/arm: Use tcg_gen_rotri_i32 for gen_swap_half
target/arm: Use ror32 instead of open-coding the operation
target/arm: Remove redundant shift tests
target/arm: Use tcg_gen_deposit_i32 for PKHBT, PKHTB
target/arm: Use tcg_gen_extract_i32 for shifter_out_im
target/arm/kvm64: Move the get/put of fpsimd registers out
target/arm/kvm64: Fix error returns
target/arm/cpu: Use div-round-up to determine predicate register array size
target/arm/helper: zcr: Add build bug next to value range assumption
target/arm/cpu: Ensure we can use the pmu with kvm
target/arm/cpu64: Ensure kvm really supports aarch64=off
target/arm: Remove helper_double_saturate
target/arm: Use unallocated_encoding for aarch32
target/arm: Remove offset argument to gen_exception_bkpt_insn
target/arm: Replace offset with pc in gen_exception_internal_insn
target/arm: Replace offset with pc in gen_exception_insn
target/arm: Replace s->pc with s->base.pc_next
target/arm: Remove redundant s->pc & ~1
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/kvm64.c')
-rw-r--r-- | target/arm/kvm64.c | 157 |
1 files changed, 97 insertions, 60 deletions
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 59ed579..28f6db5 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -24,7 +24,9 @@ #include "qemu/main-loop.h" #include "exec/gdbstub.h" #include "sysemu/kvm.h" +#include "sysemu/kvm_int.h" #include "kvm_arm.h" +#include "hw/boards.h" #include "internals.h" static bool have_guest_debug; @@ -593,6 +595,13 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) return true; } +bool kvm_arm_aarch32_supported(CPUState *cpu) +{ + KVMState *s = KVM_STATE(current_machine->accelerator); + + return kvm_check_extension(s, KVM_CAP_ARM_EL1_32BIT); +} + #define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5 int kvm_arch_init_vcpu(CPUState *cs) @@ -710,13 +719,53 @@ int kvm_arm_cpreg_level(uint64_t regidx) #define AARCH64_SIMD_CTRL_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U32 | \ KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x)) -int kvm_arch_put_registers(CPUState *cs, int level) +static int kvm_arch_put_fpsimd(CPUState *cs) { + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; struct kvm_one_reg reg; uint32_t fpr; + int i, ret; + + for (i = 0; i < 32; i++) { + uint64_t *q = aa64_vfp_qreg(env, i); +#ifdef HOST_WORDS_BIGENDIAN + uint64_t fp_val[2] = { q[1], q[0] }; + reg.addr = (uintptr_t)fp_val; +#else + reg.addr = (uintptr_t)q; +#endif + reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]); + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); + if (ret) { + return ret; + } + } + + reg.addr = (uintptr_t)(&fpr); + fpr = vfp_get_fpsr(env); + reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr); + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); + if (ret) { + return ret; + } + + reg.addr = (uintptr_t)(&fpr); + fpr = vfp_get_fpcr(env); + reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr); + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); + if (ret) { + return ret; + } + + return 0; +} + +int kvm_arch_put_registers(CPUState *cs, int level) +{ + struct kvm_one_reg reg; uint64_t val; - int i; - int ret; + int i, ret; unsigned int el; ARMCPU *cpu = ARM_CPU(cs); @@ -806,61 +855,75 @@ int kvm_arch_put_registers(CPUState *cs, int level) } } - /* Advanced SIMD and FP registers. */ + ret = kvm_arch_put_fpsimd(cs); + if (ret) { + return ret; + } + + ret = kvm_put_vcpu_events(cpu); + if (ret) { + return ret; + } + + write_cpustate_to_list(cpu, true); + + if (!write_list_to_kvmstate(cpu, level)) { + return -EINVAL; + } + + kvm_arm_sync_mpstate_to_kvm(cpu); + + return ret; +} + +static int kvm_arch_get_fpsimd(CPUState *cs) +{ + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + struct kvm_one_reg reg; + uint32_t fpr; + int i, ret; + for (i = 0; i < 32; i++) { uint64_t *q = aa64_vfp_qreg(env, i); -#ifdef HOST_WORDS_BIGENDIAN - uint64_t fp_val[2] = { q[1], q[0] }; - reg.addr = (uintptr_t)fp_val; -#else - reg.addr = (uintptr_t)q; -#endif reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]); - ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); + reg.addr = (uintptr_t)q; + ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); if (ret) { return ret; + } else { +#ifdef HOST_WORDS_BIGENDIAN + uint64_t t; + t = q[0], q[0] = q[1], q[1] = t; +#endif } } reg.addr = (uintptr_t)(&fpr); - fpr = vfp_get_fpsr(env); reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr); - ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); + ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); if (ret) { return ret; } + vfp_set_fpsr(env, fpr); - fpr = vfp_get_fpcr(env); + reg.addr = (uintptr_t)(&fpr); reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr); - ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); - if (ret) { - return ret; - } - - ret = kvm_put_vcpu_events(cpu); + ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); if (ret) { return ret; } + vfp_set_fpcr(env, fpr); - write_cpustate_to_list(cpu, true); - - if (!write_list_to_kvmstate(cpu, level)) { - return EINVAL; - } - - kvm_arm_sync_mpstate_to_kvm(cpu); - - return ret; + return 0; } int kvm_arch_get_registers(CPUState *cs) { struct kvm_one_reg reg; uint64_t val; - uint32_t fpr; unsigned int el; - int i; - int ret; + int i, ret; ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; @@ -949,36 +1012,10 @@ int kvm_arch_get_registers(CPUState *cs) env->spsr = env->banked_spsr[i]; } - /* Advanced SIMD and FP registers */ - for (i = 0; i < 32; i++) { - uint64_t *q = aa64_vfp_qreg(env, i); - reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]); - reg.addr = (uintptr_t)q; - ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); - if (ret) { - return ret; - } else { -#ifdef HOST_WORDS_BIGENDIAN - uint64_t t; - t = q[0], q[0] = q[1], q[1] = t; -#endif - } - } - - reg.addr = (uintptr_t)(&fpr); - reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr); - ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); + ret = kvm_arch_get_fpsimd(cs); if (ret) { return ret; } - vfp_set_fpsr(env, fpr); - - reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr); - ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); - if (ret) { - return ret; - } - vfp_set_fpcr(env, fpr); ret = kvm_get_vcpu_events(cpu); if (ret) { @@ -986,7 +1023,7 @@ int kvm_arch_get_registers(CPUState *cs) } if (!write_kvmstate_to_list(cpu)) { - return EINVAL; + return -EINVAL; } /* Note that it's OK to have registers which aren't in CPUState, * so we can ignore a failure return here. |