diff options
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r-- | arch/x86/kvm/emulate.c | 589 |
1 files changed, 440 insertions, 149 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 1be5cd640e93..4dade6ac0827 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <asm/kvm_emulate.h> | 33 | #include <asm/kvm_emulate.h> |
34 | 34 | ||
35 | #include "mmu.h" /* for is_long_mode() */ | 35 | #include "x86.h" |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * Opcode effective-address decode tables. | 38 | * Opcode effective-address decode tables. |
@@ -75,6 +75,10 @@ | |||
75 | #define Group (1<<14) /* Bits 3:5 of modrm byte extend opcode */ | 75 | #define Group (1<<14) /* Bits 3:5 of modrm byte extend opcode */ |
76 | #define GroupDual (1<<15) /* Alternate decoding of mod == 3 */ | 76 | #define GroupDual (1<<15) /* Alternate decoding of mod == 3 */ |
77 | #define GroupMask 0xff /* Group number stored in bits 0:7 */ | 77 | #define GroupMask 0xff /* Group number stored in bits 0:7 */ |
78 | /* Misc flags */ | ||
79 | #define Lock (1<<26) /* lock prefix is allowed for the instruction */ | ||
80 | #define Priv (1<<27) /* instruction generates #GP if current CPL != 0 */ | ||
81 | #define No64 (1<<28) | ||
78 | /* Source 2 operand type */ | 82 | /* Source 2 operand type */ |
79 | #define Src2None (0<<29) | 83 | #define Src2None (0<<29) |
80 | #define Src2CL (1<<29) | 84 | #define Src2CL (1<<29) |
@@ -86,35 +90,40 @@ | |||
86 | enum { | 90 | enum { |
87 | Group1_80, Group1_81, Group1_82, Group1_83, | 91 | Group1_80, Group1_81, Group1_82, Group1_83, |
88 | Group1A, Group3_Byte, Group3, Group4, Group5, Group7, | 92 | Group1A, Group3_Byte, Group3, Group4, Group5, Group7, |
93 | Group8, Group9, | ||
89 | }; | 94 | }; |
90 | 95 | ||
91 | static u32 opcode_table[256] = { | 96 | static u32 opcode_table[256] = { |
92 | /* 0x00 - 0x07 */ | 97 | /* 0x00 - 0x07 */ |
93 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 98 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
94 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 99 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
95 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0, | 100 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, |
101 | ImplicitOps | Stack | No64, ImplicitOps | Stack | No64, | ||
96 | /* 0x08 - 0x0F */ | 102 | /* 0x08 - 0x0F */ |
97 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 103 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
98 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 104 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
99 | 0, 0, 0, 0, | 105 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, |
106 | ImplicitOps | Stack | No64, 0, | ||
100 | /* 0x10 - 0x17 */ | 107 | /* 0x10 - 0x17 */ |
101 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 108 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
102 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 109 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
103 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0, | 110 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, |
111 | ImplicitOps | Stack | No64, ImplicitOps | Stack | No64, | ||
104 | /* 0x18 - 0x1F */ | 112 | /* 0x18 - 0x1F */ |
105 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 113 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
106 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 114 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
107 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0, | 115 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, |
116 | ImplicitOps | Stack | No64, ImplicitOps | Stack | No64, | ||
108 | /* 0x20 - 0x27 */ | 117 | /* 0x20 - 0x27 */ |
109 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 118 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
110 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 119 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
111 | DstAcc | SrcImmByte, DstAcc | SrcImm, 0, 0, | 120 | DstAcc | SrcImmByte, DstAcc | SrcImm, 0, 0, |
112 | /* 0x28 - 0x2F */ | 121 | /* 0x28 - 0x2F */ |
113 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 122 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
114 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 123 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
115 | 0, 0, 0, 0, | 124 | 0, 0, 0, 0, |
116 | /* 0x30 - 0x37 */ | 125 | /* 0x30 - 0x37 */ |
117 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 126 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
118 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 127 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
119 | 0, 0, 0, 0, | 128 | 0, 0, 0, 0, |
120 | /* 0x38 - 0x3F */ | 129 | /* 0x38 - 0x3F */ |
@@ -133,7 +142,8 @@ static u32 opcode_table[256] = { | |||
133 | DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack, | 142 | DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack, |
134 | DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack, | 143 | DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack, |
135 | /* 0x60 - 0x67 */ | 144 | /* 0x60 - 0x67 */ |
136 | 0, 0, 0, DstReg | SrcMem32 | ModRM | Mov /* movsxd (x86/64) */ , | 145 | ImplicitOps | Stack | No64, ImplicitOps | Stack | No64, |
146 | 0, DstReg | SrcMem32 | ModRM | Mov /* movsxd (x86/64) */ , | ||
137 | 0, 0, 0, 0, | 147 | 0, 0, 0, 0, |
138 | /* 0x68 - 0x6F */ | 148 | /* 0x68 - 0x6F */ |
139 | SrcImm | Mov | Stack, 0, SrcImmByte | Mov | Stack, 0, | 149 | SrcImm | Mov | Stack, 0, SrcImmByte | Mov | Stack, 0, |
@@ -149,7 +159,7 @@ static u32 opcode_table[256] = { | |||
149 | Group | Group1_80, Group | Group1_81, | 159 | Group | Group1_80, Group | Group1_81, |
150 | Group | Group1_82, Group | Group1_83, | 160 | Group | Group1_82, Group | Group1_83, |
151 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 161 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, |
152 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 162 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
153 | /* 0x88 - 0x8F */ | 163 | /* 0x88 - 0x8F */ |
154 | ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov, | 164 | ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov, |
155 | ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, | 165 | ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, |
@@ -158,7 +168,7 @@ static u32 opcode_table[256] = { | |||
158 | /* 0x90 - 0x97 */ | 168 | /* 0x90 - 0x97 */ |
159 | DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, | 169 | DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, |
160 | /* 0x98 - 0x9F */ | 170 | /* 0x98 - 0x9F */ |
161 | 0, 0, SrcImm | Src2Imm16, 0, | 171 | 0, 0, SrcImm | Src2Imm16 | No64, 0, |
162 | ImplicitOps | Stack, ImplicitOps | Stack, 0, 0, | 172 | ImplicitOps | Stack, ImplicitOps | Stack, 0, 0, |
163 | /* 0xA0 - 0xA7 */ | 173 | /* 0xA0 - 0xA7 */ |
164 | ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs, | 174 | ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs, |
@@ -185,7 +195,7 @@ static u32 opcode_table[256] = { | |||
185 | ByteOp | DstMem | SrcImm | ModRM | Mov, DstMem | SrcImm | ModRM | Mov, | 195 | ByteOp | DstMem | SrcImm | ModRM | Mov, DstMem | SrcImm | ModRM | Mov, |
186 | /* 0xC8 - 0xCF */ | 196 | /* 0xC8 - 0xCF */ |
187 | 0, 0, 0, ImplicitOps | Stack, | 197 | 0, 0, 0, ImplicitOps | Stack, |
188 | ImplicitOps, SrcImmByte, ImplicitOps, ImplicitOps, | 198 | ImplicitOps, SrcImmByte, ImplicitOps | No64, ImplicitOps, |
189 | /* 0xD0 - 0xD7 */ | 199 | /* 0xD0 - 0xD7 */ |
190 | ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM, | 200 | ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM, |
191 | ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM, | 201 | ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM, |
@@ -198,12 +208,12 @@ static u32 opcode_table[256] = { | |||
198 | ByteOp | SrcImmUByte, SrcImmUByte, | 208 | ByteOp | SrcImmUByte, SrcImmUByte, |
199 | /* 0xE8 - 0xEF */ | 209 | /* 0xE8 - 0xEF */ |
200 | SrcImm | Stack, SrcImm | ImplicitOps, | 210 | SrcImm | Stack, SrcImm | ImplicitOps, |
201 | SrcImmU | Src2Imm16, SrcImmByte | ImplicitOps, | 211 | SrcImmU | Src2Imm16 | No64, SrcImmByte | ImplicitOps, |
202 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, | 212 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, |
203 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, | 213 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, |
204 | /* 0xF0 - 0xF7 */ | 214 | /* 0xF0 - 0xF7 */ |
205 | 0, 0, 0, 0, | 215 | 0, 0, 0, 0, |
206 | ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3, | 216 | ImplicitOps | Priv, ImplicitOps, Group | Group3_Byte, Group | Group3, |
207 | /* 0xF8 - 0xFF */ | 217 | /* 0xF8 - 0xFF */ |
208 | ImplicitOps, 0, ImplicitOps, ImplicitOps, | 218 | ImplicitOps, 0, ImplicitOps, ImplicitOps, |
209 | ImplicitOps, ImplicitOps, Group | Group4, Group | Group5, | 219 | ImplicitOps, ImplicitOps, Group | Group4, Group | Group5, |
@@ -211,16 +221,20 @@ static u32 opcode_table[256] = { | |||
211 | 221 | ||
212 | static u32 twobyte_table[256] = { | 222 | static u32 twobyte_table[256] = { |
213 | /* 0x00 - 0x0F */ | 223 | /* 0x00 - 0x0F */ |
214 | 0, Group | GroupDual | Group7, 0, 0, 0, ImplicitOps, ImplicitOps, 0, | 224 | 0, Group | GroupDual | Group7, 0, 0, |
215 | ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0, | 225 | 0, ImplicitOps, ImplicitOps | Priv, 0, |
226 | ImplicitOps | Priv, ImplicitOps | Priv, 0, 0, | ||
227 | 0, ImplicitOps | ModRM, 0, 0, | ||
216 | /* 0x10 - 0x1F */ | 228 | /* 0x10 - 0x1F */ |
217 | 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, | 229 | 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, |
218 | /* 0x20 - 0x2F */ | 230 | /* 0x20 - 0x2F */ |
219 | ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0, | 231 | ModRM | ImplicitOps | Priv, ModRM | Priv, |
232 | ModRM | ImplicitOps | Priv, ModRM | Priv, | ||
233 | 0, 0, 0, 0, | ||
220 | 0, 0, 0, 0, 0, 0, 0, 0, | 234 | 0, 0, 0, 0, 0, 0, 0, 0, |
221 | /* 0x30 - 0x3F */ | 235 | /* 0x30 - 0x3F */ |
222 | ImplicitOps, 0, ImplicitOps, 0, | 236 | ImplicitOps | Priv, 0, ImplicitOps | Priv, 0, |
223 | ImplicitOps, ImplicitOps, 0, 0, | 237 | ImplicitOps, ImplicitOps | Priv, 0, 0, |
224 | 0, 0, 0, 0, 0, 0, 0, 0, | 238 | 0, 0, 0, 0, 0, 0, 0, 0, |
225 | /* 0x40 - 0x47 */ | 239 | /* 0x40 - 0x47 */ |
226 | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, | 240 | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, |
@@ -244,25 +258,29 @@ static u32 twobyte_table[256] = { | |||
244 | /* 0x90 - 0x9F */ | 258 | /* 0x90 - 0x9F */ |
245 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 259 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
246 | /* 0xA0 - 0xA7 */ | 260 | /* 0xA0 - 0xA7 */ |
247 | 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, | 261 | ImplicitOps | Stack, ImplicitOps | Stack, |
262 | 0, DstMem | SrcReg | ModRM | BitOp, | ||
248 | DstMem | SrcReg | Src2ImmByte | ModRM, | 263 | DstMem | SrcReg | Src2ImmByte | ModRM, |
249 | DstMem | SrcReg | Src2CL | ModRM, 0, 0, | 264 | DstMem | SrcReg | Src2CL | ModRM, 0, 0, |
250 | /* 0xA8 - 0xAF */ | 265 | /* 0xA8 - 0xAF */ |
251 | 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, | 266 | ImplicitOps | Stack, ImplicitOps | Stack, |
267 | 0, DstMem | SrcReg | ModRM | BitOp | Lock, | ||
252 | DstMem | SrcReg | Src2ImmByte | ModRM, | 268 | DstMem | SrcReg | Src2ImmByte | ModRM, |
253 | DstMem | SrcReg | Src2CL | ModRM, | 269 | DstMem | SrcReg | Src2CL | ModRM, |
254 | ModRM, 0, | 270 | ModRM, 0, |
255 | /* 0xB0 - 0xB7 */ | 271 | /* 0xB0 - 0xB7 */ |
256 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 0, | 272 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
257 | DstMem | SrcReg | ModRM | BitOp, | 273 | 0, DstMem | SrcReg | ModRM | BitOp | Lock, |
258 | 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, | 274 | 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, |
259 | DstReg | SrcMem16 | ModRM | Mov, | 275 | DstReg | SrcMem16 | ModRM | Mov, |
260 | /* 0xB8 - 0xBF */ | 276 | /* 0xB8 - 0xBF */ |
261 | 0, 0, DstMem | SrcImmByte | ModRM, DstMem | SrcReg | ModRM | BitOp, | 277 | 0, 0, |
278 | Group | Group8, DstMem | SrcReg | ModRM | BitOp | Lock, | ||
262 | 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, | 279 | 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, |
263 | DstReg | SrcMem16 | ModRM | Mov, | 280 | DstReg | SrcMem16 | ModRM | Mov, |
264 | /* 0xC0 - 0xCF */ | 281 | /* 0xC0 - 0xCF */ |
265 | 0, 0, 0, DstMem | SrcReg | ModRM | Mov, 0, 0, 0, ImplicitOps | ModRM, | 282 | 0, 0, 0, DstMem | SrcReg | ModRM | Mov, |
283 | 0, 0, 0, Group | GroupDual | Group9, | ||
266 | 0, 0, 0, 0, 0, 0, 0, 0, | 284 | 0, 0, 0, 0, 0, 0, 0, 0, |
267 | /* 0xD0 - 0xDF */ | 285 | /* 0xD0 - 0xDF */ |
268 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 286 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
@@ -274,25 +292,41 @@ static u32 twobyte_table[256] = { | |||
274 | 292 | ||
275 | static u32 group_table[] = { | 293 | static u32 group_table[] = { |
276 | [Group1_80*8] = | 294 | [Group1_80*8] = |
277 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, | 295 | ByteOp | DstMem | SrcImm | ModRM | Lock, |
278 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, | 296 | ByteOp | DstMem | SrcImm | ModRM | Lock, |
279 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, | 297 | ByteOp | DstMem | SrcImm | ModRM | Lock, |
280 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, | 298 | ByteOp | DstMem | SrcImm | ModRM | Lock, |
299 | ByteOp | DstMem | SrcImm | ModRM | Lock, | ||
300 | ByteOp | DstMem | SrcImm | ModRM | Lock, | ||
301 | ByteOp | DstMem | SrcImm | ModRM | Lock, | ||
302 | ByteOp | DstMem | SrcImm | ModRM, | ||
281 | [Group1_81*8] = | 303 | [Group1_81*8] = |
282 | DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM, | 304 | DstMem | SrcImm | ModRM | Lock, |
283 | DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM, | 305 | DstMem | SrcImm | ModRM | Lock, |
284 | DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM, | 306 | DstMem | SrcImm | ModRM | Lock, |
285 | DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM, | 307 | DstMem | SrcImm | ModRM | Lock, |
308 | DstMem | SrcImm | ModRM | Lock, | ||
309 | DstMem | SrcImm | ModRM | Lock, | ||
310 | DstMem | SrcImm | ModRM | Lock, | ||
311 | DstMem | SrcImm | ModRM, | ||
286 | [Group1_82*8] = | 312 | [Group1_82*8] = |
287 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, | 313 | ByteOp | DstMem | SrcImm | ModRM | No64 | Lock, |
288 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, | 314 | ByteOp | DstMem | SrcImm | ModRM | No64 | Lock, |
289 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, | 315 | ByteOp | DstMem | SrcImm | ModRM | No64 | Lock, |
290 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, | 316 | ByteOp | DstMem | SrcImm | ModRM | No64 | Lock, |
317 | ByteOp | DstMem | SrcImm | ModRM | No64 | Lock, | ||
318 | ByteOp | DstMem | SrcImm | ModRM | No64 | Lock, | ||
319 | ByteOp | DstMem | SrcImm | ModRM | No64 | Lock, | ||
320 | ByteOp | DstMem | SrcImm | ModRM | No64, | ||
291 | [Group1_83*8] = | 321 | [Group1_83*8] = |
292 | DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM, | 322 | DstMem | SrcImmByte | ModRM | Lock, |
293 | DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM, | 323 | DstMem | SrcImmByte | ModRM | Lock, |
294 | DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM, | 324 | DstMem | SrcImmByte | ModRM | Lock, |
295 | DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM, | 325 | DstMem | SrcImmByte | ModRM | Lock, |
326 | DstMem | SrcImmByte | ModRM | Lock, | ||
327 | DstMem | SrcImmByte | ModRM | Lock, | ||
328 | DstMem | SrcImmByte | ModRM | Lock, | ||
329 | DstMem | SrcImmByte | ModRM, | ||
296 | [Group1A*8] = | 330 | [Group1A*8] = |
297 | DstMem | SrcNone | ModRM | Mov | Stack, 0, 0, 0, 0, 0, 0, 0, | 331 | DstMem | SrcNone | ModRM | Mov | Stack, 0, 0, 0, 0, 0, 0, 0, |
298 | [Group3_Byte*8] = | 332 | [Group3_Byte*8] = |
@@ -311,24 +345,39 @@ static u32 group_table[] = { | |||
311 | SrcMem | ModRM | Stack, 0, | 345 | SrcMem | ModRM | Stack, 0, |
312 | SrcMem | ModRM | Stack, 0, SrcMem | ModRM | Stack, 0, | 346 | SrcMem | ModRM | Stack, 0, SrcMem | ModRM | Stack, 0, |
313 | [Group7*8] = | 347 | [Group7*8] = |
314 | 0, 0, ModRM | SrcMem, ModRM | SrcMem, | 348 | 0, 0, ModRM | SrcMem | Priv, ModRM | SrcMem | Priv, |
315 | SrcNone | ModRM | DstMem | Mov, 0, | 349 | SrcNone | ModRM | DstMem | Mov, 0, |
316 | SrcMem16 | ModRM | Mov, SrcMem | ModRM | ByteOp, | 350 | SrcMem16 | ModRM | Mov | Priv, SrcMem | ModRM | ByteOp | Priv, |
351 | [Group8*8] = | ||
352 | 0, 0, 0, 0, | ||
353 | DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM | Lock, | ||
354 | DstMem | SrcImmByte | ModRM | Lock, DstMem | SrcImmByte | ModRM | Lock, | ||
355 | [Group9*8] = | ||
356 | 0, ImplicitOps | ModRM | Lock, 0, 0, 0, 0, 0, 0, | ||
317 | }; | 357 | }; |
318 | 358 | ||
319 | static u32 group2_table[] = { | 359 | static u32 group2_table[] = { |
320 | [Group7*8] = | 360 | [Group7*8] = |
321 | SrcNone | ModRM, 0, 0, SrcNone | ModRM, | 361 | SrcNone | ModRM | Priv, 0, 0, SrcNone | ModRM, |
322 | SrcNone | ModRM | DstMem | Mov, 0, | 362 | SrcNone | ModRM | DstMem | Mov, 0, |
323 | SrcMem16 | ModRM | Mov, 0, | 363 | SrcMem16 | ModRM | Mov, 0, |
364 | [Group9*8] = | ||
365 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
324 | }; | 366 | }; |
325 | 367 | ||
326 | /* EFLAGS bit definitions. */ | 368 | /* EFLAGS bit definitions. */ |
369 | #define EFLG_ID (1<<21) | ||
370 | #define EFLG_VIP (1<<20) | ||
371 | #define EFLG_VIF (1<<19) | ||
372 | #define EFLG_AC (1<<18) | ||
327 | #define EFLG_VM (1<<17) | 373 | #define EFLG_VM (1<<17) |
328 | #define EFLG_RF (1<<16) | 374 | #define EFLG_RF (1<<16) |
375 | #define EFLG_IOPL (3<<12) | ||
376 | #define EFLG_NT (1<<14) | ||
329 | #define EFLG_OF (1<<11) | 377 | #define EFLG_OF (1<<11) |
330 | #define EFLG_DF (1<<10) | 378 | #define EFLG_DF (1<<10) |
331 | #define EFLG_IF (1<<9) | 379 | #define EFLG_IF (1<<9) |
380 | #define EFLG_TF (1<<8) | ||
332 | #define EFLG_SF (1<<7) | 381 | #define EFLG_SF (1<<7) |
333 | #define EFLG_ZF (1<<6) | 382 | #define EFLG_ZF (1<<6) |
334 | #define EFLG_AF (1<<4) | 383 | #define EFLG_AF (1<<4) |
@@ -597,7 +646,7 @@ static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, | |||
597 | 646 | ||
598 | if (linear < fc->start || linear >= fc->end) { | 647 | if (linear < fc->start || linear >= fc->end) { |
599 | size = min(15UL, PAGE_SIZE - offset_in_page(linear)); | 648 | size = min(15UL, PAGE_SIZE - offset_in_page(linear)); |
600 | rc = ops->read_std(linear, fc->data, size, ctxt->vcpu); | 649 | rc = ops->fetch(linear, fc->data, size, ctxt->vcpu, NULL); |
601 | if (rc) | 650 | if (rc) |
602 | return rc; | 651 | return rc; |
603 | fc->start = linear; | 652 | fc->start = linear; |
@@ -613,6 +662,9 @@ static int do_insn_fetch(struct x86_emulate_ctxt *ctxt, | |||
613 | { | 662 | { |
614 | int rc = 0; | 663 | int rc = 0; |
615 | 664 | ||
665 | /* x86 instructions are limited to 15 bytes. */ | ||
666 | if (eip + size - ctxt->decode.eip_orig > 15) | ||
667 | return X86EMUL_UNHANDLEABLE; | ||
616 | eip += ctxt->cs_base; | 668 | eip += ctxt->cs_base; |
617 | while (size--) { | 669 | while (size--) { |
618 | rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++); | 670 | rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++); |
@@ -649,11 +701,11 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt, | |||
649 | op_bytes = 3; | 701 | op_bytes = 3; |
650 | *address = 0; | 702 | *address = 0; |
651 | rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2, | 703 | rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2, |
652 | ctxt->vcpu); | 704 | ctxt->vcpu, NULL); |
653 | if (rc) | 705 | if (rc) |
654 | return rc; | 706 | return rc; |
655 | rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes, | 707 | rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes, |
656 | ctxt->vcpu); | 708 | ctxt->vcpu, NULL); |
657 | return rc; | 709 | return rc; |
658 | } | 710 | } |
659 | 711 | ||
@@ -871,12 +923,13 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
871 | /* Shadow copy of register state. Committed on successful emulation. */ | 923 | /* Shadow copy of register state. Committed on successful emulation. */ |
872 | 924 | ||
873 | memset(c, 0, sizeof(struct decode_cache)); | 925 | memset(c, 0, sizeof(struct decode_cache)); |
874 | c->eip = kvm_rip_read(ctxt->vcpu); | 926 | c->eip = c->eip_orig = kvm_rip_read(ctxt->vcpu); |
875 | ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS); | 927 | ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS); |
876 | memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); | 928 | memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); |
877 | 929 | ||
878 | switch (mode) { | 930 | switch (mode) { |
879 | case X86EMUL_MODE_REAL: | 931 | case X86EMUL_MODE_REAL: |
932 | case X86EMUL_MODE_VM86: | ||
880 | case X86EMUL_MODE_PROT16: | 933 | case X86EMUL_MODE_PROT16: |
881 | def_op_bytes = def_ad_bytes = 2; | 934 | def_op_bytes = def_ad_bytes = 2; |
882 | break; | 935 | break; |
@@ -962,6 +1015,11 @@ done_prefixes: | |||
962 | } | 1015 | } |
963 | } | 1016 | } |
964 | 1017 | ||
1018 | if (mode == X86EMUL_MODE_PROT64 && (c->d & No64)) { | ||
1019 | kvm_report_emulation_failure(ctxt->vcpu, "invalid x86/64 instruction"); | ||
1020 | return -1; | ||
1021 | } | ||
1022 | |||
965 | if (c->d & Group) { | 1023 | if (c->d & Group) { |
966 | group = c->d & GroupMask; | 1024 | group = c->d & GroupMask; |
967 | c->modrm = insn_fetch(u8, 1, c->eip); | 1025 | c->modrm = insn_fetch(u8, 1, c->eip); |
@@ -1179,13 +1237,119 @@ static int emulate_pop(struct x86_emulate_ctxt *ctxt, | |||
1179 | rc = ops->read_emulated(register_address(c, ss_base(ctxt), | 1237 | rc = ops->read_emulated(register_address(c, ss_base(ctxt), |
1180 | c->regs[VCPU_REGS_RSP]), | 1238 | c->regs[VCPU_REGS_RSP]), |
1181 | dest, len, ctxt->vcpu); | 1239 | dest, len, ctxt->vcpu); |
1182 | if (rc != 0) | 1240 | if (rc != X86EMUL_CONTINUE) |
1183 | return rc; | 1241 | return rc; |
1184 | 1242 | ||
1185 | register_address_increment(c, &c->regs[VCPU_REGS_RSP], len); | 1243 | register_address_increment(c, &c->regs[VCPU_REGS_RSP], len); |
1186 | return rc; | 1244 | return rc; |
1187 | } | 1245 | } |
1188 | 1246 | ||
1247 | static int emulate_popf(struct x86_emulate_ctxt *ctxt, | ||
1248 | struct x86_emulate_ops *ops, | ||
1249 | void *dest, int len) | ||
1250 | { | ||
1251 | int rc; | ||
1252 | unsigned long val, change_mask; | ||
1253 | int iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; | ||
1254 | int cpl = kvm_x86_ops->get_cpl(ctxt->vcpu); | ||
1255 | |||
1256 | rc = emulate_pop(ctxt, ops, &val, len); | ||
1257 | if (rc != X86EMUL_CONTINUE) | ||
1258 | return rc; | ||
1259 | |||
1260 | change_mask = EFLG_CF | EFLG_PF | EFLG_AF | EFLG_ZF | EFLG_SF | EFLG_OF | ||
1261 | | EFLG_TF | EFLG_DF | EFLG_NT | EFLG_RF | EFLG_AC | EFLG_ID; | ||
1262 | |||
1263 | switch(ctxt->mode) { | ||
1264 | case X86EMUL_MODE_PROT64: | ||
1265 | case X86EMUL_MODE_PROT32: | ||
1266 | case X86EMUL_MODE_PROT16: | ||
1267 | if (cpl == 0) | ||
1268 | change_mask |= EFLG_IOPL; | ||
1269 | if (cpl <= iopl) | ||
1270 | change_mask |= EFLG_IF; | ||
1271 | break; | ||
1272 | case X86EMUL_MODE_VM86: | ||
1273 | if (iopl < 3) { | ||
1274 | kvm_inject_gp(ctxt->vcpu, 0); | ||
1275 | return X86EMUL_PROPAGATE_FAULT; | ||
1276 | } | ||
1277 | change_mask |= EFLG_IF; | ||
1278 | break; | ||
1279 | default: /* real mode */ | ||
1280 | change_mask |= (EFLG_IOPL | EFLG_IF); | ||
1281 | break; | ||
1282 | } | ||
1283 | |||
1284 | *(unsigned long *)dest = | ||
1285 | (ctxt->eflags & ~change_mask) | (val & change_mask); | ||
1286 | |||
1287 | return rc; | ||
1288 | } | ||
1289 | |||
1290 | static void emulate_push_sreg(struct x86_emulate_ctxt *ctxt, int seg) | ||
1291 | { | ||
1292 | struct decode_cache *c = &ctxt->decode; | ||
1293 | struct kvm_segment segment; | ||
1294 | |||
1295 | kvm_x86_ops->get_segment(ctxt->vcpu, &segment, seg); | ||
1296 | |||
1297 | c->src.val = segment.selector; | ||
1298 | emulate_push(ctxt); | ||
1299 | } | ||
1300 | |||
1301 | static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt, | ||
1302 | struct x86_emulate_ops *ops, int seg) | ||
1303 | { | ||
1304 | struct decode_cache *c = &ctxt->decode; | ||
1305 | unsigned long selector; | ||
1306 | int rc; | ||
1307 | |||
1308 | rc = emulate_pop(ctxt, ops, &selector, c->op_bytes); | ||
1309 | if (rc != 0) | ||
1310 | return rc; | ||
1311 | |||
1312 | rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)selector, seg); | ||
1313 | return rc; | ||
1314 | } | ||
1315 | |||
1316 | static void emulate_pusha(struct x86_emulate_ctxt *ctxt) | ||
1317 | { | ||
1318 | struct decode_cache *c = &ctxt->decode; | ||
1319 | unsigned long old_esp = c->regs[VCPU_REGS_RSP]; | ||
1320 | int reg = VCPU_REGS_RAX; | ||
1321 | |||
1322 | while (reg <= VCPU_REGS_RDI) { | ||
1323 | (reg == VCPU_REGS_RSP) ? | ||
1324 | (c->src.val = old_esp) : (c->src.val = c->regs[reg]); | ||
1325 | |||
1326 | emulate_push(ctxt); | ||
1327 | ++reg; | ||
1328 | } | ||
1329 | } | ||
1330 | |||
1331 | static int emulate_popa(struct x86_emulate_ctxt *ctxt, | ||
1332 | struct x86_emulate_ops *ops) | ||
1333 | { | ||
1334 | struct decode_cache *c = &ctxt->decode; | ||
1335 | int rc = 0; | ||
1336 | int reg = VCPU_REGS_RDI; | ||
1337 | |||
1338 | while (reg >= VCPU_REGS_RAX) { | ||
1339 | if (reg == VCPU_REGS_RSP) { | ||
1340 | register_address_increment(c, &c->regs[VCPU_REGS_RSP], | ||
1341 | c->op_bytes); | ||
1342 | --reg; | ||
1343 | } | ||
1344 | |||
1345 | rc = emulate_pop(ctxt, ops, &c->regs[reg], c->op_bytes); | ||
1346 | if (rc != 0) | ||
1347 | break; | ||
1348 | --reg; | ||
1349 | } | ||
1350 | return rc; | ||
1351 | } | ||
1352 | |||
1189 | static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt, | 1353 | static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt, |
1190 | struct x86_emulate_ops *ops) | 1354 | struct x86_emulate_ops *ops) |
1191 | { | 1355 | { |
@@ -1290,7 +1454,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, | |||
1290 | int rc; | 1454 | int rc; |
1291 | 1455 | ||
1292 | rc = ops->read_emulated(memop, &old, 8, ctxt->vcpu); | 1456 | rc = ops->read_emulated(memop, &old, 8, ctxt->vcpu); |
1293 | if (rc != 0) | 1457 | if (rc != X86EMUL_CONTINUE) |
1294 | return rc; | 1458 | return rc; |
1295 | 1459 | ||
1296 | if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) || | 1460 | if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) || |
@@ -1305,7 +1469,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, | |||
1305 | (u32) c->regs[VCPU_REGS_RBX]; | 1469 | (u32) c->regs[VCPU_REGS_RBX]; |
1306 | 1470 | ||
1307 | rc = ops->cmpxchg_emulated(memop, &old, &new, 8, ctxt->vcpu); | 1471 | rc = ops->cmpxchg_emulated(memop, &old, &new, 8, ctxt->vcpu); |
1308 | if (rc != 0) | 1472 | if (rc != X86EMUL_CONTINUE) |
1309 | return rc; | 1473 | return rc; |
1310 | ctxt->eflags |= EFLG_ZF; | 1474 | ctxt->eflags |= EFLG_ZF; |
1311 | } | 1475 | } |
@@ -1327,7 +1491,7 @@ static int emulate_ret_far(struct x86_emulate_ctxt *ctxt, | |||
1327 | rc = emulate_pop(ctxt, ops, &cs, c->op_bytes); | 1491 | rc = emulate_pop(ctxt, ops, &cs, c->op_bytes); |
1328 | if (rc) | 1492 | if (rc) |
1329 | return rc; | 1493 | return rc; |
1330 | rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)cs, 1, VCPU_SREG_CS); | 1494 | rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)cs, VCPU_SREG_CS); |
1331 | return rc; | 1495 | return rc; |
1332 | } | 1496 | } |
1333 | 1497 | ||
@@ -1371,7 +1535,7 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt, | |||
1371 | &c->dst.val, | 1535 | &c->dst.val, |
1372 | c->dst.bytes, | 1536 | c->dst.bytes, |
1373 | ctxt->vcpu); | 1537 | ctxt->vcpu); |
1374 | if (rc != 0) | 1538 | if (rc != X86EMUL_CONTINUE) |
1375 | return rc; | 1539 | return rc; |
1376 | break; | 1540 | break; |
1377 | case OP_NONE: | 1541 | case OP_NONE: |
@@ -1434,9 +1598,8 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt) | |||
1434 | u64 msr_data; | 1598 | u64 msr_data; |
1435 | 1599 | ||
1436 | /* syscall is not available in real mode */ | 1600 | /* syscall is not available in real mode */ |
1437 | if (c->lock_prefix || ctxt->mode == X86EMUL_MODE_REAL | 1601 | if (ctxt->mode == X86EMUL_MODE_REAL || ctxt->mode == X86EMUL_MODE_VM86) |
1438 | || !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) | 1602 | return X86EMUL_UNHANDLEABLE; |
1439 | return -1; | ||
1440 | 1603 | ||
1441 | setup_syscalls_segments(ctxt, &cs, &ss); | 1604 | setup_syscalls_segments(ctxt, &cs, &ss); |
1442 | 1605 | ||
@@ -1473,7 +1636,7 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt) | |||
1473 | ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF); | 1636 | ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF); |
1474 | } | 1637 | } |
1475 | 1638 | ||
1476 | return 0; | 1639 | return X86EMUL_CONTINUE; |
1477 | } | 1640 | } |
1478 | 1641 | ||
1479 | static int | 1642 | static int |
@@ -1483,22 +1646,17 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt) | |||
1483 | struct kvm_segment cs, ss; | 1646 | struct kvm_segment cs, ss; |
1484 | u64 msr_data; | 1647 | u64 msr_data; |
1485 | 1648 | ||
1486 | /* inject #UD if LOCK prefix is used */ | 1649 | /* inject #GP if in real mode */ |
1487 | if (c->lock_prefix) | 1650 | if (ctxt->mode == X86EMUL_MODE_REAL) { |
1488 | return -1; | ||
1489 | |||
1490 | /* inject #GP if in real mode or paging is disabled */ | ||
1491 | if (ctxt->mode == X86EMUL_MODE_REAL || | ||
1492 | !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) { | ||
1493 | kvm_inject_gp(ctxt->vcpu, 0); | 1651 | kvm_inject_gp(ctxt->vcpu, 0); |
1494 | return -1; | 1652 | return X86EMUL_UNHANDLEABLE; |
1495 | } | 1653 | } |
1496 | 1654 | ||
1497 | /* XXX sysenter/sysexit have not been tested in 64bit mode. | 1655 | /* XXX sysenter/sysexit have not been tested in 64bit mode. |
1498 | * Therefore, we inject an #UD. | 1656 | * Therefore, we inject an #UD. |
1499 | */ | 1657 | */ |
1500 | if (ctxt->mode == X86EMUL_MODE_PROT64) | 1658 | if (ctxt->mode == X86EMUL_MODE_PROT64) |
1501 | return -1; | 1659 | return X86EMUL_UNHANDLEABLE; |
1502 | 1660 | ||
1503 | setup_syscalls_segments(ctxt, &cs, &ss); | 1661 | setup_syscalls_segments(ctxt, &cs, &ss); |
1504 | 1662 | ||
@@ -1507,13 +1665,13 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt) | |||
1507 | case X86EMUL_MODE_PROT32: | 1665 | case X86EMUL_MODE_PROT32: |
1508 | if ((msr_data & 0xfffc) == 0x0) { | 1666 | if ((msr_data & 0xfffc) == 0x0) { |
1509 | kvm_inject_gp(ctxt->vcpu, 0); | 1667 | kvm_inject_gp(ctxt->vcpu, 0); |
1510 | return -1; | 1668 | return X86EMUL_PROPAGATE_FAULT; |
1511 | } | 1669 | } |
1512 | break; | 1670 | break; |
1513 | case X86EMUL_MODE_PROT64: | 1671 | case X86EMUL_MODE_PROT64: |
1514 | if (msr_data == 0x0) { | 1672 | if (msr_data == 0x0) { |
1515 | kvm_inject_gp(ctxt->vcpu, 0); | 1673 | kvm_inject_gp(ctxt->vcpu, 0); |
1516 | return -1; | 1674 | return X86EMUL_PROPAGATE_FAULT; |
1517 | } | 1675 | } |
1518 | break; | 1676 | break; |
1519 | } | 1677 | } |
@@ -1538,7 +1696,7 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt) | |||
1538 | kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_ESP, &msr_data); | 1696 | kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_ESP, &msr_data); |
1539 | c->regs[VCPU_REGS_RSP] = msr_data; | 1697 | c->regs[VCPU_REGS_RSP] = msr_data; |
1540 | 1698 | ||
1541 | return 0; | 1699 | return X86EMUL_CONTINUE; |
1542 | } | 1700 | } |
1543 | 1701 | ||
1544 | static int | 1702 | static int |
@@ -1549,21 +1707,11 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt) | |||
1549 | u64 msr_data; | 1707 | u64 msr_data; |
1550 | int usermode; | 1708 | int usermode; |
1551 | 1709 | ||
1552 | /* inject #UD if LOCK prefix is used */ | 1710 | /* inject #GP if in real mode or Virtual 8086 mode */ |
1553 | if (c->lock_prefix) | 1711 | if (ctxt->mode == X86EMUL_MODE_REAL || |
1554 | return -1; | 1712 | ctxt->mode == X86EMUL_MODE_VM86) { |
1555 | |||
1556 | /* inject #GP if in real mode or paging is disabled */ | ||
1557 | if (ctxt->mode == X86EMUL_MODE_REAL | ||
1558 | || !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) { | ||
1559 | kvm_inject_gp(ctxt->vcpu, 0); | ||
1560 | return -1; | ||
1561 | } | ||
1562 | |||
1563 | /* sysexit must be called from CPL 0 */ | ||
1564 | if (kvm_x86_ops->get_cpl(ctxt->vcpu) != 0) { | ||
1565 | kvm_inject_gp(ctxt->vcpu, 0); | 1713 | kvm_inject_gp(ctxt->vcpu, 0); |
1566 | return -1; | 1714 | return X86EMUL_UNHANDLEABLE; |
1567 | } | 1715 | } |
1568 | 1716 | ||
1569 | setup_syscalls_segments(ctxt, &cs, &ss); | 1717 | setup_syscalls_segments(ctxt, &cs, &ss); |
@@ -1581,7 +1729,7 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt) | |||
1581 | cs.selector = (u16)(msr_data + 16); | 1729 | cs.selector = (u16)(msr_data + 16); |
1582 | if ((msr_data & 0xfffc) == 0x0) { | 1730 | if ((msr_data & 0xfffc) == 0x0) { |
1583 | kvm_inject_gp(ctxt->vcpu, 0); | 1731 | kvm_inject_gp(ctxt->vcpu, 0); |
1584 | return -1; | 1732 | return X86EMUL_PROPAGATE_FAULT; |
1585 | } | 1733 | } |
1586 | ss.selector = (u16)(msr_data + 24); | 1734 | ss.selector = (u16)(msr_data + 24); |
1587 | break; | 1735 | break; |
@@ -1589,7 +1737,7 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt) | |||
1589 | cs.selector = (u16)(msr_data + 32); | 1737 | cs.selector = (u16)(msr_data + 32); |
1590 | if (msr_data == 0x0) { | 1738 | if (msr_data == 0x0) { |
1591 | kvm_inject_gp(ctxt->vcpu, 0); | 1739 | kvm_inject_gp(ctxt->vcpu, 0); |
1592 | return -1; | 1740 | return X86EMUL_PROPAGATE_FAULT; |
1593 | } | 1741 | } |
1594 | ss.selector = cs.selector + 8; | 1742 | ss.selector = cs.selector + 8; |
1595 | cs.db = 0; | 1743 | cs.db = 0; |
@@ -1605,7 +1753,58 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt) | |||
1605 | c->eip = ctxt->vcpu->arch.regs[VCPU_REGS_RDX]; | 1753 | c->eip = ctxt->vcpu->arch.regs[VCPU_REGS_RDX]; |
1606 | c->regs[VCPU_REGS_RSP] = ctxt->vcpu->arch.regs[VCPU_REGS_RCX]; | 1754 | c->regs[VCPU_REGS_RSP] = ctxt->vcpu->arch.regs[VCPU_REGS_RCX]; |
1607 | 1755 | ||
1608 | return 0; | 1756 | return X86EMUL_CONTINUE; |
1757 | } | ||
1758 | |||
1759 | static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt) | ||
1760 | { | ||
1761 | int iopl; | ||
1762 | if (ctxt->mode == X86EMUL_MODE_REAL) | ||
1763 | return false; | ||
1764 | if (ctxt->mode == X86EMUL_MODE_VM86) | ||
1765 | return true; | ||
1766 | iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; | ||
1767 | return kvm_x86_ops->get_cpl(ctxt->vcpu) > iopl; | ||
1768 | } | ||
1769 | |||
1770 | static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt, | ||
1771 | struct x86_emulate_ops *ops, | ||
1772 | u16 port, u16 len) | ||
1773 | { | ||
1774 | struct kvm_segment tr_seg; | ||
1775 | int r; | ||
1776 | u16 io_bitmap_ptr; | ||
1777 | u8 perm, bit_idx = port & 0x7; | ||
1778 | unsigned mask = (1 << len) - 1; | ||
1779 | |||
1780 | kvm_get_segment(ctxt->vcpu, &tr_seg, VCPU_SREG_TR); | ||
1781 | if (tr_seg.unusable) | ||
1782 | return false; | ||
1783 | if (tr_seg.limit < 103) | ||
1784 | return false; | ||
1785 | r = ops->read_std(tr_seg.base + 102, &io_bitmap_ptr, 2, ctxt->vcpu, | ||
1786 | NULL); | ||
1787 | if (r != X86EMUL_CONTINUE) | ||
1788 | return false; | ||
1789 | if (io_bitmap_ptr + port/8 > tr_seg.limit) | ||
1790 | return false; | ||
1791 | r = ops->read_std(tr_seg.base + io_bitmap_ptr + port/8, &perm, 1, | ||
1792 | ctxt->vcpu, NULL); | ||
1793 | if (r != X86EMUL_CONTINUE) | ||
1794 | return false; | ||
1795 | if ((perm >> bit_idx) & mask) | ||
1796 | return false; | ||
1797 | return true; | ||
1798 | } | ||
1799 | |||
1800 | static bool emulator_io_permited(struct x86_emulate_ctxt *ctxt, | ||
1801 | struct x86_emulate_ops *ops, | ||
1802 | u16 port, u16 len) | ||
1803 | { | ||
1804 | if (emulator_bad_iopl(ctxt)) | ||
1805 | if (!emulator_io_port_access_allowed(ctxt, ops, port, len)) | ||
1806 | return false; | ||
1807 | return true; | ||
1609 | } | 1808 | } |
1610 | 1809 | ||
1611 | int | 1810 | int |
@@ -1629,6 +1828,18 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1629 | memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); | 1828 | memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); |
1630 | saved_eip = c->eip; | 1829 | saved_eip = c->eip; |
1631 | 1830 | ||
1831 | /* LOCK prefix is allowed only with some instructions */ | ||
1832 | if (c->lock_prefix && !(c->d & Lock)) { | ||
1833 | kvm_queue_exception(ctxt->vcpu, UD_VECTOR); | ||
1834 | goto done; | ||
1835 | } | ||
1836 | |||
1837 | /* Privileged instruction can be executed only in CPL=0 */ | ||
1838 | if ((c->d & Priv) && kvm_x86_ops->get_cpl(ctxt->vcpu)) { | ||
1839 | kvm_inject_gp(ctxt->vcpu, 0); | ||
1840 | goto done; | ||
1841 | } | ||
1842 | |||
1632 | if (((c->d & ModRM) && (c->modrm_mod != 3)) || (c->d & MemAbs)) | 1843 | if (((c->d & ModRM) && (c->modrm_mod != 3)) || (c->d & MemAbs)) |
1633 | memop = c->modrm_ea; | 1844 | memop = c->modrm_ea; |
1634 | 1845 | ||
@@ -1669,7 +1880,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1669 | &c->src.val, | 1880 | &c->src.val, |
1670 | c->src.bytes, | 1881 | c->src.bytes, |
1671 | ctxt->vcpu); | 1882 | ctxt->vcpu); |
1672 | if (rc != 0) | 1883 | if (rc != X86EMUL_CONTINUE) |
1673 | goto done; | 1884 | goto done; |
1674 | c->src.orig_val = c->src.val; | 1885 | c->src.orig_val = c->src.val; |
1675 | } | 1886 | } |
@@ -1688,12 +1899,15 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1688 | c->dst.ptr = (void *)c->dst.ptr + | 1899 | c->dst.ptr = (void *)c->dst.ptr + |
1689 | (c->src.val & mask) / 8; | 1900 | (c->src.val & mask) / 8; |
1690 | } | 1901 | } |
1691 | if (!(c->d & Mov) && | 1902 | if (!(c->d & Mov)) { |
1692 | /* optimisation - avoid slow emulated read */ | 1903 | /* optimisation - avoid slow emulated read */ |
1693 | ((rc = ops->read_emulated((unsigned long)c->dst.ptr, | 1904 | rc = ops->read_emulated((unsigned long)c->dst.ptr, |
1694 | &c->dst.val, | 1905 | &c->dst.val, |
1695 | c->dst.bytes, ctxt->vcpu)) != 0)) | 1906 | c->dst.bytes, |
1696 | goto done; | 1907 | ctxt->vcpu); |
1908 | if (rc != X86EMUL_CONTINUE) | ||
1909 | goto done; | ||
1910 | } | ||
1697 | } | 1911 | } |
1698 | c->dst.orig_val = c->dst.val; | 1912 | c->dst.orig_val = c->dst.val; |
1699 | 1913 | ||
@@ -1707,18 +1921,45 @@ special_insn: | |||
1707 | add: /* add */ | 1921 | add: /* add */ |
1708 | emulate_2op_SrcV("add", c->src, c->dst, ctxt->eflags); | 1922 | emulate_2op_SrcV("add", c->src, c->dst, ctxt->eflags); |
1709 | break; | 1923 | break; |
1924 | case 0x06: /* push es */ | ||
1925 | emulate_push_sreg(ctxt, VCPU_SREG_ES); | ||
1926 | break; | ||
1927 | case 0x07: /* pop es */ | ||
1928 | rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_ES); | ||
1929 | if (rc != 0) | ||
1930 | goto done; | ||
1931 | break; | ||
1710 | case 0x08 ... 0x0d: | 1932 | case 0x08 ... 0x0d: |
1711 | or: /* or */ | 1933 | or: /* or */ |
1712 | emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags); | 1934 | emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags); |
1713 | break; | 1935 | break; |
1936 | case 0x0e: /* push cs */ | ||
1937 | emulate_push_sreg(ctxt, VCPU_SREG_CS); | ||
1938 | break; | ||
1714 | case 0x10 ... 0x15: | 1939 | case 0x10 ... 0x15: |
1715 | adc: /* adc */ | 1940 | adc: /* adc */ |
1716 | emulate_2op_SrcV("adc", c->src, c->dst, ctxt->eflags); | 1941 | emulate_2op_SrcV("adc", c->src, c->dst, ctxt->eflags); |
1717 | break; | 1942 | break; |
1943 | case 0x16: /* push ss */ | ||
1944 | emulate_push_sreg(ctxt, VCPU_SREG_SS); | ||
1945 | break; | ||
1946 | case 0x17: /* pop ss */ | ||
1947 | rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_SS); | ||
1948 | if (rc != 0) | ||
1949 | goto done; | ||
1950 | break; | ||
1718 | case 0x18 ... 0x1d: | 1951 | case 0x18 ... 0x1d: |
1719 | sbb: /* sbb */ | 1952 | sbb: /* sbb */ |
1720 | emulate_2op_SrcV("sbb", c->src, c->dst, ctxt->eflags); | 1953 | emulate_2op_SrcV("sbb", c->src, c->dst, ctxt->eflags); |
1721 | break; | 1954 | break; |
1955 | case 0x1e: /* push ds */ | ||
1956 | emulate_push_sreg(ctxt, VCPU_SREG_DS); | ||
1957 | break; | ||
1958 | case 0x1f: /* pop ds */ | ||
1959 | rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_DS); | ||
1960 | if (rc != 0) | ||
1961 | goto done; | ||
1962 | break; | ||
1722 | case 0x20 ... 0x25: | 1963 | case 0x20 ... 0x25: |
1723 | and: /* and */ | 1964 | and: /* and */ |
1724 | emulate_2op_SrcV("and", c->src, c->dst, ctxt->eflags); | 1965 | emulate_2op_SrcV("and", c->src, c->dst, ctxt->eflags); |
@@ -1750,6 +1991,14 @@ special_insn: | |||
1750 | if (rc != 0) | 1991 | if (rc != 0) |
1751 | goto done; | 1992 | goto done; |
1752 | break; | 1993 | break; |
1994 | case 0x60: /* pusha */ | ||
1995 | emulate_pusha(ctxt); | ||
1996 | break; | ||
1997 | case 0x61: /* popa */ | ||
1998 | rc = emulate_popa(ctxt, ops); | ||
1999 | if (rc != 0) | ||
2000 | goto done; | ||
2001 | break; | ||
1753 | case 0x63: /* movsxd */ | 2002 | case 0x63: /* movsxd */ |
1754 | if (ctxt->mode != X86EMUL_MODE_PROT64) | 2003 | if (ctxt->mode != X86EMUL_MODE_PROT64) |
1755 | goto cannot_emulate; | 2004 | goto cannot_emulate; |
@@ -1761,7 +2010,12 @@ special_insn: | |||
1761 | break; | 2010 | break; |
1762 | case 0x6c: /* insb */ | 2011 | case 0x6c: /* insb */ |
1763 | case 0x6d: /* insw/insd */ | 2012 | case 0x6d: /* insw/insd */ |
1764 | if (kvm_emulate_pio_string(ctxt->vcpu, NULL, | 2013 | if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX], |
2014 | (c->d & ByteOp) ? 1 : c->op_bytes)) { | ||
2015 | kvm_inject_gp(ctxt->vcpu, 0); | ||
2016 | goto done; | ||
2017 | } | ||
2018 | if (kvm_emulate_pio_string(ctxt->vcpu, | ||
1765 | 1, | 2019 | 1, |
1766 | (c->d & ByteOp) ? 1 : c->op_bytes, | 2020 | (c->d & ByteOp) ? 1 : c->op_bytes, |
1767 | c->rep_prefix ? | 2021 | c->rep_prefix ? |
@@ -1777,7 +2031,12 @@ special_insn: | |||
1777 | return 0; | 2031 | return 0; |
1778 | case 0x6e: /* outsb */ | 2032 | case 0x6e: /* outsb */ |
1779 | case 0x6f: /* outsw/outsd */ | 2033 | case 0x6f: /* outsw/outsd */ |
1780 | if (kvm_emulate_pio_string(ctxt->vcpu, NULL, | 2034 | if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX], |
2035 | (c->d & ByteOp) ? 1 : c->op_bytes)) { | ||
2036 | kvm_inject_gp(ctxt->vcpu, 0); | ||
2037 | goto done; | ||
2038 | } | ||
2039 | if (kvm_emulate_pio_string(ctxt->vcpu, | ||
1781 | 0, | 2040 | 0, |
1782 | (c->d & ByteOp) ? 1 : c->op_bytes, | 2041 | (c->d & ByteOp) ? 1 : c->op_bytes, |
1783 | c->rep_prefix ? | 2042 | c->rep_prefix ? |
@@ -1863,25 +2122,19 @@ special_insn: | |||
1863 | break; | 2122 | break; |
1864 | case 0x8e: { /* mov seg, r/m16 */ | 2123 | case 0x8e: { /* mov seg, r/m16 */ |
1865 | uint16_t sel; | 2124 | uint16_t sel; |
1866 | int type_bits; | ||
1867 | int err; | ||
1868 | 2125 | ||
1869 | sel = c->src.val; | 2126 | sel = c->src.val; |
1870 | if (c->modrm_reg == VCPU_SREG_SS) | ||
1871 | toggle_interruptibility(ctxt, X86_SHADOW_INT_MOV_SS); | ||
1872 | 2127 | ||
1873 | if (c->modrm_reg <= 5) { | 2128 | if (c->modrm_reg == VCPU_SREG_CS || |
1874 | type_bits = (c->modrm_reg == 1) ? 9 : 1; | 2129 | c->modrm_reg > VCPU_SREG_GS) { |
1875 | err = kvm_load_segment_descriptor(ctxt->vcpu, sel, | 2130 | kvm_queue_exception(ctxt->vcpu, UD_VECTOR); |
1876 | type_bits, c->modrm_reg); | 2131 | goto done; |
1877 | } else { | ||
1878 | printk(KERN_INFO "Invalid segreg in modrm byte 0x%02x\n", | ||
1879 | c->modrm); | ||
1880 | goto cannot_emulate; | ||
1881 | } | 2132 | } |
1882 | 2133 | ||
1883 | if (err < 0) | 2134 | if (c->modrm_reg == VCPU_SREG_SS) |
1884 | goto cannot_emulate; | 2135 | toggle_interruptibility(ctxt, X86_SHADOW_INT_MOV_SS); |
2136 | |||
2137 | rc = kvm_load_segment_descriptor(ctxt->vcpu, sel, c->modrm_reg); | ||
1885 | 2138 | ||
1886 | c->dst.type = OP_NONE; /* Disable writeback. */ | 2139 | c->dst.type = OP_NONE; /* Disable writeback. */ |
1887 | break; | 2140 | break; |
@@ -1910,7 +2163,10 @@ special_insn: | |||
1910 | c->dst.type = OP_REG; | 2163 | c->dst.type = OP_REG; |
1911 | c->dst.ptr = (unsigned long *) &ctxt->eflags; | 2164 | c->dst.ptr = (unsigned long *) &ctxt->eflags; |
1912 | c->dst.bytes = c->op_bytes; | 2165 | c->dst.bytes = c->op_bytes; |
1913 | goto pop_instruction; | 2166 | rc = emulate_popf(ctxt, ops, &c->dst.val, c->op_bytes); |
2167 | if (rc != X86EMUL_CONTINUE) | ||
2168 | goto done; | ||
2169 | break; | ||
1914 | case 0xa0 ... 0xa1: /* mov */ | 2170 | case 0xa0 ... 0xa1: /* mov */ |
1915 | c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; | 2171 | c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; |
1916 | c->dst.val = c->src.val; | 2172 | c->dst.val = c->src.val; |
@@ -1924,11 +2180,12 @@ special_insn: | |||
1924 | c->dst.ptr = (unsigned long *)register_address(c, | 2180 | c->dst.ptr = (unsigned long *)register_address(c, |
1925 | es_base(ctxt), | 2181 | es_base(ctxt), |
1926 | c->regs[VCPU_REGS_RDI]); | 2182 | c->regs[VCPU_REGS_RDI]); |
1927 | if ((rc = ops->read_emulated(register_address(c, | 2183 | rc = ops->read_emulated(register_address(c, |
1928 | seg_override_base(ctxt, c), | 2184 | seg_override_base(ctxt, c), |
1929 | c->regs[VCPU_REGS_RSI]), | 2185 | c->regs[VCPU_REGS_RSI]), |
1930 | &c->dst.val, | 2186 | &c->dst.val, |
1931 | c->dst.bytes, ctxt->vcpu)) != 0) | 2187 | c->dst.bytes, ctxt->vcpu); |
2188 | if (rc != X86EMUL_CONTINUE) | ||
1932 | goto done; | 2189 | goto done; |
1933 | register_address_increment(c, &c->regs[VCPU_REGS_RSI], | 2190 | register_address_increment(c, &c->regs[VCPU_REGS_RSI], |
1934 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes | 2191 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes |
@@ -1943,10 +2200,11 @@ special_insn: | |||
1943 | c->src.ptr = (unsigned long *)register_address(c, | 2200 | c->src.ptr = (unsigned long *)register_address(c, |
1944 | seg_override_base(ctxt, c), | 2201 | seg_override_base(ctxt, c), |
1945 | c->regs[VCPU_REGS_RSI]); | 2202 | c->regs[VCPU_REGS_RSI]); |
1946 | if ((rc = ops->read_emulated((unsigned long)c->src.ptr, | 2203 | rc = ops->read_emulated((unsigned long)c->src.ptr, |
1947 | &c->src.val, | 2204 | &c->src.val, |
1948 | c->src.bytes, | 2205 | c->src.bytes, |
1949 | ctxt->vcpu)) != 0) | 2206 | ctxt->vcpu); |
2207 | if (rc != X86EMUL_CONTINUE) | ||
1950 | goto done; | 2208 | goto done; |
1951 | 2209 | ||
1952 | c->dst.type = OP_NONE; /* Disable writeback. */ | 2210 | c->dst.type = OP_NONE; /* Disable writeback. */ |
@@ -1954,10 +2212,11 @@ special_insn: | |||
1954 | c->dst.ptr = (unsigned long *)register_address(c, | 2212 | c->dst.ptr = (unsigned long *)register_address(c, |
1955 | es_base(ctxt), | 2213 | es_base(ctxt), |
1956 | c->regs[VCPU_REGS_RDI]); | 2214 | c->regs[VCPU_REGS_RDI]); |
1957 | if ((rc = ops->read_emulated((unsigned long)c->dst.ptr, | 2215 | rc = ops->read_emulated((unsigned long)c->dst.ptr, |
1958 | &c->dst.val, | 2216 | &c->dst.val, |
1959 | c->dst.bytes, | 2217 | c->dst.bytes, |
1960 | ctxt->vcpu)) != 0) | 2218 | ctxt->vcpu); |
2219 | if (rc != X86EMUL_CONTINUE) | ||
1961 | goto done; | 2220 | goto done; |
1962 | 2221 | ||
1963 | DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.ptr, c->dst.ptr); | 2222 | DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.ptr, c->dst.ptr); |
@@ -1987,12 +2246,13 @@ special_insn: | |||
1987 | c->dst.type = OP_REG; | 2246 | c->dst.type = OP_REG; |
1988 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; | 2247 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; |
1989 | c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; | 2248 | c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; |
1990 | if ((rc = ops->read_emulated(register_address(c, | 2249 | rc = ops->read_emulated(register_address(c, |
1991 | seg_override_base(ctxt, c), | 2250 | seg_override_base(ctxt, c), |
1992 | c->regs[VCPU_REGS_RSI]), | 2251 | c->regs[VCPU_REGS_RSI]), |
1993 | &c->dst.val, | 2252 | &c->dst.val, |
1994 | c->dst.bytes, | 2253 | c->dst.bytes, |
1995 | ctxt->vcpu)) != 0) | 2254 | ctxt->vcpu); |
2255 | if (rc != X86EMUL_CONTINUE) | ||
1996 | goto done; | 2256 | goto done; |
1997 | register_address_increment(c, &c->regs[VCPU_REGS_RSI], | 2257 | register_address_increment(c, &c->regs[VCPU_REGS_RSI], |
1998 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes | 2258 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes |
@@ -2048,11 +2308,9 @@ special_insn: | |||
2048 | case 0xe9: /* jmp rel */ | 2308 | case 0xe9: /* jmp rel */ |
2049 | goto jmp; | 2309 | goto jmp; |
2050 | case 0xea: /* jmp far */ | 2310 | case 0xea: /* jmp far */ |
2051 | if (kvm_load_segment_descriptor(ctxt->vcpu, c->src2.val, 9, | 2311 | if (kvm_load_segment_descriptor(ctxt->vcpu, c->src2.val, |
2052 | VCPU_SREG_CS) < 0) { | 2312 | VCPU_SREG_CS)) |
2053 | DPRINTF("jmp far: Failed to load CS descriptor\n"); | 2313 | goto done; |
2054 | goto cannot_emulate; | ||
2055 | } | ||
2056 | 2314 | ||
2057 | c->eip = c->src.val; | 2315 | c->eip = c->src.val; |
2058 | break; | 2316 | break; |
@@ -2070,7 +2328,13 @@ special_insn: | |||
2070 | case 0xef: /* out (e/r)ax,dx */ | 2328 | case 0xef: /* out (e/r)ax,dx */ |
2071 | port = c->regs[VCPU_REGS_RDX]; | 2329 | port = c->regs[VCPU_REGS_RDX]; |
2072 | io_dir_in = 0; | 2330 | io_dir_in = 0; |
2073 | do_io: if (kvm_emulate_pio(ctxt->vcpu, NULL, io_dir_in, | 2331 | do_io: |
2332 | if (!emulator_io_permited(ctxt, ops, port, | ||
2333 | (c->d & ByteOp) ? 1 : c->op_bytes)) { | ||
2334 | kvm_inject_gp(ctxt->vcpu, 0); | ||
2335 | goto done; | ||
2336 | } | ||
2337 | if (kvm_emulate_pio(ctxt->vcpu, io_dir_in, | ||
2074 | (c->d & ByteOp) ? 1 : c->op_bytes, | 2338 | (c->d & ByteOp) ? 1 : c->op_bytes, |
2075 | port) != 0) { | 2339 | port) != 0) { |
2076 | c->eip = saved_eip; | 2340 | c->eip = saved_eip; |
@@ -2095,13 +2359,21 @@ special_insn: | |||
2095 | c->dst.type = OP_NONE; /* Disable writeback. */ | 2359 | c->dst.type = OP_NONE; /* Disable writeback. */ |
2096 | break; | 2360 | break; |
2097 | case 0xfa: /* cli */ | 2361 | case 0xfa: /* cli */ |
2098 | ctxt->eflags &= ~X86_EFLAGS_IF; | 2362 | if (emulator_bad_iopl(ctxt)) |
2099 | c->dst.type = OP_NONE; /* Disable writeback. */ | 2363 | kvm_inject_gp(ctxt->vcpu, 0); |
2364 | else { | ||
2365 | ctxt->eflags &= ~X86_EFLAGS_IF; | ||
2366 | c->dst.type = OP_NONE; /* Disable writeback. */ | ||
2367 | } | ||
2100 | break; | 2368 | break; |
2101 | case 0xfb: /* sti */ | 2369 | case 0xfb: /* sti */ |
2102 | toggle_interruptibility(ctxt, X86_SHADOW_INT_STI); | 2370 | if (emulator_bad_iopl(ctxt)) |
2103 | ctxt->eflags |= X86_EFLAGS_IF; | 2371 | kvm_inject_gp(ctxt->vcpu, 0); |
2104 | c->dst.type = OP_NONE; /* Disable writeback. */ | 2372 | else { |
2373 | toggle_interruptibility(ctxt, X86_SHADOW_INT_STI); | ||
2374 | ctxt->eflags |= X86_EFLAGS_IF; | ||
2375 | c->dst.type = OP_NONE; /* Disable writeback. */ | ||
2376 | } | ||
2105 | break; | 2377 | break; |
2106 | case 0xfc: /* cld */ | 2378 | case 0xfc: /* cld */ |
2107 | ctxt->eflags &= ~EFLG_DF; | 2379 | ctxt->eflags &= ~EFLG_DF; |
@@ -2204,8 +2476,9 @@ twobyte_insn: | |||
2204 | } | 2476 | } |
2205 | break; | 2477 | break; |
2206 | case 0x05: /* syscall */ | 2478 | case 0x05: /* syscall */ |
2207 | if (emulate_syscall(ctxt) == -1) | 2479 | rc = emulate_syscall(ctxt); |
2208 | goto cannot_emulate; | 2480 | if (rc != X86EMUL_CONTINUE) |
2481 | goto done; | ||
2209 | else | 2482 | else |
2210 | goto writeback; | 2483 | goto writeback; |
2211 | break; | 2484 | break; |
@@ -2276,14 +2549,16 @@ twobyte_insn: | |||
2276 | c->dst.type = OP_NONE; | 2549 | c->dst.type = OP_NONE; |
2277 | break; | 2550 | break; |
2278 | case 0x34: /* sysenter */ | 2551 | case 0x34: /* sysenter */ |
2279 | if (emulate_sysenter(ctxt) == -1) | 2552 | rc = emulate_sysenter(ctxt); |
2280 | goto cannot_emulate; | 2553 | if (rc != X86EMUL_CONTINUE) |
2554 | goto done; | ||
2281 | else | 2555 | else |
2282 | goto writeback; | 2556 | goto writeback; |
2283 | break; | 2557 | break; |
2284 | case 0x35: /* sysexit */ | 2558 | case 0x35: /* sysexit */ |
2285 | if (emulate_sysexit(ctxt) == -1) | 2559 | rc = emulate_sysexit(ctxt); |
2286 | goto cannot_emulate; | 2560 | if (rc != X86EMUL_CONTINUE) |
2561 | goto done; | ||
2287 | else | 2562 | else |
2288 | goto writeback; | 2563 | goto writeback; |
2289 | break; | 2564 | break; |
@@ -2297,6 +2572,14 @@ twobyte_insn: | |||
2297 | jmp_rel(c, c->src.val); | 2572 | jmp_rel(c, c->src.val); |
2298 | c->dst.type = OP_NONE; | 2573 | c->dst.type = OP_NONE; |
2299 | break; | 2574 | break; |
2575 | case 0xa0: /* push fs */ | ||
2576 | emulate_push_sreg(ctxt, VCPU_SREG_FS); | ||
2577 | break; | ||
2578 | case 0xa1: /* pop fs */ | ||
2579 | rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_FS); | ||
2580 | if (rc != 0) | ||
2581 | goto done; | ||
2582 | break; | ||
2300 | case 0xa3: | 2583 | case 0xa3: |
2301 | bt: /* bt */ | 2584 | bt: /* bt */ |
2302 | c->dst.type = OP_NONE; | 2585 | c->dst.type = OP_NONE; |
@@ -2308,6 +2591,14 @@ twobyte_insn: | |||
2308 | case 0xa5: /* shld cl, r, r/m */ | 2591 | case 0xa5: /* shld cl, r, r/m */ |
2309 | emulate_2op_cl("shld", c->src2, c->src, c->dst, ctxt->eflags); | 2592 | emulate_2op_cl("shld", c->src2, c->src, c->dst, ctxt->eflags); |
2310 | break; | 2593 | break; |
2594 | case 0xa8: /* push gs */ | ||
2595 | emulate_push_sreg(ctxt, VCPU_SREG_GS); | ||
2596 | break; | ||
2597 | case 0xa9: /* pop gs */ | ||
2598 | rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_GS); | ||
2599 | if (rc != 0) | ||
2600 | goto done; | ||
2601 | break; | ||
2311 | case 0xab: | 2602 | case 0xab: |
2312 | bts: /* bts */ | 2603 | bts: /* bts */ |
2313 | /* only subword offset */ | 2604 | /* only subword offset */ |