diff options
-rw-r--r-- | drivers/kvm/kvm.h | 1 | ||||
-rw-r--r-- | drivers/kvm/kvm_main.c | 10 | ||||
-rw-r--r-- | drivers/kvm/svm.c | 5 | ||||
-rw-r--r-- | drivers/kvm/vmx.c | 10 |
4 files changed, 24 insertions, 2 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index 32023d1ac24b..e8fe1039e3b5 100644 --- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h | |||
@@ -283,6 +283,7 @@ struct kvm_arch_ops { | |||
283 | void (*set_segment)(struct kvm_vcpu *vcpu, | 283 | void (*set_segment)(struct kvm_vcpu *vcpu, |
284 | struct kvm_segment *var, int seg); | 284 | struct kvm_segment *var, int seg); |
285 | void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l); | 285 | void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l); |
286 | void (*decache_cr0_cr4_guest_bits)(struct kvm_vcpu *vcpu); | ||
286 | void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0); | 287 | void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0); |
287 | void (*set_cr0_no_modeswitch)(struct kvm_vcpu *vcpu, | 288 | void (*set_cr0_no_modeswitch)(struct kvm_vcpu *vcpu, |
288 | unsigned long cr0); | 289 | unsigned long cr0); |
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index aca14139a680..bc88c334664b 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -390,6 +390,7 @@ EXPORT_SYMBOL_GPL(set_cr0); | |||
390 | 390 | ||
391 | void lmsw(struct kvm_vcpu *vcpu, unsigned long msw) | 391 | void lmsw(struct kvm_vcpu *vcpu, unsigned long msw) |
392 | { | 392 | { |
393 | kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu); | ||
393 | set_cr0(vcpu, (vcpu->cr0 & ~0x0ful) | (msw & 0x0f)); | 394 | set_cr0(vcpu, (vcpu->cr0 & ~0x0ful) | (msw & 0x0f)); |
394 | } | 395 | } |
395 | EXPORT_SYMBOL_GPL(lmsw); | 396 | EXPORT_SYMBOL_GPL(lmsw); |
@@ -917,9 +918,10 @@ int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address) | |||
917 | 918 | ||
918 | int emulate_clts(struct kvm_vcpu *vcpu) | 919 | int emulate_clts(struct kvm_vcpu *vcpu) |
919 | { | 920 | { |
920 | unsigned long cr0 = vcpu->cr0; | 921 | unsigned long cr0; |
921 | 922 | ||
922 | cr0 &= ~CR0_TS_MASK; | 923 | kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu); |
924 | cr0 = vcpu->cr0 & ~CR0_TS_MASK; | ||
923 | kvm_arch_ops->set_cr0(vcpu, cr0); | 925 | kvm_arch_ops->set_cr0(vcpu, cr0); |
924 | return X86EMUL_CONTINUE; | 926 | return X86EMUL_CONTINUE; |
925 | } | 927 | } |
@@ -1072,6 +1074,7 @@ void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, | |||
1072 | 1074 | ||
1073 | unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr) | 1075 | unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr) |
1074 | { | 1076 | { |
1077 | kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu); | ||
1075 | switch (cr) { | 1078 | switch (cr) { |
1076 | case 0: | 1079 | case 0: |
1077 | return vcpu->cr0; | 1080 | return vcpu->cr0; |
@@ -1406,6 +1409,7 @@ static int kvm_dev_ioctl_get_sregs(struct kvm *kvm, struct kvm_sregs *sregs) | |||
1406 | sregs->gdt.limit = dt.limit; | 1409 | sregs->gdt.limit = dt.limit; |
1407 | sregs->gdt.base = dt.base; | 1410 | sregs->gdt.base = dt.base; |
1408 | 1411 | ||
1412 | kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu); | ||
1409 | sregs->cr0 = vcpu->cr0; | 1413 | sregs->cr0 = vcpu->cr0; |
1410 | sregs->cr2 = vcpu->cr2; | 1414 | sregs->cr2 = vcpu->cr2; |
1411 | sregs->cr3 = vcpu->cr3; | 1415 | sregs->cr3 = vcpu->cr3; |
@@ -1470,6 +1474,8 @@ static int kvm_dev_ioctl_set_sregs(struct kvm *kvm, struct kvm_sregs *sregs) | |||
1470 | #endif | 1474 | #endif |
1471 | vcpu->apic_base = sregs->apic_base; | 1475 | vcpu->apic_base = sregs->apic_base; |
1472 | 1476 | ||
1477 | kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu); | ||
1478 | |||
1473 | mmu_reset_needed |= vcpu->cr0 != sregs->cr0; | 1479 | mmu_reset_needed |= vcpu->cr0 != sregs->cr0; |
1474 | kvm_arch_ops->set_cr0_no_modeswitch(vcpu, sregs->cr0); | 1480 | kvm_arch_ops->set_cr0_no_modeswitch(vcpu, sregs->cr0); |
1475 | 1481 | ||
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index 855207a9b396..91c7f60ffd42 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c | |||
@@ -702,6 +702,10 @@ static void svm_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) | |||
702 | vcpu->svm->vmcb->save.gdtr.base = dt->base ; | 702 | vcpu->svm->vmcb->save.gdtr.base = dt->base ; |
703 | } | 703 | } |
704 | 704 | ||
705 | static void svm_decache_cr0_cr4_guest_bits(struct kvm_vcpu *vcpu) | ||
706 | { | ||
707 | } | ||
708 | |||
705 | static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | 709 | static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) |
706 | { | 710 | { |
707 | #ifdef CONFIG_X86_64 | 711 | #ifdef CONFIG_X86_64 |
@@ -1645,6 +1649,7 @@ static struct kvm_arch_ops svm_arch_ops = { | |||
1645 | .get_segment = svm_get_segment, | 1649 | .get_segment = svm_get_segment, |
1646 | .set_segment = svm_set_segment, | 1650 | .set_segment = svm_set_segment, |
1647 | .get_cs_db_l_bits = svm_get_cs_db_l_bits, | 1651 | .get_cs_db_l_bits = svm_get_cs_db_l_bits, |
1652 | .decache_cr0_cr4_guest_bits = svm_decache_cr0_cr4_guest_bits, | ||
1648 | .set_cr0 = svm_set_cr0, | 1653 | .set_cr0 = svm_set_cr0, |
1649 | .set_cr0_no_modeswitch = svm_set_cr0, | 1654 | .set_cr0_no_modeswitch = svm_set_cr0, |
1650 | .set_cr3 = svm_set_cr3, | 1655 | .set_cr3 = svm_set_cr3, |
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index c55635ddf426..aaa98e3e9caf 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c | |||
@@ -737,6 +737,15 @@ static void exit_lmode(struct kvm_vcpu *vcpu) | |||
737 | 737 | ||
738 | #endif | 738 | #endif |
739 | 739 | ||
740 | static void vmx_decache_cr0_cr4_guest_bits(struct kvm_vcpu *vcpu) | ||
741 | { | ||
742 | vcpu->cr0 &= KVM_GUEST_CR0_MASK; | ||
743 | vcpu->cr0 |= vmcs_readl(GUEST_CR0) & ~KVM_GUEST_CR0_MASK; | ||
744 | |||
745 | vcpu->cr4 &= KVM_GUEST_CR4_MASK; | ||
746 | vcpu->cr4 |= vmcs_readl(GUEST_CR4) & ~KVM_GUEST_CR4_MASK; | ||
747 | } | ||
748 | |||
740 | static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | 749 | static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) |
741 | { | 750 | { |
742 | if (vcpu->rmode.active && (cr0 & CR0_PE_MASK)) | 751 | if (vcpu->rmode.active && (cr0 & CR0_PE_MASK)) |
@@ -2002,6 +2011,7 @@ static struct kvm_arch_ops vmx_arch_ops = { | |||
2002 | .get_segment = vmx_get_segment, | 2011 | .get_segment = vmx_get_segment, |
2003 | .set_segment = vmx_set_segment, | 2012 | .set_segment = vmx_set_segment, |
2004 | .get_cs_db_l_bits = vmx_get_cs_db_l_bits, | 2013 | .get_cs_db_l_bits = vmx_get_cs_db_l_bits, |
2014 | .decache_cr0_cr4_guest_bits = vmx_decache_cr0_cr4_guest_bits, | ||
2005 | .set_cr0 = vmx_set_cr0, | 2015 | .set_cr0 = vmx_set_cr0, |
2006 | .set_cr0_no_modeswitch = vmx_set_cr0_no_modeswitch, | 2016 | .set_cr0_no_modeswitch = vmx_set_cr0_no_modeswitch, |
2007 | .set_cr3 = vmx_set_cr3, | 2017 | .set_cr3 = vmx_set_cr3, |