-/* $OpenBSD: cpu.c,v 1.174 2023/07/28 06:36:16 guenther Exp $ */
+/* $OpenBSD: cpu.c,v 1.175 2023/07/31 04:01:07 guenther Exp $ */
/* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */
/*-
{
static int replacedone = 0;
struct cpu_info *ci = &cpu_info_primary;
- int swapgs_vuln = 0, s;
-
- if (replacedone)
- return;
- replacedone = 1;
+ int swapgs_vuln = 0, ibrs = 0, s;
if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
int family = ci->ci_family;
/* KnightsLanding */
swapgs_vuln = 0;
}
+ if ((ci->ci_feature_sefflags_edx & SEFF0EDX_ARCH_CAP) &&
+ (rdmsr(MSR_ARCH_CAPABILITIES) & ARCH_CAP_IBRS_ALL)) {
+ ibrs = 2;
+ } else if (ci->ci_feature_sefflags_edx & SEFF0EDX_IBRS) {
+ ibrs = 1;
+ }
+ } else if (strcmp(cpu_vendor, "AuthenticAMD") == 0 &&
+ ci->ci_pnfeatset >= 0x80000008) {
+ if (ci->ci_feature_amdspec_ebx & CPUIDEBX_IBRS_ALWAYSON) {
+ ibrs = 2;
+ } else if ((ci->ci_feature_amdspec_ebx & CPUIDEBX_IBRS) &&
+ (ci->ci_feature_amdspec_ebx & CPUIDEBX_IBRS_PREF)) {
+ ibrs = 1;
+ }
}
+ /* Enhanced IBRS: turn it on once on each CPU and don't touch again */
+ if (ibrs == 2)
+ wrmsr(MSR_SPEC_CTRL, SPEC_CTRL_IBRS);
+
+ if (replacedone)
+ return;
+ replacedone = 1;
+
s = splhigh();
+ if (ibrs == 2 || (ci->ci_feature_sefflags_edx & SEFF0EDX_IBT)) {
+ extern const char _jmprax, _jmpr11, _jmpr13;
+ extern const short _jmprax_len, _jmpr11_len, _jmpr13_len;
+ codepatch_replace(CPTAG_RETPOLINE_RAX, &_jmprax, _jmprax_len);
+ codepatch_replace(CPTAG_RETPOLINE_R11, &_jmpr11, _jmpr11_len);
+ codepatch_replace(CPTAG_RETPOLINE_R13, &_jmpr13, _jmpr13_len);
+ }
+
if (!cpu_meltdown)
codepatch_nop(CPTAG_MELTDOWN_NOP);
else {
-/* $OpenBSD: locore.S,v 1.139 2023/07/28 06:18:35 guenther Exp $ */
+/* $OpenBSD: locore.S,v 1.140 2023/07/31 04:01:07 guenther Exp $ */
/* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */
/*
END(cpu_switchto)
NENTRY(retpoline_rax)
+ CODEPATCH_START
JMP_RETPOLINE(rax)
+ CODEPATCH_END(CPTAG_RETPOLINE_RAX)
+END(retpoline_rax)
+
+NENTRY(__x86_indirect_thunk_r11)
+ CODEPATCH_START
+ JMP_RETPOLINE(r11)
+ CODEPATCH_END(CPTAG_RETPOLINE_R11)
+END(__x86_indirect_thunk_r11)
ENTRY(cpu_idle_cycle_hlt)
RETGUARD_SETUP(cpu_idle_cycle_hlt, r11)
-/* $OpenBSD: vector.S,v 1.93 2023/07/27 00:30:07 guenther Exp $ */
+/* $OpenBSD: vector.S,v 1.94 2023/07/31 04:01:07 guenther Exp $ */
/* $NetBSD: vector.S,v 1.5 2004/06/28 09:13:11 fvdl Exp $ */
/*
* Soft interrupt handlers
*/
NENTRY(retpoline_r13)
+ CODEPATCH_START
JMP_RETPOLINE(r13)
+ CODEPATCH_END(CPTAG_RETPOLINE_R13)
END(retpoline_r13)
KIDTVEC(softtty)
movl $X86_SOFTINTR_SOFTTTY,%edi
call softintr_dispatch
decl CPUVAR(IDEPTH)
+ CODEPATCH_START
jmp retpoline_r13
+ CODEPATCH_END(CPTAG_RETPOLINE_R13)
END(Xsofttty)
KIDTVEC(softnet)
movl $X86_SOFTINTR_SOFTNET,%edi
call softintr_dispatch
decl CPUVAR(IDEPTH)
+ CODEPATCH_START
jmp retpoline_r13
+ CODEPATCH_END(CPTAG_RETPOLINE_R13)
END(Xsoftnet)
KIDTVEC(softclock)
movl $X86_SOFTINTR_SOFTCLOCK,%edi
call softintr_dispatch
decl CPUVAR(IDEPTH)
+ CODEPATCH_START
jmp retpoline_r13
+ CODEPATCH_END(CPTAG_RETPOLINE_R13)
END(Xsoftclock)
-# $OpenBSD: Makefile.amd64,v 1.132 2023/04/21 13:24:20 bluhm Exp $
+# $OpenBSD: Makefile.amd64,v 1.133 2023/07/31 04:01:07 guenther Exp $
# For instructions on building kernels consult the config(8) and options(4)
# manual pages.
CMACHFLAGS+= -mno-retpoline -fcf-protection=none
.endif
.else
-CMACHFLAGS+= -fcf-protection=branch
+CMACHFLAGS+= -mretpoline-external-thunk -fcf-protection=branch
.endif
.if ${COMPILER_VERSION:Mclang}
NO_INTEGR_AS= -no-integrated-as
-/* $OpenBSD: codepatch.h,v 1.17 2023/07/31 01:33:57 guenther Exp $ */
+/* $OpenBSD: codepatch.h,v 1.18 2023/07/31 04:01:07 guenther Exp $ */
/*
* Copyright (c) 2014-2015 Stefan Fritsch <sf@sfritsch.de>
*
#define CPTAG_FENCE_SWAPGS_MIS_TAKEN 11
#define CPTAG_FENCE_NO_SAFE_SMAP 12
#define CPTAG_XRSTORS 13
+#define CPTAG_RETPOLINE_RAX 14
+#define CPTAG_RETPOLINE_R11 15
+#define CPTAG_RETPOLINE_R13 16
/*
* stac/clac SMAP instructions have lfence like semantics. Let's