diff options
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r-- | arch/x86/kvm/emulate.c | 440 |
1 files changed, 300 insertions, 140 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 7e8faea4651e..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. |
@@ -76,6 +76,8 @@ | |||
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 */ | 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 */ | ||
79 | #define No64 (1<<28) | 81 | #define No64 (1<<28) |
80 | /* Source 2 operand type */ | 82 | /* Source 2 operand type */ |
81 | #define Src2None (0<<29) | 83 | #define Src2None (0<<29) |
@@ -88,39 +90,40 @@ | |||
88 | enum { | 90 | enum { |
89 | Group1_80, Group1_81, Group1_82, Group1_83, | 91 | Group1_80, Group1_81, Group1_82, Group1_83, |
90 | Group1A, Group3_Byte, Group3, Group4, Group5, Group7, | 92 | Group1A, Group3_Byte, Group3, Group4, Group5, Group7, |
93 | Group8, Group9, | ||
91 | }; | 94 | }; |
92 | 95 | ||
93 | static u32 opcode_table[256] = { | 96 | static u32 opcode_table[256] = { |
94 | /* 0x00 - 0x07 */ | 97 | /* 0x00 - 0x07 */ |
95 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 98 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
96 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 99 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
97 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, | 100 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, |
98 | ImplicitOps | Stack | No64, ImplicitOps | Stack | No64, | 101 | ImplicitOps | Stack | No64, ImplicitOps | Stack | No64, |
99 | /* 0x08 - 0x0F */ | 102 | /* 0x08 - 0x0F */ |
100 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 103 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
101 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 104 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
102 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, | 105 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, |
103 | ImplicitOps | Stack | No64, 0, | 106 | ImplicitOps | Stack | No64, 0, |
104 | /* 0x10 - 0x17 */ | 107 | /* 0x10 - 0x17 */ |
105 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 108 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
106 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 109 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
107 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, | 110 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, |
108 | ImplicitOps | Stack | No64, ImplicitOps | Stack | No64, | 111 | ImplicitOps | Stack | No64, ImplicitOps | Stack | No64, |
109 | /* 0x18 - 0x1F */ | 112 | /* 0x18 - 0x1F */ |
110 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 113 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
111 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 114 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
112 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, | 115 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, |
113 | ImplicitOps | Stack | No64, ImplicitOps | Stack | No64, | 116 | ImplicitOps | Stack | No64, ImplicitOps | Stack | No64, |
114 | /* 0x20 - 0x27 */ | 117 | /* 0x20 - 0x27 */ |
115 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 118 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
116 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 119 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
117 | DstAcc | SrcImmByte, DstAcc | SrcImm, 0, 0, | 120 | DstAcc | SrcImmByte, DstAcc | SrcImm, 0, 0, |
118 | /* 0x28 - 0x2F */ | 121 | /* 0x28 - 0x2F */ |
119 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 122 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
120 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 123 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
121 | 0, 0, 0, 0, | 124 | 0, 0, 0, 0, |
122 | /* 0x30 - 0x37 */ | 125 | /* 0x30 - 0x37 */ |
123 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 126 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
124 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 127 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
125 | 0, 0, 0, 0, | 128 | 0, 0, 0, 0, |
126 | /* 0x38 - 0x3F */ | 129 | /* 0x38 - 0x3F */ |
@@ -156,7 +159,7 @@ static u32 opcode_table[256] = { | |||
156 | Group | Group1_80, Group | Group1_81, | 159 | Group | Group1_80, Group | Group1_81, |
157 | Group | Group1_82, Group | Group1_83, | 160 | Group | Group1_82, Group | Group1_83, |
158 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 161 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, |
159 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 162 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
160 | /* 0x88 - 0x8F */ | 163 | /* 0x88 - 0x8F */ |
161 | ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov, | 164 | ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov, |
162 | ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, | 165 | ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, |
@@ -210,7 +213,7 @@ static u32 opcode_table[256] = { | |||
210 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, | 213 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, |
211 | /* 0xF0 - 0xF7 */ | 214 | /* 0xF0 - 0xF7 */ |
212 | 0, 0, 0, 0, | 215 | 0, 0, 0, 0, |
213 | ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3, | 216 | ImplicitOps | Priv, ImplicitOps, Group | Group3_Byte, Group | Group3, |
214 | /* 0xF8 - 0xFF */ | 217 | /* 0xF8 - 0xFF */ |
215 | ImplicitOps, 0, ImplicitOps, ImplicitOps, | 218 | ImplicitOps, 0, ImplicitOps, ImplicitOps, |
216 | ImplicitOps, ImplicitOps, Group | Group4, Group | Group5, | 219 | ImplicitOps, ImplicitOps, Group | Group4, Group | Group5, |
@@ -218,16 +221,20 @@ static u32 opcode_table[256] = { | |||
218 | 221 | ||
219 | static u32 twobyte_table[256] = { | 222 | static u32 twobyte_table[256] = { |
220 | /* 0x00 - 0x0F */ | 223 | /* 0x00 - 0x0F */ |
221 | 0, Group | GroupDual | Group7, 0, 0, 0, ImplicitOps, ImplicitOps, 0, | 224 | 0, Group | GroupDual | Group7, 0, 0, |
222 | 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, | ||
223 | /* 0x10 - 0x1F */ | 228 | /* 0x10 - 0x1F */ |
224 | 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, |
225 | /* 0x20 - 0x2F */ | 230 | /* 0x20 - 0x2F */ |
226 | 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, | ||
227 | 0, 0, 0, 0, 0, 0, 0, 0, | 234 | 0, 0, 0, 0, 0, 0, 0, 0, |
228 | /* 0x30 - 0x3F */ | 235 | /* 0x30 - 0x3F */ |
229 | ImplicitOps, 0, ImplicitOps, 0, | 236 | ImplicitOps | Priv, 0, ImplicitOps | Priv, 0, |
230 | ImplicitOps, ImplicitOps, 0, 0, | 237 | ImplicitOps, ImplicitOps | Priv, 0, 0, |
231 | 0, 0, 0, 0, 0, 0, 0, 0, | 238 | 0, 0, 0, 0, 0, 0, 0, 0, |
232 | /* 0x40 - 0x47 */ | 239 | /* 0x40 - 0x47 */ |
233 | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, | 240 | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, |
@@ -257,21 +264,23 @@ static u32 twobyte_table[256] = { | |||
257 | DstMem | SrcReg | Src2CL | ModRM, 0, 0, | 264 | DstMem | SrcReg | Src2CL | ModRM, 0, 0, |
258 | /* 0xA8 - 0xAF */ | 265 | /* 0xA8 - 0xAF */ |
259 | ImplicitOps | Stack, ImplicitOps | Stack, | 266 | ImplicitOps | Stack, ImplicitOps | Stack, |
260 | 0, DstMem | SrcReg | ModRM | BitOp, | 267 | 0, DstMem | SrcReg | ModRM | BitOp | Lock, |
261 | DstMem | SrcReg | Src2ImmByte | ModRM, | 268 | DstMem | SrcReg | Src2ImmByte | ModRM, |
262 | DstMem | SrcReg | Src2CL | ModRM, | 269 | DstMem | SrcReg | Src2CL | ModRM, |
263 | ModRM, 0, | 270 | ModRM, 0, |
264 | /* 0xB0 - 0xB7 */ | 271 | /* 0xB0 - 0xB7 */ |
265 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 0, | 272 | ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, |
266 | DstMem | SrcReg | ModRM | BitOp, | 273 | 0, DstMem | SrcReg | ModRM | BitOp | Lock, |
267 | 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, | 274 | 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, |
268 | DstReg | SrcMem16 | ModRM | Mov, | 275 | DstReg | SrcMem16 | ModRM | Mov, |
269 | /* 0xB8 - 0xBF */ | 276 | /* 0xB8 - 0xBF */ |
270 | 0, 0, DstMem | SrcImmByte | ModRM, DstMem | SrcReg | ModRM | BitOp, | 277 | 0, 0, |
278 | Group | Group8, DstMem | SrcReg | ModRM | BitOp | Lock, | ||
271 | 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, | 279 | 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, |
272 | DstReg | SrcMem16 | ModRM | Mov, | 280 | DstReg | SrcMem16 | ModRM | Mov, |
273 | /* 0xC0 - 0xCF */ | 281 | /* 0xC0 - 0xCF */ |
274 | 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, | ||
275 | 0, 0, 0, 0, 0, 0, 0, 0, | 284 | 0, 0, 0, 0, 0, 0, 0, 0, |
276 | /* 0xD0 - 0xDF */ | 285 | /* 0xD0 - 0xDF */ |
277 | 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, |
@@ -283,25 +292,41 @@ static u32 twobyte_table[256] = { | |||
283 | 292 | ||
284 | static u32 group_table[] = { | 293 | static u32 group_table[] = { |
285 | [Group1_80*8] = | 294 | [Group1_80*8] = |
286 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, | 295 | ByteOp | DstMem | SrcImm | ModRM | Lock, |
287 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, | 296 | ByteOp | DstMem | SrcImm | ModRM | Lock, |
288 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, | 297 | ByteOp | DstMem | SrcImm | ModRM | Lock, |
289 | 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, | ||
290 | [Group1_81*8] = | 303 | [Group1_81*8] = |
291 | DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM, | 304 | DstMem | SrcImm | ModRM | Lock, |
292 | DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM, | 305 | DstMem | SrcImm | ModRM | Lock, |
293 | DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM, | 306 | DstMem | SrcImm | ModRM | Lock, |
294 | 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, | ||
295 | [Group1_82*8] = | 312 | [Group1_82*8] = |
296 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, | 313 | ByteOp | DstMem | SrcImm | ModRM | No64 | Lock, |
297 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, | 314 | ByteOp | DstMem | SrcImm | ModRM | No64 | Lock, |
298 | ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, | 315 | ByteOp | DstMem | SrcImm | ModRM | No64 | Lock, |
299 | 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, | ||
300 | [Group1_83*8] = | 321 | [Group1_83*8] = |
301 | DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM, | 322 | DstMem | SrcImmByte | ModRM | Lock, |
302 | DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM, | 323 | DstMem | SrcImmByte | ModRM | Lock, |
303 | DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM, | 324 | DstMem | SrcImmByte | ModRM | Lock, |
304 | 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, | ||
305 | [Group1A*8] = | 330 | [Group1A*8] = |
306 | 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, |
307 | [Group3_Byte*8] = | 332 | [Group3_Byte*8] = |
@@ -320,24 +345,39 @@ static u32 group_table[] = { | |||
320 | SrcMem | ModRM | Stack, 0, | 345 | SrcMem | ModRM | Stack, 0, |
321 | SrcMem | ModRM | Stack, 0, SrcMem | ModRM | Stack, 0, | 346 | SrcMem | ModRM | Stack, 0, SrcMem | ModRM | Stack, 0, |
322 | [Group7*8] = | 347 | [Group7*8] = |
323 | 0, 0, ModRM | SrcMem, ModRM | SrcMem, | 348 | 0, 0, ModRM | SrcMem | Priv, ModRM | SrcMem | Priv, |
324 | SrcNone | ModRM | DstMem | Mov, 0, | 349 | SrcNone | ModRM | DstMem | Mov, 0, |
325 | 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, | ||
326 | }; | 357 | }; |
327 | 358 | ||
328 | static u32 group2_table[] = { | 359 | static u32 group2_table[] = { |
329 | [Group7*8] = | 360 | [Group7*8] = |
330 | SrcNone | ModRM, 0, 0, SrcNone | ModRM, | 361 | SrcNone | ModRM | Priv, 0, 0, SrcNone | ModRM, |
331 | SrcNone | ModRM | DstMem | Mov, 0, | 362 | SrcNone | ModRM | DstMem | Mov, 0, |
332 | SrcMem16 | ModRM | Mov, 0, | 363 | SrcMem16 | ModRM | Mov, 0, |
364 | [Group9*8] = | ||
365 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
333 | }; | 366 | }; |
334 | 367 | ||
335 | /* 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) | ||
336 | #define EFLG_VM (1<<17) | 373 | #define EFLG_VM (1<<17) |
337 | #define EFLG_RF (1<<16) | 374 | #define EFLG_RF (1<<16) |
375 | #define EFLG_IOPL (3<<12) | ||
376 | #define EFLG_NT (1<<14) | ||
338 | #define EFLG_OF (1<<11) | 377 | #define EFLG_OF (1<<11) |
339 | #define EFLG_DF (1<<10) | 378 | #define EFLG_DF (1<<10) |
340 | #define EFLG_IF (1<<9) | 379 | #define EFLG_IF (1<<9) |
380 | #define EFLG_TF (1<<8) | ||
341 | #define EFLG_SF (1<<7) | 381 | #define EFLG_SF (1<<7) |
342 | #define EFLG_ZF (1<<6) | 382 | #define EFLG_ZF (1<<6) |
343 | #define EFLG_AF (1<<4) | 383 | #define EFLG_AF (1<<4) |
@@ -606,7 +646,7 @@ static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, | |||
606 | 646 | ||
607 | if (linear < fc->start || linear >= fc->end) { | 647 | if (linear < fc->start || linear >= fc->end) { |
608 | size = min(15UL, PAGE_SIZE - offset_in_page(linear)); | 648 | size = min(15UL, PAGE_SIZE - offset_in_page(linear)); |
609 | rc = ops->read_std(linear, fc->data, size, ctxt->vcpu); | 649 | rc = ops->fetch(linear, fc->data, size, ctxt->vcpu, NULL); |
610 | if (rc) | 650 | if (rc) |
611 | return rc; | 651 | return rc; |
612 | fc->start = linear; | 652 | fc->start = linear; |
@@ -661,11 +701,11 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt, | |||
661 | op_bytes = 3; | 701 | op_bytes = 3; |
662 | *address = 0; | 702 | *address = 0; |
663 | rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2, | 703 | rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2, |
664 | ctxt->vcpu); | 704 | ctxt->vcpu, NULL); |
665 | if (rc) | 705 | if (rc) |
666 | return rc; | 706 | return rc; |
667 | rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes, | 707 | rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes, |
668 | ctxt->vcpu); | 708 | ctxt->vcpu, NULL); |
669 | return rc; | 709 | return rc; |
670 | } | 710 | } |
671 | 711 | ||
@@ -889,6 +929,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
889 | 929 | ||
890 | switch (mode) { | 930 | switch (mode) { |
891 | case X86EMUL_MODE_REAL: | 931 | case X86EMUL_MODE_REAL: |
932 | case X86EMUL_MODE_VM86: | ||
892 | case X86EMUL_MODE_PROT16: | 933 | case X86EMUL_MODE_PROT16: |
893 | def_op_bytes = def_ad_bytes = 2; | 934 | def_op_bytes = def_ad_bytes = 2; |
894 | break; | 935 | break; |
@@ -975,7 +1016,7 @@ done_prefixes: | |||
975 | } | 1016 | } |
976 | 1017 | ||
977 | if (mode == X86EMUL_MODE_PROT64 && (c->d & No64)) { | 1018 | if (mode == X86EMUL_MODE_PROT64 && (c->d & No64)) { |
978 | kvm_report_emulation_failure(ctxt->vcpu, "invalid x86/64 instruction");; | 1019 | kvm_report_emulation_failure(ctxt->vcpu, "invalid x86/64 instruction"); |
979 | return -1; | 1020 | return -1; |
980 | } | 1021 | } |
981 | 1022 | ||
@@ -1196,13 +1237,56 @@ static int emulate_pop(struct x86_emulate_ctxt *ctxt, | |||
1196 | rc = ops->read_emulated(register_address(c, ss_base(ctxt), | 1237 | rc = ops->read_emulated(register_address(c, ss_base(ctxt), |
1197 | c->regs[VCPU_REGS_RSP]), | 1238 | c->regs[VCPU_REGS_RSP]), |
1198 | dest, len, ctxt->vcpu); | 1239 | dest, len, ctxt->vcpu); |
1199 | if (rc != 0) | 1240 | if (rc != X86EMUL_CONTINUE) |
1200 | return rc; | 1241 | return rc; |
1201 | 1242 | ||
1202 | register_address_increment(c, &c->regs[VCPU_REGS_RSP], len); | 1243 | register_address_increment(c, &c->regs[VCPU_REGS_RSP], len); |
1203 | return rc; | 1244 | return rc; |
1204 | } | 1245 | } |
1205 | 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 | |||
1206 | static void emulate_push_sreg(struct x86_emulate_ctxt *ctxt, int seg) | 1290 | static void emulate_push_sreg(struct x86_emulate_ctxt *ctxt, int seg) |
1207 | { | 1291 | { |
1208 | struct decode_cache *c = &ctxt->decode; | 1292 | struct decode_cache *c = &ctxt->decode; |
@@ -1225,7 +1309,7 @@ static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt, | |||
1225 | if (rc != 0) | 1309 | if (rc != 0) |
1226 | return rc; | 1310 | return rc; |
1227 | 1311 | ||
1228 | rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)selector, 1, seg); | 1312 | rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)selector, seg); |
1229 | return rc; | 1313 | return rc; |
1230 | } | 1314 | } |
1231 | 1315 | ||
@@ -1370,7 +1454,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, | |||
1370 | int rc; | 1454 | int rc; |
1371 | 1455 | ||
1372 | rc = ops->read_emulated(memop, &old, 8, ctxt->vcpu); | 1456 | rc = ops->read_emulated(memop, &old, 8, ctxt->vcpu); |
1373 | if (rc != 0) | 1457 | if (rc != X86EMUL_CONTINUE) |
1374 | return rc; | 1458 | return rc; |
1375 | 1459 | ||
1376 | if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) || | 1460 | if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) || |
@@ -1385,7 +1469,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, | |||
1385 | (u32) c->regs[VCPU_REGS_RBX]; | 1469 | (u32) c->regs[VCPU_REGS_RBX]; |
1386 | 1470 | ||
1387 | rc = ops->cmpxchg_emulated(memop, &old, &new, 8, ctxt->vcpu); | 1471 | rc = ops->cmpxchg_emulated(memop, &old, &new, 8, ctxt->vcpu); |
1388 | if (rc != 0) | 1472 | if (rc != X86EMUL_CONTINUE) |
1389 | return rc; | 1473 | return rc; |
1390 | ctxt->eflags |= EFLG_ZF; | 1474 | ctxt->eflags |= EFLG_ZF; |
1391 | } | 1475 | } |
@@ -1407,7 +1491,7 @@ static int emulate_ret_far(struct x86_emulate_ctxt *ctxt, | |||
1407 | rc = emulate_pop(ctxt, ops, &cs, c->op_bytes); | 1491 | rc = emulate_pop(ctxt, ops, &cs, c->op_bytes); |
1408 | if (rc) | 1492 | if (rc) |
1409 | return rc; | 1493 | return rc; |
1410 | 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); |
1411 | return rc; | 1495 | return rc; |
1412 | } | 1496 | } |
1413 | 1497 | ||
@@ -1451,7 +1535,7 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt, | |||
1451 | &c->dst.val, | 1535 | &c->dst.val, |
1452 | c->dst.bytes, | 1536 | c->dst.bytes, |
1453 | ctxt->vcpu); | 1537 | ctxt->vcpu); |
1454 | if (rc != 0) | 1538 | if (rc != X86EMUL_CONTINUE) |
1455 | return rc; | 1539 | return rc; |
1456 | break; | 1540 | break; |
1457 | case OP_NONE: | 1541 | case OP_NONE: |
@@ -1514,9 +1598,8 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt) | |||
1514 | u64 msr_data; | 1598 | u64 msr_data; |
1515 | 1599 | ||
1516 | /* syscall is not available in real mode */ | 1600 | /* syscall is not available in real mode */ |
1517 | if (c->lock_prefix || ctxt->mode == X86EMUL_MODE_REAL | 1601 | if (ctxt->mode == X86EMUL_MODE_REAL || ctxt->mode == X86EMUL_MODE_VM86) |
1518 | || !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) | 1602 | return X86EMUL_UNHANDLEABLE; |
1519 | return -1; | ||
1520 | 1603 | ||
1521 | setup_syscalls_segments(ctxt, &cs, &ss); | 1604 | setup_syscalls_segments(ctxt, &cs, &ss); |
1522 | 1605 | ||
@@ -1553,7 +1636,7 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt) | |||
1553 | ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF); | 1636 | ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF); |
1554 | } | 1637 | } |
1555 | 1638 | ||
1556 | return 0; | 1639 | return X86EMUL_CONTINUE; |
1557 | } | 1640 | } |
1558 | 1641 | ||
1559 | static int | 1642 | static int |
@@ -1563,22 +1646,17 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt) | |||
1563 | struct kvm_segment cs, ss; | 1646 | struct kvm_segment cs, ss; |
1564 | u64 msr_data; | 1647 | u64 msr_data; |
1565 | 1648 | ||
1566 | /* inject #UD if LOCK prefix is used */ | 1649 | /* inject #GP if in real mode */ |
1567 | if (c->lock_prefix) | 1650 | if (ctxt->mode == X86EMUL_MODE_REAL) { |
1568 | return -1; | ||
1569 | |||
1570 | /* inject #GP if in real mode or paging is disabled */ | ||
1571 | if (ctxt->mode == X86EMUL_MODE_REAL || | ||
1572 | !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) { | ||
1573 | kvm_inject_gp(ctxt->vcpu, 0); | 1651 | kvm_inject_gp(ctxt->vcpu, 0); |
1574 | return -1; | 1652 | return X86EMUL_UNHANDLEABLE; |
1575 | } | 1653 | } |
1576 | 1654 | ||
1577 | /* XXX sysenter/sysexit have not been tested in 64bit mode. | 1655 | /* XXX sysenter/sysexit have not been tested in 64bit mode. |
1578 | * Therefore, we inject an #UD. | 1656 | * Therefore, we inject an #UD. |
1579 | */ | 1657 | */ |
1580 | if (ctxt->mode == X86EMUL_MODE_PROT64) | 1658 | if (ctxt->mode == X86EMUL_MODE_PROT64) |
1581 | return -1; | 1659 | return X86EMUL_UNHANDLEABLE; |
1582 | 1660 | ||
1583 | setup_syscalls_segments(ctxt, &cs, &ss); | 1661 | setup_syscalls_segments(ctxt, &cs, &ss); |
1584 | 1662 | ||
@@ -1587,13 +1665,13 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt) | |||
1587 | case X86EMUL_MODE_PROT32: | 1665 | case X86EMUL_MODE_PROT32: |
1588 | if ((msr_data & 0xfffc) == 0x0) { | 1666 | if ((msr_data & 0xfffc) == 0x0) { |
1589 | kvm_inject_gp(ctxt->vcpu, 0); | 1667 | kvm_inject_gp(ctxt->vcpu, 0); |
1590 | return -1; | 1668 | return X86EMUL_PROPAGATE_FAULT; |
1591 | } | 1669 | } |
1592 | break; | 1670 | break; |
1593 | case X86EMUL_MODE_PROT64: | 1671 | case X86EMUL_MODE_PROT64: |
1594 | if (msr_data == 0x0) { | 1672 | if (msr_data == 0x0) { |
1595 | kvm_inject_gp(ctxt->vcpu, 0); | 1673 | kvm_inject_gp(ctxt->vcpu, 0); |
1596 | return -1; | 1674 | return X86EMUL_PROPAGATE_FAULT; |
1597 | } | 1675 | } |
1598 | break; | 1676 | break; |
1599 | } | 1677 | } |
@@ -1618,7 +1696,7 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt) | |||
1618 | 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); |
1619 | c->regs[VCPU_REGS_RSP] = msr_data; | 1697 | c->regs[VCPU_REGS_RSP] = msr_data; |
1620 | 1698 | ||
1621 | return 0; | 1699 | return X86EMUL_CONTINUE; |
1622 | } | 1700 | } |
1623 | 1701 | ||
1624 | static int | 1702 | static int |
@@ -1629,21 +1707,11 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt) | |||
1629 | u64 msr_data; | 1707 | u64 msr_data; |
1630 | int usermode; | 1708 | int usermode; |
1631 | 1709 | ||
1632 | /* inject #UD if LOCK prefix is used */ | 1710 | /* inject #GP if in real mode or Virtual 8086 mode */ |
1633 | if (c->lock_prefix) | 1711 | if (ctxt->mode == X86EMUL_MODE_REAL || |
1634 | return -1; | 1712 | ctxt->mode == X86EMUL_MODE_VM86) { |
1635 | |||
1636 | /* inject #GP if in real mode or paging is disabled */ | ||
1637 | if (ctxt->mode == X86EMUL_MODE_REAL | ||
1638 | || !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) { | ||
1639 | kvm_inject_gp(ctxt->vcpu, 0); | ||
1640 | return -1; | ||
1641 | } | ||
1642 | |||
1643 | /* sysexit must be called from CPL 0 */ | ||
1644 | if (kvm_x86_ops->get_cpl(ctxt->vcpu) != 0) { | ||
1645 | kvm_inject_gp(ctxt->vcpu, 0); | 1713 | kvm_inject_gp(ctxt->vcpu, 0); |
1646 | return -1; | 1714 | return X86EMUL_UNHANDLEABLE; |
1647 | } | 1715 | } |
1648 | 1716 | ||
1649 | setup_syscalls_segments(ctxt, &cs, &ss); | 1717 | setup_syscalls_segments(ctxt, &cs, &ss); |
@@ -1661,7 +1729,7 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt) | |||
1661 | cs.selector = (u16)(msr_data + 16); | 1729 | cs.selector = (u16)(msr_data + 16); |
1662 | if ((msr_data & 0xfffc) == 0x0) { | 1730 | if ((msr_data & 0xfffc) == 0x0) { |
1663 | kvm_inject_gp(ctxt->vcpu, 0); | 1731 | kvm_inject_gp(ctxt->vcpu, 0); |
1664 | return -1; | 1732 | return X86EMUL_PROPAGATE_FAULT; |
1665 | } | 1733 | } |
1666 | ss.selector = (u16)(msr_data + 24); | 1734 | ss.selector = (u16)(msr_data + 24); |
1667 | break; | 1735 | break; |
@@ -1669,7 +1737,7 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt) | |||
1669 | cs.selector = (u16)(msr_data + 32); | 1737 | cs.selector = (u16)(msr_data + 32); |
1670 | if (msr_data == 0x0) { | 1738 | if (msr_data == 0x0) { |
1671 | kvm_inject_gp(ctxt->vcpu, 0); | 1739 | kvm_inject_gp(ctxt->vcpu, 0); |
1672 | return -1; | 1740 | return X86EMUL_PROPAGATE_FAULT; |
1673 | } | 1741 | } |
1674 | ss.selector = cs.selector + 8; | 1742 | ss.selector = cs.selector + 8; |
1675 | cs.db = 0; | 1743 | cs.db = 0; |
@@ -1685,7 +1753,58 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt) | |||
1685 | c->eip = ctxt->vcpu->arch.regs[VCPU_REGS_RDX]; | 1753 | c->eip = ctxt->vcpu->arch.regs[VCPU_REGS_RDX]; |
1686 | 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]; |
1687 | 1755 | ||
1688 | 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; | ||
1689 | } | 1808 | } |
1690 | 1809 | ||
1691 | int | 1810 | int |
@@ -1709,6 +1828,18 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1709 | memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); | 1828 | memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); |
1710 | saved_eip = c->eip; | 1829 | saved_eip = c->eip; |
1711 | 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 | |||
1712 | if (((c->d & ModRM) && (c->modrm_mod != 3)) || (c->d & MemAbs)) | 1843 | if (((c->d & ModRM) && (c->modrm_mod != 3)) || (c->d & MemAbs)) |
1713 | memop = c->modrm_ea; | 1844 | memop = c->modrm_ea; |
1714 | 1845 | ||
@@ -1749,7 +1880,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1749 | &c->src.val, | 1880 | &c->src.val, |
1750 | c->src.bytes, | 1881 | c->src.bytes, |
1751 | ctxt->vcpu); | 1882 | ctxt->vcpu); |
1752 | if (rc != 0) | 1883 | if (rc != X86EMUL_CONTINUE) |
1753 | goto done; | 1884 | goto done; |
1754 | c->src.orig_val = c->src.val; | 1885 | c->src.orig_val = c->src.val; |
1755 | } | 1886 | } |
@@ -1768,12 +1899,15 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1768 | c->dst.ptr = (void *)c->dst.ptr + | 1899 | c->dst.ptr = (void *)c->dst.ptr + |
1769 | (c->src.val & mask) / 8; | 1900 | (c->src.val & mask) / 8; |
1770 | } | 1901 | } |
1771 | if (!(c->d & Mov) && | 1902 | if (!(c->d & Mov)) { |
1772 | /* optimisation - avoid slow emulated read */ | 1903 | /* optimisation - avoid slow emulated read */ |
1773 | ((rc = ops->read_emulated((unsigned long)c->dst.ptr, | 1904 | rc = ops->read_emulated((unsigned long)c->dst.ptr, |
1774 | &c->dst.val, | 1905 | &c->dst.val, |
1775 | c->dst.bytes, ctxt->vcpu)) != 0)) | 1906 | c->dst.bytes, |
1776 | goto done; | 1907 | ctxt->vcpu); |
1908 | if (rc != X86EMUL_CONTINUE) | ||
1909 | goto done; | ||
1910 | } | ||
1777 | } | 1911 | } |
1778 | c->dst.orig_val = c->dst.val; | 1912 | c->dst.orig_val = c->dst.val; |
1779 | 1913 | ||
@@ -1876,7 +2010,12 @@ special_insn: | |||
1876 | break; | 2010 | break; |
1877 | case 0x6c: /* insb */ | 2011 | case 0x6c: /* insb */ |
1878 | case 0x6d: /* insw/insd */ | 2012 | case 0x6d: /* insw/insd */ |
1879 | if (kvm_emulate_pio_string(ctxt->vcpu, | 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, | ||
1880 | 1, | 2019 | 1, |
1881 | (c->d & ByteOp) ? 1 : c->op_bytes, | 2020 | (c->d & ByteOp) ? 1 : c->op_bytes, |
1882 | c->rep_prefix ? | 2021 | c->rep_prefix ? |
@@ -1892,6 +2031,11 @@ special_insn: | |||
1892 | return 0; | 2031 | return 0; |
1893 | case 0x6e: /* outsb */ | 2032 | case 0x6e: /* outsb */ |
1894 | case 0x6f: /* outsw/outsd */ | 2033 | case 0x6f: /* outsw/outsd */ |
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 | } | ||
1895 | if (kvm_emulate_pio_string(ctxt->vcpu, | 2039 | if (kvm_emulate_pio_string(ctxt->vcpu, |
1896 | 0, | 2040 | 0, |
1897 | (c->d & ByteOp) ? 1 : c->op_bytes, | 2041 | (c->d & ByteOp) ? 1 : c->op_bytes, |
@@ -1978,25 +2122,19 @@ special_insn: | |||
1978 | break; | 2122 | break; |
1979 | case 0x8e: { /* mov seg, r/m16 */ | 2123 | case 0x8e: { /* mov seg, r/m16 */ |
1980 | uint16_t sel; | 2124 | uint16_t sel; |
1981 | int type_bits; | ||
1982 | int err; | ||
1983 | 2125 | ||
1984 | sel = c->src.val; | 2126 | sel = c->src.val; |
1985 | if (c->modrm_reg == VCPU_SREG_SS) | ||
1986 | toggle_interruptibility(ctxt, X86_SHADOW_INT_MOV_SS); | ||
1987 | 2127 | ||
1988 | if (c->modrm_reg <= 5) { | 2128 | if (c->modrm_reg == VCPU_SREG_CS || |
1989 | type_bits = (c->modrm_reg == 1) ? 9 : 1; | 2129 | c->modrm_reg > VCPU_SREG_GS) { |
1990 | err = kvm_load_segment_descriptor(ctxt->vcpu, sel, | 2130 | kvm_queue_exception(ctxt->vcpu, UD_VECTOR); |
1991 | type_bits, c->modrm_reg); | 2131 | goto done; |
1992 | } else { | ||
1993 | printk(KERN_INFO "Invalid segreg in modrm byte 0x%02x\n", | ||
1994 | c->modrm); | ||
1995 | goto cannot_emulate; | ||
1996 | } | 2132 | } |
1997 | 2133 | ||
1998 | if (err < 0) | 2134 | if (c->modrm_reg == VCPU_SREG_SS) |
1999 | 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); | ||
2000 | 2138 | ||
2001 | c->dst.type = OP_NONE; /* Disable writeback. */ | 2139 | c->dst.type = OP_NONE; /* Disable writeback. */ |
2002 | break; | 2140 | break; |
@@ -2025,7 +2163,10 @@ special_insn: | |||
2025 | c->dst.type = OP_REG; | 2163 | c->dst.type = OP_REG; |
2026 | c->dst.ptr = (unsigned long *) &ctxt->eflags; | 2164 | c->dst.ptr = (unsigned long *) &ctxt->eflags; |
2027 | c->dst.bytes = c->op_bytes; | 2165 | c->dst.bytes = c->op_bytes; |
2028 | 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; | ||
2029 | case 0xa0 ... 0xa1: /* mov */ | 2170 | case 0xa0 ... 0xa1: /* mov */ |
2030 | c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; | 2171 | c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; |
2031 | c->dst.val = c->src.val; | 2172 | c->dst.val = c->src.val; |
@@ -2039,11 +2180,12 @@ special_insn: | |||
2039 | c->dst.ptr = (unsigned long *)register_address(c, | 2180 | c->dst.ptr = (unsigned long *)register_address(c, |
2040 | es_base(ctxt), | 2181 | es_base(ctxt), |
2041 | c->regs[VCPU_REGS_RDI]); | 2182 | c->regs[VCPU_REGS_RDI]); |
2042 | if ((rc = ops->read_emulated(register_address(c, | 2183 | rc = ops->read_emulated(register_address(c, |
2043 | seg_override_base(ctxt, c), | 2184 | seg_override_base(ctxt, c), |
2044 | c->regs[VCPU_REGS_RSI]), | 2185 | c->regs[VCPU_REGS_RSI]), |
2045 | &c->dst.val, | 2186 | &c->dst.val, |
2046 | c->dst.bytes, ctxt->vcpu)) != 0) | 2187 | c->dst.bytes, ctxt->vcpu); |
2188 | if (rc != X86EMUL_CONTINUE) | ||
2047 | goto done; | 2189 | goto done; |
2048 | register_address_increment(c, &c->regs[VCPU_REGS_RSI], | 2190 | register_address_increment(c, &c->regs[VCPU_REGS_RSI], |
2049 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes | 2191 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes |
@@ -2058,10 +2200,11 @@ special_insn: | |||
2058 | c->src.ptr = (unsigned long *)register_address(c, | 2200 | c->src.ptr = (unsigned long *)register_address(c, |
2059 | seg_override_base(ctxt, c), | 2201 | seg_override_base(ctxt, c), |
2060 | c->regs[VCPU_REGS_RSI]); | 2202 | c->regs[VCPU_REGS_RSI]); |
2061 | if ((rc = ops->read_emulated((unsigned long)c->src.ptr, | 2203 | rc = ops->read_emulated((unsigned long)c->src.ptr, |
2062 | &c->src.val, | 2204 | &c->src.val, |
2063 | c->src.bytes, | 2205 | c->src.bytes, |
2064 | ctxt->vcpu)) != 0) | 2206 | ctxt->vcpu); |
2207 | if (rc != X86EMUL_CONTINUE) | ||
2065 | goto done; | 2208 | goto done; |
2066 | 2209 | ||
2067 | c->dst.type = OP_NONE; /* Disable writeback. */ | 2210 | c->dst.type = OP_NONE; /* Disable writeback. */ |
@@ -2069,10 +2212,11 @@ special_insn: | |||
2069 | c->dst.ptr = (unsigned long *)register_address(c, | 2212 | c->dst.ptr = (unsigned long *)register_address(c, |
2070 | es_base(ctxt), | 2213 | es_base(ctxt), |
2071 | c->regs[VCPU_REGS_RDI]); | 2214 | c->regs[VCPU_REGS_RDI]); |
2072 | if ((rc = ops->read_emulated((unsigned long)c->dst.ptr, | 2215 | rc = ops->read_emulated((unsigned long)c->dst.ptr, |
2073 | &c->dst.val, | 2216 | &c->dst.val, |
2074 | c->dst.bytes, | 2217 | c->dst.bytes, |
2075 | ctxt->vcpu)) != 0) | 2218 | ctxt->vcpu); |
2219 | if (rc != X86EMUL_CONTINUE) | ||
2076 | goto done; | 2220 | goto done; |
2077 | 2221 | ||
2078 | 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); |
@@ -2102,12 +2246,13 @@ special_insn: | |||
2102 | c->dst.type = OP_REG; | 2246 | c->dst.type = OP_REG; |
2103 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; | 2247 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; |
2104 | c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; | 2248 | c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; |
2105 | if ((rc = ops->read_emulated(register_address(c, | 2249 | rc = ops->read_emulated(register_address(c, |
2106 | seg_override_base(ctxt, c), | 2250 | seg_override_base(ctxt, c), |
2107 | c->regs[VCPU_REGS_RSI]), | 2251 | c->regs[VCPU_REGS_RSI]), |
2108 | &c->dst.val, | 2252 | &c->dst.val, |
2109 | c->dst.bytes, | 2253 | c->dst.bytes, |
2110 | ctxt->vcpu)) != 0) | 2254 | ctxt->vcpu); |
2255 | if (rc != X86EMUL_CONTINUE) | ||
2111 | goto done; | 2256 | goto done; |
2112 | register_address_increment(c, &c->regs[VCPU_REGS_RSI], | 2257 | register_address_increment(c, &c->regs[VCPU_REGS_RSI], |
2113 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes | 2258 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes |
@@ -2163,11 +2308,9 @@ special_insn: | |||
2163 | case 0xe9: /* jmp rel */ | 2308 | case 0xe9: /* jmp rel */ |
2164 | goto jmp; | 2309 | goto jmp; |
2165 | case 0xea: /* jmp far */ | 2310 | case 0xea: /* jmp far */ |
2166 | if (kvm_load_segment_descriptor(ctxt->vcpu, c->src2.val, 9, | 2311 | if (kvm_load_segment_descriptor(ctxt->vcpu, c->src2.val, |
2167 | VCPU_SREG_CS) < 0) { | 2312 | VCPU_SREG_CS)) |
2168 | DPRINTF("jmp far: Failed to load CS descriptor\n"); | 2313 | goto done; |
2169 | goto cannot_emulate; | ||
2170 | } | ||
2171 | 2314 | ||
2172 | c->eip = c->src.val; | 2315 | c->eip = c->src.val; |
2173 | break; | 2316 | break; |
@@ -2185,7 +2328,13 @@ special_insn: | |||
2185 | case 0xef: /* out (e/r)ax,dx */ | 2328 | case 0xef: /* out (e/r)ax,dx */ |
2186 | port = c->regs[VCPU_REGS_RDX]; | 2329 | port = c->regs[VCPU_REGS_RDX]; |
2187 | io_dir_in = 0; | 2330 | io_dir_in = 0; |
2188 | do_io: if (kvm_emulate_pio(ctxt->vcpu, 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, | ||
2189 | (c->d & ByteOp) ? 1 : c->op_bytes, | 2338 | (c->d & ByteOp) ? 1 : c->op_bytes, |
2190 | port) != 0) { | 2339 | port) != 0) { |
2191 | c->eip = saved_eip; | 2340 | c->eip = saved_eip; |
@@ -2210,13 +2359,21 @@ special_insn: | |||
2210 | c->dst.type = OP_NONE; /* Disable writeback. */ | 2359 | c->dst.type = OP_NONE; /* Disable writeback. */ |
2211 | break; | 2360 | break; |
2212 | case 0xfa: /* cli */ | 2361 | case 0xfa: /* cli */ |
2213 | ctxt->eflags &= ~X86_EFLAGS_IF; | 2362 | if (emulator_bad_iopl(ctxt)) |
2214 | 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 | } | ||
2215 | break; | 2368 | break; |
2216 | case 0xfb: /* sti */ | 2369 | case 0xfb: /* sti */ |
2217 | toggle_interruptibility(ctxt, X86_SHADOW_INT_STI); | 2370 | if (emulator_bad_iopl(ctxt)) |
2218 | ctxt->eflags |= X86_EFLAGS_IF; | 2371 | kvm_inject_gp(ctxt->vcpu, 0); |
2219 | 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 | } | ||
2220 | break; | 2377 | break; |
2221 | case 0xfc: /* cld */ | 2378 | case 0xfc: /* cld */ |
2222 | ctxt->eflags &= ~EFLG_DF; | 2379 | ctxt->eflags &= ~EFLG_DF; |
@@ -2319,8 +2476,9 @@ twobyte_insn: | |||
2319 | } | 2476 | } |
2320 | break; | 2477 | break; |
2321 | case 0x05: /* syscall */ | 2478 | case 0x05: /* syscall */ |
2322 | if (emulate_syscall(ctxt) == -1) | 2479 | rc = emulate_syscall(ctxt); |
2323 | goto cannot_emulate; | 2480 | if (rc != X86EMUL_CONTINUE) |
2481 | goto done; | ||
2324 | else | 2482 | else |
2325 | goto writeback; | 2483 | goto writeback; |
2326 | break; | 2484 | break; |
@@ -2391,14 +2549,16 @@ twobyte_insn: | |||
2391 | c->dst.type = OP_NONE; | 2549 | c->dst.type = OP_NONE; |
2392 | break; | 2550 | break; |
2393 | case 0x34: /* sysenter */ | 2551 | case 0x34: /* sysenter */ |
2394 | if (emulate_sysenter(ctxt) == -1) | 2552 | rc = emulate_sysenter(ctxt); |
2395 | goto cannot_emulate; | 2553 | if (rc != X86EMUL_CONTINUE) |
2554 | goto done; | ||
2396 | else | 2555 | else |
2397 | goto writeback; | 2556 | goto writeback; |
2398 | break; | 2557 | break; |
2399 | case 0x35: /* sysexit */ | 2558 | case 0x35: /* sysexit */ |
2400 | if (emulate_sysexit(ctxt) == -1) | 2559 | rc = emulate_sysexit(ctxt); |
2401 | goto cannot_emulate; | 2560 | if (rc != X86EMUL_CONTINUE) |
2561 | goto done; | ||
2402 | else | 2562 | else |
2403 | goto writeback; | 2563 | goto writeback; |
2404 | break; | 2564 | break; |