-/* $OpenBSD: cpu.c,v 1.43 2017/12/29 14:45:15 kettenis Exp $ */
+/* $OpenBSD: cpu.c,v 1.44 2018/01/15 14:11:16 kettenis Exp $ */
/* $NetBSD: cpu.c,v 1.56 2004/04/14 04:01:49 bsh Exp $ */
printf("\n");
+ /*
+ * Some ARM processors are vulnerable to branch target
+ * injection attacks.
+ */
+ switch (cpuid & CPU_ID_CORTEX_MASK) {
+ case CPU_ID_CORTEX_A5:
+ case CPU_ID_CORTEX_A7:
+ case CPU_ID_CORTEX_A32:
+ case CPU_ID_CORTEX_A35:
+ case CPU_ID_CORTEX_A53:
+ case CPU_ID_CORTEX_A55:
+ /* Not vulnerable; no need to flush. */
+ ci->ci_flush_bp = cpufunc_nullop;
+ break;
+ case CPU_ID_CORTEX_A8:
+ case CPU_ID_CORTEX_A9:
+ case CPU_ID_CORTEX_A12:
+ case CPU_ID_CORTEX_A17:
+ case CPU_ID_CORTEX_A73:
+ case CPU_ID_CORTEX_A75:
+ default:
+ /* Vulnerable; flush BP cache. */
+ ci->ci_flush_bp = armv7_flush_bp;
+ break;
+ case CPU_ID_CORTEX_A15:
+ case CPU_ID_CORTEX_A72:
+ /*
+ * Vulnerable; BPIALL is "not effective" so must use
+ * ICIALLU and hope the firmware set the magic bit in
+ * the ACTLR that actually forces a BTB flush.
+ */
+ ci->ci_flush_bp = cortex_a15_flush_bp;
+ break;
+ case CPU_ID_CORTEX_A57:
+ /*
+ * Vulnerable; must disable and enable the MMU which
+ * can be done by a PSCI call on firmware with the
+ * appropriate fixes. Punt for now.
+ */
+ ci->ci_flush_bp = cpufunc_nullop;
+ break;
+ }
+
/* Print cache info. */
if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0)
goto skip_pcache;
-/* $OpenBSD: cpufunc_asm_armv7.S,v 1.14 2016/08/15 21:08:56 kettenis Exp $ */
+/* $OpenBSD: cpufunc_asm_armv7.S,v 1.15 2018/01/15 14:11:16 kettenis Exp $ */
/*
* Copyright (c) 2008 Dale Rahn <drahn@openbsd.org>
*
mov pc, lr
+/*
+ * BTB functions.
+ */
+ENTRY(armv7_flush_bp)
+ mcr CP15_BPIALL
+ mov pc, lr
+
+ENTRY(cortex_a15_flush_bp)
+ mcr CP15_ICIALLU /* Heavy hammer; BPIALL is a no-op */
+ mov pc, lr
+
/*
* Context switch.
*
-/* $OpenBSD: fault.c,v 1.30 2017/09/08 05:36:51 deraadt Exp $ */
+/* $OpenBSD: fault.c,v 1.31 2018/01/15 14:11:16 kettenis Exp $ */
/* $NetBSD: fault.c,v 1.46 2004/01/21 15:39:21 skrll Exp $ */
/*
goto out;
}
+ va = trunc_page((vaddr_t)far);
+
+ /*
+ * Flush BP cache on processors that are vulnerable to branch
+ * target injection attacks if access is outside user space.
+ */
+ if (va < VM_MIN_ADDRESS || va >= VM_MAX_ADDRESS)
+ curcpu()->ci_flush_bp();
+
/*
* At this point, we're dealing with one of the following data aborts:
*
dab_fatal(tf, fsr, far, p, NULL);
}
- va = trunc_page((vaddr_t)far);
-
/*
* It is only a kernel address space fault iff:
* 1. user == 0 and
-/* $OpenBSD: cpu.h,v 1.48 2017/08/12 13:18:48 tedu Exp $ */
+/* $OpenBSD: cpu.h,v 1.49 2018/01/15 14:11:16 kettenis Exp $ */
/* $NetBSD: cpu.h,v 1.34 2003/06/23 11:01:08 martin Exp $ */
/*
#ifdef GPROF
struct gmonparam *ci_gmon;
#endif
+
+ void (*ci_flush_bp)(void);
};
extern struct cpu_info cpu_info_primary;
-/* $OpenBSD: cpufunc.h,v 1.29 2017/01/06 00:06:02 jsg Exp $ */
+/* $OpenBSD: cpufunc.h,v 1.30 2018/01/15 14:11:16 kettenis Exp $ */
/* $NetBSD: cpufunc.h,v 1.29 2003/09/06 09:08:35 rearnsha Exp $ */
/*
void armv7_tlb_flushD (void);
void armv7_tlb_flushD_SE (u_int va);
+void armv7_flush_bp(void);
+void cortex_a15_flush_bp(void);
+
void armv7_drain_writebuf (void);
void armv7_cpu_sleep (int mode);