aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorDave Martin <dave.martin@linaro.org>2012-02-17 11:54:28 -0500
committerMarc Zyngier <marc.zyngier@arm.com>2012-09-19 03:32:52 -0400
commit4588c34daabb5aebee9cbe90f0ca6ab11412f207 (patch)
tree1bfb963e136e20b0efa1bad2b2c6057081f0fab5 /arch/arm
parent6a6d55c38c8b4ee77b50a33f03ea09e75b18bf82 (diff)
ARM: virt: Add boot-time diagnostics
In order to easily detect pathological cases, print some diagnostics when the kernel boots. This also provides helpers to detect that HYP mode is actually available, which can be used by other subsystems to enable HYP specific features. Signed-off-by: Dave Martin <dave.martin@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/include/asm/virt.h17
-rw-r--r--arch/arm/kernel/setup.c20
-rw-r--r--arch/arm/kernel/smp.c3
3 files changed, 40 insertions, 0 deletions
diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h
index 0a99723edbf2..86164df86cb4 100644
--- a/arch/arm/include/asm/virt.h
+++ b/arch/arm/include/asm/virt.h
@@ -47,6 +47,23 @@ unsigned long __hyp_get_vectors(void);
47#define __boot_cpu_mode (SVC_MODE) 47#define __boot_cpu_mode (SVC_MODE)
48#endif 48#endif
49 49
50#ifndef ZIMAGE
51void hyp_mode_check(void);
52
53/* Reports the availability of HYP mode */
54static inline bool is_hyp_mode_available(void)
55{
56 return ((__boot_cpu_mode & MODE_MASK) == HYP_MODE &&
57 !(__boot_cpu_mode & BOOT_CPU_MODE_MISMATCH));
58}
59
60/* Check if the bootloader has booted CPUs in different modes */
61static inline bool is_hyp_mode_mismatched(void)
62{
63 return !!(__boot_cpu_mode & BOOT_CPU_MODE_MISMATCH);
64}
65#endif
66
50#endif /* __ASSEMBLY__ */ 67#endif /* __ASSEMBLY__ */
51 68
52#endif /* ! VIRT_H */ 69#endif /* ! VIRT_H */
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index a81dcecc7343..04fd01feea86 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -55,6 +55,7 @@
55#include <asm/traps.h> 55#include <asm/traps.h>
56#include <asm/unwind.h> 56#include <asm/unwind.h>
57#include <asm/memblock.h> 57#include <asm/memblock.h>
58#include <asm/virt.h>
58 59
59#if defined(CONFIG_DEPRECATED_PARAM_STRUCT) 60#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
60#include "compat.h" 61#include "compat.h"
@@ -937,6 +938,21 @@ static int __init meminfo_cmp(const void *_a, const void *_b)
937 return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; 938 return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
938} 939}
939 940
941void __init hyp_mode_check(void)
942{
943#ifdef CONFIG_ARM_VIRT_EXT
944 if (is_hyp_mode_available()) {
945 pr_info("CPU: All CPU(s) started in HYP mode.\n");
946 pr_info("CPU: Virtualization extensions available.\n");
947 } else if (is_hyp_mode_mismatched()) {
948 pr_warn("CPU: WARNING: CPU(s) started in wrong/inconsistent modes (primary CPU mode 0x%x)\n",
949 __boot_cpu_mode & MODE_MASK);
950 pr_warn("CPU: This may indicate a broken bootloader or firmware.\n");
951 } else
952 pr_info("CPU: All CPU(s) started in SVC mode.\n");
953#endif
954}
955
940void __init setup_arch(char **cmdline_p) 956void __init setup_arch(char **cmdline_p)
941{ 957{
942 struct machine_desc *mdesc; 958 struct machine_desc *mdesc;
@@ -980,6 +996,10 @@ void __init setup_arch(char **cmdline_p)
980 if (is_smp()) 996 if (is_smp())
981 smp_init_cpus(); 997 smp_init_cpus();
982#endif 998#endif
999
1000 if (!is_smp())
1001 hyp_mode_check();
1002
983 reserve_crashkernel(); 1003 reserve_crashkernel();
984 1004
985 tcm_init(); 1005 tcm_init();
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index ebd8ad274d76..adf226e718d2 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -42,6 +42,7 @@
42#include <asm/ptrace.h> 42#include <asm/ptrace.h>
43#include <asm/localtimer.h> 43#include <asm/localtimer.h>
44#include <asm/smp_plat.h> 44#include <asm/smp_plat.h>
45#include <asm/virt.h>
45 46
46/* 47/*
47 * as from 2.5, kernels no longer have an init_tasks structure 48 * as from 2.5, kernels no longer have an init_tasks structure
@@ -287,6 +288,8 @@ void __init smp_cpus_done(unsigned int max_cpus)
287 num_online_cpus(), 288 num_online_cpus(),
288 bogosum / (500000/HZ), 289 bogosum / (500000/HZ),
289 (bogosum / (5000/HZ)) % 100); 290 (bogosum / (5000/HZ)) % 100);
291
292 hyp_mode_check();
290} 293}
291 294
292void __init smp_prepare_boot_cpu(void) 295void __init smp_prepare_boot_cpu(void)