Re: [PATCH 4.9 V2 09/24] ARM: spectre-v2: add firmware based hardening

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Marc,

Can you please ack this to say that you are now happy with it after
your comments on version 1, so we can move forward and have Greg
merge it.

Thanks.

On Wed, Nov 07, 2018 at 11:43:47AM -0500, David Long wrote:
> From: Russell King <rmk+kernel@xxxxxxxxxxxxxxx>
> 
> Commit 10115105cb3aa17b5da1cb726ae8dd5f6854bd93 upstream.
> Commit 6282e916f774e37845c65d1eae9f8c649004f033 upstream.
> 
> Add firmware based hardening for cores that require more complex
> handling in firmware.
> 
> Signed-off-by: Russell King <rmk+kernel@xxxxxxxxxxxxxxx>
> Boot-tested-by: Tony Lindgren <tony@xxxxxxxxxxx>
> Reviewed-by: Tony Lindgren <tony@xxxxxxxxxxx>
> Reviewed-by: Marc Zyngier <marc.zyngier@xxxxxxx>
> Signed-off-by: David A. Long <dave.long@xxxxxxxxxx>
> ---
>  arch/arm/mm/proc-v7-bugs.c | 60 ++++++++++++++++++++++++++++++++++++++
>  arch/arm/mm/proc-v7.S      | 21 +++++++++++++
>  2 files changed, 81 insertions(+)
> 
> diff --git a/arch/arm/mm/proc-v7-bugs.c b/arch/arm/mm/proc-v7-bugs.c
> index 85a2e3d6263c..da25a38e1897 100644
> --- a/arch/arm/mm/proc-v7-bugs.c
> +++ b/arch/arm/mm/proc-v7-bugs.c
> @@ -1,14 +1,20 @@
>  // SPDX-License-Identifier: GPL-2.0
> +#include <linux/arm-smccc.h>
>  #include <linux/kernel.h>
> +#include <linux/psci.h>
>  #include <linux/smp.h>
>  
>  #include <asm/cp15.h>
>  #include <asm/cputype.h>
> +#include <asm/proc-fns.h>
>  #include <asm/system_misc.h>
>  
>  #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
>  DEFINE_PER_CPU(harden_branch_predictor_fn_t, harden_branch_predictor_fn);
>  
> +extern void cpu_v7_smc_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
> +extern void cpu_v7_hvc_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
> +
>  static void harden_branch_predictor_bpiall(void)
>  {
>  	write_sysreg(0, BPIALL);
> @@ -19,6 +25,16 @@ static void harden_branch_predictor_iciallu(void)
>  	write_sysreg(0, ICIALLU);
>  }
>  
> +static void __maybe_unused call_smc_arch_workaround_1(void)
> +{
> +	arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL);
> +}
> +
> +static void __maybe_unused call_hvc_arch_workaround_1(void)
> +{
> +	arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL);
> +}
> +
>  static void cpu_v7_spectre_init(void)
>  {
>  	const char *spectre_v2_method = NULL;
> @@ -45,7 +61,51 @@ static void cpu_v7_spectre_init(void)
>  			harden_branch_predictor_iciallu;
>  		spectre_v2_method = "ICIALLU";
>  		break;
> +
> +#ifdef CONFIG_ARM_PSCI
> +	default:
> +		/* Other ARM CPUs require no workaround */
> +		if (read_cpuid_implementor() == ARM_CPU_IMP_ARM)
> +			break;
> +		/* fallthrough */
> +		/* Cortex A57/A72 require firmware workaround */
> +	case ARM_CPU_PART_CORTEX_A57:
> +	case ARM_CPU_PART_CORTEX_A72: {
> +		struct arm_smccc_res res;
> +
> +		if (psci_ops.smccc_version == SMCCC_VERSION_1_0)
> +			break;
> +
> +		switch (psci_ops.conduit) {
> +		case PSCI_CONDUIT_HVC:
> +			arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
> +					  ARM_SMCCC_ARCH_WORKAROUND_1, &res);
> +			if ((int)res.a0 != 0)
> +				break;
> +			per_cpu(harden_branch_predictor_fn, cpu) =
> +				call_hvc_arch_workaround_1;
> +			processor.switch_mm = cpu_v7_hvc_switch_mm;
> +			spectre_v2_method = "hypervisor";
> +			break;
> +
> +		case PSCI_CONDUIT_SMC:
> +			arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
> +					  ARM_SMCCC_ARCH_WORKAROUND_1, &res);
> +			if ((int)res.a0 != 0)
> +				break;
> +			per_cpu(harden_branch_predictor_fn, cpu) =
> +				call_smc_arch_workaround_1;
> +			processor.switch_mm = cpu_v7_smc_switch_mm;
> +			spectre_v2_method = "firmware";
> +			break;
> +
> +		default:
> +			break;
> +		}
>  	}
> +#endif
> +	}
> +
>  	if (spectre_v2_method)
>  		pr_info("CPU%u: Spectre v2: using %s workaround\n",
>  			smp_processor_id(), spectre_v2_method);
> diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
> index 2d2e5ae85816..850c22bca19c 100644
> --- a/arch/arm/mm/proc-v7.S
> +++ b/arch/arm/mm/proc-v7.S
> @@ -9,6 +9,7 @@
>   *
>   *  This is the "shell" of the ARMv7 processor support.
>   */
> +#include <linux/arm-smccc.h>
>  #include <linux/init.h>
>  #include <linux/linkage.h>
>  #include <asm/assembler.h>
> @@ -88,6 +89,26 @@ ENTRY(cpu_v7_dcache_clean_area)
>  	ret	lr
>  ENDPROC(cpu_v7_dcache_clean_area)
>  
> +#ifdef CONFIG_ARM_PSCI
> +	.arch_extension sec
> +ENTRY(cpu_v7_smc_switch_mm)
> +	stmfd	sp!, {r0 - r3}
> +	movw	r0, #:lower16:ARM_SMCCC_ARCH_WORKAROUND_1
> +	movt	r0, #:upper16:ARM_SMCCC_ARCH_WORKAROUND_1
> +	smc	#0
> +	ldmfd	sp!, {r0 - r3}
> +	b	cpu_v7_switch_mm
> +ENDPROC(cpu_v7_smc_switch_mm)
> +	.arch_extension virt
> +ENTRY(cpu_v7_hvc_switch_mm)
> +	stmfd	sp!, {r0 - r3}
> +	movw	r0, #:lower16:ARM_SMCCC_ARCH_WORKAROUND_1
> +	movt	r0, #:upper16:ARM_SMCCC_ARCH_WORKAROUND_1
> +	hvc	#0
> +	ldmfd	sp!, {r0 - r3}
> +	b	cpu_v7_switch_mm
> +ENDPROC(cpu_v7_hvc_switch_mm)
> +#endif
>  ENTRY(cpu_v7_iciallu_switch_mm)
>  	mov	r3, #0
>  	mcr	p15, 0, r3, c7, c5, 0		@ ICIALLU
> -- 
> 2.17.1
> 

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up



[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux