diff options
author | Avi Kivity <avi@redhat.com> | 2010-08-26 04:59:00 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-10-24 04:51:41 -0400 |
commit | f6b3597bded9ed261b42fdcb5e741489cb5ccbfe (patch) | |
tree | 9bb21ff6f2da81b4d2cd61ae70f733e04a881672 /arch/x86/kvm/emulate.c | |
parent | 739ae406068211b235b488f247aab349e486c382 (diff) |
KVM: x86 emulator: add macros for executing instructions that may trap
Like DIV and IDIV.
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r-- | arch/x86/kvm/emulate.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 58e715cb5172..e96cce170228 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -331,6 +331,27 @@ struct group_dual { | |||
331 | "a" (_rax), "d" (_rdx)); \ | 331 | "a" (_rax), "d" (_rdx)); \ |
332 | } while (0) | 332 | } while (0) |
333 | 333 | ||
334 | #define __emulate_1op_rax_rdx_ex(_op, _src, _rax, _rdx, _eflags, _suffix, _ex) \ | ||
335 | do { \ | ||
336 | unsigned long _tmp; \ | ||
337 | \ | ||
338 | __asm__ __volatile__ ( \ | ||
339 | _PRE_EFLAGS("0", "5", "1") \ | ||
340 | "1: \n\t" \ | ||
341 | _op _suffix " %6; " \ | ||
342 | "2: \n\t" \ | ||
343 | _POST_EFLAGS("0", "5", "1") \ | ||
344 | ".pushsection .fixup,\"ax\" \n\t" \ | ||
345 | "3: movb $1, %4 \n\t" \ | ||
346 | "jmp 2b \n\t" \ | ||
347 | ".popsection \n\t" \ | ||
348 | _ASM_EXTABLE(1b, 3b) \ | ||
349 | : "=m" (_eflags), "=&r" (_tmp), \ | ||
350 | "+a" (_rax), "+d" (_rdx), "+qm"(_ex) \ | ||
351 | : "i" (EFLAGS_MASK), "m" ((_src).val), \ | ||
352 | "a" (_rax), "d" (_rdx)); \ | ||
353 | } while (0) | ||
354 | |||
334 | /* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */ | 355 | /* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */ |
335 | #define emulate_1op_rax_rdx(_op, _src, _rax, _rdx, _eflags) \ | 356 | #define emulate_1op_rax_rdx(_op, _src, _rax, _rdx, _eflags) \ |
336 | do { \ | 357 | do { \ |
@@ -342,6 +363,28 @@ struct group_dual { | |||
342 | } \ | 363 | } \ |
343 | } while (0) | 364 | } while (0) |
344 | 365 | ||
366 | #define emulate_1op_rax_rdx_ex(_op, _src, _rax, _rdx, _eflags, _ex) \ | ||
367 | do { \ | ||
368 | switch((_src).bytes) { \ | ||
369 | case 1: \ | ||
370 | __emulate_1op_rax_rdx_ex(_op, _src, _rax, _rdx, \ | ||
371 | _eflags, "b", _ex); \ | ||
372 | break; \ | ||
373 | case 2: \ | ||
374 | __emulate_1op_rax_rdx_ex(_op, _src, _rax, _rdx, \ | ||
375 | _eflags, "w", _ex); \ | ||
376 | break; \ | ||
377 | case 4: \ | ||
378 | __emulate_1op_rax_rdx_ex(_op, _src, _rax, _rdx, \ | ||
379 | _eflags, "l", _ex); \ | ||
380 | break; \ | ||
381 | case 8: ON64( \ | ||
382 | __emulate_1op_rax_rdx_ex(_op, _src, _rax, _rdx, \ | ||
383 | _eflags, "q", _ex)); \ | ||
384 | break; \ | ||
385 | } \ | ||
386 | } while (0) | ||
387 | |||
345 | /* Fetch next part of the instruction being emulated. */ | 388 | /* Fetch next part of the instruction being emulated. */ |
346 | #define insn_fetch(_type, _size, _eip) \ | 389 | #define insn_fetch(_type, _size, _eip) \ |
347 | ({ unsigned long _x; \ | 390 | ({ unsigned long _x; \ |