Commit 1e32c079 authored by Nadav Amit's avatar Nadav Amit Committed by Paolo Bonzini

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: default avatarNadav Amit <namit@cs.technion.ac.il>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent a449c7aa
...@@ -5058,7 +5058,7 @@ static int handle_cr(struct kvm_vcpu *vcpu) ...@@ -5058,7 +5058,7 @@ static int handle_cr(struct kvm_vcpu *vcpu)
reg = (exit_qualification >> 8) & 15; reg = (exit_qualification >> 8) & 15;
switch ((exit_qualification >> 4) & 3) { switch ((exit_qualification >> 4) & 3) {
case 0: /* mov to cr */ case 0: /* mov to cr */
val = kvm_register_read(vcpu, reg); val = kvm_register_readl(vcpu, reg);
trace_kvm_cr_write(cr, val); trace_kvm_cr_write(cr, val);
switch (cr) { switch (cr) {
case 0: case 0:
...@@ -5075,7 +5075,7 @@ static int handle_cr(struct kvm_vcpu *vcpu) ...@@ -5075,7 +5075,7 @@ static int handle_cr(struct kvm_vcpu *vcpu)
return 1; return 1;
case 8: { case 8: {
u8 cr8_prev = kvm_get_cr8(vcpu); u8 cr8_prev = kvm_get_cr8(vcpu);
u8 cr8 = kvm_register_read(vcpu, reg); u8 cr8 = (u8)val;
err = kvm_set_cr8(vcpu, cr8); err = kvm_set_cr8(vcpu, cr8);
kvm_complete_insn_gp(vcpu, err); kvm_complete_insn_gp(vcpu, err);
if (irqchip_in_kernel(vcpu->kvm)) if (irqchip_in_kernel(vcpu->kvm))
...@@ -6770,7 +6770,7 @@ static bool nested_vmx_exit_handled_cr(struct kvm_vcpu *vcpu, ...@@ -6770,7 +6770,7 @@ static bool nested_vmx_exit_handled_cr(struct kvm_vcpu *vcpu,
unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
int cr = exit_qualification & 15; int cr = exit_qualification & 15;
int reg = (exit_qualification >> 8) & 15; int reg = (exit_qualification >> 8) & 15;
unsigned long val = kvm_register_read(vcpu, reg); unsigned long val = kvm_register_readl(vcpu, reg);
switch ((exit_qualification >> 4) & 3) { switch ((exit_qualification >> 4) & 3) {
case 0: /* mov to cr */ case 0: /* mov to cr */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment