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 */