aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-05-02 13:40:00 -0400
committerAvi Kivity <avi@qumranet.com>2007-07-16 05:05:39 -0400
commit5fd86fcfc0dbdd42296b1182945f7a0a05578211 (patch)
tree0fffa1f468d9b44f00ee16a5b82bb1c65713d4a6 /drivers/kvm
parentabd3f2d622a810b7f6687f7ddb405e90e4cfb7ab (diff)
KVM: Consolidate guest fpu activation and deactivation
Easier to keep track of where the fpu is this way. Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm')
-rw-r--r--drivers/kvm/kvm.h2
-rw-r--r--drivers/kvm/vmx.c50
2 files changed, 32 insertions, 20 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index bb32383ddfff..472408743d70 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -42,7 +42,7 @@
42 (CR0_PG_MASK | CR0_PE_MASK | CR0_WP_MASK | CR0_NE_MASK \ 42 (CR0_PG_MASK | CR0_PE_MASK | CR0_WP_MASK | CR0_NE_MASK \
43 | CR0_NW_MASK | CR0_CD_MASK) 43 | CR0_NW_MASK | CR0_CD_MASK)
44#define KVM_VM_CR0_ALWAYS_ON \ 44#define KVM_VM_CR0_ALWAYS_ON \
45 (CR0_PG_MASK | CR0_PE_MASK | CR0_WP_MASK | CR0_NE_MASK) 45 (CR0_PG_MASK | CR0_PE_MASK | CR0_WP_MASK | CR0_NE_MASK | CR0_TS_MASK)
46#define KVM_GUEST_CR4_MASK \ 46#define KVM_GUEST_CR4_MASK \
47 (CR4_PSE_MASK | CR4_PAE_MASK | CR4_PGE_MASK | CR4_VMXE_MASK | CR4_VME_MASK) 47 (CR4_PSE_MASK | CR4_PAE_MASK | CR4_PGE_MASK | CR4_VMXE_MASK | CR4_VME_MASK)
48#define KVM_PMODE_VM_CR4_ALWAYS_ON (CR4_VMXE_MASK | CR4_PAE_MASK) 48#define KVM_PMODE_VM_CR4_ALWAYS_ON (CR4_VMXE_MASK | CR4_PAE_MASK)
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 2190020e055b..096cb6a1e899 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -396,6 +396,26 @@ static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
396 put_cpu(); 396 put_cpu();
397} 397}
398 398
399static void vmx_fpu_activate(struct kvm_vcpu *vcpu)
400{
401 if (vcpu->fpu_active)
402 return;
403 vcpu->fpu_active = 1;
404 vmcs_clear_bits(GUEST_CR0, CR0_TS_MASK);
405 if (vcpu->cr0 & CR0_TS_MASK)
406 vmcs_set_bits(GUEST_CR0, CR0_TS_MASK);
407 update_exception_bitmap(vcpu);
408}
409
410static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu)
411{
412 if (!vcpu->fpu_active)
413 return;
414 vcpu->fpu_active = 0;
415 vmcs_set_bits(GUEST_CR0, CR0_TS_MASK);
416 update_exception_bitmap(vcpu);
417}
418
399static void vmx_vcpu_decache(struct kvm_vcpu *vcpu) 419static void vmx_vcpu_decache(struct kvm_vcpu *vcpu)
400{ 420{
401 vcpu_clear(vcpu); 421 vcpu_clear(vcpu);
@@ -925,6 +945,8 @@ static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
925 945
926static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) 946static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
927{ 947{
948 vmx_fpu_deactivate(vcpu);
949
928 if (vcpu->rmode.active && (cr0 & CR0_PE_MASK)) 950 if (vcpu->rmode.active && (cr0 & CR0_PE_MASK))
929 enter_pmode(vcpu); 951 enter_pmode(vcpu);
930 952
@@ -940,26 +962,20 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
940 } 962 }
941#endif 963#endif
942 964
943 if (!(cr0 & CR0_TS_MASK)) {
944 vcpu->fpu_active = 1;
945 update_exception_bitmap(vcpu);
946 }
947
948 vmcs_writel(CR0_READ_SHADOW, cr0); 965 vmcs_writel(CR0_READ_SHADOW, cr0);
949 vmcs_writel(GUEST_CR0, 966 vmcs_writel(GUEST_CR0,
950 (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON); 967 (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON);
951 vcpu->cr0 = cr0; 968 vcpu->cr0 = cr0;
969
970 if (!(cr0 & CR0_TS_MASK) || !(cr0 & CR0_PE_MASK))
971 vmx_fpu_activate(vcpu);
952} 972}
953 973
954static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) 974static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
955{ 975{
956 vmcs_writel(GUEST_CR3, cr3); 976 vmcs_writel(GUEST_CR3, cr3);
957 977 if (vcpu->cr0 & CR0_PE_MASK)
958 if (!(vcpu->cr0 & CR0_TS_MASK)) { 978 vmx_fpu_deactivate(vcpu);
959 vcpu->fpu_active = 0;
960 vmcs_set_bits(GUEST_CR0, CR0_TS_MASK);
961 update_exception_bitmap(vcpu);
962 }
963} 979}
964 980
965static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) 981static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
@@ -1328,6 +1344,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
1328#ifdef CONFIG_X86_64 1344#ifdef CONFIG_X86_64
1329 vmx_set_efer(vcpu, 0); 1345 vmx_set_efer(vcpu, 0);
1330#endif 1346#endif
1347 vmx_fpu_activate(vcpu);
1331 update_exception_bitmap(vcpu); 1348 update_exception_bitmap(vcpu);
1332 1349
1333 return 0; 1350 return 0;
@@ -1488,10 +1505,7 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1488 } 1505 }
1489 1506
1490 if (is_no_device(intr_info)) { 1507 if (is_no_device(intr_info)) {
1491 vcpu->fpu_active = 1; 1508 vmx_fpu_activate(vcpu);
1492 update_exception_bitmap(vcpu);
1493 if (!(vcpu->cr0 & CR0_TS_MASK))
1494 vmcs_clear_bits(GUEST_CR0, CR0_TS_MASK);
1495 return 1; 1509 return 1;
1496 } 1510 }
1497 1511
@@ -1683,11 +1697,10 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1683 break; 1697 break;
1684 case 2: /* clts */ 1698 case 2: /* clts */
1685 vcpu_load_rsp_rip(vcpu); 1699 vcpu_load_rsp_rip(vcpu);
1686 vcpu->fpu_active = 1; 1700 vmx_fpu_deactivate(vcpu);
1687 update_exception_bitmap(vcpu);
1688 vmcs_clear_bits(GUEST_CR0, CR0_TS_MASK);
1689 vcpu->cr0 &= ~CR0_TS_MASK; 1701 vcpu->cr0 &= ~CR0_TS_MASK;
1690 vmcs_writel(CR0_READ_SHADOW, vcpu->cr0); 1702 vmcs_writel(CR0_READ_SHADOW, vcpu->cr0);
1703 vmx_fpu_activate(vcpu);
1691 skip_emulated_instruction(vcpu); 1704 skip_emulated_instruction(vcpu);
1692 return 1; 1705 return 1;
1693 case 1: /*mov from cr*/ 1706 case 1: /*mov from cr*/
@@ -2158,7 +2171,6 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu)
2158 vmcs_clear(vmcs); 2171 vmcs_clear(vmcs);
2159 vcpu->vmcs = vmcs; 2172 vcpu->vmcs = vmcs;
2160 vcpu->launched = 0; 2173 vcpu->launched = 0;
2161 vcpu->fpu_active = 1;
2162 2174
2163 return 0; 2175 return 0;
2164 2176