projects
/
firefly-linux-kernel-4.4.55.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge tag 'v4.4.1' into linux-linaro-lsk-v4.4
[firefly-linux-kernel-4.4.55.git]
/
arch
/
x86
/
kvm
/
mtrr.c
diff --git
a/arch/x86/kvm/mtrr.c
b/arch/x86/kvm/mtrr.c
index 9e8bf13572e6dc3f95d33d24f079d63e256a3a7a..3f8c732117eccf73140fded817e1b155dfa76073 100644
(file)
--- a/
arch/x86/kvm/mtrr.c
+++ b/
arch/x86/kvm/mtrr.c
@@
-120,14
+120,22
@@
static u8 mtrr_default_type(struct kvm_mtrr *mtrr_state)
return mtrr_state->deftype & IA32_MTRR_DEF_TYPE_TYPE_MASK;
}
return mtrr_state->deftype & IA32_MTRR_DEF_TYPE_TYPE_MASK;
}
-static u8 mtrr_disabled_type(
void
)
+static u8 mtrr_disabled_type(
struct kvm_vcpu *vcpu
)
{
/*
* Intel SDM 11.11.2.2: all MTRRs are disabled when
* IA32_MTRR_DEF_TYPE.E bit is cleared, and the UC
* memory type is applied to all of physical memory.
{
/*
* Intel SDM 11.11.2.2: all MTRRs are disabled when
* IA32_MTRR_DEF_TYPE.E bit is cleared, and the UC
* memory type is applied to all of physical memory.
+ *
+ * However, 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 and we use WB.
*/
*/
- return MTRR_TYPE_UNCACHABLE;
+ if (guest_cpuid_has_mtrr(vcpu))
+ return MTRR_TYPE_UNCACHABLE;
+ else
+ return MTRR_TYPE_WRBACK;
}
/*
}
/*
@@
-267,7
+275,7
@@
static int fixed_mtrr_addr_to_seg(u64 addr)
for (seg = 0; seg < seg_num; seg++) {
mtrr_seg = &fixed_seg_table[seg];
for (seg = 0; seg < seg_num; seg++) {
mtrr_seg = &fixed_seg_table[seg];
- if (mtrr_seg->start
>
= addr && addr < mtrr_seg->end)
+ if (mtrr_seg->start
<
= addr && addr < mtrr_seg->end)
return seg;
}
return seg;
}
@@
-300,7
+308,6
@@
static void var_mtrr_range(struct kvm_mtrr_range *range, u64 *start, u64 *end)
*start = range->base & PAGE_MASK;
mask = range->mask & PAGE_MASK;
*start = range->base & PAGE_MASK;
mask = range->mask & PAGE_MASK;
- mask |= ~0ULL << boot_cpu_data.x86_phys_bits;
/* This cannot overflow because writing to the reserved bits of
* variable MTRRs causes a #GP.
/* This cannot overflow because writing to the reserved bits of
* variable MTRRs causes a #GP.
@@
-356,10
+363,14
@@
static void set_var_mtrr_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
if (var_mtrr_range_is_valid(cur))
list_del(&mtrr_state->var_ranges[index].node);
if (var_mtrr_range_is_valid(cur))
list_del(&mtrr_state->var_ranges[index].node);
+ /* Extend the mask with all 1 bits to the left, since those
+ * bits must implicitly be 0. The bits are then cleared
+ * when reading them.
+ */
if (!is_mtrr_mask)
cur->base = data;
else
if (!is_mtrr_mask)
cur->base = data;
else
- cur->mask = data;
+ cur->mask = data
| (-1LL << cpuid_maxphyaddr(vcpu))
;
/* add it to the list if it's enabled. */
if (var_mtrr_range_is_valid(cur)) {
/* add it to the list if it's enabled. */
if (var_mtrr_range_is_valid(cur)) {
@@
-426,6
+437,8
@@
int kvm_mtrr_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
*pdata = vcpu->arch.mtrr_state.var_ranges[index].base;
else
*pdata = vcpu->arch.mtrr_state.var_ranges[index].mask;
*pdata = vcpu->arch.mtrr_state.var_ranges[index].base;
else
*pdata = vcpu->arch.mtrr_state.var_ranges[index].mask;
+
+ *pdata &= (1ULL << cpuid_maxphyaddr(vcpu)) - 1;
}
return 0;
}
return 0;
@@
-670,7
+683,7
@@
u8 kvm_mtrr_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn)
}
if (iter.mtrr_disabled)
}
if (iter.mtrr_disabled)
- return mtrr_disabled_type();
+ return mtrr_disabled_type(
vcpu
);
/* not contained in any MTRRs. */
if (type == -1)
/* not contained in any MTRRs. */
if (type == -1)