| From foo@baz Tue Aug 14 16:14:56 CEST 2018 |
| From: Paolo Bonzini <pbonzini@redhat.com> |
| Date: Mon, 2 Jul 2018 13:03:48 +0200 |
| Subject: x86/KVM/VMX: Add L1D MSR based flush |
| |
| From: Paolo Bonzini <pbonzini@redhat.com> |
| |
| 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: David Woodhouse <dwmw@amazon.co.uk> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/x86/include/asm/msr-index.h | 6 ++++++ |
| arch/x86/kvm/vmx.c | 15 +++++++++++---- |
| 2 files changed, 17 insertions(+), 4 deletions(-) |
| |
| --- a/arch/x86/include/asm/msr-index.h |
| +++ b/arch/x86/include/asm/msr-index.h |
| @@ -69,6 +69,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 |
| |
| --- a/arch/x86/kvm/vmx.c |
| +++ b/arch/x86/kvm/vmx.c |
| @@ -8553,6 +8553,11 @@ static void __maybe_unused vmx_l1d_flush |
| { |
| 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" |
| @@ -11601,11 +11606,13 @@ static int __init vmx_setup_l1d_flush(vo |
| !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; |
| } |