KVM: x86: fix checking of cr0 validity
authorGleb Natapov <gleb@redhat.com>
Thu, 21 Jan 2010 13:28:46 +0000 (15:28 +0200)
committerMarcelo Tosatti <mtosatti@redhat.com>
Mon, 1 Mar 2010 15:36:03 +0000 (12:36 -0300)
Move to/from Control Registers chapter of Intel SDM says.  "Reserved bits
in CR0 remain clear after any load of those registers; attempts to set
them have no impact". Control Register chapter says "Bits 63:32 of CR0 are
reserved and must be written with zeros. Writing a nonzero value to any
of the upper 32 bits results in a general-protection exception, #GP(0)."

This patch tries to implement this twisted logic.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
Reported-by: Lorenzo Martignoni <martignlo@gmail.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
arch/x86/kvm/x86.c

index fd5101b..ce267d9 100644 (file)
@@ -430,12 +430,16 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 {
        cr0 |= X86_CR0_ET;
 
-       if (cr0 & CR0_RESERVED_BITS) {
+#ifdef CONFIG_X86_64
+       if (cr0 & 0xffffffff00000000UL) {
                printk(KERN_DEBUG "set_cr0: 0x%lx #GP, reserved bits 0x%lx\n",
                       cr0, kvm_read_cr0(vcpu));
                kvm_inject_gp(vcpu, 0);
                return;
        }
+#endif
+
+       cr0 &= ~CR0_RESERVED_BITS;
 
        if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD)) {
                printk(KERN_DEBUG "set_cr0: #GP, CD == 0 && NW == 1\n");