diff options
author | Avi Kivity <avi@qumranet.com> | 2007-05-02 13:40:00 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2007-07-16 05:05:39 -0400 |
commit | 5fd86fcfc0dbdd42296b1182945f7a0a05578211 (patch) | |
tree | 0fffa1f468d9b44f00ee16a5b82bb1c65713d4a6 /drivers/kvm | |
parent | abd3f2d622a810b7f6687f7ddb405e90e4cfb7ab (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.h | 2 | ||||
-rw-r--r-- | drivers/kvm/vmx.c | 50 |
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 | ||
399 | static 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 | |||
410 | static 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 | |||
399 | static void vmx_vcpu_decache(struct kvm_vcpu *vcpu) | 419 | static 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 | ||
926 | static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | 946 | static 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 | ||
954 | static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) | 974 | static 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 | ||
965 | static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) | 981 | static 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 | ||