* [PATCH] test: Add XSAVE unit test
@ 2010-05-31 11:17 Sheng Yang
2010-06-01 8:51 ` Avi Kivity
0 siblings, 1 reply; 4+ messages in thread
From: Sheng Yang @ 2010-05-31 11:17 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Sheng Yang
Only test legal action so far, we can extend it later.
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
kvm/test/config-x86-common.mak | 5 +-
kvm/test/x86/xsave.c | 173 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 177 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 9084e2d..2110e4e 100644
--- a/kvm/test/config-x86-common.mak
+++ b/kvm/test/config-x86-common.mak
@@ -24,7 +24,8 @@ FLATLIBS = lib/libcflat.a $(libgcc)
tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \
$(TEST_DIR)/smptest.flat $(TEST_DIR)/port80.flat \
- $(TEST_DIR)/realmode.flat $(TEST_DIR)/msr.flat
+ $(TEST_DIR)/realmode.flat $(TEST_DIR)/msr.flat \
+ $(TEST_DIR)/xsave.flat
test_cases: $(tests-common) $(tests)
@@ -58,6 +59,8 @@ $(TEST_DIR)/realmode.o: bits = 32
$(TEST_DIR)/msr.flat: $(cstart.o) $(TEST_DIR)/msr.o
+$(TEST_DIR)/xsave.flat: $(cstart.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/x86/xsave.c b/kvm/test/x86/xsave.c
new file mode 100644
index 0000000..2d6ea07
--- /dev/null
+++ b/kvm/test/x86/xsave.c
@@ -0,0 +1,173 @@
+#include "libcflat.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);
+}
+
+u64 xgetbv(u32 index)
+{
+ u32 eax, edx;
+
+ asm volatile(".byte 0x0f,0x01,0xd0" /* xgetbv */
+ : "=a" (eax), "=d" (edx)
+ : "c" (index));
+ return eax + ((u64)edx << 32);
+}
+
+void xsetbv(u32 index, u64 value)
+{
+ u32 eax = value;
+ u32 edx = value >> 32;
+
+ asm volatile(".byte 0x0f,0x01,0xd1" /* xsetbv */
+ : : "a" (eax), "d" (edx), "c" (index));
+}
+
+unsigned long read_cr4(void)
+{
+ unsigned long val;
+ asm volatile("mov %%cr4,%0" : "=r" (val));
+ return val;
+}
+
+void write_cr4(unsigned long val)
+{
+ asm volatile("mov %0,%%cr4": : "r" (val));
+}
+
+#define CPUID_1_ECX_XSAVE (1 << 26)
+int check_xsave()
+{
+ unsigned int eax, ebx, ecx, edx;
+ cpuid(1, &eax, &ebx, &ecx, &edx);
+ if (ecx & CPUID_1_ECX_XSAVE)
+ return 1;
+ return 0;
+}
+
+uint64_t get_supported_xcr0()
+{
+ 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 XSTATE_FP 0x1
+#define XSTATE_SSE 0x2
+#define XSTATE_YMM 0x4
+
+static unsigned int fault_mask;
+
+void pass_if(int condition)
+{
+ if (condition)
+ printf("Pass!\n");
+ else
+ printf("Fail!\n");
+}
+
+void pass_if_no_fault(void)
+{
+ pass_if(!fault_mask);
+ fault_mask = 0;
+}
+
+void pass_if_fault(unsigned int fault_bit)
+{
+ pass_if(fault_mask & fault_bit);
+ fault_mask = 0;
+}
+
+#define UD_VECTOR_MASK (1 << 6)
+#define GP_VECTOR_MASK (1 << 13)
+
+void test_xsave()
+{
+ unsigned int cr4;
+ uint64_t supported_xcr0;
+ uint64_t test_bits;
+
+ 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 | XSTATE_YMM;
+ pass_if((supported_xcr0 & test_bits) == test_bits);
+
+ printf("Check CR4 OSXSAVE: ");
+ cr4 = read_cr4();
+ write_cr4(cr4 | X86_CR4_OSXSAVE);
+ pass_if_no_fault();
+
+ printf("Check XSETBV for XCR0 bits\n");
+ printf(" Legal tests\n");
+ printf(" XSTATE_FP: ");
+ test_bits = XSTATE_FP;
+ xsetbv(XCR_XFEATURE_ENABLED_MASK, test_bits);
+ pass_if_no_fault();
+ printf(" XSTATE_FP | XSTATE_SSE: ");
+ test_bits = XSTATE_FP | XSTATE_SSE;
+ xsetbv(XCR_XFEATURE_ENABLED_MASK, test_bits);
+ pass_if_no_fault();
+ printf(" XSTATE_FP | XSTATE_SSE | XSTATE_YMM: ");
+ test_bits = XSTATE_FP | XSTATE_SSE | XSTATE_YMM;
+ xsetbv(XCR_XFEATURE_ENABLED_MASK, test_bits);
+ pass_if_no_fault();
+}
+
+int main()
+{
+ int cpuid_has_xsave;
+
+ cpuid_has_xsave = check_xsave();
+ if (cpuid_has_xsave) {
+ printf("CPU has XSAVE feature\n");
+ test_xsave();
+ } else
+ printf("CPU don't has XSAVE feature\n");
+ return 0;
+}
+
--
1.7.0.1
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH] test: Add XSAVE unit test
2010-05-31 11:17 [PATCH] test: Add XSAVE unit test Sheng Yang
@ 2010-06-01 8:51 ` Avi Kivity
2010-06-01 9:00 ` Sheng Yang
0 siblings, 1 reply; 4+ messages in thread
From: Avi Kivity @ 2010-06-01 8:51 UTC (permalink / raw)
To: Sheng Yang; +Cc: Marcelo Tosatti, kvm
On 05/31/2010 02:17 PM, Sheng Yang wrote:
> Only test legal action so far, we can extend it later.
>
The legal actions are tested by guests, so it's more important for unit
tests to check illegal (and potentially subversive) actions.
> +
> +void test_xsave()
> +{
> + unsigned int cr4;
> + uint64_t supported_xcr0;
> + uint64_t test_bits;
> +
> + 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 | XSTATE_YMM;
> + pass_if((supported_xcr0& test_bits) == test_bits);
>
This will fail on a cpu without YMM but with xsave.
> +
> +int main()
> +{
> + int cpuid_has_xsave;
> +
> + cpuid_has_xsave = check_xsave();
> + if (cpuid_has_xsave) {
> + printf("CPU has XSAVE feature\n");
> + test_xsave();
> + } else
> + printf("CPU don't has XSAVE feature\n");
> + return 0;
>
Should return 1 if any failure for autotest integration.
> +}
> +
>
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] test: Add XSAVE unit test
2010-06-01 8:51 ` Avi Kivity
@ 2010-06-01 9:00 ` Sheng Yang
2010-06-01 9:08 ` Avi Kivity
0 siblings, 1 reply; 4+ messages in thread
From: Sheng Yang @ 2010-06-01 9:00 UTC (permalink / raw)
To: Avi Kivity; +Cc: Marcelo Tosatti, kvm
On Tuesday 01 June 2010 16:51:05 Avi Kivity wrote:
> On 05/31/2010 02:17 PM, Sheng Yang wrote:
> > Only test legal action so far, we can extend it later.
>
> The legal actions are tested by guests, so it's more important for unit
> tests to check illegal (and potentially subversive) actions.
Yes. This is just the first step. I think we need construct IDT and use something
similar to fixup exception table. That's not a quick work, and we need some base
for it.
>
> > +
> > +void test_xsave()
> > +{
> > + unsigned int cr4;
> > + uint64_t supported_xcr0;
> > + uint64_t test_bits;
> > +
> > + 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 | XSTATE_YMM;
> > + pass_if((supported_xcr0& test_bits) == test_bits);
>
> This will fail on a cpu without YMM but with xsave.
Yes, would discard this...
>
> > +
> > +int main()
> > +{
> > + int cpuid_has_xsave;
> > +
> > + cpuid_has_xsave = check_xsave();
> > + if (cpuid_has_xsave) {
> > + printf("CPU has XSAVE feature\n");
> > + test_xsave();
> > + } else
> > + printf("CPU don't has XSAVE feature\n");
> > + return 0;
>
> Should return 1 if any failure for autotest integration.
OK
>
> > +}
> > +
--
regards
Yang, Sheng
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] test: Add XSAVE unit test
2010-06-01 9:00 ` Sheng Yang
@ 2010-06-01 9:08 ` Avi Kivity
0 siblings, 0 replies; 4+ messages in thread
From: Avi Kivity @ 2010-06-01 9:08 UTC (permalink / raw)
To: Sheng Yang; +Cc: Marcelo Tosatti, kvm
On 06/01/2010 12:00 PM, Sheng Yang wrote:
> On Tuesday 01 June 2010 16:51:05 Avi Kivity wrote:
>
>> On 05/31/2010 02:17 PM, Sheng Yang wrote:
>>
>>> Only test legal action so far, we can extend it later.
>>>
>> The legal actions are tested by guests, so it's more important for unit
>> tests to check illegal (and potentially subversive) actions.
>>
> Yes. This is just the first step. I think we need construct IDT and use something
> similar to fixup exception table. That's not a quick work, and we need some base
> for it.
>
Sure, it's fine to proceed in steps. We do need a framework for
trapping exceptions. There's a bit in access.flat (also for running
code from cpl 3), we could generalize it.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-06-01 9:08 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-31 11:17 [PATCH] test: Add XSAVE unit test Sheng Yang
2010-06-01 8:51 ` Avi Kivity
2010-06-01 9:00 ` Sheng Yang
2010-06-01 9:08 ` Avi Kivity
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).