x86/KVM/VMX: Add L1D MSR based flush
authorPaolo Bonzini <pbonzini@redhat.com>
Mon, 2 Jul 2018 11:03:48 +0000 (13:03 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Wed, 4 Jul 2018 18:49:39 +0000 (20:49 +0200)
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>
arch/x86/include/asm/msr-index.h
arch/x86/kvm/vmx.c

index 68b2c3150de1534fda2e43ccc4a464522a350c11..0e7517089b8094a4368ff12a863b2b15856def97 100644 (file)
                                                    * 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
 
index b072264eb464df3e8247a9ad9f72f3b40ed02e08..a1dbc17c7a0318083951741bf0a5ca92f3711b6e 100644 (file)
@@ -9580,6 +9580,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"
@@ -13158,11 +13163,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;
 }