]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/5.0.19/x86-kvm-hyper-v-deal-with-buggy-tlb-flush-requests-f.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 5.0.19 / x86-kvm-hyper-v-deal-with-buggy-tlb-flush-requests-f.patch
CommitLineData
e6832405
SL
1From d570385a431a75e0b8e2c31b8b4feb542a031aaa Mon Sep 17 00:00:00 2001
2From: Vitaly Kuznetsov <vkuznets@redhat.com>
3Date: Wed, 20 Mar 2019 18:43:20 +0100
4Subject: x86: kvm: hyper-v: deal with buggy TLB flush requests from WS2012
5
6[ Upstream commit da66761c2d93a46270d69001abb5692717495a68 ]
7
8It was reported that with some special Multi Processor Group configuration,
9e.g:
10 bcdedit.exe /set groupsize 1
11 bcdedit.exe /set maxgroup on
12 bcdedit.exe /set groupaware on
13for a 16-vCPU guest WS2012 shows BSOD on boot when PV TLB flush mechanism
14is in use.
15
16Tracing kvm_hv_flush_tlb immediately reveals the issue:
17
18 kvm_hv_flush_tlb: processor_mask 0x0 address_space 0x0 flags 0x2
19
20The only flag set in this request is HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES,
21however, processor_mask is 0x0 and no HV_FLUSH_ALL_PROCESSORS is specified.
22We don't flush anything and apparently it's not what Windows expects.
23
24TLFS doesn't say anything about such requests and newer Windows versions
25seem to be unaffected. This all feels like a WS2012 bug, which is, however,
26easy to workaround in KVM: let's flush everything when we see an empty
27flush request, over-flushing doesn't hurt.
28
29Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
30Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
31Signed-off-by: Sasha Levin <sashal@kernel.org>
32---
33 arch/x86/kvm/hyperv.c | 11 ++++++++++-
34 1 file changed, 10 insertions(+), 1 deletion(-)
35
36diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
37index 371c669696d70..610c0f1fbdd71 100644
38--- a/arch/x86/kvm/hyperv.c
39+++ b/arch/x86/kvm/hyperv.c
40@@ -1371,7 +1371,16 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *current_vcpu, u64 ingpa,
41
42 valid_bank_mask = BIT_ULL(0);
43 sparse_banks[0] = flush.processor_mask;
44- all_cpus = flush.flags & HV_FLUSH_ALL_PROCESSORS;
45+
46+ /*
47+ * Work around possible WS2012 bug: it sends hypercalls
48+ * with processor_mask = 0x0 and HV_FLUSH_ALL_PROCESSORS clear,
49+ * while also expecting us to flush something and crashing if
50+ * we don't. Let's treat processor_mask == 0 same as
51+ * HV_FLUSH_ALL_PROCESSORS.
52+ */
53+ all_cpus = (flush.flags & HV_FLUSH_ALL_PROCESSORS) ||
54+ flush.processor_mask == 0;
55 } else {
56 if (unlikely(kvm_read_guest(kvm, ingpa, &flush_ex,
57 sizeof(flush_ex))))
58--
592.20.1
60