From: Arthur Chunqi Li <yzt356@gmail.com>
To: kvm@vger.kernel.org
Cc: gleb@redhat.com, pbonzini@redhat.com,
Arthur Chunqi Li <yzt356@gmail.com>
Subject: [PATCH 1/2] kvm-unit-tests: Add a func to run instruction in emulator
Date: Mon, 10 Jun 2013 21:38:32 +0800 [thread overview]
Message-ID: <1370871513-31815-1-git-send-email-yzt356@gmail.com> (raw)
Add a function trap_emulator to run an instruction in emulator.
Set inregs first (%rax is invalid because it is used as return
address), put instruction codec in alt_insn and call func with
alt_insn_length. Get results in outregs.
Signed-off-by: Arthur Chunqi Li <yzt356@gmail.com>
---
x86/emulator.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 106 insertions(+)
diff --git a/x86/emulator.c b/x86/emulator.c
index 96576e5..a1bd92e 100644
--- 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,105 @@ 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, int reserve_stack)
+{
+ ulong *cr3 = (ulong *)read_cr3();
+ int i;
+ static struct regs save;
+
+ // Pad with RET instructions
+ memset(insn_page, 0x90, 4096);
+ memset(alt_insn_page, 0x90, 4096);
+
+ asm volatile(
+ "movw $1, %0\n\t"
+ : : "m"(mem)
+ : "memory"
+ );
+ // Place a trapping instruction in the page to trigger a VMEXIT
+ insn_page[0] = 0xc3; // ret
+ if (!reserve_stack)
+ {
+ insn_page[1] = 0x49; // xchg %rsp,%r9
+ insn_page[2] = 0x87;
+ insn_page[3] = 0xe1;
+ insn_page[4] = 0x49; // xchg %rbp,%r10
+ insn_page[5] = 0x87;
+ insn_page[6] = 0xea;
+ }
+ //in (%dx),%al, may change in the future
+ insn_page[7] = 0xec;
+
+ // Place the instruction we want the hypervisor to see in the alternate page
+ for (i=7; i<alt_insn_length+7; i++)
+ alt_insn_page[i] = alt_insn[i-7];
+
+ if (!reserve_stack)
+ {
+ insn_page[i+0] = 0x49; // xchg %rsp,%r9
+ insn_page[i+1] = 0x87;
+ insn_page[i+2] = 0xe1;
+ insn_page[i+3] = 0x49; // xchg %rbp,%r10
+ insn_page[i+4] = 0x87;
+ insn_page[i+5] = 0xea;
+ }
+ else
+ {
+ insn_page[i+0] = 0x49; // mov %rsp,%r9
+ insn_page[i+1] = 0x89;
+ insn_page[i+2] = 0xe1;
+ insn_page[i+3] = 0x49; // mov %rbp,%r10
+ insn_page[i+4] = 0x89;
+ insn_page[i+5] = 0xea;
+ }
+ insn_page[i+6] = 0xc3; // ret
+
+ save = inregs;
+
+ // Load the code TLB with insn_page, but point the page tables at
+ // alt_insn_page (and keep the data TLB clear, for AMD decode assist).
+ // This will make the CPU trap on the insn_page instruction but the
+ // hypervisor will see alt_insn_page.
+ install_page(cr3, virt_to_phys(insn_page), insn_ram);
+ invlpg(insn_ram);
+ // Load code TLB
+ asm volatile("call *%0" : : "r"(insn_ram));
+ install_page(cr3, virt_to_phys(alt_insn_page), insn_ram);
+ // Trap, let hypervisor emulate at alt_insn_page
+ asm volatile(
+ "push 72+%[save]; popf\n\t"
+ "mov %2, %%r8\n\t"
+ "xchg %%rax, 0+%[save] \n\t"
+ "xchg %%rbx, 8+%[save] \n\t"
+ "xchg %%rcx, 16+%[save] \n\t"
+ "xchg %%rdx, 24+%[save] \n\t"
+ "xchg %%rsi, 32+%[save] \n\t"
+ "xchg %%rdi, 40+%[save] \n\t"
+ "xchg %%r9, 48+%[save]\n\t"
+ "xchg %%r10, 56+%[save]\n\t"
+
+ "call *%1\n\t"
+
+ "xchg %%rax, 0+%[save] \n\t"
+ "xchg %%rbx, 8+%[save] \n\t"
+ "xchg %%rcx, 16+%[save] \n\t"
+ "xchg %%rdx, 24+%[save] \n\t"
+ "xchg %%rsi, 32+%[save] \n\t"
+ "xchg %%rdi, 40+%[save] \n\t"
+ "xchg %%r9, 48+%[save] \n\t"
+ "xchg %%r10, 56+%[save] \n\t"
+ /* Save RFLAGS in outregs*/
+ "pushf \n\t"
+ "pop 72+%[save] \n\t"
+ : [save]"+m"(save)
+ : "r"(insn_ram+1), "r"(mem)
+ : "memory", "cc", "r8", "r9", "r10"
+ );
+ outregs = save;
+}
+
static void advance_rip_by_3_and_note_exception(struct ex_regs *regs)
{
++exceptions;
--
1.7.9.5
next reply other threads:[~2013-06-10 13:38 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-10 13:38 Arthur Chunqi Li [this message]
2013-06-10 13:38 ` [PATCH 2/2] kvm-unit-tests: Change two cases to use trap_emulator Arthur Chunqi Li
2013-06-10 17:36 ` [PATCH 1/2] kvm-unit-tests: Add a func to run instruction in emulator Gleb Natapov
-- strict thread matches above, loose matches on Subject: below --
2013-06-20 10:45 Arthur Chunqi Li
2013-06-20 10:47 ` Jan Kiszka
2013-06-20 12:32 ` Gleb Natapov
2013-06-19 15:00 Arthur Chunqi Li
2013-06-19 15:07 ` 李春奇 <Arthur Chunqi Li>
2013-06-19 16:03 ` Gleb Natapov
2013-06-19 17:48 ` Gmail
2013-06-20 5:42 ` Gleb Natapov
2013-06-20 8:29 ` Paolo Bonzini
2013-06-20 8:31 ` Gleb Natapov
2013-06-20 8:48 ` Gleb Natapov
2013-06-20 8:58 ` Gmail
2013-06-13 15:16 Arthur Chunqi Li
2013-06-07 2:31 Arthur Chunqi Li
2013-06-09 11:07 ` Gleb Natapov
2013-06-09 12:44 ` 李春奇 <Arthur Chunqi Li>
2013-06-09 12:49 ` Gleb Natapov
2013-06-09 12:56 ` 李春奇 <Arthur Chunqi Li>
2013-06-09 12:58 ` Gleb Natapov
2013-06-09 13:22 ` 李春奇 <Arthur Chunqi Li>
2013-06-09 14:09 ` Gleb Natapov
2013-06-09 15:23 ` 李春奇 <Arthur Chunqi Li>
2013-06-09 16:00 ` Gleb Natapov
2013-06-09 17:09 ` 李春奇 <Arthur Chunqi Li>
2013-06-09 17:13 ` Gleb Natapov
2013-06-09 17:28 ` 李春奇 <Arthur Chunqi Li>
2013-06-09 17:39 ` Gleb Natapov
2013-06-06 15:24 Arthur Chunqi Li
2013-06-07 2:14 ` 李春奇 <Arthur Chunqi Li>
2013-06-12 20:50 ` Paolo Bonzini
2013-06-13 4:50 ` 李春奇 <Arthur Chunqi Li>
2013-06-13 9:30 ` 李春奇 <Arthur Chunqi Li>
2013-06-13 13:12 ` Paolo Bonzini
2013-06-18 12:45 ` Gleb Natapov
2013-06-18 13:40 ` 李春奇 <Arthur Chunqi Li>
2013-06-18 14:28 ` 李春奇 <Arthur Chunqi Li>
2013-06-18 15:47 ` Gleb Natapov
2013-06-18 15:56 ` 李春奇 <Arthur Chunqi Li>
2013-06-18 16:09 ` Gleb Natapov
2013-06-18 16:14 ` 李春奇 <Arthur Chunqi Li>
2013-06-18 16:44 ` Gleb Natapov
2013-06-19 1:26 ` 李春奇 <Arthur Chunqi Li>
2013-06-19 9:31 ` Gleb Natapov
2013-06-19 12:18 ` 李春奇 <Arthur Chunqi Li>
2013-06-19 12:26 ` Gleb Natapov
2013-06-19 12:30 ` 李春奇 <Arthur Chunqi Li>
2013-06-19 12:32 ` Gleb Natapov
2013-06-19 14:01 ` 李春奇 <Arthur Chunqi Li>
2013-06-19 14:13 ` Gleb Natapov
2013-06-19 14:20 ` 李春奇 <Arthur Chunqi Li>
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1370871513-31815-1-git-send-email-yzt356@gmail.com \
--to=yzt356@gmail.com \
--cc=gleb@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=pbonzini@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).