aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/kvm/vmx.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index b40066854c14..d63e82e5dbf8 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -54,7 +54,8 @@ struct vcpu_vmx {
54 struct { 54 struct {
55 int loaded; 55 int loaded;
56 u16 fs_sel, gs_sel, ldt_sel; 56 u16 fs_sel, gs_sel, ldt_sel;
57 int fs_gs_ldt_reload_needed; 57 int gs_ldt_reload_needed;
58 int fs_reload_needed;
58 }host_state; 59 }host_state;
59 60
60}; 61};
@@ -353,20 +354,21 @@ static void vmx_save_host_state(struct vcpu_vmx *vmx)
353 * allow segment selectors with cpl > 0 or ti == 1. 354 * allow segment selectors with cpl > 0 or ti == 1.
354 */ 355 */
355 vmx->host_state.ldt_sel = read_ldt(); 356 vmx->host_state.ldt_sel = read_ldt();
356 vmx->host_state.fs_gs_ldt_reload_needed = vmx->host_state.ldt_sel; 357 vmx->host_state.gs_ldt_reload_needed = vmx->host_state.ldt_sel;
357 vmx->host_state.fs_sel = read_fs(); 358 vmx->host_state.fs_sel = read_fs();
358 if (!(vmx->host_state.fs_sel & 7)) 359 if (!(vmx->host_state.fs_sel & 7)) {
359 vmcs_write16(HOST_FS_SELECTOR, vmx->host_state.fs_sel); 360 vmcs_write16(HOST_FS_SELECTOR, vmx->host_state.fs_sel);
360 else { 361 vmx->host_state.fs_reload_needed = 0;
362 } else {
361 vmcs_write16(HOST_FS_SELECTOR, 0); 363 vmcs_write16(HOST_FS_SELECTOR, 0);
362 vmx->host_state.fs_gs_ldt_reload_needed = 1; 364 vmx->host_state.fs_reload_needed = 1;
363 } 365 }
364 vmx->host_state.gs_sel = read_gs(); 366 vmx->host_state.gs_sel = read_gs();
365 if (!(vmx->host_state.gs_sel & 7)) 367 if (!(vmx->host_state.gs_sel & 7))
366 vmcs_write16(HOST_GS_SELECTOR, vmx->host_state.gs_sel); 368 vmcs_write16(HOST_GS_SELECTOR, vmx->host_state.gs_sel);
367 else { 369 else {
368 vmcs_write16(HOST_GS_SELECTOR, 0); 370 vmcs_write16(HOST_GS_SELECTOR, 0);
369 vmx->host_state.fs_gs_ldt_reload_needed = 1; 371 vmx->host_state.gs_ldt_reload_needed = 1;
370 } 372 }
371 373
372#ifdef CONFIG_X86_64 374#ifdef CONFIG_X86_64
@@ -396,9 +398,10 @@ static void vmx_load_host_state(struct vcpu_vmx *vmx)
396 return; 398 return;
397 399
398 vmx->host_state.loaded = 0; 400 vmx->host_state.loaded = 0;
399 if (vmx->host_state.fs_gs_ldt_reload_needed) { 401 if (vmx->host_state.fs_reload_needed)
400 load_ldt(vmx->host_state.ldt_sel);
401 load_fs(vmx->host_state.fs_sel); 402 load_fs(vmx->host_state.fs_sel);
403 if (vmx->host_state.gs_ldt_reload_needed) {
404 load_ldt(vmx->host_state.ldt_sel);
402 /* 405 /*
403 * If we have to reload gs, we must take care to 406 * If we have to reload gs, we must take care to
404 * preserve our gs base. 407 * preserve our gs base.
@@ -409,9 +412,8 @@ static void vmx_load_host_state(struct vcpu_vmx *vmx)
409 wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE)); 412 wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE));
410#endif 413#endif
411 local_irq_restore(flags); 414 local_irq_restore(flags);
412
413 reload_tss();
414 } 415 }
416 reload_tss();
415 save_msrs(vmx->guest_msrs, vmx->save_nmsrs); 417 save_msrs(vmx->guest_msrs, vmx->save_nmsrs);
416 load_msrs(vmx->host_msrs, vmx->save_nmsrs); 418 load_msrs(vmx->host_msrs, vmx->save_nmsrs);
417 if (msr_efer_need_save_restore(vmx)) 419 if (msr_efer_need_save_restore(vmx))