提交 4588c34d 编写于 作者: D Dave Martin 提交者: Marc Zyngier

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: NDave Martin <dave.martin@linaro.org>
Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
上级 6a6d55c3
...@@ -47,6 +47,23 @@ unsigned long __hyp_get_vectors(void); ...@@ -47,6 +47,23 @@ unsigned long __hyp_get_vectors(void);
#define __boot_cpu_mode (SVC_MODE) #define __boot_cpu_mode (SVC_MODE)
#endif #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 /* __ASSEMBLY__ */
#endif /* ! VIRT_H */ #endif /* ! VIRT_H */
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#include <asm/traps.h> #include <asm/traps.h>
#include <asm/unwind.h> #include <asm/unwind.h>
#include <asm/memblock.h> #include <asm/memblock.h>
#include <asm/virt.h>
#if defined(CONFIG_DEPRECATED_PARAM_STRUCT) #if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
#include "compat.h" #include "compat.h"
...@@ -937,6 +938,21 @@ static int __init meminfo_cmp(const void *_a, const void *_b) ...@@ -937,6 +938,21 @@ static int __init meminfo_cmp(const void *_a, const void *_b)
return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; 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) void __init setup_arch(char **cmdline_p)
{ {
struct machine_desc *mdesc; struct machine_desc *mdesc;
...@@ -980,6 +996,10 @@ void __init setup_arch(char **cmdline_p) ...@@ -980,6 +996,10 @@ void __init setup_arch(char **cmdline_p)
if (is_smp()) if (is_smp())
smp_init_cpus(); smp_init_cpus();
#endif #endif
if (!is_smp())
hyp_mode_check();
reserve_crashkernel(); reserve_crashkernel();
tcm_init(); tcm_init();
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/localtimer.h> #include <asm/localtimer.h>
#include <asm/smp_plat.h> #include <asm/smp_plat.h>
#include <asm/virt.h>
/* /*
* as from 2.5, kernels no longer have an init_tasks structure * 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,6 +288,8 @@ void __init smp_cpus_done(unsigned int max_cpus)
num_online_cpus(), num_online_cpus(),
bogosum / (500000/HZ), bogosum / (500000/HZ),
(bogosum / (5000/HZ)) % 100); (bogosum / (5000/HZ)) % 100);
hyp_mode_check();
} }
void __init smp_prepare_boot_cpu(void) void __init smp_prepare_boot_cpu(void)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册