aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/kvm')
-rw-r--r--drivers/kvm/kvm.h3
-rw-r--r--drivers/kvm/kvm_main.c22
-rw-r--r--drivers/kvm/vmx.c12
3 files changed, 28 insertions, 9 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 1c040d80c641..152312c1fafa 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -304,6 +304,7 @@ struct kvm_vcpu {
304 char *host_fx_image; 304 char *host_fx_image;
305 char *guest_fx_image; 305 char *guest_fx_image;
306 int fpu_active; 306 int fpu_active;
307 int guest_fpu_loaded;
307 308
308 int mmio_needed; 309 int mmio_needed;
309 int mmio_read_completed; 310 int mmio_read_completed;
@@ -508,6 +509,8 @@ void fx_init(struct kvm_vcpu *vcpu);
508void load_msrs(struct vmx_msr_entry *e, int n); 509void load_msrs(struct vmx_msr_entry *e, int n);
509void save_msrs(struct vmx_msr_entry *e, int n); 510void save_msrs(struct vmx_msr_entry *e, int n);
510void kvm_resched(struct kvm_vcpu *vcpu); 511void kvm_resched(struct kvm_vcpu *vcpu);
512void kvm_load_guest_fpu(struct kvm_vcpu *vcpu);
513void kvm_put_guest_fpu(struct kvm_vcpu *vcpu);
511 514
512int kvm_read_guest(struct kvm_vcpu *vcpu, 515int kvm_read_guest(struct kvm_vcpu *vcpu,
513 gva_t addr, 516 gva_t addr,
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index da985b31b17e..8f1f07adb04e 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -253,6 +253,28 @@ int kvm_write_guest(struct kvm_vcpu *vcpu, gva_t addr, unsigned long size,
253} 253}
254EXPORT_SYMBOL_GPL(kvm_write_guest); 254EXPORT_SYMBOL_GPL(kvm_write_guest);
255 255
256void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
257{
258 if (!vcpu->fpu_active || vcpu->guest_fpu_loaded)
259 return;
260
261 vcpu->guest_fpu_loaded = 1;
262 fx_save(vcpu->host_fx_image);
263 fx_restore(vcpu->guest_fx_image);
264}
265EXPORT_SYMBOL_GPL(kvm_load_guest_fpu);
266
267void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
268{
269 if (!vcpu->guest_fpu_loaded)
270 return;
271
272 vcpu->guest_fpu_loaded = 0;
273 fx_save(vcpu->guest_fx_image);
274 fx_restore(vcpu->host_fx_image);
275}
276EXPORT_SYMBOL_GPL(kvm_put_guest_fpu);
277
256/* 278/*
257 * Switches to specified vcpu, until a matching vcpu_put() 279 * Switches to specified vcpu, until a matching vcpu_put()
258 */ 280 */
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 184238e2ece4..c1ac106ace8c 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -280,6 +280,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu)
280 280
281static void vmx_vcpu_put(struct kvm_vcpu *vcpu) 281static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
282{ 282{
283 kvm_put_guest_fpu(vcpu);
283 put_cpu(); 284 put_cpu();
284} 285}
285 286
@@ -1847,10 +1848,8 @@ again:
1847 if (vcpu->guest_debug.enabled) 1848 if (vcpu->guest_debug.enabled)
1848 kvm_guest_debug_pre(vcpu); 1849 kvm_guest_debug_pre(vcpu);
1849 1850
1850 if (vcpu->fpu_active) { 1851 kvm_load_guest_fpu(vcpu);
1851 fx_save(vcpu->host_fx_image); 1852
1852 fx_restore(vcpu->guest_fx_image);
1853 }
1854 /* 1853 /*
1855 * Loading guest fpu may have cleared host cr0.ts 1854 * Loading guest fpu may have cleared host cr0.ts
1856 */ 1855 */
@@ -2012,11 +2011,6 @@ again:
2012 } 2011 }
2013#endif 2012#endif
2014 2013
2015 if (vcpu->fpu_active) {
2016 fx_save(vcpu->guest_fx_image);
2017 fx_restore(vcpu->host_fx_image);
2018 }
2019
2020 vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0; 2014 vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
2021 2015
2022 asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS)); 2016 asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));