CHROMIUM: arch/x86: Prevent buffer flushing for trusted tasks
Core-scheduling allows us to know if tasks are trusted or not. Untrusted tasks
are tagged with ->core_cookie set. Leverage this to prevent unwanted flushing.
BUG=b:152605392
TEST=boot
Signed-off-by: Joel Fernandes <joelaf@google.com>
Change-Id: If3309edd42ed01c3cefcf5f23bdcce0ac44a3688
diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
index 98044d0..37b27a1 100644
--- a/arch/x86/entry/common.c
+++ b/arch/x86/entry/common.c
@@ -216,9 +216,13 @@
#ifdef CONFIG_SCHED_CORE
sched_core_user_enter();
-#endif
+ /* Only clear arch buffers for untrusted tasks. */
+ if (current->core_cookie)
+ mds_user_clear_cpu_buffers();
+#else
mds_user_clear_cpu_buffers();
+#endif
}
#define SYSCALL_EXIT_WORK_FLAGS \
diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
index e3f70c6..253d98e 100644
--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -364,8 +364,14 @@
*/
static inline void mds_idle_clear_cpu_buffers(void)
{
+ /*
+ * Core-scheduling already protects from cross-HT MDS.
+ * Clearing CPU buffers on idle is not needed.
+ */
+#ifndef CONFIG_SCHED_CORE
if (static_branch_likely(&mds_idle_clear))
mds_clear_cpu_buffers();
+#endif
}
#endif /* __ASSEMBLY__ */
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 1004121..113f448 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -998,7 +998,10 @@
if (!boot_cpu_has_bug(X86_BUG_MSBDS_ONLY))
return;
- if (sched_smt_active())
+ /*
+ * If core-scheduling is enabled, MSBDS is already protected.
+ */
+ if (sched_smt_active() && !IS_ENABLED(CONFIG_SCHED_CORE))
static_branch_enable(&mds_idle_clear);
else
static_branch_disable(&mds_idle_clear);
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index da4e92f..e863b45 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -10771,13 +10771,16 @@
/* VM entries need to wait if the core is not ready. */
#ifdef CONFIG_SCHED_CORE
sched_core_user_enter();
-#endif
+ /* Don't need to flush if VM is trusted. */
+ if (current->core_cookie)
+#else
/* L1D Flush includes CPU buffer clear to mitigate MDS */
if (static_branch_unlikely(&vmx_l1d_should_flush))
vmx_l1d_flush(vcpu);
else if (static_branch_unlikely(&mds_user_clear))
mds_clear_cpu_buffers();
+#endif
asm volatile (
/* Store host registers */