From owner-svn-src-head@freebsd.org Tue Jul 31 12:53:29 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 015B1105982D; Tue, 31 Jul 2018 12:53:29 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id A8EA689B73; Tue, 31 Jul 2018 12:53:28 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 8953C13E58; Tue, 31 Jul 2018 12:53:28 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w6VCrSHN080216; Tue, 31 Jul 2018 12:53:28 GMT (envelope-from andrew@FreeBSD.org) Received: (from andrew@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w6VCrR6Y080209; Tue, 31 Jul 2018 12:53:27 GMT (envelope-from andrew@FreeBSD.org) Message-Id: <201807311253.w6VCrR6Y080209@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: andrew set sender to andrew@FreeBSD.org using -f From: Andrew Turner Date: Tue, 31 Jul 2018 12:53:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r336967 - in head/sys: arm64/arm64 arm64/include dev/psci X-SVN-Group: head X-SVN-Commit-Author: andrew X-SVN-Commit-Paths: in head/sys: arm64/arm64 arm64/include dev/psci X-SVN-Commit-Revision: 336967 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 31 Jul 2018 12:53:29 -0000 Author: andrew Date: Tue Jul 31 12:53:27 2018 New Revision: 336967 URL: https://svnweb.freebsd.org/changeset/base/336967 Log: Implement the SSBD (CVE-2018-3639) workaround on arm64 This calls into the Arm Trusted Firmware to enable and disable the workaround for the Speculative Store Bypass Disable (SSBD) issue, also known as Spectre Variant 4. As this may have a large performance overhead, and how exploitable SSBD is is unknown we follow the Linux lead of allowing the administrator to select between always on, always off, or only enabled in the kernel, with the latter being the default. PR: 228955 Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D15819 Modified: head/sys/arm64/arm64/cpu_errata.c head/sys/arm64/arm64/exception.S head/sys/arm64/arm64/genassym.c head/sys/arm64/include/pcpu.h head/sys/dev/psci/smccc.c head/sys/dev/psci/smccc.h Modified: head/sys/arm64/arm64/cpu_errata.c ============================================================================== --- head/sys/arm64/arm64/cpu_errata.c Tue Jul 31 12:44:28 2018 (r336966) +++ head/sys/arm64/arm64/cpu_errata.c Tue Jul 31 12:53:27 2018 (r336967) @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include @@ -50,7 +51,14 @@ struct cpu_quirks { 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 @@ static struct cpu_quirks cpu_quirks[] = { 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 @@ -89,6 +102,40 @@ install_psci_bp_hardening(void) return; 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 Modified: head/sys/arm64/arm64/exception.S ============================================================================== --- head/sys/arm64/arm64/exception.S Tue Jul 31 12:44:28 2018 (r336966) +++ head/sys/arm64/arm64/exception.S Tue Jul 31 12:53:27 2018 (r336967) @@ -66,6 +66,14 @@ __FBSDID("$FreeBSD$"); 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 @@ __FBSDID("$FreeBSD$"); * 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)] Modified: head/sys/arm64/arm64/genassym.c ============================================================================== --- head/sys/arm64/arm64/genassym.c Tue Jul 31 12:44:28 2018 (r336966) +++ head/sys/arm64/arm64/genassym.c Tue Jul 31 12:53:27 2018 (r336967) @@ -43,6 +43,7 @@ ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED); 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)); Modified: head/sys/arm64/include/pcpu.h ============================================================================== --- head/sys/arm64/include/pcpu.h Tue Jul 31 12:44:28 2018 (r336966) +++ head/sys/arm64/include/pcpu.h Tue Jul 31 12:53:27 2018 (r336967) @@ -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 Modified: head/sys/dev/psci/smccc.c ============================================================================== --- head/sys/dev/psci/smccc.c Tue Jul 31 12:44:28 2018 (r336966) +++ head/sys/dev/psci/smccc.c Tue Jul 31 12:53:27 2018 (r336967) @@ -91,3 +91,12 @@ smccc_arch_workaround_1(void) ("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)); +} Modified: head/sys/dev/psci/smccc.h ============================================================================== --- head/sys/dev/psci/smccc.h Tue Jul 31 12:44:28 2018 (r336966) +++ head/sys/dev/psci/smccc.h Tue Jul 31 12:53:27 2018 (r336967) @@ -59,6 +59,8 @@ SMCCC_FUNC_ID(SMCCC_FAST_CALL, SMCCC_32BIT_CALL, 0, 1) #define SMCCC_ARCH_WORKAROUND_1 \ SMCCC_FUNC_ID(SMCCC_FAST_CALL, SMCCC_32BIT_CALL, 0, 0x8000) +#define SMCCC_ARCH_WORKAROUND_2 \ + SMCCC_FUNC_ID(SMCCC_FAST_CALL, SMCCC_32BIT_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_ */