diff options
-rw-r--r-- | drivers/kvm/vmx.c | 22 |
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)) |