KVM: x86: fix missing checks in syscall emulation
authorStephan Bärwolf <stephan.baerwolf@tu-ilmenau.de>
Thu, 12 Jan 2012 15:43:04 +0000 (16:43 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 7 Oct 2012 21:37:21 +0000 (23:37 +0200)
commitb9a6939d5c580a3dfbcf37c0d617c7e3f181cbf1
treeebb8138f36b5092d2f17399bd8d2f9957da8213c
parenta0c74fba63e4a6ba2c94192f5b79ac3a11cd70f1
KVM: x86: fix missing checks in syscall emulation

commit c2226fc9e87ba3da060e47333657cd6616652b84 upstream

On hosts without this patch, 32bit guests will crash (and 64bit guests
may behave in a wrong way) for example by simply executing following
nasm-demo-application:

[bits 32]
global _start
SECTION .text
_start: syscall

(I tested it with winxp and linux - both always crashed)

Disassembly of section .text:

00000000 <_start>:
   0:   0f 05                   syscall

The reason seems a missing "invalid opcode"-trap (int6) for the
syscall opcode "0f05", which is not available on Intel CPUs
within non-longmodes, as also on some AMD CPUs within legacy-mode.
(depending on CPU vendor, MSR_EFER and cpuid)

Because previous mentioned OSs may not engage corresponding
syscall target-registers (STAR, LSTAR, CSTAR), they remain
NULL and (non trapping) syscalls are leading to multiple
faults and finally crashs.

Depending on the architecture (AMD or Intel) pretended by
guests, various checks according to vendor's documentation
are implemented to overcome the current issue and behave
like the CPUs physical counterparts.

[mtosatti: cleanup/beautify code]

[bwh: Backport to 2.6.32:
 - Add the prerequisite read of EFER
 - Return -1 in the error cases rather than invoking emulate_ud()
   directly
 - Adjust context]
[dannf: fix build by passing x86_emulate_ops through each call]

Signed-off-by: Stephan Baerwolf <stephan.baerwolf@tu-ilmenau.de>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Willy Tarreau <w@1wt.eu>
arch/x86/include/asm/kvm_emulate.h
arch/x86/kvm/emulate.c