Skip to content

Commit e24dea2

Browse files
committed
KVM: MTRR: treat memory as writeback if MTRR is disabled in guest CPUID
Virtual machines can be run with CPUID such that there are no MTRRs. In that case, the firmware will never enable MTRRs and it is obviously undesirable to run the guest entirely with UC memory. Check out guest CPUID, and use WB memory if MTRR do not exist. Cc: qemu-stable@nongnu.org Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=107561 Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent fa7c4eb commit e24dea2

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

arch/x86/kvm/cpuid.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu)
3838
return best && (best->ecx & bit(X86_FEATURE_XSAVE));
3939
}
4040

41+
static inline bool guest_cpuid_has_mtrr(struct kvm_vcpu *vcpu)
42+
{
43+
struct kvm_cpuid_entry2 *best;
44+
45+
best = kvm_find_cpuid_entry(vcpu, 1, 0);
46+
return best && (best->edx & bit(X86_FEATURE_MTRR));
47+
}
48+
4149
static inline bool guest_cpuid_has_tsc_adjust(struct kvm_vcpu *vcpu)
4250
{
4351
struct kvm_cpuid_entry2 *best;

arch/x86/kvm/mtrr.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,22 @@ static u8 mtrr_default_type(struct kvm_mtrr *mtrr_state)
120120
return mtrr_state->deftype & IA32_MTRR_DEF_TYPE_TYPE_MASK;
121121
}
122122

123-
static u8 mtrr_disabled_type(void)
123+
static u8 mtrr_disabled_type(struct kvm_vcpu *vcpu)
124124
{
125125
/*
126126
* Intel SDM 11.11.2.2: all MTRRs are disabled when
127127
* IA32_MTRR_DEF_TYPE.E bit is cleared, and the UC
128128
* memory type is applied to all of physical memory.
129+
*
130+
* However, virtual machines can be run with CPUID such that
131+
* there are no MTRRs. In that case, the firmware will never
132+
* enable MTRRs and it is obviously undesirable to run the
133+
* guest entirely with UC memory and we use WB.
129134
*/
130-
return MTRR_TYPE_UNCACHABLE;
135+
if (guest_cpuid_has_mtrr(vcpu))
136+
return MTRR_TYPE_UNCACHABLE;
137+
else
138+
return MTRR_TYPE_WRBACK;
131139
}
132140

133141
/*
@@ -675,7 +683,7 @@ u8 kvm_mtrr_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn)
675683
}
676684

677685
if (iter.mtrr_disabled)
678-
return mtrr_disabled_type();
686+
return mtrr_disabled_type(vcpu);
679687

680688
/* not contained in any MTRRs. */
681689
if (type == -1)

0 commit comments

Comments
 (0)