Date: Thu, 24 May 2018 13:17:24 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r334152 - in stable/11/sys: amd64/amd64 amd64/include dev/cpuctl i386/include x86/acpica x86/include x86/x86 Message-ID: <201805241317.w4ODHOQL068672@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Thu May 24 13:17:24 2018 New Revision: 334152 URL: https://svnweb.freebsd.org/changeset/base/334152 Log: MFC r334004: Add Intel Spec Store Bypass Disable control. This also includes the i386/include/pcpu.h part of the r334018. Security: CVE-2018-3639 Approved by: re (gjb) Modified: stable/11/sys/amd64/amd64/initcpu.c stable/11/sys/amd64/amd64/machdep.c stable/11/sys/amd64/include/md_var.h stable/11/sys/dev/cpuctl/cpuctl.c stable/11/sys/i386/include/pcpu.h stable/11/sys/x86/acpica/acpi_wakeup.c stable/11/sys/x86/include/x86_var.h stable/11/sys/x86/x86/cpu_machdep.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/amd64/amd64/initcpu.c ============================================================================== --- stable/11/sys/amd64/amd64/initcpu.c Thu May 24 12:14:14 2018 (r334151) +++ stable/11/sys/amd64/amd64/initcpu.c Thu May 24 13:17:24 2018 (r334152) @@ -222,6 +222,7 @@ initializecpu(void) pg_nx = PG_NX; } hw_ibrs_recalculate(); + hw_ssb_recalculate(false); switch (cpu_vendor_id) { case CPU_VENDOR_AMD: init_amd(); Modified: stable/11/sys/amd64/amd64/machdep.c ============================================================================== --- stable/11/sys/amd64/amd64/machdep.c Thu May 24 12:14:14 2018 (r334151) +++ stable/11/sys/amd64/amd64/machdep.c Thu May 24 13:17:24 2018 (r334152) @@ -1850,6 +1850,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) thread0.td_critnest = 0; TUNABLE_INT_FETCH("hw.ibrs_disable", &hw_ibrs_disable); + TUNABLE_INT_FETCH("hw.spec_store_bypass_disable", &hw_ssb_disable); /* Location of kernel stack for locore */ return ((u_int64_t)thread0.td_pcb); Modified: stable/11/sys/amd64/include/md_var.h ============================================================================== --- stable/11/sys/amd64/include/md_var.h Thu May 24 12:14:14 2018 (r334151) +++ stable/11/sys/amd64/include/md_var.h Thu May 24 13:17:24 2018 (r334152) @@ -37,6 +37,7 @@ extern uint64_t *vm_page_dump; extern int hw_lower_amd64_sharedpage; extern int hw_ibrs_disable; +extern int hw_ssb_disable; /* * The file "conf/ldscript.amd64" defines the symbol "kernphys". Its Modified: stable/11/sys/dev/cpuctl/cpuctl.c ============================================================================== --- stable/11/sys/dev/cpuctl/cpuctl.c Thu May 24 12:14:14 2018 (r334151) +++ stable/11/sys/dev/cpuctl/cpuctl.c Thu May 24 13:17:24 2018 (r334152) @@ -527,6 +527,7 @@ cpuctl_do_eval_cpu_features(int cpu, struct thread *td identify_cpu2(); hw_ibrs_recalculate(); restore_cpu(oldcpu, is_bound, td); + hw_ssb_recalculate(true); printcpuinfo(); return (0); } Modified: stable/11/sys/i386/include/pcpu.h ============================================================================== --- stable/11/sys/i386/include/pcpu.h Thu May 24 12:14:14 2018 (r334151) +++ stable/11/sys/i386/include/pcpu.h Thu May 24 13:17:24 2018 (r334152) @@ -68,7 +68,8 @@ caddr_t pc_cmap_addr2; \ vm_offset_t pc_qmap_addr; /* KVA for temporary mappings */\ uint32_t pc_smp_tlb_done; /* TLB op acknowledgement */ \ - char __pad[189] + uint32_t pc_ibpb_set; \ + char __pad[185] #ifdef _KERNEL Modified: stable/11/sys/x86/acpica/acpi_wakeup.c ============================================================================== --- stable/11/sys/x86/acpica/acpi_wakeup.c Thu May 24 12:14:14 2018 (r334151) +++ stable/11/sys/x86/acpica/acpi_wakeup.c Thu May 24 13:17:24 2018 (r334152) @@ -225,6 +225,7 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state) #endif #ifdef __amd64__ hw_ibrs_active = 0; + hw_ssb_active = 0; cpu_stdext_feature3 = 0; CPU_FOREACH(i) { pc = pcpu_find(i); Modified: stable/11/sys/x86/include/x86_var.h ============================================================================== --- stable/11/sys/x86/include/x86_var.h Thu May 24 12:14:14 2018 (r334151) +++ stable/11/sys/x86/include/x86_var.h Thu May 24 13:17:24 2018 (r334152) @@ -83,6 +83,7 @@ extern int use_xsave; extern uint64_t xsave_mask; extern int pti; extern int hw_ibrs_active; +extern int hw_ssb_active; struct pcb; struct thread; @@ -133,6 +134,7 @@ int isa_nmi(int cd); void handle_ibrs_entry(void); void handle_ibrs_exit(void); void hw_ibrs_recalculate(void); +void hw_ssb_recalculate(bool all_cpus); void nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame); void nmi_call_kdb_smp(u_int type, struct trapframe *frame); void nmi_handle_intr(u_int type, struct trapframe *frame); Modified: stable/11/sys/x86/x86/cpu_machdep.c ============================================================================== --- stable/11/sys/x86/x86/cpu_machdep.c Thu May 24 12:14:14 2018 (r334151) +++ stable/11/sys/x86/x86/cpu_machdep.c Thu May 24 13:17:24 2018 (r334152) @@ -158,6 +158,7 @@ void acpi_cpu_idle_mwait(uint32_t mwait_hint) { int *state; + uint64_t v; /* * A comment in Linux patch claims that 'CPUs run faster with @@ -174,13 +175,26 @@ acpi_cpu_idle_mwait(uint32_t mwait_hint) KASSERT(atomic_load_int(state) == STATE_SLEEPING, ("cpu_mwait_cx: wrong monitorbuf state")); atomic_store_int(state, STATE_MWAIT); - handle_ibrs_exit(); + if (PCPU_GET(ibpb_set) || hw_ssb_active) { + v = rdmsr(MSR_IA32_SPEC_CTRL); + wrmsr(MSR_IA32_SPEC_CTRL, v & ~(IA32_SPEC_CTRL_IBRS | + IA32_SPEC_CTRL_STIBP | IA32_SPEC_CTRL_SSBD)); + } else { + v = 0; + } cpu_monitor(state, 0, 0); if (atomic_load_int(state) == STATE_MWAIT) cpu_mwait(MWAIT_INTRBREAK, mwait_hint); - handle_ibrs_entry(); /* + * SSB cannot be disabled while we sleep, or rather, if it was + * disabled, the sysctl thread will bind to our cpu to tweak + * MSR. + */ + if (v != 0) + wrmsr(MSR_IA32_SPEC_CTRL, v); + + /* * We should exit on any event that interrupts mwait, because * that event might be a wanted interrupt. */ @@ -836,3 +850,93 @@ hw_ibrs_disable_handler(SYSCTL_HANDLER_ARGS) SYSCTL_PROC(_hw, OID_AUTO, ibrs_disable, CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_NOFETCH | CTLFLAG_MPSAFE, NULL, 0, hw_ibrs_disable_handler, "I", "Disable Indirect Branch Restricted Speculation"); + +int hw_ssb_active; +int hw_ssb_disable; + +SYSCTL_INT(_hw, OID_AUTO, spec_store_bypass_disable_active, CTLFLAG_RD, + &hw_ssb_active, 0, + "Speculative Store Bypass Disable active"); + +static void +hw_ssb_set_one(bool enable) +{ + uint64_t v; + + v = rdmsr(MSR_IA32_SPEC_CTRL); + if (enable) + v |= (uint64_t)IA32_SPEC_CTRL_SSBD; + else + v &= ~(uint64_t)IA32_SPEC_CTRL_SSBD; + wrmsr(MSR_IA32_SPEC_CTRL, v); +} + +static void +hw_ssb_set(bool enable, bool for_all_cpus) +{ + struct thread *td; + int bound_cpu, i, is_bound; + + if ((cpu_stdext_feature3 & CPUID_STDEXT3_SSBD) == 0) { + hw_ssb_active = 0; + return; + } + hw_ssb_active = enable; + if (for_all_cpus) { + td = curthread; + thread_lock(td); + is_bound = sched_is_bound(td); + bound_cpu = td->td_oncpu; + CPU_FOREACH(i) { + sched_bind(td, i); + hw_ssb_set_one(enable); + } + if (is_bound) + sched_bind(td, bound_cpu); + else + sched_unbind(td); + thread_unlock(td); + } else { + hw_ssb_set_one(enable); + } +} + +void +hw_ssb_recalculate(bool all_cpus) +{ + + switch (hw_ssb_disable) { + default: + hw_ssb_disable = 0; + /* FALLTHROUGH */ + case 0: /* off */ + hw_ssb_set(false, all_cpus); + break; + case 1: /* on */ + hw_ssb_set(true, all_cpus); + break; + case 2: /* auto */ + hw_ssb_set((cpu_ia32_arch_caps & IA32_ARCH_CAP_SSBD_NO) != 0 ? + false : true, all_cpus); + break; + } +} + +static int +hw_ssb_disable_handler(SYSCTL_HANDLER_ARGS) +{ + int error, val; + + val = hw_ssb_disable; + error = sysctl_handle_int(oidp, &val, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + hw_ssb_disable = val; + hw_ssb_recalculate(true); + return (0); +} +SYSCTL_PROC(_hw, OID_AUTO, spec_store_bypass_disable, CTLTYPE_INT | + CTLFLAG_RWTUN | CTLFLAG_NOFETCH | CTLFLAG_MPSAFE, NULL, 0, + hw_ssb_disable_handler, "I", + "Speculative Store Bypass Disable (0 - off, 1 - on, 2 - auto"); +
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201805241317.w4ODHOQL068672>