Page MenuHomeFreeBSD

D15819.id43804.diff
No OneTemporary

D15819.id43804.diff

Index: sys/arm64/arm64/cpu_errata.c
===================================================================
--- sys/arm64/arm64/cpu_errata.c
+++ sys/arm64/arm64/cpu_errata.c
@@ -38,6 +38,7 @@
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/pcpu.h>
+#include <sys/systm.h>
#include <machine/cpu.h>
@@ -50,7 +51,14 @@
u_int midr_value;
};
+static enum {
+ SSBD_FORCE_ON,
+ SSBD_FORCE_OFF,
+ SSBD_KERNEL,
+} ssbd_method = SSBD_KERNEL;
+
static cpu_quirk_install install_psci_bp_hardening;
+static cpu_quirk_install install_ssbd_workaround;
static struct cpu_quirks cpu_quirks[] = {
{
@@ -79,6 +87,11 @@
CPU_ID_RAW(CPU_IMPL_CAVIUM, CPU_PART_THUNDERX2, 0,0),
.quirk_install = install_psci_bp_hardening,
},
+ {
+ .midr_mask = 0,
+ .midr_value = 0,
+ .quirk_install = install_ssbd_workaround,
+ },
};
static void
@@ -91,6 +104,40 @@
PCPU_SET(bp_harden, smccc_arch_workaround_1);
}
+static void
+install_ssbd_workaround(void)
+{
+ char *env;
+
+ if (PCPU_GET(cpuid) == 0) {
+ env = kern_getenv("kern.cfg.ssbd");
+ if (env != NULL) {
+ if (strcmp(env, "force-on") == 0) {
+ ssbd_method = SSBD_FORCE_ON;
+ } else if (strcmp(env, "force-off") == 0) {
+ ssbd_method = SSBD_FORCE_OFF;
+ }
+ }
+ }
+
+ /* Enable the workaround on this CPU if it's enabled in the firmware */
+ if (smccc_arch_features(SMCCC_ARCH_WORKAROUND_2) != SMCCC_RET_SUCCESS)
+ return;
+
+ switch(ssbd_method) {
+ case SSBD_FORCE_ON:
+ smccc_arch_workaround_2(true);
+ break;
+ case SSBD_FORCE_OFF:
+ smccc_arch_workaround_2(false);
+ break;
+ case SSBD_KERNEL:
+ default:
+ PCPU_SET(ssbd, smccc_arch_workaround_2);
+ break;
+ }
+}
+
void
install_cpu_errata(void)
{
Index: sys/arm64/arm64/exception.S
===================================================================
--- sys/arm64/arm64/exception.S
+++ sys/arm64/arm64/exception.S
@@ -66,6 +66,14 @@
stp x18, lr, [sp, #(TF_SP)]
mrs x18, tpidr_el1
add x29, sp, #(TF_SIZE)
+.if \el == 0
+ /* Apply the SSBD (CVE-2018-3639) workaround if needed */
+ ldr x1, [x18, #PC_SSBD]
+ cbz x1, 1f
+ mov w0, #1
+ blr x1
+1:
+.endif
.endm
.macro restore_registers el
@@ -75,6 +83,14 @@
* Disable interrupts, x18 may change in the interrupt exception
* handler. For EL0 exceptions, do_ast already did this.
*/
+.endif
+.if \el == 0
+ /* Remove the SSBD (CVE-2018-3639) workaround if needed */
+ ldr x1, [x18, #PC_SSBD]
+ cbz x1, 1f
+ mov w0, #0
+ blr x1
+1:
.endif
ldp x18, lr, [sp, #(TF_SP)]
ldp x10, x11, [sp, #(TF_ELR)]
Index: sys/arm64/arm64/genassym.c
===================================================================
--- sys/arm64/arm64/genassym.c
+++ sys/arm64/arm64/genassym.c
@@ -43,6 +43,7 @@
ASSYM(PCPU_SIZE, sizeof(struct pcpu));
ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
+ASSYM(PC_SSBD, offsetof(struct pcpu, pc_ssbd));
/* Size of pcb, rounded to keep stack alignment */
ASSYM(PCB_SIZE, roundup2(sizeof(struct pcb), STACKALIGNBYTES + 1));
Index: sys/arm64/include/pcpu.h
===================================================================
--- sys/arm64/include/pcpu.h
+++ sys/arm64/include/pcpu.h
@@ -36,13 +36,15 @@
#define ALT_STACK_SIZE 128
typedef int (*pcpu_bp_harden)(void);
+typedef int (*pcpu_ssbd)(bool);
#define PCPU_MD_FIELDS \
u_int pc_acpi_id; /* ACPI CPU id */ \
u_int pc_midr; /* stored MIDR value */ \
uint64_t pc_clock; \
pcpu_bp_harden pc_bp_harden; \
- char __pad[233]
+ pcpu_ssbd pc_ssbd; \
+ char __pad[225]
#ifdef _KERNEL
Index: sys/dev/psci/smccc.h
===================================================================
--- sys/dev/psci/smccc.h
+++ sys/dev/psci/smccc.h
@@ -59,6 +59,8 @@
SMCCC_FUNC_ID(SMCCC_FAST_CALL, SMCCC_64BIT_CALL, 0, 1)
#define SMCCC_ARCH_WORKAROUND_1 \
SMCCC_FUNC_ID(SMCCC_FAST_CALL, SMCCC_64BIT_CALL, 0, 0x8000)
+#define SMCCC_ARCH_WORKAROUND_2 \
+ SMCCC_FUNC_ID(SMCCC_FAST_CALL, SMCCC_64BIT_CALL, 0, 0x7fff)
/* The return values from ARM DEN 0070A. */
#define SMCCC_RET_SUCCESS 0
@@ -67,6 +69,7 @@
int32_t smccc_arch_features(uint32_t);
int smccc_arch_workaround_1(void);
+int smccc_arch_workaround_2(bool);
#endif /* _PSCI_SMCCC_H_ */
Index: sys/dev/psci/smccc.c
===================================================================
--- sys/dev/psci/smccc.c
+++ sys/dev/psci/smccc.c
@@ -91,3 +91,12 @@
("SMCCC arch workaround 1 called with an invalid SMCCC interface"));
return (psci_call(SMCCC_ARCH_WORKAROUND_1, 0, 0, 0));
}
+
+int
+smccc_arch_workaround_2(bool enable)
+{
+
+ KASSERT(smccc_version != SMCCC_VERSION_1_0,
+ ("SMCCC arch workaround 2 called with an invalid SMCCC interface"));
+ return (psci_call(SMCCC_ARCH_WORKAROUND_2, enable ? 1 : 0, 0, 0));
+}

File Metadata

Mime Type
text/plain
Expires
Tue, Feb 4, 11:50 AM (13 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16452842
Default Alt Text
D15819.id43804.diff (4 KB)

Event Timeline