diff options
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 2 | ||||
-rw-r--r-- | arch/x86/kvm/kvm_cache_regs.h | 2 | ||||
-rw-r--r-- | arch/x86/kvm/svm.c | 5 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 9 |
4 files changed, 18 insertions, 0 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index a4de557ad733..693046a7a12d 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -269,6 +269,7 @@ struct kvm_vcpu_arch { | |||
269 | u32 regs_dirty; | 269 | u32 regs_dirty; |
270 | 270 | ||
271 | unsigned long cr0; | 271 | unsigned long cr0; |
272 | unsigned long cr0_guest_owned_bits; | ||
272 | unsigned long cr2; | 273 | unsigned long cr2; |
273 | unsigned long cr3; | 274 | unsigned long cr3; |
274 | unsigned long cr4; | 275 | unsigned long cr4; |
@@ -489,6 +490,7 @@ struct kvm_x86_ops { | |||
489 | void (*set_segment)(struct kvm_vcpu *vcpu, | 490 | void (*set_segment)(struct kvm_vcpu *vcpu, |
490 | struct kvm_segment *var, int seg); | 491 | struct kvm_segment *var, int seg); |
491 | void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l); | 492 | void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l); |
493 | void (*decache_cr0_guest_bits)(struct kvm_vcpu *vcpu); | ||
492 | void (*decache_cr4_guest_bits)(struct kvm_vcpu *vcpu); | 494 | void (*decache_cr4_guest_bits)(struct kvm_vcpu *vcpu); |
493 | void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0); | 495 | void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0); |
494 | void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3); | 496 | void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3); |
diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h index f46859751b30..6b419a36cbd9 100644 --- a/arch/x86/kvm/kvm_cache_regs.h +++ b/arch/x86/kvm/kvm_cache_regs.h | |||
@@ -40,6 +40,8 @@ static inline u64 kvm_pdptr_read(struct kvm_vcpu *vcpu, int index) | |||
40 | 40 | ||
41 | static inline ulong kvm_read_cr0_bits(struct kvm_vcpu *vcpu, ulong mask) | 41 | static inline ulong kvm_read_cr0_bits(struct kvm_vcpu *vcpu, ulong mask) |
42 | { | 42 | { |
43 | if (mask & vcpu->arch.cr0_guest_owned_bits) | ||
44 | kvm_x86_ops->decache_cr0_guest_bits(vcpu); | ||
43 | return vcpu->arch.cr0 & mask; | 45 | return vcpu->arch.cr0 & mask; |
44 | } | 46 | } |
45 | 47 | ||
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index d3246ce70ae8..3899c2d19830 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -956,6 +956,10 @@ static void svm_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) | |||
956 | svm->vmcb->save.gdtr.base = dt->base ; | 956 | svm->vmcb->save.gdtr.base = dt->base ; |
957 | } | 957 | } |
958 | 958 | ||
959 | static void svm_decache_cr0_guest_bits(struct kvm_vcpu *vcpu) | ||
960 | { | ||
961 | } | ||
962 | |||
959 | static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) | 963 | static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) |
960 | { | 964 | { |
961 | } | 965 | } |
@@ -2948,6 +2952,7 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
2948 | .set_segment = svm_set_segment, | 2952 | .set_segment = svm_set_segment, |
2949 | .get_cpl = svm_get_cpl, | 2953 | .get_cpl = svm_get_cpl, |
2950 | .get_cs_db_l_bits = kvm_get_cs_db_l_bits, | 2954 | .get_cs_db_l_bits = kvm_get_cs_db_l_bits, |
2955 | .decache_cr0_guest_bits = svm_decache_cr0_guest_bits, | ||
2951 | .decache_cr4_guest_bits = svm_decache_cr4_guest_bits, | 2956 | .decache_cr4_guest_bits = svm_decache_cr4_guest_bits, |
2952 | .set_cr0 = svm_set_cr0, | 2957 | .set_cr0 = svm_set_cr0, |
2953 | .set_cr3 = svm_set_cr3, | 2958 | .set_cr3 = svm_set_cr3, |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 4c7177c489ac..dbcdb55094f7 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -1653,6 +1653,14 @@ static void vmx_flush_tlb(struct kvm_vcpu *vcpu) | |||
1653 | ept_sync_context(construct_eptp(vcpu->arch.mmu.root_hpa)); | 1653 | ept_sync_context(construct_eptp(vcpu->arch.mmu.root_hpa)); |
1654 | } | 1654 | } |
1655 | 1655 | ||
1656 | static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu) | ||
1657 | { | ||
1658 | ulong cr0_guest_owned_bits = vcpu->arch.cr0_guest_owned_bits; | ||
1659 | |||
1660 | vcpu->arch.cr0 &= ~cr0_guest_owned_bits; | ||
1661 | vcpu->arch.cr0 |= vmcs_readl(GUEST_CR0) & cr0_guest_owned_bits; | ||
1662 | } | ||
1663 | |||
1656 | static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) | 1664 | static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) |
1657 | { | 1665 | { |
1658 | ulong cr4_guest_owned_bits = vcpu->arch.cr4_guest_owned_bits; | 1666 | ulong cr4_guest_owned_bits = vcpu->arch.cr4_guest_owned_bits; |
@@ -4106,6 +4114,7 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
4106 | .set_segment = vmx_set_segment, | 4114 | .set_segment = vmx_set_segment, |
4107 | .get_cpl = vmx_get_cpl, | 4115 | .get_cpl = vmx_get_cpl, |
4108 | .get_cs_db_l_bits = vmx_get_cs_db_l_bits, | 4116 | .get_cs_db_l_bits = vmx_get_cs_db_l_bits, |
4117 | .decache_cr0_guest_bits = vmx_decache_cr0_guest_bits, | ||
4109 | .decache_cr4_guest_bits = vmx_decache_cr4_guest_bits, | 4118 | .decache_cr4_guest_bits = vmx_decache_cr4_guest_bits, |
4110 | .set_cr0 = vmx_set_cr0, | 4119 | .set_cr0 = vmx_set_cr0, |
4111 | .set_cr3 = vmx_set_cr3, | 4120 | .set_cr3 = vmx_set_cr3, |