1 From e24dea2afc6a0852983dc741072d8e96155e13f5 Mon Sep 17 00:00:00 2001
2 From: Paolo Bonzini <pbonzini@redhat.com>
3 Date: Tue, 22 Dec 2015 15:20:00 +0100
4 Subject: KVM: MTRR: treat memory as writeback if MTRR is disabled in guest
7 Virtual machines can be run with CPUID such that there are no MTRRs.
8 In that case, the firmware will never enable MTRRs and it is obviously
9 undesirable to run the guest entirely with UC memory. Check out guest
10 CPUID, and use WB memory if MTRR do not exist.
12 Cc: qemu-stable@nongnu.org
13 Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=107561
14 Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
16 arch/x86/kvm/cpuid.h | 8 ++++++++
17 arch/x86/kvm/mtrr.c | 14 +++++++++++---
18 2 files changed, 19 insertions(+), 3 deletions(-)
20 diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
21 index 06332cb..3f5c48d 100644
22 --- a/arch/x86/kvm/cpuid.h
23 +++ b/arch/x86/kvm/cpuid.h
24 @@ -38,6 +38,14 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu)
25 return best && (best->ecx & bit(X86_FEATURE_XSAVE));
28 +static inline bool guest_cpuid_has_mtrr(struct kvm_vcpu *vcpu)
30 + struct kvm_cpuid_entry2 *best;
32 + best = kvm_find_cpuid_entry(vcpu, 1, 0);
33 + return best && (best->edx & bit(X86_FEATURE_MTRR));
36 static inline bool guest_cpuid_has_tsc_adjust(struct kvm_vcpu *vcpu)
38 struct kvm_cpuid_entry2 *best;
39 diff --git a/arch/x86/kvm/mtrr.c b/arch/x86/kvm/mtrr.c
40 index 7747b6d..3f8c732 100644
41 --- a/arch/x86/kvm/mtrr.c
42 +++ b/arch/x86/kvm/mtrr.c
43 @@ -120,14 +120,22 @@ static u8 mtrr_default_type(struct kvm_mtrr *mtrr_state)
44 return mtrr_state->deftype & IA32_MTRR_DEF_TYPE_TYPE_MASK;
47 -static u8 mtrr_disabled_type(void)
48 +static u8 mtrr_disabled_type(struct kvm_vcpu *vcpu)
51 * Intel SDM 11.11.2.2: all MTRRs are disabled when
52 * IA32_MTRR_DEF_TYPE.E bit is cleared, and the UC
53 * memory type is applied to all of physical memory.
55 + * However, virtual machines can be run with CPUID such that
56 + * there are no MTRRs. In that case, the firmware will never
57 + * enable MTRRs and it is obviously undesirable to run the
58 + * guest entirely with UC memory and we use WB.
60 - return MTRR_TYPE_UNCACHABLE;
61 + if (guest_cpuid_has_mtrr(vcpu))
62 + return MTRR_TYPE_UNCACHABLE;
64 + return MTRR_TYPE_WRBACK;
68 @@ -675,7 +683,7 @@ u8 kvm_mtrr_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn)
71 if (iter.mtrr_disabled)
72 - return mtrr_disabled_type();
73 + return mtrr_disabled_type(vcpu);
75 /* not contained in any MTRRs. */