diff options
Diffstat (limited to 'drivers/kvm/x86_emulate.c')
-rw-r--r-- | drivers/kvm/x86_emulate.c | 76 |
1 files changed, 37 insertions, 39 deletions
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c index e294d8409571..75fd23bade9c 100644 --- a/drivers/kvm/x86_emulate.c +++ b/drivers/kvm/x86_emulate.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <stdio.h> | 23 | #include <stdio.h> |
24 | #include <stdint.h> | 24 | #include <stdint.h> |
25 | #include <public/xen.h> | 25 | #include <public/xen.h> |
26 | #define DPRINTF(_f, _a ...) printf( _f , ## _a ) | 26 | #define DPRINTF(_f, _a ...) printf(_f , ## _a) |
27 | #else | 27 | #else |
28 | #include "kvm.h" | 28 | #include "kvm.h" |
29 | #define DPRINTF(x...) do {} while (0) | 29 | #define DPRINTF(x...) do {} while (0) |
@@ -285,21 +285,21 @@ static u16 twobyte_table[256] = { | |||
285 | switch ((_dst).bytes) { \ | 285 | switch ((_dst).bytes) { \ |
286 | case 2: \ | 286 | case 2: \ |
287 | __asm__ __volatile__ ( \ | 287 | __asm__ __volatile__ ( \ |
288 | _PRE_EFLAGS("0","4","2") \ | 288 | _PRE_EFLAGS("0", "4", "2") \ |
289 | _op"w %"_wx"3,%1; " \ | 289 | _op"w %"_wx"3,%1; " \ |
290 | _POST_EFLAGS("0","4","2") \ | 290 | _POST_EFLAGS("0", "4", "2") \ |
291 | : "=m" (_eflags), "=m" ((_dst).val), \ | 291 | : "=m" (_eflags), "=m" ((_dst).val), \ |
292 | "=&r" (_tmp) \ | 292 | "=&r" (_tmp) \ |
293 | : _wy ((_src).val), "i" (EFLAGS_MASK) ); \ | 293 | : _wy ((_src).val), "i" (EFLAGS_MASK)); \ |
294 | break; \ | 294 | break; \ |
295 | case 4: \ | 295 | case 4: \ |
296 | __asm__ __volatile__ ( \ | 296 | __asm__ __volatile__ ( \ |
297 | _PRE_EFLAGS("0","4","2") \ | 297 | _PRE_EFLAGS("0", "4", "2") \ |
298 | _op"l %"_lx"3,%1; " \ | 298 | _op"l %"_lx"3,%1; " \ |
299 | _POST_EFLAGS("0","4","2") \ | 299 | _POST_EFLAGS("0", "4", "2") \ |
300 | : "=m" (_eflags), "=m" ((_dst).val), \ | 300 | : "=m" (_eflags), "=m" ((_dst).val), \ |
301 | "=&r" (_tmp) \ | 301 | "=&r" (_tmp) \ |
302 | : _ly ((_src).val), "i" (EFLAGS_MASK) ); \ | 302 | : _ly ((_src).val), "i" (EFLAGS_MASK)); \ |
303 | break; \ | 303 | break; \ |
304 | case 8: \ | 304 | case 8: \ |
305 | __emulate_2op_8byte(_op, _src, _dst, \ | 305 | __emulate_2op_8byte(_op, _src, _dst, \ |
@@ -311,16 +311,15 @@ static u16 twobyte_table[256] = { | |||
311 | #define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \ | 311 | #define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \ |
312 | do { \ | 312 | do { \ |
313 | unsigned long _tmp; \ | 313 | unsigned long _tmp; \ |
314 | switch ( (_dst).bytes ) \ | 314 | switch ((_dst).bytes) { \ |
315 | { \ | ||
316 | case 1: \ | 315 | case 1: \ |
317 | __asm__ __volatile__ ( \ | 316 | __asm__ __volatile__ ( \ |
318 | _PRE_EFLAGS("0","4","2") \ | 317 | _PRE_EFLAGS("0", "4", "2") \ |
319 | _op"b %"_bx"3,%1; " \ | 318 | _op"b %"_bx"3,%1; " \ |
320 | _POST_EFLAGS("0","4","2") \ | 319 | _POST_EFLAGS("0", "4", "2") \ |
321 | : "=m" (_eflags), "=m" ((_dst).val), \ | 320 | : "=m" (_eflags), "=m" ((_dst).val), \ |
322 | "=&r" (_tmp) \ | 321 | "=&r" (_tmp) \ |
323 | : _by ((_src).val), "i" (EFLAGS_MASK) ); \ | 322 | : _by ((_src).val), "i" (EFLAGS_MASK)); \ |
324 | break; \ | 323 | break; \ |
325 | default: \ | 324 | default: \ |
326 | __emulate_2op_nobyte(_op, _src, _dst, _eflags, \ | 325 | __emulate_2op_nobyte(_op, _src, _dst, _eflags, \ |
@@ -349,34 +348,33 @@ static u16 twobyte_table[256] = { | |||
349 | do { \ | 348 | do { \ |
350 | unsigned long _tmp; \ | 349 | unsigned long _tmp; \ |
351 | \ | 350 | \ |
352 | switch ( (_dst).bytes ) \ | 351 | switch ((_dst).bytes) { \ |
353 | { \ | ||
354 | case 1: \ | 352 | case 1: \ |
355 | __asm__ __volatile__ ( \ | 353 | __asm__ __volatile__ ( \ |
356 | _PRE_EFLAGS("0","3","2") \ | 354 | _PRE_EFLAGS("0", "3", "2") \ |
357 | _op"b %1; " \ | 355 | _op"b %1; " \ |
358 | _POST_EFLAGS("0","3","2") \ | 356 | _POST_EFLAGS("0", "3", "2") \ |
359 | : "=m" (_eflags), "=m" ((_dst).val), \ | 357 | : "=m" (_eflags), "=m" ((_dst).val), \ |
360 | "=&r" (_tmp) \ | 358 | "=&r" (_tmp) \ |
361 | : "i" (EFLAGS_MASK) ); \ | 359 | : "i" (EFLAGS_MASK)); \ |
362 | break; \ | 360 | break; \ |
363 | case 2: \ | 361 | case 2: \ |
364 | __asm__ __volatile__ ( \ | 362 | __asm__ __volatile__ ( \ |
365 | _PRE_EFLAGS("0","3","2") \ | 363 | _PRE_EFLAGS("0", "3", "2") \ |
366 | _op"w %1; " \ | 364 | _op"w %1; " \ |
367 | _POST_EFLAGS("0","3","2") \ | 365 | _POST_EFLAGS("0", "3", "2") \ |
368 | : "=m" (_eflags), "=m" ((_dst).val), \ | 366 | : "=m" (_eflags), "=m" ((_dst).val), \ |
369 | "=&r" (_tmp) \ | 367 | "=&r" (_tmp) \ |
370 | : "i" (EFLAGS_MASK) ); \ | 368 | : "i" (EFLAGS_MASK)); \ |
371 | break; \ | 369 | break; \ |
372 | case 4: \ | 370 | case 4: \ |
373 | __asm__ __volatile__ ( \ | 371 | __asm__ __volatile__ ( \ |
374 | _PRE_EFLAGS("0","3","2") \ | 372 | _PRE_EFLAGS("0", "3", "2") \ |
375 | _op"l %1; " \ | 373 | _op"l %1; " \ |
376 | _POST_EFLAGS("0","3","2") \ | 374 | _POST_EFLAGS("0", "3", "2") \ |
377 | : "=m" (_eflags), "=m" ((_dst).val), \ | 375 | : "=m" (_eflags), "=m" ((_dst).val), \ |
378 | "=&r" (_tmp) \ | 376 | "=&r" (_tmp) \ |
379 | : "i" (EFLAGS_MASK) ); \ | 377 | : "i" (EFLAGS_MASK)); \ |
380 | break; \ | 378 | break; \ |
381 | case 8: \ | 379 | case 8: \ |
382 | __emulate_1op_8byte(_op, _dst, _eflags); \ | 380 | __emulate_1op_8byte(_op, _dst, _eflags); \ |
@@ -389,21 +387,21 @@ static u16 twobyte_table[256] = { | |||
389 | #define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy) \ | 387 | #define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy) \ |
390 | do { \ | 388 | do { \ |
391 | __asm__ __volatile__ ( \ | 389 | __asm__ __volatile__ ( \ |
392 | _PRE_EFLAGS("0","4","2") \ | 390 | _PRE_EFLAGS("0", "4", "2") \ |
393 | _op"q %"_qx"3,%1; " \ | 391 | _op"q %"_qx"3,%1; " \ |
394 | _POST_EFLAGS("0","4","2") \ | 392 | _POST_EFLAGS("0", "4", "2") \ |
395 | : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \ | 393 | : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \ |
396 | : _qy ((_src).val), "i" (EFLAGS_MASK) ); \ | 394 | : _qy ((_src).val), "i" (EFLAGS_MASK)); \ |
397 | } while (0) | 395 | } while (0) |
398 | 396 | ||
399 | #define __emulate_1op_8byte(_op, _dst, _eflags) \ | 397 | #define __emulate_1op_8byte(_op, _dst, _eflags) \ |
400 | do { \ | 398 | do { \ |
401 | __asm__ __volatile__ ( \ | 399 | __asm__ __volatile__ ( \ |
402 | _PRE_EFLAGS("0","3","2") \ | 400 | _PRE_EFLAGS("0", "3", "2") \ |
403 | _op"q %1; " \ | 401 | _op"q %1; " \ |
404 | _POST_EFLAGS("0","3","2") \ | 402 | _POST_EFLAGS("0", "3", "2") \ |
405 | : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \ | 403 | : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \ |
406 | : "i" (EFLAGS_MASK) ); \ | 404 | : "i" (EFLAGS_MASK)); \ |
407 | } while (0) | 405 | } while (0) |
408 | 406 | ||
409 | #elif defined(__i386__) | 407 | #elif defined(__i386__) |
@@ -415,8 +413,8 @@ static u16 twobyte_table[256] = { | |||
415 | #define insn_fetch(_type, _size, _eip) \ | 413 | #define insn_fetch(_type, _size, _eip) \ |
416 | ({ unsigned long _x; \ | 414 | ({ unsigned long _x; \ |
417 | rc = ops->read_std((unsigned long)(_eip) + ctxt->cs_base, &_x, \ | 415 | rc = ops->read_std((unsigned long)(_eip) + ctxt->cs_base, &_x, \ |
418 | (_size), ctxt->vcpu); \ | 416 | (_size), ctxt->vcpu); \ |
419 | if ( rc != 0 ) \ | 417 | if (rc != 0) \ |
420 | goto done; \ | 418 | goto done; \ |
421 | (_eip) += (_size); \ | 419 | (_eip) += (_size); \ |
422 | (_type)_x; \ | 420 | (_type)_x; \ |
@@ -780,7 +778,7 @@ done_prefixes: | |||
780 | } | 778 | } |
781 | if (c->ad_bytes != 8) | 779 | if (c->ad_bytes != 8) |
782 | c->modrm_ea = (u32)c->modrm_ea; | 780 | c->modrm_ea = (u32)c->modrm_ea; |
783 | modrm_done: | 781 | modrm_done: |
784 | ; | 782 | ; |
785 | } | 783 | } |
786 | 784 | ||
@@ -828,10 +826,9 @@ done_prefixes: | |||
828 | c->src.bytes = (c->d & ByteOp) ? 1 : | 826 | c->src.bytes = (c->d & ByteOp) ? 1 : |
829 | c->op_bytes; | 827 | c->op_bytes; |
830 | /* Don't fetch the address for invlpg: it could be unmapped. */ | 828 | /* Don't fetch the address for invlpg: it could be unmapped. */ |
831 | if (c->twobyte && c->b == 0x01 | 829 | if (c->twobyte && c->b == 0x01 && c->modrm_reg == 7) |
832 | && c->modrm_reg == 7) | ||
833 | break; | 830 | break; |
834 | srcmem_common: | 831 | srcmem_common: |
835 | /* | 832 | /* |
836 | * For instructions with a ModR/M byte, switch to register | 833 | * For instructions with a ModR/M byte, switch to register |
837 | * access if Mod = 3. | 834 | * access if Mod = 3. |
@@ -1175,10 +1172,11 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1175 | if (c->src.type == OP_MEM) { | 1172 | if (c->src.type == OP_MEM) { |
1176 | c->src.ptr = (unsigned long *)cr2; | 1173 | c->src.ptr = (unsigned long *)cr2; |
1177 | c->src.val = 0; | 1174 | c->src.val = 0; |
1178 | if ((rc = ops->read_emulated((unsigned long)c->src.ptr, | 1175 | rc = ops->read_emulated((unsigned long)c->src.ptr, |
1179 | &c->src.val, | 1176 | &c->src.val, |
1180 | c->src.bytes, | 1177 | c->src.bytes, |
1181 | ctxt->vcpu)) != 0) | 1178 | ctxt->vcpu); |
1179 | if (rc != 0) | ||
1182 | goto done; | 1180 | goto done; |
1183 | c->src.orig_val = c->src.val; | 1181 | c->src.orig_val = c->src.val; |
1184 | } | 1182 | } |