aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/kvm/kvm.h1
-rw-r--r--drivers/kvm/kvm_main.c10
-rw-r--r--drivers/kvm/svm.c5
-rw-r--r--drivers/kvm/vmx.c10
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
391void lmsw(struct kvm_vcpu *vcpu, unsigned long msw) 391void 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}
395EXPORT_SYMBOL_GPL(lmsw); 396EXPORT_SYMBOL_GPL(lmsw);
@@ -917,9 +918,10 @@ int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address)
917 918
918int emulate_clts(struct kvm_vcpu *vcpu) 919int 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
1073unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr) 1075unsigned 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
705static void svm_decache_cr0_cr4_guest_bits(struct kvm_vcpu *vcpu)
706{
707}
708
705static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) 709static 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
740static 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
740static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) 749static 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,