kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Simple test for sysenter instruction
@ 2021-03-15 21:09 Maxim Levitsky
  2021-03-15 21:09 ` [PATCH v2 1/2] x86/msr: run this test with intel vendor id Maxim Levitsky
  2021-03-15 21:09 ` [PATCH v2 2/2] Add a simple test for SYSENTER instruction Maxim Levitsky
  0 siblings, 2 replies; 3+ messages in thread
From: Maxim Levitsky @ 2021-03-15 21:09 UTC (permalink / raw)
  To: kvm; +Cc: Maxim Levitsky

Hi,

This patch series adds a simple test for sysenter instruction running in
comp32 mode, while using Intel vendor ID.

In this setting, KVM emulates this instruction to help with cross-vendor
migration on AMD.

I also added a patch to 'msr' test to run it with Intel's vendor ID, since this
test tests that SYSENTER EIP/ESP msrs are 64 bit wide which is only true on AMD.

KVM used to emulate these msrs to be always 64 bit on AMD, but this soon will
be changed to do the emulation only when guest CPU vendor ID is of Intel.

Best regards,
    Maxim Levitsky

Maxim Levitsky (2):
  x86/msr: run this test with intel vendor id
  Add a simple test for SYSENTER instruction.

 x86/Makefile.x86_64 |  3 ++
 x86/cstart64.S      |  1 +
 x86/sysenter.c      | 91 +++++++++++++++++++++++++++++++++++++++++++++
 x86/unittests.cfg   |  6 +++
 4 files changed, 101 insertions(+)
 create mode 100644 x86/sysenter.c

-- 
2.26.2



^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH v2 1/2] x86/msr: run this test with intel vendor id
  2021-03-15 21:09 [PATCH v2 0/2] Simple test for sysenter instruction Maxim Levitsky
@ 2021-03-15 21:09 ` Maxim Levitsky
  2021-03-15 21:09 ` [PATCH v2 2/2] Add a simple test for SYSENTER instruction Maxim Levitsky
  1 sibling, 0 replies; 3+ messages in thread
From: Maxim Levitsky @ 2021-03-15 21:09 UTC (permalink / raw)
  To: kvm; +Cc: Maxim Levitsky

Part of this test, tests that sysenter msrs are 64 bit wide
which is only true on Intel.

We emulate Intel variant of SYSENTER in KVM when
Intel's vendor ID is used to help with cross-vendor migration,
which includes extending SYSENTER msrs to 64 bit.

The later was done unconditionally which soon will be limited
to VMs which use Intel's vendor ID.

So run the test with Intel's vendor ID so it continues to pass.

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 x86/unittests.cfg | 1 +
 1 file changed, 1 insertion(+)

diff --git a/x86/unittests.cfg b/x86/unittests.cfg
index 0698d15..60c4b13 100644
--- a/x86/unittests.cfg
+++ b/x86/unittests.cfg
@@ -168,6 +168,7 @@ arch = x86_64
 
 [msr]
 file = msr.flat
+extra_params = -cpu host,vendor=GenuineIntel
 
 [pmu]
 file = pmu.flat
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v2 2/2] Add a simple test for SYSENTER instruction.
  2021-03-15 21:09 [PATCH v2 0/2] Simple test for sysenter instruction Maxim Levitsky
  2021-03-15 21:09 ` [PATCH v2 1/2] x86/msr: run this test with intel vendor id Maxim Levitsky
@ 2021-03-15 21:09 ` Maxim Levitsky
  1 sibling, 0 replies; 3+ messages in thread
From: Maxim Levitsky @ 2021-03-15 21:09 UTC (permalink / raw)
  To: kvm; +Cc: Maxim Levitsky

Run the test with Intel's vendor ID and in the long mode,
to test the emulation of this instruction on AMD.

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 x86/Makefile.x86_64 |  3 ++
 x86/cstart64.S      |  1 +
 x86/sysenter.c      | 91 +++++++++++++++++++++++++++++++++++++++++++++
 x86/unittests.cfg   |  5 +++
 4 files changed, 100 insertions(+)
 create mode 100644 x86/sysenter.c

diff --git a/x86/Makefile.x86_64 b/x86/Makefile.x86_64
index 8134952..c430bfb 100644
--- a/x86/Makefile.x86_64
+++ b/x86/Makefile.x86_64
@@ -16,6 +16,7 @@ tests = $(TEST_DIR)/access.flat $(TEST_DIR)/apic.flat \
 	  $(TEST_DIR)/ioapic.flat $(TEST_DIR)/memory.flat \
 	  $(TEST_DIR)/pku.flat $(TEST_DIR)/hyperv_clock.flat
 tests += $(TEST_DIR)/syscall.flat
+tests += $(TEST_DIR)/sysenter.flat
 tests += $(TEST_DIR)/svm.flat
 tests += $(TEST_DIR)/vmx.flat
 tests += $(TEST_DIR)/tscdeadline_latency.flat
@@ -35,3 +36,5 @@ $(TEST_DIR)/hyperv_clock.elf: $(TEST_DIR)/hyperv_clock.o
 
 $(TEST_DIR)/vmx.elf: $(TEST_DIR)/vmx_tests.o
 $(TEST_DIR)/svm.elf: $(TEST_DIR)/svm_tests.o
+
+$(TEST_DIR)/sysenter.o: CFLAGS += -Wa,-mintel64
\ No newline at end of file
diff --git a/x86/cstart64.S b/x86/cstart64.S
index 5c6ad38..62ace35 100644
--- a/x86/cstart64.S
+++ b/x86/cstart64.S
@@ -62,6 +62,7 @@ gdt64_desc:
 	.word gdt64_end - gdt64 - 1
 	.quad gdt64
 
+.globl gdt64
 gdt64:
 	.quad 0
 	.quad 0x00af9b000000ffff // 64-bit code segment
diff --git a/x86/sysenter.c b/x86/sysenter.c
new file mode 100644
index 0000000..c1fc9d5
--- /dev/null
+++ b/x86/sysenter.c
@@ -0,0 +1,91 @@
+
+#include "libcflat.h"
+#include "processor.h"
+#include "msr.h"
+#include "desc.h"
+
+extern uint64_t gdt64[];
+
+// undefine this to run the syscall instruction in 64 bit mode.
+// this won't work on AMD due to disabled code in the emulator.
+#define COMP32
+
+int main(int ac, char **av)
+{
+    extern void sysenter_target(void);
+    int gdt_index = 0x50 >> 3;
+    ulong rax = 0xDEAD;
+
+    /* init the sysenter GDT block */
+    gdt64[gdt_index+0] = gdt64[KERNEL_CS >> 3];
+    gdt64[gdt_index+1] = gdt64[KERNEL_DS >> 3];
+    gdt64[gdt_index+2] = gdt64[USER_CS >> 3];
+    gdt64[gdt_index+3] = gdt64[USER_DS >> 3];
+
+    /* init the sysenter msrs*/
+    wrmsr(MSR_IA32_SYSENTER_CS, gdt_index << 3);
+    wrmsr(MSR_IA32_SYSENTER_ESP, 0xAAFFFFFFFF);
+    wrmsr(MSR_IA32_SYSENTER_EIP, (uint64_t)sysenter_target);
+
+    asm volatile (
+#ifdef COMP32
+        "# switch to comp32, mode prior to running the test\n"
+        "ljmpl *1f\n"
+        "1:\n"
+        ".long 1f\n"
+        ".long " xstr(KERNEL_CS32) "\n"
+        "1:\n"
+        ".code32\n"
+#endif
+        "# use sysenter\n"
+        "mov %%esp, %%ecx #stash rsp value\n"
+        "mov $1, %%ebx\n"
+        "sysenter\n"
+        "ud2\n"
+
+        "# 64 bit cpl=0 code\n"
+        "sysenter_target:\n"
+        ".code64\n"
+        "test %%rbx, %%rbx # check if we are here for second time \n"
+        "jne 1f\n"
+        "movq %%rcx, %%rsp # restore stack pointer manually\n"
+        "jmp test_done\n"
+
+        "1:\n"
+        "# test that MSR_IA32_SYSENTER_ESP is correct\n"
+        "movq $0xAAFFFFFFFF, %%rbx\n"
+        "movq $0xDEAD, %%rax\n"
+        "cmpq %%rsp, %%rbx \n"
+        "jne 1f\n"
+        "movq $0xACED, %%rax\n"
+
+        "# use sysexit to exit back to cpl=3 32 bit code\n"
+        "1:\n"
+        "leaq sysexit_target, %%rdx\n"
+        "sysexit\n"
+        "ud2\n"
+
+        "# second sysenter to return to CPL=0 and 64 bit\n"
+        "# the sysenter handler will jump back to here without sysexit due to ebx=0\n"
+        "sysexit_target:\n"
+        ".code32\n"
+        "mov $0, %%ebx\n"
+        "sysenter\n"
+        "test_done:\n"
+        ".code64\n"
+
+        : /*outputs*/
+        "=a" (rax)
+        : /* inputs*/
+        : /*clobbers*/
+        "rbx",  /* action flag for sysenter_target */
+        "rcx",  /* saved RSP */
+        "rdx",  /* used for SYSEXIT*/
+        "flags"
+     );
+
+    report(rax == 0xACED, "MSR_IA32_SYSENTER_ESP has correct value");
+    return report_summary();
+}
+
+
diff --git a/x86/unittests.cfg b/x86/unittests.cfg
index 60c4b13..5fe39f5 100644
--- a/x86/unittests.cfg
+++ b/x86/unittests.cfg
@@ -205,6 +205,11 @@ file = syscall.flat
 arch = x86_64
 extra_params = -cpu Opteron_G1,vendor=AuthenticAMD
 
+[sysenter]
+file = sysenter.flat
+arch = x86_64
+extra_params = -cpu host,vendor=GenuineIntel
+
 [tsc]
 file = tsc.flat
 extra_params = -cpu kvm64,+rdtscp
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-03-15 21:10 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-15 21:09 [PATCH v2 0/2] Simple test for sysenter instruction Maxim Levitsky
2021-03-15 21:09 ` [PATCH v2 1/2] x86/msr: run this test with intel vendor id Maxim Levitsky
2021-03-15 21:09 ` [PATCH v2 2/2] Add a simple test for SYSENTER instruction Maxim Levitsky

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).