aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2009-12-02 05:28:47 -0500
committerAvi Kivity <avi@redhat.com>2009-12-03 02:34:20 -0500
commitd5696725b2a4c59503f5e0bc33adeee7f30cd45b (patch)
tree56069b502c198fbfef0eb0d9bd3a2329b3d37cef /arch/x86/kvm/x86.c
parentf50146bd7bdb75435638e60d4960edd9bcdf88b8 (diff)
KVM: VMX: Fix comparison of guest efer with stale host value
update_transition_efer() masks out some efer bits when deciding whether to switch the msr during guest entry; for example, NX is emulated using the mmu so we don't need to disable it, and LMA/LME are handled by the hardware. However, with shared msrs, the comparison is made against a stale value; at the time of the guest switch we may be running with another guest's efer. Fix by deferring the mask/compare to the actual point of guest entry. Noted by Marcelo. Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 106f9f1f78c0..ce677b20bf86 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -185,11 +185,11 @@ static void kvm_shared_msr_cpu_online(void)
185 locals->current_value[i] = shared_msrs_global.msrs[i].value; 185 locals->current_value[i] = shared_msrs_global.msrs[i].value;
186} 186}
187 187
188void kvm_set_shared_msr(unsigned slot, u64 value) 188void kvm_set_shared_msr(unsigned slot, u64 value, u64 mask)
189{ 189{
190 struct kvm_shared_msrs *smsr = &__get_cpu_var(shared_msrs); 190 struct kvm_shared_msrs *smsr = &__get_cpu_var(shared_msrs);
191 191
192 if (value == smsr->current_value[slot]) 192 if (((value ^ smsr->current_value[slot]) & mask) == 0)
193 return; 193 return;
194 smsr->current_value[slot] = value; 194 smsr->current_value[slot] = value;
195 wrmsrl(shared_msrs_global.msrs[slot].msr, value); 195 wrmsrl(shared_msrs_global.msrs[slot].msr, value);