aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/emulate.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-08-26 04:59:00 -0400
committerAvi Kivity <avi@redhat.com>2010-10-24 04:51:41 -0400
commitf6b3597bded9ed261b42fdcb5e741489cb5ccbfe (patch)
tree9bb21ff6f2da81b4d2cd61ae70f733e04a881672 /arch/x86/kvm/emulate.c
parent739ae406068211b235b488f247aab349e486c382 (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.c43
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; \