diff options
-rw-r--r-- | arch/x86/kvm/emulate.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 6eaedac7cf6a..71450aca3b86 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -1892,6 +1892,17 @@ setup_syscalls_segments(struct x86_emulate_ctxt *ctxt, | |||
1892 | ss->p = 1; | 1892 | ss->p = 1; |
1893 | } | 1893 | } |
1894 | 1894 | ||
1895 | static bool vendor_intel(struct x86_emulate_ctxt *ctxt) | ||
1896 | { | ||
1897 | u32 eax, ebx, ecx, edx; | ||
1898 | |||
1899 | eax = ecx = 0; | ||
1900 | return ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx) | ||
1901 | && ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx | ||
1902 | && ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx | ||
1903 | && edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx; | ||
1904 | } | ||
1905 | |||
1895 | static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt) | 1906 | static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt) |
1896 | { | 1907 | { |
1897 | struct x86_emulate_ops *ops = ctxt->ops; | 1908 | struct x86_emulate_ops *ops = ctxt->ops; |
@@ -2008,6 +2019,14 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt) | |||
2008 | if (ctxt->mode == X86EMUL_MODE_REAL) | 2019 | if (ctxt->mode == X86EMUL_MODE_REAL) |
2009 | return emulate_gp(ctxt, 0); | 2020 | return emulate_gp(ctxt, 0); |
2010 | 2021 | ||
2022 | /* | ||
2023 | * Not recognized on AMD in compat mode (but is recognized in legacy | ||
2024 | * mode). | ||
2025 | */ | ||
2026 | if ((ctxt->mode == X86EMUL_MODE_PROT32) && (efer & EFER_LMA) | ||
2027 | && !vendor_intel(ctxt)) | ||
2028 | return emulate_ud(ctxt); | ||
2029 | |||
2011 | /* XXX sysenter/sysexit have not been tested in 64bit mode. | 2030 | /* XXX sysenter/sysexit have not been tested in 64bit mode. |
2012 | * Therefore, we inject an #UD. | 2031 | * Therefore, we inject an #UD. |
2013 | */ | 2032 | */ |