]>
Commit | Line | Data |
---|---|---|
2b10ecdc AD |
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 | |
5 | CPUID | |
6 | ||
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. | |
11 | ||
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> | |
15 | --- | |
16 | arch/x86/kvm/cpuid.h | 8 ++++++++ | |
17 | arch/x86/kvm/mtrr.c | 14 +++++++++++--- | |
18 | 2 files changed, 19 insertions(+), 3 deletions(-) | |
19 | ||
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)); | |
26 | } | |
27 | ||
28 | +static inline bool guest_cpuid_has_mtrr(struct kvm_vcpu *vcpu) | |
29 | +{ | |
30 | + struct kvm_cpuid_entry2 *best; | |
31 | + | |
32 | + best = kvm_find_cpuid_entry(vcpu, 1, 0); | |
33 | + return best && (best->edx & bit(X86_FEATURE_MTRR)); | |
34 | +} | |
35 | + | |
36 | static inline bool guest_cpuid_has_tsc_adjust(struct kvm_vcpu *vcpu) | |
37 | { | |
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; | |
45 | } | |
46 | ||
47 | -static u8 mtrr_disabled_type(void) | |
48 | +static u8 mtrr_disabled_type(struct kvm_vcpu *vcpu) | |
49 | { | |
50 | /* | |
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. | |
54 | + * | |
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. | |
59 | */ | |
60 | - return MTRR_TYPE_UNCACHABLE; | |
61 | + if (guest_cpuid_has_mtrr(vcpu)) | |
62 | + return MTRR_TYPE_UNCACHABLE; | |
63 | + else | |
64 | + return MTRR_TYPE_WRBACK; | |
65 | } | |
66 | ||
67 | /* | |
68 | @@ -675,7 +683,7 @@ u8 kvm_mtrr_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn) | |
69 | } | |
70 | ||
71 | if (iter.mtrr_disabled) | |
72 | - return mtrr_disabled_type(); | |
73 | + return mtrr_disabled_type(vcpu); | |
74 | ||
75 | /* not contained in any MTRRs. */ | |
76 | if (type == -1) | |
77 | -- | |
78 | cgit v0.11.2 |