public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] test: Add IDT framework
@ 2010-06-10  3:31 Sheng Yang
  2010-06-10  3:31 ` [PATCH 2/2] test: Add XSAVE unit test Sheng Yang
  2010-06-10  9:49 ` [PATCH 1/2] test: Add IDT framework Avi Kivity
  0 siblings, 2 replies; 6+ messages in thread
From: Sheng Yang @ 2010-06-10  3:31 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Sheng Yang


Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
 kvm/test/config-x86-common.mak |    2 +
 kvm/test/config-x86_64.mak     |    2 +-
 kvm/test/lib/x86/idt.h         |   19 +++++++++
 kvm/test/x86/idt.c             |   85 ++++++++++++++++++++++++++++++++++++++++
 kvm/test/x86/idt_test.c        |   48 ++++++++++++++++++++++
 5 files changed, 155 insertions(+), 1 deletions(-)
 create mode 100644 kvm/test/lib/x86/idt.h
 create mode 100644 kvm/test/x86/idt.c
 create mode 100644 kvm/test/x86/idt_test.c

diff --git a/kvm/test/config-x86-common.mak b/kvm/test/config-x86-common.mak
index c97de52..800b635 100644
--- a/kvm/test/config-x86-common.mak
+++ b/kvm/test/config-x86-common.mak
@@ -59,6 +59,8 @@ $(TEST_DIR)/realmode.o: bits = 32
 
 $(TEST_DIR)/msr.flat: $(cstart.o) $(TEST_DIR)/msr.o
 
+$(TEST_DIR)/idt_test.flat: $(cstart.o) $(TEST_DIR)/idt.o $(TEST_DIR)/idt_test.o
+
 arch_clean:
 	$(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat \
 	$(TEST_DIR)/.*.d $(TEST_DIR)/lib/.*.d $(TEST_DIR)/lib/*.o
diff --git a/kvm/test/config-x86_64.mak b/kvm/test/config-x86_64.mak
index d8fd2b5..f9cd121 100644
--- a/kvm/test/config-x86_64.mak
+++ b/kvm/test/config-x86_64.mak
@@ -5,6 +5,6 @@ ldarch = elf64-x86-64
 CFLAGS += -D__x86_64__
 
 tests = $(TEST_DIR)/access.flat $(TEST_DIR)/apic.flat \
-	  $(TEST_DIR)/emulator.flat
+	  $(TEST_DIR)/emulator.flat $(TEST_DIR)/idt_test.flat
 
 include config-x86-common.mak
diff --git a/kvm/test/lib/x86/idt.h b/kvm/test/lib/x86/idt.h
new file mode 100644
index 0000000..f449f01
--- /dev/null
+++ b/kvm/test/lib/x86/idt.h
@@ -0,0 +1,19 @@
+#ifndef __IDT_TEST__
+#define __IDT_TEST__
+
+void setup_idt(void);
+
+#define EXCEPTION_REGION_BEGIN(r, lb) \
+    asm volatile("pushq $"lb"\n\t" \
+                 "mov $2, %0\n\t" \
+                 : "=r"(r))
+#define EXCEPTION_REGION_END(r, lb) \
+    asm volatile("popq %%rdx\n\t" \
+		 "mov $0, %0\n\t" \
+                 lb":\n\t": \
+                 "=r"(r) :: "%rdx")
+
+#define UD_VECTOR   6
+#define GP_VECTOR   13
+
+#endif
diff --git a/kvm/test/x86/idt.c b/kvm/test/x86/idt.c
new file mode 100644
index 0000000..e3172cb
--- /dev/null
+++ b/kvm/test/x86/idt.c
@@ -0,0 +1,85 @@
+#include "idt.h"
+
+typedef struct {
+    unsigned short offset0;
+    unsigned short selector;
+    unsigned short ist : 3;
+    unsigned short : 5;
+    unsigned short type : 4;
+    unsigned short : 1;
+    unsigned short dpl : 2;
+    unsigned short p : 1;
+    unsigned short offset1;
+    unsigned offset2;
+    unsigned reserved;
+} idt_entry_t;
+
+static idt_entry_t idt[256];
+
+typedef struct {
+    unsigned short limit;
+    unsigned long linear_addr;
+} __attribute__((packed)) descriptor_table_t;
+
+void lidt(idt_entry_t *idt, int nentries)
+{
+    descriptor_table_t dt;
+
+    dt.limit = nentries * sizeof(*idt) - 1;
+    dt.linear_addr = (unsigned long)idt;
+    asm volatile ("lidt %0" : : "m"(dt));
+}
+
+unsigned short read_cs()
+{
+    unsigned short r;
+
+    asm volatile ("mov %%cs, %0" : "=r"(r));
+    return r;
+}
+
+void memset(void *a, unsigned char v, int n)
+{
+    unsigned char *x = a;
+
+    while (n--)
+	*x++ = v;
+}
+
+void set_idt_entry(idt_entry_t *e, void *addr, int dpl)
+{
+    memset(e, 0, sizeof *e);
+    e->offset0 = (unsigned long)addr;
+    e->selector = read_cs();
+    e->ist = 0;
+    e->type = 14;
+    e->dpl = dpl;
+    e->p = 1;
+    e->offset1 = (unsigned long)addr >> 16;
+    e->offset2 = (unsigned long)addr >> 32;
+}
+
+void setup_idt(void)
+{
+    asm volatile (".section .text.ud \n\t"
+                  "ud_fault: \n\t"
+		  "mov 40(%%rsp), %%rax\n\t"
+                  "mov %%rax, (%%rsp)\n\t"
+                  "mov $6, %%rax\n\t"
+                  "iretq \n\t"
+                  ".section .text":);
+
+    asm volatile (".section .text.gp \n\t"
+                  "gp_fault: \n\t"
+                  "pop %%rax \n\t"
+		  "mov 40(%%rsp), %%rax\n\t"
+                  "mov %%rax, (%%rsp)\n\t"
+                  "mov $13, %%rax\n\t"
+                  "iretq \n\t"
+                  ".section .text":);
+    extern char ud_fault, gp_fault;
+
+    lidt(idt, 256);
+    set_idt_entry(&idt[6], &ud_fault, 0);
+    set_idt_entry(&idt[13], &gp_fault, 0);
+}
diff --git a/kvm/test/x86/idt_test.c b/kvm/test/x86/idt_test.c
new file mode 100644
index 0000000..08f0da8
--- /dev/null
+++ b/kvm/test/x86/idt_test.c
@@ -0,0 +1,48 @@
+#include "libcflat.h"
+#include "idt.h"
+
+int test_ud2(void)
+{
+    int r;
+    EXCEPTION_REGION_BEGIN(r, "fixed_ud");
+    asm volatile("ud2;\n\t");
+    EXCEPTION_REGION_END(r, "fixed_ud");
+    return r;
+}
+
+int test_gp(void)
+{
+    int r;
+    EXCEPTION_REGION_BEGIN(r, "fixed_gp");
+    asm volatile("mov $0xffffffff, %%rax\n\t"
+		 "mov %%rax, %%cr4\n\t":);
+    EXCEPTION_REGION_END(r, "fixed_gp");
+    return r;
+}
+
+int test(void)
+{
+    int r;
+
+    setup_idt();
+    printf("GP testing: ");
+    r = test_gp();
+    if (r == GP_VECTOR)
+        printf("Pass!\n");
+    else
+        printf("Fail!\n");
+    printf("UD testing: ");
+    r = test_ud2();
+    if (r == UD_VECTOR)
+        printf("Pass!\n");
+    else
+        printf("Fail!\n");
+    return 0;
+}
+
+int main(void)
+{
+    printf("start testing\n");
+    test();
+    return 0;
+}
-- 
1.7.0.1


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

* [PATCH 2/2] test: Add XSAVE unit test
  2010-06-10  3:31 [PATCH 1/2] test: Add IDT framework Sheng Yang
@ 2010-06-10  3:31 ` Sheng Yang
  2010-06-10  9:49 ` [PATCH 1/2] test: Add IDT framework Avi Kivity
  1 sibling, 0 replies; 6+ messages in thread
From: Sheng Yang @ 2010-06-10  3:31 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Sheng Yang

Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
 kvm/test/config-x86-common.mak |    2 +
 kvm/test/config-x86_64.mak     |    3 +-
 kvm/test/x86/xsave.c           |  263 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 267 insertions(+), 1 deletions(-)
 create mode 100644 kvm/test/x86/xsave.c

diff --git a/kvm/test/config-x86-common.mak b/kvm/test/config-x86-common.mak
index 800b635..0e1ccce 100644
--- a/kvm/test/config-x86-common.mak
+++ b/kvm/test/config-x86-common.mak
@@ -61,6 +61,8 @@ $(TEST_DIR)/msr.flat: $(cstart.o) $(TEST_DIR)/msr.o
 
 $(TEST_DIR)/idt_test.flat: $(cstart.o) $(TEST_DIR)/idt.o $(TEST_DIR)/idt_test.o
 
+$(TEST_DIR)/xsave.flat: $(cstart.o) $(TEST_DIR)/idt.o $(TEST_DIR)/xsave.o
+
 arch_clean:
 	$(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat \
 	$(TEST_DIR)/.*.d $(TEST_DIR)/lib/.*.d $(TEST_DIR)/lib/*.o
diff --git a/kvm/test/config-x86_64.mak b/kvm/test/config-x86_64.mak
index f9cd121..2da2906 100644
--- a/kvm/test/config-x86_64.mak
+++ b/kvm/test/config-x86_64.mak
@@ -5,6 +5,7 @@ ldarch = elf64-x86-64
 CFLAGS += -D__x86_64__
 
 tests = $(TEST_DIR)/access.flat $(TEST_DIR)/apic.flat \
-	  $(TEST_DIR)/emulator.flat $(TEST_DIR)/idt_test.flat
+	  $(TEST_DIR)/emulator.flat $(TEST_DIR)/idt_test.flat \
+	  $(TEST_DIR)/xsave.flat
 
 include config-x86-common.mak
diff --git a/kvm/test/x86/xsave.c b/kvm/test/x86/xsave.c
new file mode 100644
index 0000000..556d2c7
--- /dev/null
+++ b/kvm/test/x86/xsave.c
@@ -0,0 +1,263 @@
+#include "libcflat.h"
+#include "idt.h"
+
+#ifdef __x86_64__
+#define uint64_t unsigned long
+#else
+#define uint64_t unsigned long long
+#endif
+
+static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
+				unsigned int *ecx, unsigned int *edx)
+{
+	/* ecx is often an input as well as an output. */
+	asm volatile("cpuid"
+	    : "=a" (*eax),
+	      "=b" (*ebx),
+	      "=c" (*ecx),
+	      "=d" (*edx)
+	    : "0" (*eax), "2" (*ecx));
+}
+
+/*
+ * Generic CPUID function
+ * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
+ * resulting in stale register contents being returned.
+ */
+void cpuid(unsigned int op,
+		 unsigned int *eax, unsigned int *ebx,
+		 unsigned int *ecx, unsigned int *edx)
+{
+	*eax = op;
+	*ecx = 0;
+	__cpuid(eax, ebx, ecx, edx);
+}
+
+/* Some CPUID calls want 'count' to be placed in ecx */
+void cpuid_count(unsigned int op, int count,
+		       unsigned int *eax, unsigned int *ebx,
+		       unsigned int *ecx, unsigned int *edx)
+{
+	*eax = op;
+	*ecx = count;
+	__cpuid(eax, ebx, ecx, edx);
+}
+
+int xgetbv_checking(u32 index, u64 *result)
+{
+	int r = 0;
+	u32 eax, edx;
+
+	EXCEPTION_REGION_BEGIN(r, "fixed_xgetbv");
+	asm volatile(".byte 0x0f,0x01,0xd0" /* xgetbv */
+		     : "=a" (eax), "=d" (edx)
+		     : "c" (index));
+	*result = eax + ((u64)edx << 32);
+	EXCEPTION_REGION_END(r, "fixed_xgetbv");
+	return r;
+}
+
+int xsetbv_checking(u32 index, u64 value)
+{
+	int r = 0;
+	u32 eax = value;
+	u32 edx = value >> 32;
+
+	EXCEPTION_REGION_BEGIN(r, "fixed_xsetbv");
+	asm volatile(".byte 0x0f,0x01,0xd1" /* xsetbv */
+		     : : "a" (eax), "d" (edx), "c" (index));
+	EXCEPTION_REGION_END(r, "fixed_xsetbv");
+	return r;
+}
+
+unsigned long read_cr4(void)
+{
+	unsigned long val;
+	asm volatile("mov %%cr4,%0" : "=r" (val));
+	return val;
+}
+
+int write_cr4_checking(unsigned long val)
+{
+	int r = 0;
+	EXCEPTION_REGION_BEGIN(r, "fixed_cr4");
+	asm volatile("mov %0,%%cr4": : "r" (val));
+	EXCEPTION_REGION_END(r, "fixed_cr4");
+	return r;
+}
+
+#define CPUID_1_ECX_XSAVE	    (1 << 26)
+#define CPUID_1_ECX_OSXSAVE	    (1 << 27)
+int check_cpuid_1_ecx(unsigned int bit)
+{
+	unsigned int eax, ebx, ecx, edx;
+	cpuid(1, &eax, &ebx, &ecx, &edx);
+	if (ecx & bit)
+		return 1;
+	return 0;
+}
+
+uint64_t get_supported_xcr0(void)
+{
+	unsigned int eax, ebx, ecx, edx;
+	cpuid_count(0xd, 0, &eax, &ebx, &ecx, &edx);
+	printf("eax %x, ebx %x, ecx %x, edx %x\n",
+		eax, ebx, ecx, edx);
+	return eax + ((u64)edx << 32);
+}
+
+#define X86_CR4_OSXSAVE			0x00040000
+#define XCR_XFEATURE_ENABLED_MASK       0x00000000
+#define XCR_XFEATURE_ILLEGAL_MASK       0x00000010
+
+#define XSTATE_FP       0x1
+#define XSTATE_SSE      0x2
+#define XSTATE_YMM      0x4
+
+static int total_tests, fail_tests;
+
+void pass_if(int condition)
+{
+	total_tests ++;
+	if (condition)
+		printf("Pass!\n");
+	else {
+		printf("Fail!\n");
+		fail_tests ++;
+	}
+}
+
+void test_xsave(void)
+{
+	unsigned long cr4;
+	uint64_t supported_xcr0;
+	uint64_t test_bits;
+	u64 xcr0;
+	int r;
+
+	printf("Legal instruction testing:\n");
+	supported_xcr0 = get_supported_xcr0();
+	printf("Supported XCR0 bits: 0x%x\n", supported_xcr0);
+
+	printf("Check minimal XSAVE required bits: ");
+	test_bits = XSTATE_FP | XSTATE_SSE;
+	pass_if((supported_xcr0 & test_bits) == test_bits);
+
+	printf("Set CR4 OSXSAVE: ");
+	cr4 = read_cr4();
+	r = write_cr4_checking(cr4 | X86_CR4_OSXSAVE);
+	pass_if(r == 0);
+
+	printf("Check CPUID.1.ECX.OSXSAVE - expect 1: ");
+	pass_if(check_cpuid_1_ecx(CPUID_1_ECX_OSXSAVE));
+
+	printf("    Legal tests\n");
+	printf("        xsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_FP): ");
+	test_bits = XSTATE_FP;
+	r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits);
+	pass_if(r == 0);
+	printf("        xsetbv(XCR_XFEATURE_ENABLED_MASK, "
+			"XSTATE_FP | XSTATE_SSE): ");
+	test_bits = XSTATE_FP | XSTATE_SSE;
+	r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits);
+	pass_if(r == 0);
+	printf("        xgetbv(XCR_XFEATURE_ENABLED_MASK): ");
+	r = xgetbv_checking(XCR_XFEATURE_ENABLED_MASK, &xcr0);
+	pass_if(r == 0);
+	printf("    Illegal tests\n");
+	printf("        xsetbv(XCR_XFEATURE_ENABLED_MASK, 0) - expect #GP: ");
+	test_bits = 0;
+	r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits);
+	pass_if(r == GP_VECTOR);
+	printf("        xsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_SSE) "
+		       "- expect #GP: ");
+	test_bits = XSTATE_SSE;
+	r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits);
+	pass_if(r == GP_VECTOR);
+	if (supported_xcr0 & XSTATE_YMM) {
+		printf("        xsetbv(XCR_XFEATURE_ENABLED_MASK, "
+				"XSTATE_YMM) - expect #GP: ");
+		test_bits = XSTATE_YMM;
+		r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits);
+		pass_if(r == GP_VECTOR);
+		printf("        xsetbv(XCR_XFEATURE_ENABLED_MASK, "
+				"XSTATE_FP | XSTATE_YMM) - expect #GP: ");
+		test_bits = XSTATE_FP | XSTATE_YMM;
+		r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits);
+		pass_if(r == GP_VECTOR);
+	}
+	printf("        xsetbv(XCR_XFEATURE_ILLEGAL_MASK, XSTATE_FP) "
+		       "- expect #GP: ");
+	test_bits = XSTATE_SSE;
+	r = xsetbv_checking(XCR_XFEATURE_ILLEGAL_MASK, test_bits);
+	pass_if(r == GP_VECTOR);
+	printf("        xgetbv(XCR_XFEATURE_ILLEGAL_MASK, XSTATE_FP) "
+		       "- expect #GP: ");
+	test_bits = XSTATE_SSE;
+	r = xsetbv_checking(XCR_XFEATURE_ILLEGAL_MASK, test_bits);
+	pass_if(r == GP_VECTOR);
+
+	printf("Unset CR4 OSXSAVE: ");
+	cr4 &= ~X86_CR4_OSXSAVE;
+	r = write_cr4_checking(cr4);
+	pass_if(r == 0);
+	printf("Check CPUID.1.ECX.OSXSAVE - expect 0: ");
+	pass_if(check_cpuid_1_ecx(CPUID_1_ECX_OSXSAVE) == 0);
+	printf("    Illegal tests:\n");
+	printf("        xsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_FP) - expect #UD: ");
+	test_bits = XSTATE_FP;
+	r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits);
+	pass_if(r == UD_VECTOR);
+	printf("        xsetbv(XCR_XFEATURE_ENABLED_MASK, "
+			"XSTATE_FP | XSTATE_SSE) - expect #UD: ");
+	test_bits = XSTATE_FP | XSTATE_SSE;
+	r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits);
+	pass_if(r == UD_VECTOR);
+	printf("    Illegal tests:\n");
+	printf("	xgetbv(XCR_XFEATURE_ENABLED_MASK) - expect #UD: ");
+	r = xgetbv_checking(XCR_XFEATURE_ENABLED_MASK, &xcr0);
+	pass_if(r == UD_VECTOR);
+}
+
+void test_no_xsave(void)
+{
+	unsigned long cr4;
+	u64 xcr0;
+	int r;
+
+	printf("Check CPUID.1.ECX.OSXSAVE - expect 0: ");
+	pass_if(check_cpuid_1_ecx(CPUID_1_ECX_OSXSAVE) == 0);
+
+	printf("Illegal instruction testing:\n");
+
+	printf("Set OSXSAVE in CR4 - expect #GP: ");
+	cr4 = read_cr4();
+	r = write_cr4_checking(cr4 | X86_CR4_OSXSAVE);
+	pass_if(r == GP_VECTOR);
+
+	printf("Execute xgetbv - expect #UD: ");
+	r = xgetbv_checking(XCR_XFEATURE_ENABLED_MASK, &xcr0);
+	pass_if(r == UD_VECTOR);
+
+	printf("Execute xsetbv - expect #UD: ");
+	r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, 0x3);
+	pass_if(r == UD_VECTOR);
+}
+
+int main(void)
+{
+	setup_idt();
+	if (check_cpuid_1_ecx(CPUID_1_ECX_XSAVE)) {
+		printf("CPU has XSAVE feature\n");
+		test_xsave();
+	} else {
+		printf("CPU don't has XSAVE feature\n");
+		test_no_xsave();
+	}
+	printf("Total test: %d\n", total_tests);
+	if (fail_tests == 0)
+		printf("ALL PASS!\n");
+	else
+		printf("Fail %d tests.\n", fail_tests);
+	return 1;
+}
-- 
1.7.0.1


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

* Re: [PATCH 1/2] test: Add IDT framework
  2010-06-10  3:31 [PATCH 1/2] test: Add IDT framework Sheng Yang
  2010-06-10  3:31 ` [PATCH 2/2] test: Add XSAVE unit test Sheng Yang
@ 2010-06-10  9:49 ` Avi Kivity
  2010-06-10  9:55   ` Sheng Yang
  1 sibling, 1 reply; 6+ messages in thread
From: Avi Kivity @ 2010-06-10  9:49 UTC (permalink / raw)
  To: Sheng Yang; +Cc: Marcelo Tosatti, kvm

On 06/10/2010 06:31 AM, Sheng Yang wrote:
> +
> +#define EXCEPTION_REGION_BEGIN(r, lb) \
> +    asm volatile("pushq $"lb"\n\t" \
> +                 "mov $2, %0\n\t" \
> +                 : "=r"(r))
> +#define EXCEPTION_REGION_END(r, lb) \
> +    asm volatile("popq %%rdx\n\t" \
> +		 "mov $0, %0\n\t" \
> +                 lb":\n\t": \
> +                 "=r"(r) :: "%rdx")
>    

These mess up the stack, no?  So if any intervening code uses %rsp based 
addressing, it will get incorrect information.

I suggest using a special data section like the kernel.

Also, most tests that use asm don't need an exception region, but will 
want to trap an exception on a single address.  So need a macro designed 
to be placed in asm in front of the faulting instruction.


-- 
error compiling committee.c: too many arguments to function


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

* Re: [PATCH 1/2] test: Add IDT framework
  2010-06-10  9:49 ` [PATCH 1/2] test: Add IDT framework Avi Kivity
@ 2010-06-10  9:55   ` Sheng Yang
  2010-06-10 10:55     ` Avi Kivity
  0 siblings, 1 reply; 6+ messages in thread
From: Sheng Yang @ 2010-06-10  9:55 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, kvm

On Thursday 10 June 2010 17:49:16 Avi Kivity wrote:
> On 06/10/2010 06:31 AM, Sheng Yang wrote:
> > +
> > +#define EXCEPTION_REGION_BEGIN(r, lb) \
> > +    asm volatile("pushq $"lb"\n\t" \
> > +                 "mov $2, %0\n\t" \
> > +                 : "=r"(r))
> > +#define EXCEPTION_REGION_END(r, lb) \
> > +    asm volatile("popq %%rdx\n\t" \
> > +		 "mov $0, %0\n\t" \
> > +                 lb":\n\t": \
> > +                 "=r"(r) :: "%rdx")
> 
> These mess up the stack, no?  So if any intervening code uses %rsp based
> addressing, it will get incorrect information.

Yes, but I meant to only include instruction directly in the “region”, and support 
nobody should touch $rsp then. It's directly and simple enough.
> 
> I suggest using a special data section like the kernel.

Kind of more complex...
> 
> Also, most tests that use asm don't need an exception region, but will
> want to trap an exception on a single address.  So need a macro designed
> to be placed in asm in front of the faulting instruction.

Use region here is due to we don't know the size of instruction(or I don't know 
how to get it)... Use a label here seems the simplest way to get the address 
right.

--
regards
Yang, Sheng

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

* Re: [PATCH 1/2] test: Add IDT framework
  2010-06-10  9:55   ` Sheng Yang
@ 2010-06-10 10:55     ` Avi Kivity
  2010-06-10 13:32       ` Avi Kivity
  0 siblings, 1 reply; 6+ messages in thread
From: Avi Kivity @ 2010-06-10 10:55 UTC (permalink / raw)
  To: Sheng Yang; +Cc: Marcelo Tosatti, kvm

On 06/10/2010 12:55 PM, Sheng Yang wrote:
> On Thursday 10 June 2010 17:49:16 Avi Kivity wrote:
>    
>> On 06/10/2010 06:31 AM, Sheng Yang wrote:
>>      
>>> +
>>> +#define EXCEPTION_REGION_BEGIN(r, lb) \
>>> +    asm volatile("pushq $"lb"\n\t" \
>>> +                 "mov $2, %0\n\t" \
>>> +                 : "=r"(r))
>>> +#define EXCEPTION_REGION_END(r, lb) \
>>> +    asm volatile("popq %%rdx\n\t" \
>>> +		 "mov $0, %0\n\t" \
>>> +                 lb":\n\t": \
>>> +                 "=r"(r) :: "%rdx")
>>>        
>> These mess up the stack, no?  So if any intervening code uses %rsp based
>> addressing, it will get incorrect information.
>>      
> Yes, but I meant to only include instruction directly in the “region”, and support
> nobody should touch $rsp then. It's directly and simple enough.
>    

Something like "=m"(blah) can cause access to %rsp, usually when 
compiling without frame pointers.

>> I suggest using a special data section like the kernel.
>>      
> Kind of more complex...
>    

Makes it more fun.  I'll have a go.

-- 
error compiling committee.c: too many arguments to function


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

* Re: [PATCH 1/2] test: Add IDT framework
  2010-06-10 10:55     ` Avi Kivity
@ 2010-06-10 13:32       ` Avi Kivity
  0 siblings, 0 replies; 6+ messages in thread
From: Avi Kivity @ 2010-06-10 13:32 UTC (permalink / raw)
  To: Sheng Yang; +Cc: Marcelo Tosatti, kvm

On 06/10/2010 01:55 PM, Avi Kivity wrote:
> Something like "=m"(blah) can cause access to %rsp, usually when 
> compiling without frame pointers.
>
>>> I suggest using a special data section like the kernel.
>> Kind of more complex...
>
> Makes it more fun.  I'll have a go.
>

Posted.  Currently fails due to a bug in kvm (writing to cr4 causes the 
fault rip to point to the following instruction, patch to follow).

-- 
error compiling committee.c: too many arguments to function


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

end of thread, other threads:[~2010-06-10 13:32 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-10  3:31 [PATCH 1/2] test: Add IDT framework Sheng Yang
2010-06-10  3:31 ` [PATCH 2/2] test: Add XSAVE unit test Sheng Yang
2010-06-10  9:49 ` [PATCH 1/2] test: Add IDT framework Avi Kivity
2010-06-10  9:55   ` Sheng Yang
2010-06-10 10:55     ` Avi Kivity
2010-06-10 13:32       ` Avi Kivity

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox