diff --git a/[refs] b/[refs] index 4fe7e3f16c8a..0d820b221629 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6a6d55c38c8b4ee77b50a33f03ea09e75b18bf82 +refs/heads/master: 4588c34daabb5aebee9cbe90f0ca6ab11412f207 diff --git a/trunk/arch/arm/include/asm/virt.h b/trunk/arch/arm/include/asm/virt.h index 0a99723edbf2..86164df86cb4 100644 --- a/trunk/arch/arm/include/asm/virt.h +++ b/trunk/arch/arm/include/asm/virt.h @@ -47,6 +47,23 @@ unsigned long __hyp_get_vectors(void); #define __boot_cpu_mode (SVC_MODE) #endif +#ifndef ZIMAGE +void hyp_mode_check(void); + +/* Reports the availability of HYP mode */ +static inline bool is_hyp_mode_available(void) +{ + return ((__boot_cpu_mode & MODE_MASK) == HYP_MODE && + !(__boot_cpu_mode & BOOT_CPU_MODE_MISMATCH)); +} + +/* Check if the bootloader has booted CPUs in different modes */ +static inline bool is_hyp_mode_mismatched(void) +{ + return !!(__boot_cpu_mode & BOOT_CPU_MODE_MISMATCH); +} +#endif + #endif /* __ASSEMBLY__ */ #endif /* ! VIRT_H */ diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index a81dcecc7343..04fd01feea86 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -55,6 +55,7 @@ #include #include #include +#include #if defined(CONFIG_DEPRECATED_PARAM_STRUCT) #include "compat.h" @@ -937,6 +938,21 @@ static int __init meminfo_cmp(const void *_a, const void *_b) return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; } +void __init hyp_mode_check(void) +{ +#ifdef CONFIG_ARM_VIRT_EXT + if (is_hyp_mode_available()) { + pr_info("CPU: All CPU(s) started in HYP mode.\n"); + pr_info("CPU: Virtualization extensions available.\n"); + } else if (is_hyp_mode_mismatched()) { + pr_warn("CPU: WARNING: CPU(s) started in wrong/inconsistent modes (primary CPU mode 0x%x)\n", + __boot_cpu_mode & MODE_MASK); + pr_warn("CPU: This may indicate a broken bootloader or firmware.\n"); + } else + pr_info("CPU: All CPU(s) started in SVC mode.\n"); +#endif +} + void __init setup_arch(char **cmdline_p) { struct machine_desc *mdesc; @@ -980,6 +996,10 @@ void __init setup_arch(char **cmdline_p) if (is_smp()) smp_init_cpus(); #endif + + if (!is_smp()) + hyp_mode_check(); + reserve_crashkernel(); tcm_init(); diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index ebd8ad274d76..adf226e718d2 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -42,6 +42,7 @@ #include #include #include +#include /* * 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) num_online_cpus(), bogosum / (500000/HZ), (bogosum / (5000/HZ)) % 100); + + hyp_mode_check(); } void __init smp_prepare_boot_cpu(void)