]>
Commit | Line | Data |
---|---|---|
e09414b6 GKH |
1 | From: Avi Kivity <avi@redhat.com> |
2 | Date: Tue, 24 Nov 2009 13:20:15 +0000 (+0200) | |
3 | Subject: KVM: x86 emulator: limit instructions to 15 bytes | |
4 | ||
5 | commit eb3c79e64a70fb8f7473e30fa07e89c1ecc2c9bb upstream | |
6 | ||
7 | [ <cebbert@redhat.com>: backport to 2.6.27 ] | |
8 | ||
9 | While we are never normally passed an instruction that exceeds 15 bytes, | |
10 | smp games can cause us to attempt to interpret one, which will cause | |
11 | large latencies in non-preempt hosts. | |
12 | ||
13 | Signed-off-by: Avi Kivity <avi@redhat.com> | |
14 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
15 | ||
16 | --- | |
17 | arch/x86/kvm/x86_emulate.c | 5 ++++- | |
18 | include/asm-x86/kvm_x86_emulate.h | 2 +- | |
19 | 2 files changed, 5 insertions(+), 2 deletions(-) | |
20 | ||
21 | --- a/arch/x86/kvm/x86_emulate.c | |
22 | +++ b/arch/x86/kvm/x86_emulate.c | |
23 | @@ -581,6 +581,9 @@ static int do_insn_fetch(struct x86_emul | |
24 | { | |
25 | int rc = 0; | |
26 | ||
27 | + /* x86 instructions are limited to 15 bytes. */ | |
28 | + if (eip + size - ctxt->decode.eip_orig > 15) | |
29 | + return X86EMUL_UNHANDLEABLE; | |
30 | eip += ctxt->cs_base; | |
31 | while (size--) { | |
32 | rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++); | |
33 | @@ -839,7 +842,7 @@ x86_decode_insn(struct x86_emulate_ctxt | |
34 | /* Shadow copy of register state. Committed on successful emulation. */ | |
35 | ||
36 | memset(c, 0, sizeof(struct decode_cache)); | |
37 | - c->eip = ctxt->vcpu->arch.rip; | |
38 | + c->eip = c->eip_orig = ctxt->vcpu->arch.rip; | |
39 | ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS); | |
40 | memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); | |
41 | ||
42 | --- a/include/asm-x86/kvm_x86_emulate.h | |
43 | +++ b/include/asm-x86/kvm_x86_emulate.h | |
44 | @@ -128,7 +128,7 @@ struct decode_cache { | |
45 | u8 seg_override; | |
46 | unsigned int d; | |
47 | unsigned long regs[NR_VCPU_REGS]; | |
48 | - unsigned long eip; | |
49 | + unsigned long eip, eip_orig; | |
50 | /* modrm */ | |
51 | u8 modrm; | |
52 | u8 modrm_mod; |