aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNadav Amit <namit@cs.technion.ac.il>2014-06-18 10:19:25 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-06-19 06:52:15 -0400
commit1e32c07955b43e7f827174bf320ed35971117275 (patch)
treea1479742bd802791c1d71b456296ef2ea6ff7d64
parenta449c7aa51e10c9bde0ea9bee4e682d6d067ebab (diff)
KVM: vmx: handle_cr ignores 32/64-bit mode
On 32-bit mode only bits [31:0] of the CR should be used for setting the CR value. Otherwise, the host may incorrectly assume the value is invalid if bits [63:32] are not zero. Moreover, the CR is currently being read twice when CR8 is used. Last, nested mov-cr exiting is modified to handle the CR value correctly as well. Signed-off-by: Nadav Amit <namit@cs.technion.ac.il> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/kvm/vmx.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index b362a1a38e51..45024bf0e229 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -5058,7 +5058,7 @@ static int handle_cr(struct kvm_vcpu *vcpu)
5058 reg = (exit_qualification >> 8) & 15; 5058 reg = (exit_qualification >> 8) & 15;
5059 switch ((exit_qualification >> 4) & 3) { 5059 switch ((exit_qualification >> 4) & 3) {
5060 case 0: /* mov to cr */ 5060 case 0: /* mov to cr */
5061 val = kvm_register_read(vcpu, reg); 5061 val = kvm_register_readl(vcpu, reg);
5062 trace_kvm_cr_write(cr, val); 5062 trace_kvm_cr_write(cr, val);
5063 switch (cr) { 5063 switch (cr) {
5064 case 0: 5064 case 0:
@@ -5075,7 +5075,7 @@ static int handle_cr(struct kvm_vcpu *vcpu)
5075 return 1; 5075 return 1;
5076 case 8: { 5076 case 8: {
5077 u8 cr8_prev = kvm_get_cr8(vcpu); 5077 u8 cr8_prev = kvm_get_cr8(vcpu);
5078 u8 cr8 = kvm_register_read(vcpu, reg); 5078 u8 cr8 = (u8)val;
5079 err = kvm_set_cr8(vcpu, cr8); 5079 err = kvm_set_cr8(vcpu, cr8);
5080 kvm_complete_insn_gp(vcpu, err); 5080 kvm_complete_insn_gp(vcpu, err);
5081 if (irqchip_in_kernel(vcpu->kvm)) 5081 if (irqchip_in_kernel(vcpu->kvm))
@@ -6770,7 +6770,7 @@ static bool nested_vmx_exit_handled_cr(struct kvm_vcpu *vcpu,
6770 unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); 6770 unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
6771 int cr = exit_qualification & 15; 6771 int cr = exit_qualification & 15;
6772 int reg = (exit_qualification >> 8) & 15; 6772 int reg = (exit_qualification >> 8) & 15;
6773 unsigned long val = kvm_register_read(vcpu, reg); 6773 unsigned long val = kvm_register_readl(vcpu, reg);
6774 6774
6775 switch ((exit_qualification >> 4) & 3) { 6775 switch ((exit_qualification >> 4) & 3) {
6776 case 0: /* mov to cr */ 6776 case 0: /* mov to cr */