Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Dave Martin and committed by
Marc Zyngier
4588c34d 6a6d55c3

+40
+17
arch/arm/include/asm/virt.h
··· 47 47 #define __boot_cpu_mode (SVC_MODE) 48 48 #endif 49 49 50 + #ifndef ZIMAGE 51 + void hyp_mode_check(void); 52 + 53 + /* Reports the availability of HYP mode */ 54 + static 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 */ 61 + static inline bool is_hyp_mode_mismatched(void) 62 + { 63 + return !!(__boot_cpu_mode & BOOT_CPU_MODE_MISMATCH); 64 + } 65 + #endif 66 + 50 67 #endif /* __ASSEMBLY__ */ 51 68 52 69 #endif /* ! VIRT_H */
+20
arch/arm/kernel/setup.c
··· 55 55 #include <asm/traps.h> 56 56 #include <asm/unwind.h> 57 57 #include <asm/memblock.h> 58 + #include <asm/virt.h> 58 59 59 60 #if defined(CONFIG_DEPRECATED_PARAM_STRUCT) 60 61 #include "compat.h" ··· 938 937 return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; 939 938 } 940 939 940 + void __init hyp_mode_check(void) 941 + { 942 + #ifdef CONFIG_ARM_VIRT_EXT 943 + if (is_hyp_mode_available()) { 944 + pr_info("CPU: All CPU(s) started in HYP mode.\n"); 945 + pr_info("CPU: Virtualization extensions available.\n"); 946 + } else if (is_hyp_mode_mismatched()) { 947 + pr_warn("CPU: WARNING: CPU(s) started in wrong/inconsistent modes (primary CPU mode 0x%x)\n", 948 + __boot_cpu_mode & MODE_MASK); 949 + pr_warn("CPU: This may indicate a broken bootloader or firmware.\n"); 950 + } else 951 + pr_info("CPU: All CPU(s) started in SVC mode.\n"); 952 + #endif 953 + } 954 + 941 955 void __init setup_arch(char **cmdline_p) 942 956 { 943 957 struct machine_desc *mdesc; ··· 996 980 if (is_smp()) 997 981 smp_init_cpus(); 998 982 #endif 983 + 984 + if (!is_smp()) 985 + hyp_mode_check(); 986 + 999 987 reserve_crashkernel(); 1000 988 1001 989 tcm_init();
+3
arch/arm/kernel/smp.c
··· 42 42 #include <asm/ptrace.h> 43 43 #include <asm/localtimer.h> 44 44 #include <asm/smp_plat.h> 45 + #include <asm/virt.h> 45 46 46 47 /* 47 48 * as from 2.5, kernels no longer have an init_tasks structure ··· 288 287 num_online_cpus(), 289 288 bogosum / (500000/HZ), 290 289 (bogosum / (5000/HZ)) % 100); 290 + 291 + hyp_mode_check(); 291 292 } 292 293 293 294 void __init smp_prepare_boot_cpu(void)