diff options
author | Nadav Amit <namit@cs.technion.ac.il> | 2014-06-18 10:19:25 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-06-19 06:52:15 -0400 |
commit | 1e32c07955b43e7f827174bf320ed35971117275 (patch) | |
tree | a1479742bd802791c1d71b456296ef2ea6ff7d64 | |
parent | a449c7aa51e10c9bde0ea9bee4e682d6d067ebab (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.c | 6 |
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 */ |