diff options
| author | Avi Kivity <avi@redhat.com> | 2009-12-29 11:43:06 -0500 |
|---|---|---|
| committer | Marcelo Tosatti <mtosatti@redhat.com> | 2010-03-01 10:35:50 -0500 |
| commit | e8467fda83cdc9de53972fee0cd2e6916cf66f41 (patch) | |
| tree | 3a1644bf9b26f29eee74614f70e9d9a82c079ea9 | |
| parent | 4d4ec0874583b127caac1d0f84033c8971b2fd2a (diff) | |
KVM: VMX: Allow the guest to own some cr0 bits
We will use this later to give the guest ownership of cr0.ts.
Signed-off-by: Avi Kivity <avi@redhat.com>
| -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, |
