1842
1842
ss->present = 1;
1845
static bool syscall_is_enabled(struct x86_emulate_ctxt *ctxt,
1846
struct x86_emulate_ops *ops)
1848
u32 eax, ebx, ecx, edx;
1851
* syscall should always be enabled in longmode - so only become
1852
* vendor specific (cpuid) if other modes are active...
1854
if (ctxt->mode == X86EMUL_MODE_PROT64)
1859
if (ops->get_cpuid(ctxt->vcpu, &eax, &ebx, &ecx, &edx)) {
1861
* Intel ("GenuineIntel")
1862
* remark: Intel CPUs only support "syscall" in 64bit
1863
* longmode. Also an 64bit guest with a
1864
* 32bit compat-app running will #UD !! While this
1865
* behaviour can be fixed (by emulating) into AMD
1866
* response - CPUs of AMD can't behave like Intel.
1868
if (ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx &&
1869
ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx &&
1870
edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx)
1873
/* AMD ("AuthenticAMD") */
1874
if (ebx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx &&
1875
ecx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx &&
1876
edx == X86EMUL_CPUID_VENDOR_AuthenticAMD_edx)
1879
/* AMD ("AMDisbetter!") */
1880
if (ebx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx &&
1881
ecx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx &&
1882
edx == X86EMUL_CPUID_VENDOR_AMDisbetterI_edx)
1886
/* default: (not Intel, not AMD), apply Intel's stricter rules... */
1846
emulate_syscall(struct x86_emulate_ctxt *ctxt)
1891
emulate_syscall(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
1848
1893
struct decode_cache *c = &ctxt->decode;
1849
1894
struct kvm_segment cs, ss;
1852
1898
/* syscall is not available in real mode */
1853
1899
if (ctxt->mode == X86EMUL_MODE_REAL ||
1856
1902
return X86EMUL_PROPAGATE_FAULT;
1905
if (!(syscall_is_enabled(ctxt, ops))) {
1906
kvm_queue_exception(ctxt->vcpu, UD_VECTOR);
1907
return X86EMUL_PROPAGATE_FAULT;
1910
kvm_x86_ops->get_msr(ctxt->vcpu, MSR_EFER, &efer);
1859
1911
setup_syscalls_segments(ctxt, &cs, &ss);
1913
if (!(efer & EFER_SCE)) {
1914
kvm_queue_exception(ctxt->vcpu, UD_VECTOR);
1915
return X86EMUL_PROPAGATE_FAULT;
1861
1918
kvm_x86_ops->get_msr(ctxt->vcpu, MSR_STAR, &msr_data);
1862
1919
msr_data >>= 32;
1863
1920
cs.selector = (u16)(msr_data & 0xfffc);