]> xenbits.xensource.com Git - people/royger/xen-test-framework.git/commitdiff
Basic hypercall infrastructure. Tests now shut down as opposed to spinning in a...
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 17 Mar 2015 23:38:31 +0000 (00:38 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 24 Sep 2015 20:08:08 +0000 (21:08 +0100)
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
17 files changed:
Doxyfile
README
arch/x86/boot/head_pv.S
arch/x86/hypercall_page.S [new file with mode: 0644]
common/setup.c
config/files.mk
include/arch/x86/page.h [new file with mode: 0644]
include/arch/x86/x86_32/hypercall-x86_32.h [new file with mode: 0644]
include/arch/x86/x86_64/hypercall-x86_64.h [new file with mode: 0644]
include/xen/elfnote.h
include/xen/sched.h [new file with mode: 0644]
include/xen/xen.h [new file with mode: 0644]
include/xtf/asm_macros.h
include/xtf/compiler.h [new file with mode: 0644]
include/xtf/hypercall.h [new file with mode: 0644]
include/xtf/types.h [new file with mode: 0644]
tests/example/main.c

index 2d4102bda246973fb2730a4919deaedf98d9323a..7247d53a0a4e6e844c112faa7c948ba02b813d5d 100644 (file)
--- a/Doxyfile
+++ b/Doxyfile
@@ -1986,6 +1986,7 @@ INCLUDE_FILE_PATTERNS  =
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
 PREDEFINED             = __attribute__(x)= \
+                         __noreturn \
 
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
diff --git a/README b/README
index b7b48be61d86caf3c038de9b491be70c30c99391..91c9ca8dfda3dbbdfaaf221f377d2895d3495605 100644 (file)
--- a/README
+++ b/README
@@ -12,12 +12,12 @@ machine.
 ## The framework consists of:
 
 * PV 32 and 64 bit entry points
+* Hypercall interface
 
 ## TODO List:
 
 * More introductory text
 * Entry points for 32 and 64bit HVM guests
-* Hypercall infrastructure
 * PV console driver
 * Common reporting framework
 * Tests
index bdf413690e331cda3367ceda589fc718098ff455..35efa0bf7346d2d4bf486230ba22164f3122c5ab 100644 (file)
@@ -8,6 +8,7 @@ ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "0")
 
 /* PV loader */
 ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz "generic")
+ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, _WORD hypercall_page)
 
 /* Xen ABI information */
 ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0")
diff --git a/arch/x86/hypercall_page.S b/arch/x86/hypercall_page.S
new file mode 100644 (file)
index 0000000..4e8ed73
--- /dev/null
@@ -0,0 +1,12 @@
+#include <arch/x86/page.h>
+#include <xtf/asm_macros.h>
+#include <xen/xen.h>
+
+.text
+.align PAGE_SIZE
+GLOBAL(hypercall_page)
+         /* Poisoned with `ret` for safety before hypercalls are set up. */
+        .fill PAGE_SIZE, 1, 0xc3
+        .size hypercall_page, PAGE_SIZE
+
+DECLARE_HYPERCALL(sched_op)
index a0a66a46c702f483a9b31c075b26392cb4bb3973..219150744694176180b89e03e0fe7c09ae1c45c7 100644 (file)
@@ -4,6 +4,8 @@
  * C entry point.
  */
 
+#include <xtf/compiler.h>
+#include <xtf/hypercall.h>
 #include <xtf/test.h>
 
 /**
  *
  * Set up the microkernel and invoke the test.
  */
-void xtf_main(void)
+void __noreturn xtf_main(void)
 {
     test_main();
+
+    hypercall_shutdown(SHUTDOWN_poweroff);
+    unreachable();
 }
 
 /*
index b19ecc7bc4877d4d556b76b80aa7af3f67e3aee0..145df002a507cc26e5f49e496e0184eade731166 100644 (file)
@@ -5,3 +5,6 @@
 # obj-$(env)   are objects unique to a specific environment
 
 obj-perarch += $(ROOT)/common/setup.o
+
+# Always link hypercall_page.S last as it is a page of data replaced by the hyperisor
+obj-perenv += $(ROOT)/arch/x86/hypercall_page.o
diff --git a/include/arch/x86/page.h b/include/arch/x86/page.h
new file mode 100644 (file)
index 0000000..662abee
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef XTF_X86_PAGE_H
+#define XTF_X86_PAGE_H
+
+/*
+ * Nomenclature inherited from Xen.
+ */
+
+#define PAGE_SHIFT              12
+
+#ifdef __ASSEMBLY__
+#define PAGE_SIZE               (1 << PAGE_SHIFT)
+#else
+#define PAGE_SIZE               (1L << PAGE_SHIFT)
+#endif
+
+#define PAGE_MASK               (~(PAGE_SIZE - 1))
+
+#endif /* XTF_X86_PAGE_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/include/arch/x86/x86_32/hypercall-x86_32.h b/include/arch/x86/x86_32/hypercall-x86_32.h
new file mode 100644 (file)
index 0000000..0394cd9
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef XTF_X86_32_HYPERCALL_H
+#define XTF_X86_32_HYPERCALL_H
+
+/*
+ * Hypercall primatives for 32bit
+ *
+ * Inputs: %ebx, %ecx, %edx, %esi, %edi, %ebp (arguments 1-6)
+ */
+
+#define _hypercall32_2(type, name, a1, a2)                              \
+    ({                                                                  \
+        long __res, __ign1, __ign2;                                     \
+        asm volatile (                                                  \
+            "call hypercall_page + %c[offset]"                          \
+            : "=a" (__res), "=b" (__ign1), "=c" (__ign2)                \
+            : [offset] "i" (__HYPERVISOR_##name * 32),                  \
+              "1" ((long)(a1)), "2" ((long)(a2))                        \
+            : "memory" );                                               \
+        (type)__res;                                                    \
+    })
+
+#endif /* XTF_X86_32_HYPERCALL_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/include/arch/x86/x86_64/hypercall-x86_64.h b/include/arch/x86/x86_64/hypercall-x86_64.h
new file mode 100644 (file)
index 0000000..916dd42
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef XTF_X86_64_HYPERCALL_H
+#define XTF_X86_64_HYPERCALL_H
+
+/*
+ * Hypercall primatives for 64bit
+ *
+ * Inputs: %rdi, %rsi, %rdx, %r10, %r8, %r9 (arguments 1-6)
+ */
+
+#define _hypercall64_2(type, name, a1, a2)                              \
+    ({                                                                  \
+        long __res, __ign1, __ign2;                                     \
+        asm volatile (                                                  \
+            "call hypercall_page + %c[offset]"                          \
+            : "=a" (__res), "=D" (__ign1), "=S" (__ign2)                \
+            : [offset] "i" (__HYPERVISOR_##name * 32),                  \
+              "1" ((long)(a1)), "2" ((long)(a2))                        \
+            : "memory" );                                               \
+        (type)__res;                                                    \
+    })
+
+#endif /* XTF_X86_64_HYPERCALL_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
index 05716f4ebd92b17077f4266b0f6def6d8cb3b3d9..98516b87fc7d047ad03f102ec3156bbcb96118a6 100644 (file)
@@ -5,6 +5,7 @@
 #ifndef XEN_PUBLIC_ELFNOTE_H
 #define XEN_PUBLIC_ELFNOTE_H
 
+#define XEN_ELFNOTE_HYPERCALL_PAGE 2
 #define XEN_ELFNOTE_XEN_VERSION    5
 #define XEN_ELFNOTE_GUEST_OS       6
 #define XEN_ELFNOTE_GUEST_VERSION  7
diff --git a/include/xen/sched.h b/include/xen/sched.h
new file mode 100644 (file)
index 0000000..bf3868b
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Xen public xen_version hypercall interface
+ */
+
+#ifndef XEN_PUBLIC_SCHED_H
+#define XEN_PUBLIC_SCHED_H
+
+#define SCHEDOP_shutdown 2
+
+#ifndef __ASSEMBLY__
+struct sched_shutdown {
+    unsigned int reason; /* SHUTDOWN_* */
+};
+#endif
+
+#define SHUTDOWN_poweroff   0  /* Domain exited normally. Clean up and kill. */
+#define SHUTDOWN_reboot     1  /* Clean up, kill, and then restart.          */
+#define SHUTDOWN_suspend    2  /* Clean up, save suspend info, kill.         */
+#define SHUTDOWN_crash      3  /* Tell controller we've crashed.             */
+#define SHUTDOWN_watchdog   4  /* Restart because watchdog time expired.     */
+
+#endif /* XEN_PUBLIC_SCHED_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/include/xen/xen.h b/include/xen/xen.h
new file mode 100644 (file)
index 0000000..f56fd89
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Xen public hypercall interface
+ */
+
+#ifndef XEN_PUBLIC_XEN_H
+#define XEN_PUBLIC_XEN_H
+
+#define __HYPERVISOR_sched_op             29
+
+#endif /* XEN_PUBLIC_XEN_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
index c8cfeebc5fe72300385589008ba9f89572216d4f..4f356b2e8e79e787d52d4f728cfb4f4116cc4d5d 100644 (file)
@@ -6,6 +6,15 @@
 #ifndef XTF_ASM_MACROS_H
 #define XTF_ASM_MACROS_H
 
+/* Declare data at the architectures width. */
+#if defined(__x86_64__)
+# define _WORD .quad
+#elif defined(__i386__)
+# define _WORD .long
+#else
+# error Bad architecture for _WORD
+#endif
+
 /**
  * Declare a global symbol.
  * @param name Symbol name.
@@ -21,6 +30,15 @@ name:
 #define SIZE(name)                              \
     .size name, . - name;
 
+/**
+ * Identify a specific hypercall in the hypercall page
+ * @param name Hypercall name.
+ */
+#define DECLARE_HYPERCALL(name)                                         \
+    .globl HYPERCALL_ ## name;                                          \
+    .set HYPERCALL_ ## name, hypercall_page + __HYPERVISOR_ ## name * 32; \
+    .size HYPERCALL_ ## name, 32
+
 /**
  * Create an ELF note entry.
  *
diff --git a/include/xtf/compiler.h b/include/xtf/compiler.h
new file mode 100644 (file)
index 0000000..efeed58
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef XTF_COMPILER_H
+#define XTF_COMPILER_H
+
+#define __noreturn            __attribute__((noreturn))
+#define unreachable()         __builtin_unreachable()
+
+#endif /* XTF_COMPILER_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/include/xtf/hypercall.h b/include/xtf/hypercall.h
new file mode 100644 (file)
index 0000000..c6f8ec0
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef XTF_HYPERCALL_H
+#define XTF_HYPERCALL_H
+
+#include <xtf/types.h>
+
+#if defined(__x86_64__)
+
+# include <arch/x86/x86_64/hypercall-x86_64.h>
+# define HYPERCALL2 _hypercall64_2
+
+#elif defined(__i386__)
+
+# include <arch/x86/x86_32/hypercall-x86_32.h>
+# define HYPERCALL2 _hypercall32_2
+
+#else
+# error Bad architecture for hypercalls
+#endif
+
+/* All Xen ABI for includers convenience .*/
+#include <xen/xen.h>
+#include <xen/sched.h>
+
+/*
+ * Hypercall primatives, compiled for the correct bitness
+ */
+static inline long hypercall_sched_op(unsigned int cmd, void *arg)
+{
+    return HYPERCALL2(long, sched_op, cmd, arg);
+}
+
+/*
+ * Higher level hypercall helpers
+ */
+static inline long hypercall_shutdown(unsigned int reason)
+{
+    return hypercall_sched_op(SCHEDOP_shutdown, &reason);
+}
+
+#endif /* XTF_HYPERCALL_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/include/xtf/types.h b/include/xtf/types.h
new file mode 100644 (file)
index 0000000..efa1c8e
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef XTF_TYPES_H
+#define XTF_TYPES_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdarg.h>
+
+#define __need_size_t
+#define __need_ptrsize_t
+#define __need_NULL
+#include <stddef.h>
+
+#endif /* XTF_TYPES_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
index 678d448df9c1acf83fc13ee0c2fc07c0f935493e..beb74de68395d2e687b342d70b2beedc56b4b0fd 100644 (file)
@@ -2,8 +2,6 @@
 
 void test_main(void)
 {
-    for ( ; ; )
-        asm volatile ("rep; nop");
 }
 
 /*