aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/x86_emulate.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/kvm/x86_emulate.c')
-rw-r--r--drivers/kvm/x86_emulate.c76
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: 781modrm_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 }