Jiri Slaby ef7db2
From: KP Singh <kpsingh@kernel.org>
Jiri Slaby ef7db2
Date: Mon, 27 Feb 2023 07:05:40 +0100
Jiri Slaby ef7db2
Subject: [PATCH] x86/speculation: Allow enabling STIBP with legacy IBRS
Jiri Slaby ef7db2
MIME-Version: 1.0
Jiri Slaby ef7db2
Content-Type: text/plain; charset=UTF-8
Jiri Slaby ef7db2
Content-Transfer-Encoding: 8bit
Jiri Slaby ef7db2
References: bsc#1012628
Jiri Slaby ef7db2
Patch-mainline: 6.2.3
Jiri Slaby ef7db2
Git-commit: 6921ed9049bc7457f66c1596c5b78aec0dae4a9d
Jiri Slaby ef7db2
Jiri Slaby ef7db2
commit 6921ed9049bc7457f66c1596c5b78aec0dae4a9d upstream.
Jiri Slaby ef7db2
Jiri Slaby ef7db2
When plain IBRS is enabled (not enhanced IBRS), the logic in
Jiri Slaby ef7db2
spectre_v2_user_select_mitigation() determines that STIBP is not needed.
Jiri Slaby ef7db2
Jiri Slaby ef7db2
The IBRS bit implicitly protects against cross-thread branch target
Jiri Slaby ef7db2
injection. However, with legacy IBRS, the IBRS bit is cleared on
Jiri Slaby ef7db2
returning to userspace for performance reasons which leaves userspace
Jiri Slaby ef7db2
threads vulnerable to cross-thread branch target injection against which
Jiri Slaby ef7db2
STIBP protects.
Jiri Slaby ef7db2
Jiri Slaby ef7db2
Exclude IBRS from the spectre_v2_in_ibrs_mode() check to allow for
Jiri Slaby ef7db2
enabling STIBP (through seccomp/prctl() by default or always-on, if
Jiri Slaby ef7db2
selected by spectre_v2_user kernel cmdline parameter).
Jiri Slaby ef7db2
Jiri Slaby ef7db2
  [ bp: Massage. ]
Jiri Slaby ef7db2
Jiri Slaby ef7db2
Fixes: 7c693f54c873 ("x86/speculation: Add spectre_v2=ibrs option to support Kernel IBRS")
Jiri Slaby ef7db2
Reported-by: José Oliveira <joseloliveira11@gmail.com>
Jiri Slaby ef7db2
Reported-by: Rodrigo Branco <rodrigo@kernelhacking.com>
Jiri Slaby ef7db2
Signed-off-by: KP Singh <kpsingh@kernel.org>
Jiri Slaby ef7db2
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Jiri Slaby ef7db2
Cc: stable@vger.kernel.org
Jiri Slaby ef7db2
Link: https://lore.kernel.org/r/20230220120127.1975241-1-kpsingh@kernel.org
Jiri Slaby ef7db2
Link: https://lore.kernel.org/r/20230221184908.2349578-1-kpsingh@kernel.org
Jiri Slaby ef7db2
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Jiri Slaby ef7db2
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Jiri Slaby ef7db2
---
Jiri Slaby ef7db2
 arch/x86/kernel/cpu/bugs.c | 25 ++++++++++++++++++-------
Jiri Slaby ef7db2
 1 file changed, 18 insertions(+), 7 deletions(-)
Jiri Slaby ef7db2
Jiri Slaby ef7db2
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
Jiri Slaby ef7db2
index 374bc620..daad10e7 100644
Jiri Slaby ef7db2
--- a/arch/x86/kernel/cpu/bugs.c
Jiri Slaby ef7db2
+++ b/arch/x86/kernel/cpu/bugs.c
Jiri Slaby ef7db2
@@ -1132,14 +1132,18 @@ spectre_v2_parse_user_cmdline(void)
Jiri Slaby ef7db2
 	return SPECTRE_V2_USER_CMD_AUTO;
Jiri Slaby ef7db2
 }
Jiri Slaby ef7db2
 
Jiri Slaby ef7db2
-static inline bool spectre_v2_in_ibrs_mode(enum spectre_v2_mitigation mode)
Jiri Slaby ef7db2
+static inline bool spectre_v2_in_eibrs_mode(enum spectre_v2_mitigation mode)
Jiri Slaby ef7db2
 {
Jiri Slaby ef7db2
-	return mode == SPECTRE_V2_IBRS ||
Jiri Slaby ef7db2
-	       mode == SPECTRE_V2_EIBRS ||
Jiri Slaby ef7db2
+	return mode == SPECTRE_V2_EIBRS ||
Jiri Slaby ef7db2
 	       mode == SPECTRE_V2_EIBRS_RETPOLINE ||
Jiri Slaby ef7db2
 	       mode == SPECTRE_V2_EIBRS_LFENCE;
Jiri Slaby ef7db2
 }
Jiri Slaby ef7db2
 
Jiri Slaby ef7db2
+static inline bool spectre_v2_in_ibrs_mode(enum spectre_v2_mitigation mode)
Jiri Slaby ef7db2
+{
Jiri Slaby ef7db2
+	return spectre_v2_in_eibrs_mode(mode) || mode == SPECTRE_V2_IBRS;
Jiri Slaby ef7db2
+}
Jiri Slaby ef7db2
+
Jiri Slaby ef7db2
 static void __init
Jiri Slaby ef7db2
 spectre_v2_user_select_mitigation(void)
Jiri Slaby ef7db2
 {
Jiri Slaby ef7db2
@@ -1202,12 +1206,19 @@ spectre_v2_user_select_mitigation(void)
Jiri Slaby ef7db2
 	}
Jiri Slaby ef7db2
 
Jiri Slaby ef7db2
 	/*
Jiri Slaby ef7db2
-	 * If no STIBP, IBRS or enhanced IBRS is enabled, or SMT impossible,
Jiri Slaby ef7db2
-	 * STIBP is not required.
Jiri Slaby ef7db2
+	 * If no STIBP, enhanced IBRS is enabled, or SMT impossible, STIBP
Jiri Slaby ef7db2
+	 * is not required.
Jiri Slaby ef7db2
+	 *
Jiri Slaby ef7db2
+	 * Enhanced IBRS also protects against cross-thread branch target
Jiri Slaby ef7db2
+	 * injection in user-mode as the IBRS bit remains always set which
Jiri Slaby ef7db2
+	 * implicitly enables cross-thread protections.  However, in legacy IBRS
Jiri Slaby ef7db2
+	 * mode, the IBRS bit is set only on kernel entry and cleared on return
Jiri Slaby ef7db2
+	 * to userspace. This disables the implicit cross-thread protection,
Jiri Slaby ef7db2
+	 * so allow for STIBP to be selected in that case.
Jiri Slaby ef7db2
 	 */
Jiri Slaby ef7db2
 	if (!boot_cpu_has(X86_FEATURE_STIBP) ||
Jiri Slaby ef7db2
 	    !smt_possible ||
Jiri Slaby ef7db2
-	    spectre_v2_in_ibrs_mode(spectre_v2_enabled))
Jiri Slaby ef7db2
+	    spectre_v2_in_eibrs_mode(spectre_v2_enabled))
Jiri Slaby ef7db2
 		return;
Jiri Slaby ef7db2
 
Jiri Slaby ef7db2
 	/*
Jiri Slaby ef7db2
@@ -2335,7 +2346,7 @@ static ssize_t mmio_stale_data_show_state(char *buf)
Jiri Slaby ef7db2
 
Jiri Slaby ef7db2
 static char *stibp_state(void)
Jiri Slaby ef7db2
 {
Jiri Slaby ef7db2
-	if (spectre_v2_in_ibrs_mode(spectre_v2_enabled))
Jiri Slaby ef7db2
+	if (spectre_v2_in_eibrs_mode(spectre_v2_enabled))
Jiri Slaby ef7db2
 		return "";
Jiri Slaby ef7db2
 
Jiri Slaby ef7db2
 	switch (spectre_v2_user_stibp) {
Jiri Slaby ef7db2
-- 
Jiri Slaby ef7db2
2.35.3
Jiri Slaby ef7db2