]> git.proxmox.com Git - pve-kernel-jessie.git/blob - 0002-mttr.patch
update kernel source to Ubuntu-4.2.0-27.32
[pve-kernel-jessie.git] / 0002-mttr.patch
1 From fa7c4ebd5ae0c22f9908436303106a9ffcf0cf42 Mon Sep 17 00:00:00 2001
2 From: Paolo Bonzini <pbonzini@redhat.com>
3 Date: Mon, 14 Dec 2015 16:57:31 +0100
4 Subject: KVM: MTRR: observe maxphyaddr from guest CPUID, not host
5
6 Conversion of MTRRs to ranges used the maxphyaddr from the boot CPU.
7 This is wrong, because var_mtrr_range's mask variable then is discontiguous
8 (like FF00FFFF000, where the first run of 0s corresponds to the bits
9 between host and guest maxphyaddr). Instead always set up the masks
10 to be full 64-bit values---we know that the reserved bits at the top
11 are zero, and we can restore them when reading the MSR. This way
12 var_mtrr_range gets a mask that just works.
13
14 Fixes: a13842dc668b40daef4327294a6d3bdc8bd30276
15 Cc: qemu-stable@nongnu.org
16 Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=107561
17 Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
18 ---
19 arch/x86/kvm/mtrr.c | 9 +++++++--
20 1 file changed, 7 insertions(+), 2 deletions(-)
21
22 diff --git a/arch/x86/kvm/mtrr.c b/arch/x86/kvm/mtrr.c
23 index adc54e1..7747b6d 100644
24 --- a/arch/x86/kvm/mtrr.c
25 +++ b/arch/x86/kvm/mtrr.c
26 @@ -300,7 +300,6 @@ static void var_mtrr_range(struct kvm_mtrr_range *range, u64 *start, u64 *end)
27 *start = range->base & PAGE_MASK;
28
29 mask = range->mask & PAGE_MASK;
30 - mask |= ~0ULL << boot_cpu_data.x86_phys_bits;
31
32 /* This cannot overflow because writing to the reserved bits of
33 * variable MTRRs causes a #GP.
34 @@ -356,10 +355,14 @@ static void set_var_mtrr_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
35 if (var_mtrr_range_is_valid(cur))
36 list_del(&mtrr_state->var_ranges[index].node);
37
38 + /* Extend the mask with all 1 bits to the left, since those
39 + * bits must implicitly be 0. The bits are then cleared
40 + * when reading them.
41 + */
42 if (!is_mtrr_mask)
43 cur->base = data;
44 else
45 - cur->mask = data;
46 + cur->mask = data | (-1LL << cpuid_maxphyaddr(vcpu));
47
48 /* add it to the list if it's enabled. */
49 if (var_mtrr_range_is_valid(cur)) {
50 @@ -426,6 +429,8 @@ int kvm_mtrr_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
51 *pdata = vcpu->arch.mtrr_state.var_ranges[index].base;
52 else
53 *pdata = vcpu->arch.mtrr_state.var_ranges[index].mask;
54 +
55 + *pdata &= (1ULL << cpuid_maxphyaddr(vcpu)) - 1;
56 }
57
58 return 0;
59 --
60 cgit v0.11.2
61