From patchwork Wed Feb 15 18:15:56 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Martin X-Patchwork-Id: 6797 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 7B7C723DE1 for ; Wed, 15 Feb 2012 18:17:06 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id 47B79A18A1D for ; Wed, 15 Feb 2012 18:16:26 +0000 (UTC) Received: by mail-iy0-f180.google.com with SMTP id z7so2416596iab.11 for ; Wed, 15 Feb 2012 10:16:26 -0800 (PST) Received: by 10.42.80.3 with SMTP id t3mr35419521ick.49.1329329786002; Wed, 15 Feb 2012 10:16:26 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.80.19 with SMTP id r19cs2660ibk; Wed, 15 Feb 2012 10:16:25 -0800 (PST) Received: by 10.180.86.198 with SMTP id r6mr6217427wiz.22.1329329784218; Wed, 15 Feb 2012 10:16:24 -0800 (PST) Received: from mail-we0-f178.google.com (mail-we0-f178.google.com [74.125.82.178]) by mx.google.com with ESMTPS id t7si22561552wit.3.2012.02.15.10.16.23 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 15 Feb 2012 10:16:24 -0800 (PST) Received-SPF: neutral (google.com: 74.125.82.178 is neither permitted nor denied by best guess record for domain of dave.martin@linaro.org) client-ip=74.125.82.178; Authentication-Results: mx.google.com; spf=neutral (google.com: 74.125.82.178 is neither permitted nor denied by best guess record for domain of dave.martin@linaro.org) smtp.mail=dave.martin@linaro.org Received: by mail-we0-f178.google.com with SMTP id b12so1115693wer.37 for ; Wed, 15 Feb 2012 10:16:23 -0800 (PST) MIME-Version: 1.0 Received: by 10.180.92.73 with SMTP id ck9mr37247404wib.2.1329329783363; Wed, 15 Feb 2012 10:16:23 -0800 (PST) Received: from localhost.localdomain ([213.123.120.124]) by mx.google.com with ESMTPS id dw7sm35106696wib.4.2012.02.15.10.16.21 (version=SSLv3 cipher=OTHER); Wed, 15 Feb 2012 10:16:22 -0800 (PST) From: Dave Martin To: Nicolas Pitre , Christoffer Dall , Marc Zyngier , Will Deacon Cc: patches@linaro.org, Dave Martin Subject: [PATCH 03/10] fixup! ARM: virt: Initial Virtualization Extensions support Date: Wed, 15 Feb 2012 18:15:56 +0000 Message-Id: <1329329763-31508-4-git-send-email-dave.martin@linaro.org> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1329329763-31508-1-git-send-email-dave.martin@linaro.org> References: <1329329763-31508-1-git-send-email-dave.martin@linaro.org> X-Gm-Message-State: ALoCoQl/Lf568Fg69Xq6x1lYAOwac3JGg1dYpdM7MGzhxwOhZ7LSaq5UabN0kz1P5hobv9YSLPtW Instead of counting how many CPUs the hypervisor stub was installed on, we simply record what mode the primary CPU was booted and set a flag if an inconsistency is detected. Signed-off-by: Dave Martin --- arch/arm/include/asm/virt.h | 27 ++++++++++++++++++++++- arch/arm/kernel/hyp-stub.S | 51 ++++++++++++++++++++++++++++-------------- 2 files changed, 60 insertions(+), 18 deletions(-) diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h index 77d7a65..3659eb5 100644 --- a/arch/arm/include/asm/virt.h +++ b/arch/arm/include/asm/virt.h @@ -30,8 +30,33 @@ #ifndef VIRT_H #define VIRT_H -extern int __hyp_stub_install_count; +#include + +#ifndef __ASSEMBLY__ + +/* + * __boot_cpu_mode records what mode the primary CPU was booted in. + * A correctly-implemented bootloader must start all CPUs in the same mode: + * if it fails to do this, the flag BOOT_CPU_MODE_MISMATCH is set to indicate + * that some CPU(s) were booted in a different mode. + * + * This allows the kernel to flag an error when the secondaries have come up. + */ +extern int __boot_cpu_mode; void __hyp_set_vectors(unsigned long phys_vector_base); +#endif /* __ASSEMBLY__ */ + +/* + * Helper macro to extract the mode the primary CPU mode booted in from + * __boot_cpu_mode: + */ +#define BOOT_CPU_MODE_PRIMARY(x) (x & MODE_MASK) +#define BOOT_CPU_MODE_MISMATCH (1<<31) + +#define BOOT_CPU_MODE_HAVE_HYP(x) \ + (BOOT_CPU_MODE_PRIMARY(x) == HYP_MODE && \ + !((x) & BOOT_CPU_MODE_MISMATCH)) + #endif /* ! VIRT_H */ diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S index ec16e46..5c5f49f 100644 --- a/arch/arm/kernel/hyp-stub.S +++ b/arch/arm/kernel/hyp-stub.S @@ -30,6 +30,7 @@ #include #include #include +#include /* * Hypervisor stub installation functions. @@ -41,19 +42,32 @@ @ Call this from the primary CPU ENTRY(__hyp_stub_install) adr r4, 1f - ldr r5, .L__hyp_stub_install_count_offset - mov r6, #0 - str r6, [r4, r5] @ reset __hyp_stub_install_count to 0 + ldr r5, .L__boot_cpu_mode_offset + mrs r6, cpsr + and r6, r6, #MODE_MASK + str r6, [r4, r5] @ record the CPU mode we were booted in ENDPROC(__hyp_stub_install) @ fall through... @ Secondary CPUs should call here ENTRY(__hyp_stub_install_secondary) + adr r4, 1f + ldr r5, .L__boot_cpu_mode_offset mrs r6, cpsr - and r7, r6, #MODE_MASK - cmp r7, #HYP_MODE - bxne lr @ give up if not in hyp mode + and r6, r6, #MODE_MASK + ldr r7, [r4, r5] + cmp r6, r7 + beq 2f @ matches primary CPU boot mode? + + orr r6, r6, #BOOT_CPU_MODE_MISMATCH + str r6, [r4, r5] + bx lr @ record what happened and give up + + @ otherwise ... + +2: cmp r6, #HYP_MODE + bxne lr @ give up if the CPU is not in HYP mode /* * BUG: hyp mode init needs to happen here: @@ -67,11 +81,12 @@ ENTRY(__hyp_stub_install_secondary) * for that) */ @ Now install the hypervisor stub: + adr r7, __hyp_stub_vectors mcr p15, 4, r7, c12, c0, 0 @ set hypervisor vector base (HVBAR) adr r4, 1f - ldr r5, .L__hyp_stub_install_count_offset + ldr r5, .L__boot_cpu_mode_offset 1: ldr r7, [r4, r5] add r7, r7, #1 str r7, [r4, r5] @ increment __hyp_stub_install_count @@ -102,14 +117,16 @@ ENDPROC(__hyp_stub_do_trap) * r0 must be 32-byte aligned. * * Before calling this, you must check that the stub hypervisor is installed - * everywhere, by checking that __hyp_stub_install_count == the number of - * booted CPUs. If not, there is a pre-existing hypervisor, some CPUs failed - * to boot, or something else went wrong... in such cases, trying to install - * a new hypervisor is unlikely to work as desired. + * everywhere, by waiting for any secondary CPUs to be brought up and then + * checking that BOOT_CPU_MODE_HAVE_HYP(__boot_cpu_mode) is true. + * + * If not, there is a pre-existing hypervisor, some CPUs failed to boot, or + * something else went wrong... in such cases, trying to install a new + * hypervisor is unlikely to work as desired. * * When you call into your shiny new hypervisor, sp_hyp will contain junk, - * so you will need to set that to something sensible when calling into the - * new hypervisor to initialise it. + * so you will need to set that to something sensible at the new hypervisor's + * initialisation entry point. */ ENTRY(__hyp_set_vectors) hvc #0 @@ -117,8 +134,8 @@ ENTRY(__hyp_set_vectors) ENDPROC(__hyp_set_vectors) .align 2 -.L__hyp_stub_install_count_offset: - .long __hyp_stub_install_count - 1b +.L__boot_cpu_mode_offset: + .long __boot_cpu_mode - 1b .align 5 __hyp_stub_vectors: @@ -134,5 +151,5 @@ ENDPROC(__hyp_stub_vectors) .bss -__hyp_stub_install_count: - .long 0 +ENTRY(__boot_cpu_mode) + .long 0