diff options
author | Avi Kivity <avi@redhat.com> | 2009-12-02 05:28:47 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-12-03 02:34:20 -0500 |
commit | d5696725b2a4c59503f5e0bc33adeee7f30cd45b (patch) | |
tree | 56069b502c198fbfef0eb0d9bd3a2329b3d37cef /arch/x86/kvm/x86.c | |
parent | f50146bd7bdb75435638e60d4960edd9bcdf88b8 (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.c | 4 |
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 | ||
188 | void kvm_set_shared_msr(unsigned slot, u64 value) | 188 | void 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); |