diff options
Diffstat (limited to 'drivers/kvm')
-rw-r--r-- | drivers/kvm/kvm.h | 3 | ||||
-rw-r--r-- | drivers/kvm/kvm_main.c | 22 | ||||
-rw-r--r-- | drivers/kvm/vmx.c | 12 |
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); | |||
508 | void load_msrs(struct vmx_msr_entry *e, int n); | 509 | void load_msrs(struct vmx_msr_entry *e, int n); |
509 | void save_msrs(struct vmx_msr_entry *e, int n); | 510 | void save_msrs(struct vmx_msr_entry *e, int n); |
510 | void kvm_resched(struct kvm_vcpu *vcpu); | 511 | void kvm_resched(struct kvm_vcpu *vcpu); |
512 | void kvm_load_guest_fpu(struct kvm_vcpu *vcpu); | ||
513 | void kvm_put_guest_fpu(struct kvm_vcpu *vcpu); | ||
511 | 514 | ||
512 | int kvm_read_guest(struct kvm_vcpu *vcpu, | 515 | int 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 | } |
254 | EXPORT_SYMBOL_GPL(kvm_write_guest); | 254 | EXPORT_SYMBOL_GPL(kvm_write_guest); |
255 | 255 | ||
256 | void 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 | } | ||
265 | EXPORT_SYMBOL_GPL(kvm_load_guest_fpu); | ||
266 | |||
267 | void 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 | } | ||
276 | EXPORT_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 | ||
281 | static void vmx_vcpu_put(struct kvm_vcpu *vcpu) | 281 | static 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)); |