Date: Fri, 12 Jan 2018 15:10:58 +0100 From: Marcin Wojtas <mw@semihalf.com> To: Andrew Turner <andrew@freebsd.org> Cc: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r327876 - in head/sys/arm64: arm64 include Message-ID: <CAPv3WKcESa_AL=R-BFwef2GXxHcYsnmbUOV3Zx5qL8WdMS-o3Q@mail.gmail.com> In-Reply-To: <201801121401.w0CE1cW4058239@repo.freebsd.org> References: <201801121401.w0CE1cW4058239@repo.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Hi Andrew, 2018-01-12 15:01 GMT+01:00 Andrew Turner <andrew@freebsd.org>: > Author: andrew > Date: Fri Jan 12 14:01:38 2018 > New Revision: 327876 > URL: https://svnweb.freebsd.org/changeset/base/327876 > > Log: > Workaround Spectre Variant 2 on arm64. > > We need to handle two cases: > > 1. One process attacking another process. > 2. A process attacking the kernel. > > For the first case we clear the branch predictor state on context switch > between different processes. For the second we do this when taking an > instruction abort on a non-userspace address. > > To clear the branch predictor state a per-CPU function pointer has been > added. This is set by the new cpu errata code based on if the CPU is > known to be affected. > > On Cortex-A57, A72, A73, and A75 we call into the PSCI firmware as newer > versions of this will clear the branch predictor state for us. > > It has been reported the ThunderX is unaffected, however the ThunderX2 is > vulnerable. The Qualcomm Falkor core is also affected. As FreeBSD doesn't > yet run on the ThunderX2 or Falkor no workaround is included for these CPUs. Regardless ThunderX2 / Falkor work-arounds, do I understand correctly that pure CA72 machines, such as Marvell Armada 7k/8k are immune to Variant 2 now? Thanks, Marcin > > MFC after: 3 days > Sponsored by: DARPA, AFRL > Differential Revision: https://reviews.freebsd.org/D13812 > > Modified: > head/sys/arm64/arm64/cpu_errata.c > head/sys/arm64/arm64/pmap.c > head/sys/arm64/arm64/trap.c > head/sys/arm64/include/pcpu.h > > Modified: head/sys/arm64/arm64/cpu_errata.c > ============================================================================== > --- head/sys/arm64/arm64/cpu_errata.c Fri Jan 12 13:40:50 2018 (r327875) > +++ head/sys/arm64/arm64/cpu_errata.c Fri Jan 12 14:01:38 2018 (r327876) > @@ -30,6 +30,8 @@ > * SUCH DAMAGE. > */ > > +#include "opt_platform.h" > + > #include <sys/cdefs.h> > __FBSDID("$FreeBSD$"); > > @@ -39,6 +41,10 @@ __FBSDID("$FreeBSD$"); > > #include <machine/cpu.h> > > +#ifdef DEV_PSCI > +#include <dev/psci/psci.h> > +#endif > + > typedef void (cpu_quirk_install)(void); > struct cpu_quirks { > cpu_quirk_install *quirk_install; > @@ -49,7 +55,36 @@ struct cpu_quirks { > static cpu_quirk_install install_psci_bp_hardening; > > static struct cpu_quirks cpu_quirks[] = { > + { > + .midr_mask = CPU_IMPL_MASK | CPU_PART_MASK, > + .midr_value = CPU_ID_RAW(CPU_IMPL_ARM, CPU_PART_CORTEX_A57,0,0), > + .quirk_install = install_psci_bp_hardening, > + }, > + { > + .midr_mask = CPU_IMPL_MASK | CPU_PART_MASK, > + .midr_value = CPU_ID_RAW(CPU_IMPL_ARM, CPU_PART_CORTEX_A72,0,0), > + .quirk_install = install_psci_bp_hardening, > + }, > + { > + .midr_mask = CPU_IMPL_MASK | CPU_PART_MASK, > + .midr_value = CPU_ID_RAW(CPU_IMPL_ARM, CPU_PART_CORTEX_A73,0,0), > + .quirk_install = install_psci_bp_hardening, > + }, > + { > + .midr_mask = CPU_IMPL_MASK | CPU_PART_MASK, > + .midr_value = CPU_ID_RAW(CPU_IMPL_ARM, CPU_PART_CORTEX_A75,0,0), > + .quirk_install = install_psci_bp_hardening, > + }, > }; > + > +static void > +install_psci_bp_hardening(void) > +{ > + > +#ifdef DEV_PSCI > + PCPU_SET(bp_harden, psci_get_version); > +#endif > +} > > void > install_cpu_errata(void) > > Modified: head/sys/arm64/arm64/pmap.c > ============================================================================== > --- head/sys/arm64/arm64/pmap.c Fri Jan 12 13:40:50 2018 (r327875) > +++ head/sys/arm64/arm64/pmap.c Fri Jan 12 14:01:38 2018 (r327876) > @@ -4663,6 +4663,7 @@ pmap_activate(struct thread *td) > struct pcb * > pmap_switch(struct thread *old, struct thread *new) > { > + pcpu_bp_harden bp_harden; > struct pcb *pcb; > > /* Store the new curthread */ > @@ -4690,6 +4691,15 @@ pmap_switch(struct thread *old, struct thread *new) > "dsb ish \n" > "isb \n" > : : "r"(new->td_proc->p_md.md_l0addr)); > + > + /* > + * Stop userspace from training the branch predictor against > + * other processes. This will call into a CPU specific > + * function that clears the branch predictor state. > + */ > + bp_harden = PCPU_GET(bp_harden); > + if (bp_harden != NULL) > + bp_harden(); > } > > return (pcb); > > Modified: head/sys/arm64/arm64/trap.c > ============================================================================== > --- head/sys/arm64/arm64/trap.c Fri Jan 12 13:40:50 2018 (r327875) > +++ head/sys/arm64/arm64/trap.c Fri Jan 12 14:01:38 2018 (r327876) > @@ -352,6 +352,7 @@ do_el1h_sync(struct thread *td, struct trapframe *fram > void > do_el0_sync(struct thread *td, struct trapframe *frame) > { > + pcpu_bp_harden bp_harden; > uint32_t exception; > uint64_t esr, far; > > @@ -363,11 +364,25 @@ do_el0_sync(struct thread *td, struct trapframe *frame > esr = frame->tf_esr; > exception = ESR_ELx_EXCEPTION(esr); > switch (exception) { > - case EXCP_UNKNOWN: > case EXCP_INSN_ABORT_L: > + far = READ_SPECIALREG(far_el1); > + > + /* > + * Userspace may be trying to train the branch predictor to > + * attack the kernel. If we are on a CPU affected by this > + * call the handler to clear the branch predictor state. > + */ > + if (far > VM_MAXUSER_ADDRESS) { > + bp_harden = PCPU_GET(bp_harden); > + if (bp_harden != NULL) > + bp_harden(); > + } > + break; > + case EXCP_UNKNOWN: > case EXCP_DATA_ABORT_L: > case EXCP_DATA_ABORT: > far = READ_SPECIALREG(far_el1); > + break; > } > intr_enable(); > > > Modified: head/sys/arm64/include/pcpu.h > ============================================================================== > --- head/sys/arm64/include/pcpu.h Fri Jan 12 13:40:50 2018 (r327875) > +++ head/sys/arm64/include/pcpu.h Fri Jan 12 14:01:38 2018 (r327876) > @@ -35,11 +35,14 @@ > > #define ALT_STACK_SIZE 128 > > +typedef int (*pcpu_bp_harden)(void); > + > #define PCPU_MD_FIELDS \ > u_int pc_acpi_id; /* ACPI CPU id */ \ > u_int pc_midr; /* stored MIDR value */ \ > uint64_t pc_clock; \ > - char __pad[241] > + pcpu_bp_harden pc_bp_harden; \ > + char __pad[233] > > #ifdef _KERNEL > >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAPv3WKcESa_AL=R-BFwef2GXxHcYsnmbUOV3Zx5qL8WdMS-o3Q>