|
@@ -985,6 +985,7 @@ struct vcpu_vmx {
|
|
|
struct shared_msr_entry *guest_msrs;
|
|
|
int nmsrs;
|
|
|
int save_nmsrs;
|
|
|
+ bool guest_msrs_dirty;
|
|
|
unsigned long host_idt_base;
|
|
|
#ifdef CONFIG_X86_64
|
|
|
u64 msr_host_kernel_gs_base;
|
|
@@ -2898,6 +2899,20 @@ static void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
|
|
|
|
|
|
vmx->req_immediate_exit = false;
|
|
|
|
|
|
+ /*
|
|
|
+ * Note that guest MSRs to be saved/restored can also be changed
|
|
|
+ * when guest state is loaded. This happens when guest transitions
|
|
|
+ * to/from long-mode by setting MSR_EFER.LMA.
|
|
|
+ */
|
|
|
+ if (!vmx->loaded_cpu_state || vmx->guest_msrs_dirty) {
|
|
|
+ vmx->guest_msrs_dirty = false;
|
|
|
+ for (i = 0; i < vmx->save_nmsrs; ++i)
|
|
|
+ kvm_set_shared_msr(vmx->guest_msrs[i].index,
|
|
|
+ vmx->guest_msrs[i].data,
|
|
|
+ vmx->guest_msrs[i].mask);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
if (vmx->loaded_cpu_state)
|
|
|
return;
|
|
|
|
|
@@ -2958,11 +2973,6 @@ static void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
|
|
|
vmcs_writel(HOST_GS_BASE, gs_base);
|
|
|
host_state->gs_base = gs_base;
|
|
|
}
|
|
|
-
|
|
|
- for (i = 0; i < vmx->save_nmsrs; ++i)
|
|
|
- kvm_set_shared_msr(vmx->guest_msrs[i].index,
|
|
|
- vmx->guest_msrs[i].data,
|
|
|
- vmx->guest_msrs[i].mask);
|
|
|
}
|
|
|
|
|
|
static void vmx_prepare_switch_to_host(struct vcpu_vmx *vmx)
|
|
@@ -3437,6 +3447,7 @@ static void setup_msrs(struct vcpu_vmx *vmx)
|
|
|
move_msr_up(vmx, index, save_nmsrs++);
|
|
|
|
|
|
vmx->save_nmsrs = save_nmsrs;
|
|
|
+ vmx->guest_msrs_dirty = true;
|
|
|
|
|
|
if (cpu_has_vmx_msr_bitmap())
|
|
|
vmx_update_msr_bitmap(&vmx->vcpu);
|