From patchwork Tue Jul 3 09:00:28 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 1149541 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id B5C54DFF72 for ; Tue, 3 Jul 2012 09:00:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753258Ab2GCJAc (ORCPT ); Tue, 3 Jul 2012 05:00:32 -0400 Received: from mail-qa0-f46.google.com ([209.85.216.46]:47376 "EHLO mail-qa0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752987Ab2GCJAa (ORCPT ); Tue, 3 Jul 2012 05:00:30 -0400 Received: by mail-qa0-f46.google.com with SMTP id b17so2419395qad.19 for ; Tue, 03 Jul 2012 02:00:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=subject:to:from:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-type:content-transfer-encoding :x-gm-message-state; bh=smmZgKAn1npdjWg6tXilvpMe5Y0Tvrbs2Z1jm6BHRm8=; b=cuRCmrUcWNKFmRoCFr28cLWTESuU6MDSiyxD5NuK6ELUwrI6OJ5heszHD2qI0Vpj+p bWIqXIFaRXG3HsJb5Yb9uXdGC472gDnTIlN5cQ4DeFxzFw1UcbZOQ+msRnWe6yXcv1yK uZenUjcjhi5dssnRIfBPNupfGoPV4VSvuEsYgoAzGlNKS8UVrRKNXtyH9s9e0+p3ulSJ ohdlYFnbhIz6xn7Nfom5PHItNH+U/ZBB1/DRHWOHrOAr2OOf9eTNWupu7+GaldYU9qoj RlHuVwFLWByIKqT1/w5p7dF8S8YmdySAmIBKu7yV6BJoZBsSSCCHnuDynlVoeU0kjCzk dN9A== Received: by 10.229.134.195 with SMTP id k3mr4647699qct.6.1341306030163; Tue, 03 Jul 2012 02:00:30 -0700 (PDT) Received: from [127.0.1.1] (fireball.cs.columbia.edu. [128.59.13.10]) by mx.google.com with ESMTPS id w2sm37043389qao.2.2012.07.03.02.00.29 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 03 Jul 2012 02:00:29 -0700 (PDT) Subject: [PATCH v9 07/16] ARM: KVM: Support Cortex-A15 VCPUs reset To: android-virt@lists.cs.columbia.edu, kvm@vger.kernel.org From: Christoffer Dall Cc: tech@virtualopensystems.com Date: Tue, 03 Jul 2012 05:00:28 -0400 Message-ID: <20120703090028.27746.62871.stgit@ubuntu> In-Reply-To: <20120703085841.27746.82730.stgit@ubuntu> References: <20120703085841.27746.82730.stgit@ubuntu> User-Agent: StGit/0.15 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQnYIsDqvJggxPK5510QNEmCYbkKVEMoEznppbOiXnk2tl21ZDfcsS3OxvvjCnqTOv1VGpBu Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Reset all core and cp15 registers to their architecturally defined reset values at VCPU init time. Signed-off-by: Christoffer Dall --- arch/arm/include/asm/kvm_arm.h | 6 ++ arch/arm/kvm/exports.c | 2 + arch/arm/kvm/reset.c | 100 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h index c5bbef0..2f9d28e 100644 --- a/arch/arm/include/asm/kvm_arm.h +++ b/arch/arm/include/asm/kvm_arm.h @@ -19,4 +19,10 @@ #ifndef __ARM_KVM_ARM_H__ #define __ARM_KVM_ARM_H__ +/* Supported Processor Types */ +#define CORTEX_A15 (0xC0F) + +/* Multiprocessor Affinity Register */ +#define MPIDR_CPUID (0x3 << 0) + #endif /* __ARM_KVM_ARM_H__ */ diff --git a/arch/arm/kvm/exports.c b/arch/arm/kvm/exports.c index 01a2e41..3e38c95 100644 --- a/arch/arm/kvm/exports.c +++ b/arch/arm/kvm/exports.c @@ -17,3 +17,5 @@ */ #include + +EXPORT_SYMBOL_GPL(smp_send_reschedule); diff --git a/arch/arm/kvm/reset.c b/arch/arm/kvm/reset.c index c250024..78488be 100644 --- a/arch/arm/kvm/reset.c +++ b/arch/arm/kvm/reset.c @@ -15,6 +15,73 @@ * along with this program; if not, write to the Free Software * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define CT_ASSERT(expr, name) extern char name[(expr) ? 1 : -1] +#define CP15_REGS_ASSERT(_array, _name) \ + CT_ASSERT((sizeof(_array) / sizeof(_array[0])) == nr_cp15_regs, _name) +#define UNKNOWN 0xdecafbad + +/****************************************************************************** + * Cortex-A15 Register Reset Values + */ + +static const int a15_max_cpu_idx = 3; + +static struct kvm_vcpu_regs a15_regs_reset = { + .cpsr = SVC_MODE | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT, +}; + +static u32 a15_cp15_regs_reset[][2] = { + { c0_MIDR, 0x412FC0F0 }, + { c0_MPIDR, 0x00000000 }, /* see kvm_arch_vcpu_init */ + { c1_SCTLR, 0x00C50078 }, + { c1_ACTLR, 0x00000000 }, + { c1_CPACR, 0x00000000 }, + { c2_TTBR0, UNKNOWN }, + { c2_TTBR0_high, UNKNOWN }, + { c2_TTBR1, UNKNOWN }, + { c2_TTBR1_high, UNKNOWN }, + { c2_TTBCR, 0x00000000 }, + { c3_DACR, UNKNOWN }, + { c5_DFSR, UNKNOWN }, + { c5_IFSR, UNKNOWN }, + { c5_ADFSR, UNKNOWN }, + { c5_AIFSR, UNKNOWN }, + { c6_DFAR, UNKNOWN }, + { c6_IFAR, UNKNOWN }, + { c10_PRRR, 0x00098AA4 }, + { c10_NMRR, 0x44E048E0 }, + { c12_VBAR, 0x00000000 }, + { c13_CID, 0x00000000 }, + { c13_TID_URW, UNKNOWN }, + { c13_TID_URO, UNKNOWN }, + { c13_TID_PRIV, UNKNOWN }, +}; +CP15_REGS_ASSERT(a15_cp15_regs_reset, a15_cp15_regs_reset_init); + +static void a15_reset_vcpu(struct kvm_vcpu *vcpu) +{ + /* + * Compute guest MPIDR: + * (Even if we present only one VCPU to the guest on an SMP + * host we don't set the U bit in the MPIDR, or vice versa, as + * revealing the underlying hardware properties is likely to + * be the best choice). + */ + vcpu->arch.cp15[c0_MPIDR] = (read_cpuid_mpidr() & ~MPIDR_CPUID) + | (vcpu->vcpu_id & MPIDR_CPUID); +} + /******************************************************************************* * Exported reset function @@ -29,5 +96,38 @@ */ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) { + unsigned int i; + struct kvm_vcpu_regs *cpu_reset; + u32 (*cp15_reset)[2]; + void (*cpu_reset_vcpu)(struct kvm_vcpu *vcpu); + + switch (kvm_target_cpu()) { + case CORTEX_A15: + if (vcpu->vcpu_id > a15_max_cpu_idx) + return -EINVAL; + cpu_reset = &a15_regs_reset; + cp15_reset = a15_cp15_regs_reset; + cpu_reset_vcpu = a15_reset_vcpu; + break; + default: + return -ENODEV; + } + + /* Reset core registers */ + memcpy(&vcpu->arch.regs, cpu_reset, sizeof(vcpu->arch.regs)); + + /* Reset CP15 registers */ + for (i = 0; i < nr_cp15_regs; i++) { + if (cp15_reset[i][0] != i) { + kvm_err("CP15 field %d is %d, expected %d\n", + i, cp15_reset[i][0], i); + return -ENXIO; + } + vcpu->arch.cp15[i] = cp15_reset[i][1]; + } + + /* Physical CPU specific runtime reset operations */ + cpu_reset_vcpu(vcpu); + return 0; }