aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/vmx.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-01-05 19:36:38 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2007-01-06 02:55:23 -0500
commit399badf315bd4dd571b4b3b7cf666d9a2af40229 (patch)
tree5c84e0392454df650cb4ce25d6bfcb3bac843bc3 /drivers/kvm/vmx.c
parentcb26b572dc39467ba0969d1a76c2f723d2d6a2a6 (diff)
[PATCH] KVM: Prevent stale bits in cr0 and cr4
Hardware virtualization implementations allow the guests to freely change some of the bits in cr0 and cr4, but trap when changing the other bits. This is useful to avoid excessive exits due to changing, for example, the ts flag. It also means the kvm's copy of cr0 and cr4 may be stale with respect to these bits. most of the time this doesn't matter as these bits are not very interesting. Other times, however (for example when returning cr0 to userspace), they are, so get the fresh contents of these bits from the guest by means of a new arch operation. Signed-off-by: Avi Kivity <avi@qumranet.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/kvm/vmx.c')
-rw-r--r--drivers/kvm/vmx.c10
1 files changed, 10 insertions, 0 deletions
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,