Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[sfrench/cifs-2.6.git] / arch / x86 / kvm / emulate.c
index bc00642e5d3b7b158cb410ed6d39a1724661904b..bddaba9c68dd2c945209d5d4774f4bed3d3a441c 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <linux/kvm_host.h>
 #include "kvm_cache_regs.h"
-#include <asm/kvm_emulate.h>
+#include "kvm_emulate.h"
 #include <linux/stringify.h>
 #include <asm/fpu/api.h>
 #include <asm/debugreg.h>
@@ -665,6 +665,17 @@ static void set_segment_selector(struct x86_emulate_ctxt *ctxt, u16 selector,
        ctxt->ops->set_segment(ctxt, selector, &desc, base3, seg);
 }
 
+static inline u8 ctxt_virt_addr_bits(struct x86_emulate_ctxt *ctxt)
+{
+       return (ctxt->ops->get_cr(ctxt, 4) & X86_CR4_LA57) ? 57 : 48;
+}
+
+static inline bool emul_is_noncanonical_address(u64 la,
+                                               struct x86_emulate_ctxt *ctxt)
+{
+       return get_canonical(la, ctxt_virt_addr_bits(ctxt)) != la;
+}
+
 /*
  * x86 defines three classes of vector instructions: explicitly
  * aligned, explicitly unaligned, and the rest, which change behaviour
@@ -2711,10 +2722,8 @@ static bool vendor_intel(struct x86_emulate_ctxt *ctxt)
        u32 eax, ebx, ecx, edx;
 
        eax = ecx = 0;
-       ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, false);
-       return ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx
-               && ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx
-               && edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx;
+       ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, true);
+       return is_guest_vendor_intel(ebx, ecx, edx);
 }
 
 static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt)
@@ -2731,36 +2740,18 @@ static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt)
 
        eax = 0x00000000;
        ecx = 0x00000000;
-       ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, false);
+       ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, true);
        /*
-        * Intel ("GenuineIntel")
-        * remark: Intel CPUs only support "syscall" in 64bit
-        * longmode. Also an 64bit guest with a
-        * 32bit compat-app running will #UD !! While this
-        * behaviour can be fixed (by emulating) into AMD
-        * response - CPUs of AMD can't behave like Intel.
+        * remark: Intel CPUs only support "syscall" in 64bit longmode. Also a
+        * 64bit guest with a 32bit compat-app running will #UD !! While this
+        * behaviour can be fixed (by emulating) into AMD response - CPUs of
+        * AMD can't behave like Intel.
         */
-       if (ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx &&
-           ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx &&
-           edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx)
+       if (is_guest_vendor_intel(ebx, ecx, edx))
                return false;
 
-       /* AMD ("AuthenticAMD") */
-       if (ebx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx &&
-           ecx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx &&
-           edx == X86EMUL_CPUID_VENDOR_AuthenticAMD_edx)
-               return true;
-
-       /* AMD ("AMDisbetter!") */
-       if (ebx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx &&
-           ecx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx &&
-           edx == X86EMUL_CPUID_VENDOR_AMDisbetterI_edx)
-               return true;
-
-       /* Hygon ("HygonGenuine") */
-       if (ebx == X86EMUL_CPUID_VENDOR_HygonGenuine_ebx &&
-           ecx == X86EMUL_CPUID_VENDOR_HygonGenuine_ecx &&
-           edx == X86EMUL_CPUID_VENDOR_HygonGenuine_edx)
+       if (is_guest_vendor_amd(ebx, ecx, edx) ||
+           is_guest_vendor_hygon(ebx, ecx, edx))
                return true;
 
        /*
@@ -3980,7 +3971,7 @@ static int em_cpuid(struct x86_emulate_ctxt *ctxt)
 
        eax = reg_read(ctxt, VCPU_REGS_RAX);
        ecx = reg_read(ctxt, VCPU_REGS_RCX);
-       ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, true);
+       ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, false);
        *reg_write(ctxt, VCPU_REGS_RAX) = eax;
        *reg_write(ctxt, VCPU_REGS_RBX) = ebx;
        *reg_write(ctxt, VCPU_REGS_RCX) = ecx;
@@ -4250,7 +4241,7 @@ static int check_cr_write(struct x86_emulate_ctxt *ctxt)
                        eax = 0x80000008;
                        ecx = 0;
                        if (ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx,
-                                                &edx, false))
+                                                &edx, true))
                                maxphyaddr = eax & 0xff;
                        else
                                maxphyaddr = 36;