From patchwork Tue Jul 23 09:33:12 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Mian M. Hamayun" X-Patchwork-Id: 261012 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 3855C2C00AD for ; Tue, 23 Jul 2013 19:38:06 +1000 (EST) Received: from localhost ([::1]:46951 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V1Z2h-0005ZE-Td for incoming@patchwork.ozlabs.org; Tue, 23 Jul 2013 05:38:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48205) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V1YyY-0007yh-TK for qemu-devel@nongnu.org; Tue, 23 Jul 2013 05:33:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V1YyS-0000jX-LC for qemu-devel@nongnu.org; Tue, 23 Jul 2013 05:33:45 -0400 Received: from mail-we0-f182.google.com ([74.125.82.182]:54309) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V1YyS-0000jQ-9J for qemu-devel@nongnu.org; Tue, 23 Jul 2013 05:33:40 -0400 Received: by mail-we0-f182.google.com with SMTP id u55so2064434wes.41 for ; Tue, 23 Jul 2013 02:33:39 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=gXLZI4p0HhBIcu70uXh2JueCM/y5WESfwNVSjLhEneo=; b=JRHdiWnxUoQtmsYRlNRRExFfSfuMHs1QYBIFBE2xnuOyagV/O+f0imLVWeNv9xdcxG woWEJlMMRBNGBWeZ8jL4ar5fiqxvrABhDVsioVyNoSHB4vghp89z2qCN6aBgJNT6bSb/ 2MrKJJhTVTVZFoxYNNBXLE5+O/oCKiCNy3bgkVKX/7lBFshFlvAMNO6J87F0QALM5cFc SoV4FRN9Rx0kQ0Zp2euT+WqIWKg4bn9Iv91iHtWUaDfgwq4M1U4aSRmBjGTjyUDv16hp DOMpB15j2DWZWnUqgQw+zjfCCBGJQAVHVIT2Fh8s/DBBAYQyLuw+NGNN/QnosucHE1KG Hjbg== X-Received: by 10.180.74.197 with SMTP id w5mr32468448wiv.20.1374572019556; Tue, 23 Jul 2013 02:33:39 -0700 (PDT) Received: from localhost.localdomain (68.107.73.86.rev.sfr.net. [86.73.107.68]) by mx.google.com with ESMTPSA id f8sm2158705wiv.0.2013.07.23.02.33.37 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 23 Jul 2013 02:33:38 -0700 (PDT) From: "Mian M. Hamayun" To: qemu-devel@nongnu.org Date: Tue, 23 Jul 2013 11:33:12 +0200 Message-Id: <1374571996-9228-4-git-send-email-m.hamayun@virtualopensystems.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1374571996-9228-1-git-send-email-m.hamayun@virtualopensystems.com> References: <1374571996-9228-1-git-send-email-m.hamayun@virtualopensystems.com> X-Gm-Message-State: ALoCoQn8NWmiZ1sSTrq5kR/ivHMNljLgd/cJfnzLn43ijNTVluBuAeHwcpztt8eiMC/dM713cJ3l X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 74.125.82.182 Cc: peter.maydell@linaro.org, tech@virtualopensystems.com, kvmarm@lists.cs.columbia.edu Subject: [Qemu-devel] [PATCH v2 3/7] AARCH64: Add aarch64 CPU initialization, get and put registers support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: "Mian M. Hamayun" The cpu init function tries to initialize with all possible cpu types, as KVM does not provide a means to detect the real cpu type and simply refuses to initialize on cpu type mis-match. By using the loop based init function, we avoid the need to modify code if the underlying platform is different, such as Fast Models instead of Foundation Models. Get and Put Registers deal with the basic state of Aarch64 CPUs for the moment. Signed-off-by: Mian M. Hamayun Conflicts: target-arm/kvm.c Conflicts: target-arm/cpu.c --- linux-headers/linux/kvm.h | 1 + target-arm/kvm.c | 125 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index c614070..4df5292 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -783,6 +783,7 @@ struct kvm_dirty_tlb { #define KVM_REG_IA64 0x3000000000000000ULL #define KVM_REG_ARM 0x4000000000000000ULL #define KVM_REG_S390 0x5000000000000000ULL +#define KVM_REG_ARM64 0x6000000000000000ULL #define KVM_REG_SIZE_SHIFT 52 #define KVM_REG_SIZE_MASK 0x00f0000000000000ULL diff --git a/target-arm/kvm.c b/target-arm/kvm.c index b92e00d..c96b871 100644 --- a/target-arm/kvm.c +++ b/target-arm/kvm.c @@ -32,6 +32,11 @@ #error mismatch between cpu.h and KVM header definitions #endif +#ifdef TARGET_AARCH64 +#define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \ + KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x)) +#endif + const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_LAST_INFO }; @@ -50,6 +55,33 @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu) return cpu->cpu_index; } +#ifdef TARGET_AARCH64 +static uint32_t kvm_arm_targets[KVM_ARM_NUM_TARGETS] = { + KVM_ARM_TARGET_AEM_V8, + KVM_ARM_TARGET_FOUNDATION_V8, + KVM_ARM_TARGET_CORTEX_A57 +}; + +int kvm_arch_init_vcpu(CPUState *cs) +{ + struct kvm_vcpu_init init; + int ret, i; + + memset(init.features, 0, sizeof(init.features)); + /* Find an appropriate target CPU type. + * KVM does not provide means to detect the host CPU type on aarch64, + * and simply refuses to initialize, if the CPU type mis-matches; + * so we try each possible CPU type on aarch64 before giving up! */ + for (i = 0; i < KVM_ARM_NUM_TARGETS; ++i) { + init.target = kvm_arm_targets[i]; + ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); + if (!ret) + break; + } + + return ret; +} +#else static bool reg_syncs_via_tuple_list(uint64_t regidx) { /* Return true if the regidx is a register we should synchronize @@ -173,6 +205,7 @@ out: g_free(rlp); return ret; } +#endif /* We track all the KVM devices which need their memory addresses * passing to the kernel in a list of these structures. @@ -339,6 +372,7 @@ typedef struct Reg { int offset; } Reg; +#ifndef TARGET_AARCH64 #define COREREG(KERNELNAME, QEMUFIELD) \ { \ KVM_REG_ARM | KVM_REG_SIZE_U32 | \ @@ -402,7 +436,52 @@ static const Reg regs[] = { VFPSYSREG(FPINST), VFPSYSREG(FPINST2), }; +#endif +#ifdef TARGET_AARCH64 +int kvm_arch_put_registers(CPUState *cs, int level) +{ + struct kvm_one_reg reg; + int i; + int ret; + + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + + for (i = 0; i < ARRAY_SIZE(env->xregs); 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; + } + + reg.id = AARCH64_CORE_REG(regs.pstate); + reg.addr = (uintptr_t) &env->pstate; + 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: Set Rest of Registers */ + return ret; +} +#else int kvm_arch_put_registers(CPUState *cs, int level) { ARMCPU *cpu = ARM_CPU(cs); @@ -488,7 +567,52 @@ int kvm_arch_put_registers(CPUState *cs, int level) return ret; } +#endif +#ifdef TARGET_AARCH64 +int kvm_arch_get_registers(CPUState *cs) +{ + struct kvm_one_reg reg; + int i; + int ret; + + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + + for (i = 0; i < ARRAY_SIZE(env->xregs); 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) &env->pstate; + ret = kvm_vcpu_ioctl(cs, KVM_GET_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_GET_ONE_REG, ®); + if (ret) { + return ret; + } + + /* TODO: Set Rest of Registers */ + return ret; +} +#else int kvm_arch_get_registers(CPUState *cs) { ARMCPU *cpu = ARM_CPU(cs); @@ -559,6 +683,7 @@ int kvm_arch_get_registers(CPUState *cs) return 0; } +#endif void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) {