]>
Commit | Line | Data |
---|---|---|
9659d8ac GKH |
1 | From stefan.bader@canonical.com Wed Apr 7 14:41:50 2010 |
2 | From: Gleb Natapov <gleb@redhat.com> | |
3 | Date: Fri, 19 Mar 2010 15:47:30 +0100 | |
4 | Subject: KVM: x86 emulator: Add Virtual-8086 mode of emulation | |
5 | To: stable@kernel.org | |
6 | Cc: Marcelo Tosatti <mtosatti@redhat.com>, Avi Kivity <avi@redhat.com>, Gleb Natapov <gleb@redhat.com> | |
7 | Message-ID: <1269010059-25309-3-git-send-email-stefan.bader@canonical.com> | |
8 | ||
9 | ||
10 | From: Gleb Natapov <gleb@redhat.com> | |
11 | ||
12 | commit a0044755679f3e761b8b95995e5f2db2b7efd0f6 upstream | |
13 | ||
14 | For some instructions CPU behaves differently for real-mode and | |
15 | virtual 8086. Let emulator know which mode cpu is in, so it will | |
16 | not poke into vcpu state directly. | |
17 | ||
18 | Signed-off-by: Gleb Natapov <gleb@redhat.com> | |
19 | Signed-off-by: Avi Kivity <avi@redhat.com> | |
20 | Signed-off-by: Stefan Bader <stefan.bader@canonical.com> | |
21 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
22 | --- | |
23 | arch/x86/include/asm/kvm_emulate.h | 1 + | |
24 | arch/x86/kvm/emulate.c | 14 +++++++------- | |
25 | arch/x86/kvm/x86.c | 3 ++- | |
26 | 3 files changed, 10 insertions(+), 8 deletions(-) | |
27 | ||
28 | --- a/arch/x86/include/asm/kvm_emulate.h | |
29 | +++ b/arch/x86/include/asm/kvm_emulate.h | |
30 | @@ -168,6 +168,7 @@ struct x86_emulate_ctxt { | |
31 | ||
32 | /* Execution mode, passed to the emulator. */ | |
33 | #define X86EMUL_MODE_REAL 0 /* Real mode. */ | |
34 | +#define X86EMUL_MODE_VM86 1 /* Virtual 8086 mode. */ | |
35 | #define X86EMUL_MODE_PROT16 2 /* 16-bit protected mode. */ | |
36 | #define X86EMUL_MODE_PROT32 4 /* 32-bit protected mode. */ | |
37 | #define X86EMUL_MODE_PROT64 8 /* 64-bit (long) mode. */ | |
38 | --- a/arch/x86/kvm/emulate.c | |
39 | +++ b/arch/x86/kvm/emulate.c | |
40 | @@ -895,6 +895,7 @@ x86_decode_insn(struct x86_emulate_ctxt | |
41 | ||
42 | switch (mode) { | |
43 | case X86EMUL_MODE_REAL: | |
44 | + case X86EMUL_MODE_VM86: | |
45 | case X86EMUL_MODE_PROT16: | |
46 | def_op_bytes = def_ad_bytes = 2; | |
47 | break; | |
48 | @@ -1453,7 +1454,7 @@ emulate_syscall(struct x86_emulate_ctxt | |
49 | ||
50 | /* syscall is not available in real mode */ | |
51 | if (c->lock_prefix || ctxt->mode == X86EMUL_MODE_REAL | |
52 | - || !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) | |
53 | + || ctxt->mode == X86EMUL_MODE_VM86) | |
54 | return -1; | |
55 | ||
56 | setup_syscalls_segments(ctxt, &cs, &ss); | |
57 | @@ -1505,9 +1506,8 @@ emulate_sysenter(struct x86_emulate_ctxt | |
58 | if (c->lock_prefix) | |
59 | return -1; | |
60 | ||
61 | - /* inject #GP if in real mode or paging is disabled */ | |
62 | - if (ctxt->mode == X86EMUL_MODE_REAL || | |
63 | - !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) { | |
64 | + /* inject #GP if in real mode */ | |
65 | + if (ctxt->mode == X86EMUL_MODE_REAL) { | |
66 | kvm_inject_gp(ctxt->vcpu, 0); | |
67 | return -1; | |
68 | } | |
69 | @@ -1571,9 +1571,9 @@ emulate_sysexit(struct x86_emulate_ctxt | |
70 | if (c->lock_prefix) | |
71 | return -1; | |
72 | ||
73 | - /* inject #GP if in real mode or paging is disabled */ | |
74 | - if (ctxt->mode == X86EMUL_MODE_REAL | |
75 | - || !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) { | |
76 | + /* inject #GP if in real mode or Virtual 8086 mode */ | |
77 | + if (ctxt->mode == X86EMUL_MODE_REAL || | |
78 | + ctxt->mode == X86EMUL_MODE_VM86) { | |
79 | kvm_inject_gp(ctxt->vcpu, 0); | |
80 | return -1; | |
81 | } | |
82 | --- a/arch/x86/kvm/x86.c | |
83 | +++ b/arch/x86/kvm/x86.c | |
84 | @@ -2828,8 +2828,9 @@ int emulate_instruction(struct kvm_vcpu | |
85 | vcpu->arch.emulate_ctxt.vcpu = vcpu; | |
86 | vcpu->arch.emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu); | |
87 | vcpu->arch.emulate_ctxt.mode = | |
88 | + (!(vcpu->arch.cr0 & X86_CR0_PE)) ? X86EMUL_MODE_REAL : | |
89 | (vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM) | |
90 | - ? X86EMUL_MODE_REAL : cs_l | |
91 | + ? X86EMUL_MODE_VM86 : cs_l | |
92 | ? X86EMUL_MODE_PROT64 : cs_db | |
93 | ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; | |
94 |