aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2018-07-02 13:03:48 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-08-15 17:37:28 +0200
commit43cb51f8ef3776065fe983454f0c6449d75d1995 (patch)
treeeca7b854f7984599decb444445eafd0e2f7ef4c2
parentf1b4a0b93e9f9a5bfadd257edc53935920595d3f (diff)
downloadlinux-43cb51f8ef3776065fe983454f0c6449d75d1995.tar.gz
x86/KVM/VMX: Add L1D MSR based flush
commit 3fa045be4c720146b18a19cea7a767dc6ad5df94 upstream. 336996-Speculative-Execution-Side-Channel-Mitigations.pdf defines a new MSR (IA32_FLUSH_CMD aka 0x10B) which has similar write-only semantics to other MSRs defined in the document. The semantics of this MSR is to allow "finer granularity invalidation of caching structures than existing mechanisms like WBINVD. It will writeback and invalidate the L1 data cache, including all cachelines brought in by preceding instructions, without invalidating all caches (eg. L2 or LLC). Some processors may also invalidate the first level level instruction cache on a L1D_FLUSH command. The L1 data and instruction caches may be shared across the logical processors of a core." Use it instead of the loop based L1 flush algorithm. A copy of this document is available at https://bugzilla.kernel.org/show_bug.cgi?id=199511 [ tglx: Avoid allocating pages when the MSR is available ] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--arch/x86/include/asm/msr-index.h6
-rw-r--r--arch/x86/kvm/vmx.c15
2 files changed, 17 insertions, 4 deletions
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 68b2c3150de15..0e7517089b809 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -76,6 +76,12 @@
* control required.
*/
+#define MSR_IA32_FLUSH_CMD 0x0000010b
+#define L1D_FLUSH (1 << 0) /*
+ * Writeback and invalidate the
+ * L1 data cache.
+ */
+
#define MSR_IA32_BBL_CR_CTL 0x00000119
#define MSR_IA32_BBL_CR_CTL3 0x0000011e
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index cb75e051dd9f9..e0ee175be73c9 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -9616,6 +9616,11 @@ static void __maybe_unused vmx_l1d_flush(void)
{
int size = PAGE_SIZE << L1D_CACHE_ORDER;
+ if (static_cpu_has(X86_FEATURE_FLUSH_L1D)) {
+ wrmsrl(MSR_IA32_FLUSH_CMD, L1D_FLUSH);
+ return;
+ }
+
asm volatile(
/* First ensure the pages are in the TLB */
"xorl %%eax, %%eax\n"
@@ -13246,11 +13251,13 @@ static int __init vmx_setup_l1d_flush(void)
!boot_cpu_has_bug(X86_BUG_L1TF))
return 0;
- page = alloc_pages(GFP_KERNEL, L1D_CACHE_ORDER);
- if (!page)
- return -ENOMEM;
+ if (!boot_cpu_has(X86_FEATURE_FLUSH_L1D)) {
+ page = alloc_pages(GFP_KERNEL, L1D_CACHE_ORDER);
+ if (!page)
+ return -ENOMEM;
+ vmx_l1d_flush_pages = page_address(page);
+ }
- vmx_l1d_flush_pages = page_address(page);
static_branch_enable(&vmx_l1d_should_flush);
return 0;
}