[PATCH v2 2/6] arm: Invalidate BTB on prefetch abort outside of user mapping on Cortex A8, A9, A12 and A17

Marc Zyngier marc.zyngier at arm.com
Tue Jan 9 01:56:19 PST 2018


On 08/01/18 18:55, Marc Zyngier wrote:
> In order to prevent aliasing attacks on the branch predictor,
> invalidate the BTB on CPUs that are known to be affected when taking
> a prefetch abort on a address that is outside of a user task limit.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  arch/arm/include/asm/cp15.h |  2 ++
>  arch/arm/mm/fault.c         | 19 +++++++++++++
>  arch/arm/mm/fsr-2level.c    |  4 +--
>  arch/arm/mm/fsr-3level.c    | 67 ++++++++++++++++++++++++++++++++++++++++++++-
>  4 files changed, 89 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h
> index 4c9fa72b59f5..9e900ae855aa 100644
> --- a/arch/arm/include/asm/cp15.h
> +++ b/arch/arm/include/asm/cp15.h
> @@ -65,6 +65,8 @@
>  #define __write_sysreg(v, r, w, c, t)	asm volatile(w " " c : : "r" ((t)(v)))
>  #define write_sysreg(v, ...)		__write_sysreg(v, __VA_ARGS__)
>  
> +#define BPIALL				__ACCESS_CP15(c7, 0, c5, 6)
> +
>  extern unsigned long cr_alignment;	/* defined in entry-armv.S */
>  
>  static inline unsigned long get_cr(void)
> diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
> index 42f585379e19..ff272ffcf741 100644
> --- a/arch/arm/mm/fault.c
> +++ b/arch/arm/mm/fault.c
> @@ -21,6 +21,7 @@
>  #include <linux/highmem.h>
>  #include <linux/perf_event.h>
>  
> +#include <asm/cp15.h>
>  #include <asm/exception.h>
>  #include <asm/pgtable.h>
>  #include <asm/system_misc.h>
> @@ -181,6 +182,7 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
>  	si.si_errno = 0;
>  	si.si_code = code;
>  	si.si_addr = (void __user *)addr;
> +
>  	force_sig_info(sig, &si, tsk);
>  }
>  
> @@ -404,6 +406,23 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
>  }
>  #endif					/* CONFIG_MMU */
>  
> +static int
> +do_pabt_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
> +{
> +	if (addr > TASK_SIZE) {
> +		switch(read_cpuid_part()) {
> +		case ARM_CPU_PART_CORTEX_A8:
> +		case ARM_CPU_PART_CORTEX_A9:
> +		case ARM_CPU_PART_CORTEX_A12:
> +		case ARM_CPU_PART_CORTEX_A17:
> +			write_sysreg(0, BPIALL);
> +			break;
> +		}
> +	}
> +
> +	return do_page_fault(addr, fsr, regs);
> +}

For the record, this breaks !MMU. I've fixed it locally by moving this
function inside the CONFIG_MMU part, and provided a dummy stub for !MMU.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...



More information about the linux-arm-kernel mailing list