From: Arthur Chunqi Li <yzt356@gmail.com>
To: kvm@vger.kernel.org
Cc: gleb@redhat.com, pbonzini@redhat.com, jan.kiszka@web.de,
Arthur Chunqi Li <yzt356@gmail.com>
Subject: [PATCH 1/2] kvm-unit-tests: Add a func to run instruction in emulator
Date: Thu, 20 Jun 2013 18:45:21 +0800 [thread overview]
Message-ID: <1371725122-6111-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>
---
lib/libcflat.h | 1 +
lib/string.c | 12 +++++++++
x86/emulator.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 91 insertions(+)
diff --git a/lib/libcflat.h b/lib/libcflat.h
index 0875bd9..fadc33d 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -50,6 +50,7 @@ extern int vsnprintf(char *buf, int size, const char *fmt, va_list va);
extern void puts(const char *s);
extern void *memset(void *s, int c, size_t n);
+extern void *memcpy(void *dest, const void *src, size_t n);
extern long atol(const char *ptr);
#define ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0]))
diff --git a/lib/string.c b/lib/string.c
index 9dc94a1..e798f86 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -42,6 +42,18 @@ void *memset(void *s, int c, size_t n)
return s;
}
+void *memcpy(void *dest, const void *src, size_t n)
+{
+ size_t i;
+ char *a = dest;
+ char *b = src;
+
+ for (i = 0; i < n; ++i)
+ a[i] = b[i];
+
+ return dest;
+}
+
long atol(const char *ptr)
{
long acc = 0;
diff --git a/x86/emulator.c b/x86/emulator.c
index 96576e5..b3626fa 100644
--- a/x86/emulator.c
+++ b/x86/emulator.c
@@ -11,6 +11,15 @@ int fails, tests;
static int exceptions;
+struct regs {
+ u64 rax, rbx, rcx, rdx;
+ u64 rsi, rdi, rsp, rbp;
+ u64 r8, r9, r10, r11;
+ u64 r12, r13, r14, r15;
+ u64 rip, rflags;
+};
+struct regs inregs, outregs, save;
+
void report(const char *name, int result)
{
++tests;
@@ -685,6 +694,75 @@ static void test_shld_shrd(u32 *mem)
report("shrd (cl)", *mem == ((0x12345678 >> 3) | (5u << 29)));
}
+#define INSN_XCHG_ALL \
+ "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 %rsp, 48+save \n\t" \
+ "xchg %rbp, 56+save \n\t" \
+ "xchg %r8, 64+save \n\t" \
+ "xchg %r9, 72+save \n\t" \
+ "xchg %r10, 80+save \n\t" \
+ "xchg %r11, 88+save \n\t" \
+ "xchg %r12, 96+save \n\t" \
+ "xchg %r13, 104+save \n\t" \
+ "xchg %r14, 112+save \n\t" \
+ "xchg %r15, 120+save \n\t" \
+
+asm(
+ ".align 4096\n\t"
+ "insn_page:\n\t"
+ "ret\n\t"
+ "pushf\n\t"
+ "push 136+save \n\t"
+ "popf \n\t"
+ INSN_XCHG_ALL
+ "test_insn:\n\t"
+ "in (%dx),%al\n\t"
+ ".skip 31, 0x90\n\t"
+ "test_insn_end:\n\t"
+ INSN_XCHG_ALL
+ "pushf \n\t"
+ "pop 136+save \n\t"
+ "popf \n\t"
+ "ret \n\t"
+ "insn_page_end:\n\t"
+ ".align 4096\n\t"
+
+ "alt_insn_page:\n\t"
+ ". = . + 4096\n\t"
+ ".align 4096\n\t"
+);
+
+static void trap_emulator(uint64_t *mem, uint8_t* alt_insn, int alt_insn_length)
+{
+ ulong *cr3 = (ulong *)read_cr3();
+ void *insn_ram;
+ extern u8 insn_page[], test_insn[], alt_insn_page[];
+
+ insn_ram = vmap(virt_to_phys(insn_page), 4096);
+ memcpy(alt_insn_page, test_insn, 4096);
+ memcpy(alt_insn_page + (test_insn - insn_page), alt_insn, alt_insn_length);
+ 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("call *%0": : "r"(insn_ram+1));
+
+ 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-20 10:45 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-20 10:45 Arthur Chunqi Li [this message]
2013-06-20 10:45 ` [PATCH 2/2] kvm-unit-tests: Change two cases to use trap_emulator Arthur Chunqi Li
2013-06-20 12:33 ` Gleb Natapov
2013-06-20 10:47 ` [PATCH 1/2] kvm-unit-tests: Add a func to run instruction in emulator Jan Kiszka
2013-06-20 12:32 ` Gleb Natapov
-- strict thread matches above, loose matches on Subject: below --
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-10 13:38 Arthur Chunqi Li
2013-06-10 17:36 ` Gleb Natapov
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=1371725122-6111-1-git-send-email-yzt356@gmail.com \
--to=yzt356@gmail.com \
--cc=gleb@redhat.com \
--cc=jan.kiszka@web.de \
--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).