From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932115AbcDNMTa (ORCPT ); Thu, 14 Apr 2016 08:19:30 -0400 Received: from mail-wm0-f47.google.com ([74.125.82.47]:35428 "EHLO mail-wm0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755137AbcDNMT1 (ORCPT ); Thu, 14 Apr 2016 08:19:27 -0400 Date: Thu, 14 Apr 2016 14:19:47 +0200 From: Christoffer Dall To: Suzuki K Poulose Cc: linux-arm-kernel@lists.infradead.org, marc.zyngier@arm.com, will.deacon@arm.com, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, mark.rutland@arm.com Subject: Re: [PATCH v2 2/2] arm64: vhe: Verify CPU Exception Levels Message-ID: <20160414121947.GK30804@cbox> References: <1460472361-28419-2-git-send-email-suzuki.poulose@arm.com> <1460554893-26120-1-git-send-email-suzuki.poulose@arm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1460554893-26120-1-git-send-email-suzuki.poulose@arm.com> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Apr 13, 2016 at 02:41:33PM +0100, Suzuki K Poulose wrote: > With a VHE capable CPU, kernel can run at EL2 and is a decided at early > boot. If some of the CPUs didn't start it EL2 or doesn't have VHE, we > could have CPUs running at different exception levels, all in the same > kernel! This patch adds an early check for the secondary CPUs to detect > such situations. > > For each non-boot CPU add a sanity check to make sure we don't have > different run levels w.r.t the boot CPU. We save the information on > whether the boot CPU is running in hyp mode or not and ensure the > remaining CPUs match it. > > Applies on 4.6-rc3. > > Cc: Marc Zyngier > Cc: Christoffer Dall > Cc: Will Deacon > Cc: Mark Rutland > Cc: Catalin Marinas > Signed-off-by: Suzuki K Poulose > > --- > Changes since v1 > - Move is_boot_cpu_in_hyp_mode() to smp.c > --- > arch/arm64/include/asm/virt.h | 6 ++++++ > arch/arm64/kernel/cpufeature.c | 1 + > arch/arm64/kernel/smp.c | 38 ++++++++++++++++++++++++++++++++++++++ > 3 files changed, 45 insertions(+) > > diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h > index 9f22dd6..a5c2b48 100644 > --- a/arch/arm64/include/asm/virt.h > +++ b/arch/arm64/include/asm/virt.h > @@ -60,6 +60,12 @@ static inline bool is_kernel_in_hyp_mode(void) > return el == CurrentEL_EL2; > } > > +#ifdef CONFIG_ARM64_VHE > +extern void verify_cpu_run_el(void); > +#else > +static inline void verify_cpu_run_el(void) {} > +#endif > + > /* The section containing the hypervisor text */ > extern char __hyp_text_start[]; > extern char __hyp_text_end[]; > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c > index 943f514..91088de 100644 > --- a/arch/arm64/kernel/cpufeature.c > +++ b/arch/arm64/kernel/cpufeature.c > @@ -908,6 +908,7 @@ static u64 __raw_read_system_reg(u32 sys_id) > */ > static void check_early_cpu_features(void) > { > + verify_cpu_run_el(); > verify_cpu_asid_bits(); > } > > diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c > index b2d5f4e..e97af155 100644 > --- a/arch/arm64/kernel/smp.c > +++ b/arch/arm64/kernel/smp.c > @@ -75,6 +75,43 @@ enum ipi_msg_type { > IPI_WAKEUP > }; > > +#ifdef CONFIG_ARM64_VHE > + > +/* Whether the boot CPU is running in HYP mode or not*/ > +bool boot_cpu_hyp_mode; you can make this static now. > + > +static inline void save_boot_cpu_run_el(void) > +{ > + boot_cpu_hyp_mode = is_kernel_in_hyp_mode(); > +} > + > +static inline bool is_boot_cpu_in_hyp_mode(void) > +{ > + return boot_cpu_hyp_mode; > +} > + > +/* > + * Verify that a secondary CPU is running the kernel at the same > + * EL as that of the boot CPU. > + */ > +void verify_cpu_run_el(void) > +{ > + bool in_el2 = is_kernel_in_hyp_mode(); > + bool boot_cpu_el2 = is_boot_cpu_in_hyp_mode(); > + > + if (in_el2 ^ boot_cpu_el2) { > + pr_crit("CPU%d: mismatched Exception Level(EL%d) with boot CPU(EL%d)\n", > + smp_processor_id(), > + in_el2 ? 2 : 1, > + boot_cpu_el2 ? 2 : 1); > + cpu_panic_kernel(); > + } > +} > + > +#else > +static inline void save_boot_cpu_run_el(void) {} > +#endif > + > #ifdef CONFIG_HOTPLUG_CPU > static int op_cpu_kill(unsigned int cpu); > #else > @@ -401,6 +438,7 @@ void __init smp_cpus_done(unsigned int max_cpus) > void __init smp_prepare_boot_cpu(void) > { > cpuinfo_store_boot_cpu(); > + save_boot_cpu_run_el(); > set_my_cpu_offset(per_cpu_offset(smp_processor_id())); > } > > -- > 1.7.9.5 > Otherwise, Reviewed-by: Christoffer Dall From mboxrd@z Thu Jan 1 00:00:00 1970 From: christoffer.dall@linaro.org (Christoffer Dall) Date: Thu, 14 Apr 2016 14:19:47 +0200 Subject: [PATCH v2 2/2] arm64: vhe: Verify CPU Exception Levels In-Reply-To: <1460554893-26120-1-git-send-email-suzuki.poulose@arm.com> References: <1460472361-28419-2-git-send-email-suzuki.poulose@arm.com> <1460554893-26120-1-git-send-email-suzuki.poulose@arm.com> Message-ID: <20160414121947.GK30804@cbox> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On Wed, Apr 13, 2016 at 02:41:33PM +0100, Suzuki K Poulose wrote: > With a VHE capable CPU, kernel can run at EL2 and is a decided at early > boot. If some of the CPUs didn't start it EL2 or doesn't have VHE, we > could have CPUs running at different exception levels, all in the same > kernel! This patch adds an early check for the secondary CPUs to detect > such situations. > > For each non-boot CPU add a sanity check to make sure we don't have > different run levels w.r.t the boot CPU. We save the information on > whether the boot CPU is running in hyp mode or not and ensure the > remaining CPUs match it. > > Applies on 4.6-rc3. > > Cc: Marc Zyngier > Cc: Christoffer Dall > Cc: Will Deacon > Cc: Mark Rutland > Cc: Catalin Marinas > Signed-off-by: Suzuki K Poulose > > --- > Changes since v1 > - Move is_boot_cpu_in_hyp_mode() to smp.c > --- > arch/arm64/include/asm/virt.h | 6 ++++++ > arch/arm64/kernel/cpufeature.c | 1 + > arch/arm64/kernel/smp.c | 38 ++++++++++++++++++++++++++++++++++++++ > 3 files changed, 45 insertions(+) > > diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h > index 9f22dd6..a5c2b48 100644 > --- a/arch/arm64/include/asm/virt.h > +++ b/arch/arm64/include/asm/virt.h > @@ -60,6 +60,12 @@ static inline bool is_kernel_in_hyp_mode(void) > return el == CurrentEL_EL2; > } > > +#ifdef CONFIG_ARM64_VHE > +extern void verify_cpu_run_el(void); > +#else > +static inline void verify_cpu_run_el(void) {} > +#endif > + > /* The section containing the hypervisor text */ > extern char __hyp_text_start[]; > extern char __hyp_text_end[]; > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c > index 943f514..91088de 100644 > --- a/arch/arm64/kernel/cpufeature.c > +++ b/arch/arm64/kernel/cpufeature.c > @@ -908,6 +908,7 @@ static u64 __raw_read_system_reg(u32 sys_id) > */ > static void check_early_cpu_features(void) > { > + verify_cpu_run_el(); > verify_cpu_asid_bits(); > } > > diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c > index b2d5f4e..e97af155 100644 > --- a/arch/arm64/kernel/smp.c > +++ b/arch/arm64/kernel/smp.c > @@ -75,6 +75,43 @@ enum ipi_msg_type { > IPI_WAKEUP > }; > > +#ifdef CONFIG_ARM64_VHE > + > +/* Whether the boot CPU is running in HYP mode or not*/ > +bool boot_cpu_hyp_mode; you can make this static now. > + > +static inline void save_boot_cpu_run_el(void) > +{ > + boot_cpu_hyp_mode = is_kernel_in_hyp_mode(); > +} > + > +static inline bool is_boot_cpu_in_hyp_mode(void) > +{ > + return boot_cpu_hyp_mode; > +} > + > +/* > + * Verify that a secondary CPU is running the kernel at the same > + * EL as that of the boot CPU. > + */ > +void verify_cpu_run_el(void) > +{ > + bool in_el2 = is_kernel_in_hyp_mode(); > + bool boot_cpu_el2 = is_boot_cpu_in_hyp_mode(); > + > + if (in_el2 ^ boot_cpu_el2) { > + pr_crit("CPU%d: mismatched Exception Level(EL%d) with boot CPU(EL%d)\n", > + smp_processor_id(), > + in_el2 ? 2 : 1, > + boot_cpu_el2 ? 2 : 1); > + cpu_panic_kernel(); > + } > +} > + > +#else > +static inline void save_boot_cpu_run_el(void) {} > +#endif > + > #ifdef CONFIG_HOTPLUG_CPU > static int op_cpu_kill(unsigned int cpu); > #else > @@ -401,6 +438,7 @@ void __init smp_cpus_done(unsigned int max_cpus) > void __init smp_prepare_boot_cpu(void) > { > cpuinfo_store_boot_cpu(); > + save_boot_cpu_run_el(); > set_my_cpu_offset(per_cpu_offset(smp_processor_id())); > } > > -- > 1.7.9.5 > Otherwise, Reviewed-by: Christoffer Dall