]> git.ipfire.org Git - people/ms/linux.git/commitdiff
KVM: x86: Warn if guest virtual address space is not 48-bits
authorNadav Amit <namit@cs.technion.ac.il>
Thu, 18 Sep 2014 19:39:35 +0000 (22:39 +0300)
committerJiri Slaby <jslaby@suse.cz>
Mon, 16 Feb 2015 13:06:44 +0000 (14:06 +0100)
commit dd598091de4aabbc8bd7290a04f364e443c03455 upstream.

The KVM emulator code assumes that the guest virtual address space (in 64-bit)
is 48-bits wide.  Since we are about to add more code that makes the same
assumption, this patch adds an assertion to make sure guest virtual address
space is indeed 48-bits wide.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Signed-off-by: Bruce Rogers <brogers@suse.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
arch/x86/kvm/cpuid.c
arch/x86/kvm/cpuid.h

index b110fe6c03d43908146d05ad689937d3bd991bb9..b132551528e5be25e190c9e30db4aca7fe315a57 100644 (file)
 #include "mmu.h"
 #include "trace.h"
 
-void kvm_update_cpuid(struct kvm_vcpu *vcpu)
+int kvm_update_cpuid(struct kvm_vcpu *vcpu)
 {
        struct kvm_cpuid_entry2 *best;
        struct kvm_lapic *apic = vcpu->arch.apic;
 
        best = kvm_find_cpuid_entry(vcpu, 1, 0);
        if (!best)
-               return;
+               return 0;
 
        /* Update OSXSAVE bit */
        if (cpu_has_xsave && best->function == 0x1) {
@@ -46,7 +46,15 @@ void kvm_update_cpuid(struct kvm_vcpu *vcpu)
                        apic->lapic_timer.timer_mode_mask = 1 << 17;
        }
 
+       /* The existing code assumes virtual address is 48-bit in the canonical
+        * address checks; exit if it is ever changed */
+       best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0);
+       if (best && ((best->eax & 0xff00) >> 8) != 48 &&
+               ((best->eax & 0xff00) >> 8) != 0)
+               return -EINVAL;
+
        kvm_pmu_cpuid_update(vcpu);
+       return 0;
 }
 
 static int is_efer_nx(void)
@@ -109,10 +117,9 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
        }
        vcpu->arch.cpuid_nent = cpuid->nent;
        cpuid_fix_nx_cap(vcpu);
-       r = 0;
        kvm_apic_set_version(vcpu);
        kvm_x86_ops->cpuid_update(vcpu);
-       kvm_update_cpuid(vcpu);
+       r = kvm_update_cpuid(vcpu);
 
 out_free:
        vfree(cpuid_entries);
@@ -136,9 +143,7 @@ int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
        vcpu->arch.cpuid_nent = cpuid->nent;
        kvm_apic_set_version(vcpu);
        kvm_x86_ops->cpuid_update(vcpu);
-       kvm_update_cpuid(vcpu);
-       return 0;
-
+       r = kvm_update_cpuid(vcpu);
 out:
        return r;
 }
index b7fd07984888e9f348c04df9043c6596928c1cd3..6c458e37defb31485f7ca6509954ce2694ddaec9 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "x86.h"
 
-void kvm_update_cpuid(struct kvm_vcpu *vcpu);
+int kvm_update_cpuid(struct kvm_vcpu *vcpu);
 struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
                                              u32 function, u32 index);
 int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,