]> xenbits.xensource.com Git - people/liuw/xtf.git/commitdiff
Introduce xtf_set_idte() to allow tests to add extra IDT entries
authorAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 15 Jul 2016 16:02:56 +0000 (16:02 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 12 Aug 2016 12:20:46 +0000 (13:20 +0100)
Add an extra entry to the selftests.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
arch/x86/hvm/traps.c
arch/x86/pv/traps.c
include/arch/x86/idt.h
tests/selftest/main.c

index f1f78c75df5ccbba6f91da985fbea0802171f433..792a5968f85168e51c48af1e6a47640e44b99125 100644 (file)
@@ -82,6 +82,17 @@ static void setup_gate(unsigned int entry, void *addr, unsigned int dpl)
 #endif
 }
 
+int xtf_set_idte(unsigned int vector, struct xtf_idte *idte)
+{
+#if defined(__i386__)
+    pack_gate32(&idt[vector], 14, idte->addr, idte->dpl, idte->cs);
+#elif defined(__x86_64__)
+    pack_gate64(&idt[vector], 14, idte->addr, idte->dpl, 0, idte->cs);
+#endif
+
+    return 0;
+}
+
 void arch_init_traps(void)
 {
     setup_gate(X86_EXC_DE,  &entry_DE,  0);
index 6c2405cfe32d556bec317bf5cd36ca3f802f5d83..625f2ddc5487c88775ef489b09067ecdcf4e67d6 100644 (file)
@@ -59,6 +59,17 @@ struct xen_trap_info pv_default_trap_info[] =
     { 0, 0, 0, 0 }, /* Sentinel. */
 };
 
+int xtf_set_idte(unsigned int vector, struct xtf_idte *idte)
+{
+    struct xen_trap_info ti[2] =
+    {
+        { vector, idte->dpl | 4, idte->cs, idte->addr },
+        { 0, 0, 0, 0 }, /* Sentinel. */
+    };
+
+    return hypercall_set_trap_table(ti);
+}
+
 #ifdef __i386__
 static bool __used ex_pf_user(struct cpu_regs *regs,
                               const struct extable_entry *ex)
index 5c7399d21efb03ba8a6f1e0f1a1e47a0b1bad81d..453d75d34701e4ebf0fd15c99f5ac03a9a67c95e 100644 (file)
  */
 #define X86_VEC_RET2KERN 0x20
 
+/**
+ * Available for test use.
+ */
+#define X86_VEC_AVAIL    0x21
+
+
+#ifndef __ASSEMBLY__
+
+/** A guest agnostic represention of IDT information. */
+struct xtf_idte
+{
+    unsigned long addr;
+    unsigned int cs, dpl;
+};
+
+/**
+ * Set up an IDT Entry, in a guest agnostic way.
+ *
+ * Construct an IDT Entry at the specified @p vector, using configuration
+ * provided in @p idte.
+ *
+ * @param vector Vector to set up.
+ * @param idte Details to set up.
+ * @returns 0 for HVM guests, hypercall result for PV guests.
+ */
+int xtf_set_idte(unsigned int vector,
+                 struct xtf_idte *idte);
+
+#endif /* __ASSEMBLY__ */
+
 #endif /* XTF_X86_IDT_H */
 
 /*
index 72b4045ed5fa4f5890accc981121da2c25a1374e..5ff24674203e66de66a4b3b6794f25d232662351 100644 (file)
@@ -11,6 +11,7 @@
  */
 #include <xtf.h>
 
+#include <arch/x86/idt.h>
 #include <arch/x86/processor.h>
 #include <arch/x86/segment.h>
 
@@ -245,6 +246,52 @@ static void test_extable_handler(void)
         xtf_failure("Fail: Custom handler didn't run\n");
 }
 
+void test_idte_handler(void);
+asm ("test_idte_handler:;"
+#if defined (CONFIG_PV) && defined (CONFIG_64BIT)
+     "pop %rcx; pop %r11;"
+#endif
+     "mov $0x1e51c0de, %eax;"
+#if defined (CONFIG_HVM)
+#ifdef __x86_64__
+     "rex64 "
+#endif
+     "iret;"
+#else /* CONFIG_HVM */
+#ifdef __x86_64__
+     "push $0;"
+#endif
+     "jmp HYPERCALL_iret;"
+#endif
+    );
+
+static void test_custom_idte(void)
+{
+    struct xtf_idte idte =
+        {
+            .addr = (unsigned long)test_idte_handler,
+            /* PV guests need DPL1, HVM need DPL0. */
+            .dpl = IS_DEFINED(CONFIG_PV) ? 1 : 0,
+            .cs = __KERN_CS,
+        };
+
+    printk("Test: Custom IDT entry\n");
+
+    int rc = xtf_set_idte(X86_VEC_AVAIL, &idte);
+
+    if ( rc )
+        return xtf_failure("Fail: xtf_set_idte() returned %d\n", rc);
+
+    unsigned int res;
+    asm volatile ("int $%c[vec]"
+                  : "=a" (res)
+                  : "0" (0),
+                    [vec] "i" (X86_VEC_AVAIL));
+
+    if ( res != 0x1e51c0de )
+        xtf_failure("Fail: Unexpected result %#x\n", res);
+};
+
 void test_main(void)
 {
     printk("XTF Selftests\n");
@@ -257,6 +304,7 @@ void test_main(void)
         test_NULL_unmapped();
     test_unhandled_exception_hook();
     test_extable_handler();
+    test_custom_idte();
 
     xtf_success(NULL);
 }