From: Christoffer Dall <christoffer.dall@linaro.org>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: patches@linaro.org, qemu-devel@nongnu.org, kvmarm@lists.cs.columbia.edu
Subject: Re: [Qemu-devel] [PATCH 3/7] target-arm: Add minimal KVM AArch64 support
Date: Mon, 16 Dec 2013 15:39:50 -0800 [thread overview]
Message-ID: <20131216233950.GC5711@cbox> (raw)
In-Reply-To: <1385645602-18662-4-git-send-email-peter.maydell@linaro.org>
On Thu, Nov 28, 2013 at 01:33:18PM +0000, Peter Maydell wrote:
> From: "Mian M. Hamayun" <m.hamayun@virtualopensystems.com>
>
> Add the bare minimum set of functions needed for control of an
> AArch64 KVM vcpu:
> * CPU initialization
> * minimal get/put register functions which only handle the
> basic state of the CPU
>
> Signed-off-by: Mian M. Hamayun <m.hamayun@virtualopensystems.com>
> [PMM: significantly overhauled; most notably:
> * code lives in kvm64.c rather than using #ifdefs
> * support '-cpu host' rather than implicitly using whatever the
> host's CPU is regardless of what the user requests
> * fix bug attempting to get/set nonexistent X[31]
> * fix bug writing 64 bit kernel pstate into uint32_t env field
> ]
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Besides the minor nits/questions below:
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
> ---
> target-arm/Makefile.objs | 1 +
> target-arm/kvm.c | 4 +
> target-arm/kvm64.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 209 insertions(+)
> create mode 100644 target-arm/kvm64.c
>
> diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
> index d1db77c..5493a4c 100644
> --- a/target-arm/Makefile.objs
> +++ b/target-arm/Makefile.objs
> @@ -7,3 +7,4 @@ obj-y += neon_helper.o iwmmxt_helper.o
> obj-y += gdbstub.o
> obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o gdbstub64.o
> obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) += kvm32.o
> +obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o
> diff --git a/target-arm/kvm.c b/target-arm/kvm.c
> index 5cdb3b9..1d2688d 100644
> --- a/target-arm/kvm.c
> +++ b/target-arm/kvm.c
> @@ -128,7 +128,11 @@ static void kvm_arm_host_cpu_initfn(Object *obj)
>
> static const TypeInfo host_arm_cpu_type_info = {
> .name = TYPE_ARM_HOST_CPU,
> +#ifdef TARGET_AARCH64
> + .parent = TYPE_AARCH64_CPU,
> +#else
> .parent = TYPE_ARM_CPU,
> +#endif
> .instance_init = kvm_arm_host_cpu_initfn,
> .class_init = kvm_arm_host_cpu_class_init,
> .class_size = sizeof(ARMHostCPUClass),
> diff --git a/target-arm/kvm64.c b/target-arm/kvm64.c
> new file mode 100644
> index 0000000..599db5d
> --- /dev/null
> +++ b/target-arm/kvm64.c
> @@ -0,0 +1,204 @@
> +/*
> + * ARM implementation of KVM hooks, 64 bit specific code
> + *
> + * Copyright Mian-M. Hamayun 2013, Virtual Open Systems
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + */
> +
> +#include <stdio.h>
> +#include <sys/types.h>
> +#include <sys/ioctl.h>
> +#include <sys/mman.h>
> +
> +#include <linux/kvm.h>
> +
> +#include "qemu-common.h"
> +#include "qemu/timer.h"
> +#include "sysemu/sysemu.h"
> +#include "sysemu/kvm.h"
> +#include "kvm_arm.h"
> +#include "cpu.h"
> +#include "hw/arm/arm.h"
> +
> +static inline void set_feature(uint64_t *features, int feature)
> +{
> + *features |= 1ULL << feature;
> +}
> +
> +bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
> +{
> + /* Identify the feature bits corresponding to the host CPU, and
> + * fill out the ARMHostCPUClass fields accordingly. To do this
> + * we have to create a scratch VM, create a single CPU inside it,
> + * and then query that CPU for the relevant ID registers.
> + * For AArch64 we currently don't care about ID registers at
> + * all; we just want to know the CPU type.
> + */
> + int fdarray[3];
> + uint64_t features = 0;
> + /* Old kernels may not know about the PREFERRED_TARGET ioctl: however
> + * we know these will only support creating one kind of guest CPU,
> + * which is its preferred CPU type. Fortunately these old kernels
> + * support only a very limited number of CPUs.
> + */
> + static const uint32_t cpus_to_try[] = {
> + KVM_ARM_TARGET_AEM_V8,
> + KVM_ARM_TARGET_FOUNDATION_V8,
> + KVM_ARM_TARGET_CORTEX_A57,
> + QEMU_KVM_ARM_TARGET_NONE
> + };
> + struct kvm_vcpu_init init;
> +
> + if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
> + return false;
> + }
> +
> + ahcc->target = init.target;
> + ahcc->dtb_compatible = "arm,arm-v7";
arm,arm-v8 ?
> +
> + kvm_arm_destroy_scratch_host_vcpu(fdarray);
> +
> + /* We can assume any KVM supporting CPU is at least a v8
> + * with VFPv4+Neon; this in turn implies most of the other
> + * feature bits.
not sure I understand the bit about implying other feature bits, the
only other thing we're setting here is AARCH64 and the features bits are
enum values?
> + */
> + set_feature(&features, ARM_FEATURE_V8);
> + set_feature(&features, ARM_FEATURE_VFP4);
> + set_feature(&features, ARM_FEATURE_NEON);
> + set_feature(&features, ARM_FEATURE_AARCH64);
> +
> + ahcc->features = features;
> +
> + return true;
> +}
> +
> +int kvm_arch_init_vcpu(CPUState *cs)
> +{
> + ARMCPU *cpu = ARM_CPU(cs);
> + struct kvm_vcpu_init init;
> + int ret;
> +
> + if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE ||
> + !arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
> + fprintf(stderr, "KVM is not supported for this guest CPU type\n");
> + return -EINVAL;
> + }
> +
> + init.target = cpu->kvm_target;
> + memset(init.features, 0, sizeof(init.features));
> + if (cpu->start_powered_off) {
> + init.features[0] = 1 << KVM_ARM_VCPU_POWER_OFF;
> + }
> + ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
> +
> + /* TODO : support for save/restore/reset of system regs via tuple list */
> +
> + return ret;
> +}
> +
> +#define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
> + KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
> +
> +int kvm_arch_put_registers(CPUState *cs, int level)
> +{
> + struct kvm_one_reg reg;
> + uint64_t val;
> + int i;
> + int ret;
> +
> + ARMCPU *cpu = ARM_CPU(cs);
> + CPUARMState *env = &cpu->env;
> +
> + for (i = 0; i < 31; i++) {
> + reg.id = AARCH64_CORE_REG(regs.regs[i]);
> + reg.addr = (uintptr_t) &env->xregs[i];
> + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
> + if (ret) {
> + return ret;
> + }
> + }
> +
> + reg.id = AARCH64_CORE_REG(regs.sp);
> + reg.addr = (uintptr_t) &env->xregs[31];
> + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
> + if (ret) {
> + return ret;
> + }
> +
> + /* Note that KVM thinks pstate is 64 bit but we use a uint32_t */
> + val = pstate_read(env);
> + reg.id = AARCH64_CORE_REG(regs.pstate);
> + reg.addr = (uintptr_t) &val;
> + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
> + if (ret) {
> + return ret;
> + }
> +
> + reg.id = AARCH64_CORE_REG(regs.pc);
> + reg.addr = (uintptr_t) &env->pc;
> + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
> + if (ret) {
> + return ret;
> + }
> +
> + /* TODO:
> + * SP_EL1
> + * ELR_EL1
> + * SPSR[]
> + * FP state
> + * system registers
> + */
> + return ret;
> +}
> +
> +int kvm_arch_get_registers(CPUState *cs)
> +{
> + struct kvm_one_reg reg;
> + uint64_t val;
> + int i;
> + int ret;
> +
> + ARMCPU *cpu = ARM_CPU(cs);
> + CPUARMState *env = &cpu->env;
> +
> + for (i = 0; i < 31; i++) {
> + reg.id = AARCH64_CORE_REG(regs.regs[i]);
> + reg.addr = (uintptr_t) &env->xregs[i];
> + ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
> + if (ret) {
> + return ret;
> + }
> + }
> +
> + reg.id = AARCH64_CORE_REG(regs.sp);
> + reg.addr = (uintptr_t) &env->xregs[31];
> + ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
> + if (ret) {
> + return ret;
> + }
> +
> + reg.id = AARCH64_CORE_REG(regs.pstate);
> + reg.addr = (uintptr_t) &val;
> + ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
> + if (ret) {
> + return ret;
> + }
> + pstate_write(env, val);
> +
> + reg.id = AARCH64_CORE_REG(regs.pc);
> + reg.addr = (uintptr_t) &env->pc;
> + ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
> + if (ret) {
> + return ret;
> + }
> +
> + /* TODO: other registers */
> + return ret;
> +}
> +
> +void kvm_arch_reset_vcpu(CPUState *cs)
> +{
> +}
> --
> 1.7.9.5
>
> _______________________________________________
> kvmarm mailing list
> kvmarm@lists.cs.columbia.edu
> https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm
next prev parent reply other threads:[~2013-12-16 23:40 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-28 13:33 [Qemu-devel] [PATCH 0/7] target-arm: Support AArch64 KVM Peter Maydell
2013-11-28 13:33 ` [Qemu-devel] [PATCH 1/7] target-arm/kvm: Split 32 bit only code into its own file Peter Maydell
2013-12-16 23:39 ` Christoffer Dall
2013-11-28 13:33 ` [Qemu-devel] [PATCH 2/7] target-arm: Clean up handling of AArch64 PSTATE Peter Maydell
2013-12-16 23:39 ` Christoffer Dall
2013-12-17 0:15 ` Peter Maydell
2013-12-17 4:45 ` Christoffer Dall
2013-12-17 11:42 ` Peter Maydell
2013-12-17 18:44 ` Christoffer Dall
2013-11-28 13:33 ` [Qemu-devel] [PATCH 3/7] target-arm: Add minimal KVM AArch64 support Peter Maydell
2013-12-16 23:39 ` Christoffer Dall [this message]
2013-12-17 0:21 ` Peter Maydell
2013-12-17 4:46 ` Christoffer Dall
2013-11-28 13:33 ` [Qemu-devel] [PATCH 4/7] configure: Enable KVM for aarch64 host/target combination Peter Maydell
2013-12-16 23:40 ` Christoffer Dall
2013-11-28 13:33 ` [Qemu-devel] [PATCH 5/7] hw/arm/boot: Allow easier swapping in of different loader code Peter Maydell
2013-12-13 3:19 ` Peter Crosthwaite
2013-12-13 10:05 ` Peter Maydell
2013-12-17 0:52 ` Peter Crosthwaite
2013-12-17 0:58 ` Peter Maydell
2013-12-17 1:24 ` Peter Crosthwaite
2013-12-17 4:56 ` Christoffer Dall
2013-12-17 10:31 ` Peter Maydell
2013-12-17 11:36 ` Peter Crosthwaite
2013-12-17 11:47 ` Peter Maydell
2013-12-17 12:02 ` Peter Crosthwaite
2013-12-16 23:40 ` Christoffer Dall
2013-12-17 0:23 ` Peter Maydell
2013-11-28 13:33 ` [Qemu-devel] [PATCH 6/7] hw/arm/boot: Add boot support for AArch64 processor Peter Maydell
2013-12-16 23:40 ` Christoffer Dall
2013-12-17 0:25 ` Peter Maydell
2013-12-17 4:50 ` Christoffer Dall
2013-11-28 13:33 ` [Qemu-devel] [PATCH 7/7] default-configs: Add config for aarch64-softmmu Peter Maydell
2013-12-16 23:40 ` Christoffer Dall
2013-12-17 0:27 ` Peter Maydell
2013-12-17 13:33 ` Christopher Covington
2013-12-05 15:23 ` [Qemu-devel] [PATCH 0/7] target-arm: Support AArch64 KVM Peter Maydell
2013-12-12 16:41 ` Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20131216233950.GC5711@cbox \
--to=christoffer.dall@linaro.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=patches@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.