From: Arthur Chunqi Li Subject: [PATCH 1/2] kvm-unit-tests: Add a func to run instruction in emulator Date: Fri, 7 Jun 2013 10:31:38 +0800 Message-ID: <1370572299-2706-1-git-send-email-yzt356@gmail.com> Cc: gleb@redhat.com, pbonzini@redhat.com, Arthur Chunqi Li To: kvm@vger.kernel.org Return-path: Received: from mail-pd0-f169.google.com ([209.85.192.169]:47471 "EHLO mail-pd0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752807Ab3FGCbw (ORCPT ); Thu, 6 Jun 2013 22:31:52 -0400 Received: by mail-pd0-f169.google.com with SMTP id y10so4195623pdj.14 for ; Thu, 06 Jun 2013 19:31:52 -0700 (PDT) Sender: kvm-owner@vger.kernel.org List-ID: Add a function trap_emulator to run an instruction in emulator. Set inregs first (%rax, %rsp, %rbp, %rflags have special usage and cannot set in inregs), put instruction codec in alt_insn and call func with alt_insn_length. Get results in outregs. Signed-off-by: Arthur Chunqi Li --- x86/emulator.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) mode change 100644 => 100755 x86/emulator.c diff --git a/x86/emulator.c b/x86/emulator.c old mode 100644 new mode 100755 index 96576e5..770e8f7 --- a/x86/emulator.c +++ b/x86/emulator.c @@ -11,6 +11,13 @@ int fails, tests; static int exceptions; +struct regs { + u64 rax, rbx, rcx, rdx; + u64 rsi, rdi, rsp, rbp; + u64 rip, rflags; +}; +static struct regs inregs, outregs; + void report(const char *name, int result) { ++tests; @@ -685,6 +692,66 @@ static void test_shld_shrd(u32 *mem) report("shrd (cl)", *mem == ((0x12345678 >> 3) | (5u << 29))); } +static void trap_emulator(uint64_t *mem, uint8_t *insn_page, + uint8_t *alt_insn_page, void *insn_ram, + uint8_t *alt_insn, int alt_insn_length) +{ + ulong *cr3 = (ulong *)read_cr3(); + int i; + static struct regs save; + + // Pad with RET instructions + memset(insn_page, 0xc3, 4096); + memset(alt_insn_page, 0xc3, 4096); + + // Place a trapping instruction in the page to trigger a VMEXIT + insn_page[0] = 0x89; // mov %eax, (%rax) + insn_page[1] = 0x00; + insn_page[2] = 0x90; // nop + insn_page[3] = 0xc3; // ret + + // Place the instruction we want the hypervisor to see in the alternate page + for (i=0; i