]> xenbits.xensource.com Git - people/andrewcoop/xen-test-framework.git/commitdiff
Don't automatically recover from traps
authorAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 1 Jun 2017 11:13:22 +0000 (12:13 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 28 Jun 2017 18:58:54 +0000 (19:58 +0100)
While this property is useful for swint-emulation, it is unhelpful in other
situations, as it causes unexpected traps to get swallowed silently.

Reuse the existing extable logic (with fault == fixup) to recover, and
introduce _ASM_TRAP_OK() to introduce such an extable entry.

Adjust the swint-emulation and selftest logic following this behaviour change,
which removes the test_int3_breakpoint() case entirely.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
arch/x86/traps.c
include/xtf/extable.h
tests/selftest/main.c
tests/swint-emulation/lowlevel.S

index f755d56230de6a1539c2d7063e4c4b91ca890a66..5804e0866ea2a4880f5834d7ed6a10223f87bf6d 100644 (file)
@@ -8,53 +8,6 @@
 
 bool (*xtf_unhandled_exception_hook)(struct cpu_regs *regs);
 
-/*
- * Evaluate whether this exception is a trap or an interrupt.  i.e. whether it
- * save to just return at the current %eip, or whether further action is
- * required to resolve the source of the exception.
- */
-static bool is_trap_or_interrupt(const struct cpu_regs *regs)
-{
-    /* All non-reserved vectors are interrupts. */
-    if ( regs->entry_vector >= X86_NR_RESERVED_VECTORS )
-        return true;
-
-    uint32_t vec_bit = 1u << regs->entry_vector;
-
-    if ( vec_bit & (X86_EXC_TRAPS | X86_EXC_INTERRUPTS) )
-        return true;
-
-    /* Architectural faults and aborts all need further action. */
-    if ( vec_bit & (X86_EXC_FAULTS | X86_EXC_ABORTS) )
-        return false;
-
-    /*
-     * The Debug Exception is awkward, and either a trap or a fault depending
-     * on other conditions.
-     */
-    unsigned long dr6 = read_dr6();
-
-    /* General Detect is a fault. */
-    if ( dr6 & X86_DR6_BD )
-        return false;
-
-    /* Instruction breakpoints are faults. */
-    if ( dr6 & (X86_DR6_B0 | X86_DR6_B1 | X86_DR6_B2 | X86_DR6_B3) )
-    {
-        unsigned long dr7 = read_dr7(), bp;
-
-        for ( bp = 0; bp < 4; ++bp )
-        {
-            if ( (dr6 & (1u << bp)) &&              /* Breakpoint triggered? */
-                 ((dr7 & (3u << (bp + 16))) == 0) ) /* Instruction breakpoint? */
-                return false;
-        }
-    }
-
-    /* All other debug conditions are traps. */
-    return true;
-}
-
 /*
  * C entry-point for exceptions, after the per-environment stubs have suitably
  * adjusted the stack.
@@ -62,7 +15,7 @@ static bool is_trap_or_interrupt(const struct cpu_regs *regs)
 void do_exception(struct cpu_regs *regs)
 {
     const struct extable_entry *ex;
-    bool safe = is_trap_or_interrupt(regs);
+    bool safe = false;
 
     xtf_exlog_log_exception(regs);
 
index daedd9e840308cad551834ceb588b10f40e4581f..23bfcc1e7e48f71c75e0abe934bfd45964d43e9d 100644 (file)
  */
 #define _ASM_EXTABLE(fault, fixup) _ASM_EXTABLE_HANDLER(fault, fixup, 0)
 
+/**
+ * Create an exception table entry, whitelisting a trap as being ok at @param
+ * loc.  (ab)uses the fault fixup logic to fixup to its current position.
+ */
+#define _ASM_TRAP_OK(loc) _ASM_EXTABLE(loc, loc)
+
 #ifndef __ASSEMBLY__
 
 struct cpu_regs;
index 402c3e3bc9fef501168cabdaa0aa7328ac8d7095..322b357afa9da2b8fe1d6668a02e4c85f95514be 100644 (file)
 
 const char test_title[] = "XTF Selftests";
 
-static void test_int3_breakpoint(void)
-{
-    printk("Test: int3 breakpoint\n");
-
-    /*
-     * Check that a breakpoint returns normally from the trap handler.
-     */
-    asm volatile ("int3");
-}
-
 static void test_extable(void)
 {
     printk("Test: Exception Table\n");
@@ -82,7 +72,8 @@ static bool check_exlog_entry(unsigned int entry, unsigned int cs,
 
 static void test_exlog(void)
 {
-    extern unsigned long label_test_exlog_int3[], label_test_exlog_ud2a[];
+    extern unsigned long exlog_int3[] asm(".Lexlog_int3");
+    extern unsigned long exlog_ud2a[] asm(".Lexlog_ud2a");
 
     printk("Test: Exception Logging\n");
 
@@ -92,19 +83,20 @@ static void test_exlog(void)
     if ( !check_nr_entries(0) )
         goto out;
 
-    asm volatile ("int3; label_test_exlog_int3:");
+    asm volatile ("int3; .Lexlog_int3:"
+                  _ASM_TRAP_OK(.Lexlog_int3));
 
     /* Check that one entry has now been logged. */
     if ( !check_nr_entries(1) ||
-         !check_exlog_entry(0, __KERN_CS, _u(label_test_exlog_int3), X86_EXC_BP, 0) )
+         !check_exlog_entry(0, __KERN_CS, _u(exlog_int3), X86_EXC_BP, 0) )
         goto out;
 
-    asm volatile ("label_test_exlog_ud2a: ud2a; 1:"
-                  _ASM_EXTABLE(label_test_exlog_ud2a, 1b));
+    asm volatile (".Lexlog_ud2a: ud2a; 1:"
+                  _ASM_EXTABLE(.Lexlog_ud2a, 1b));
 
     /* Check that two entries have now been logged. */
     if ( !check_nr_entries(2) ||
-         !check_exlog_entry(1, __KERN_CS, _u(label_test_exlog_ud2a), X86_EXC_UD, 0) )
+         !check_exlog_entry(1, __KERN_CS, _u(exlog_ud2a), X86_EXC_UD, 0) )
         goto out;
 
     xtf_exlog_reset();
@@ -113,7 +105,8 @@ static void test_exlog(void)
     if ( !check_nr_entries(0) )
         goto out;
 
-    asm volatile ("int3");
+    asm volatile ("int3; 1:"
+                  _ASM_TRAP_OK(1b));
 
     /* Check that one entry now exists. */
     if ( !check_nr_entries(1) )
@@ -125,7 +118,8 @@ static void test_exlog(void)
     if ( !check_nr_entries(1) )
         goto out;
 
-    asm volatile ("int3");
+    asm volatile ("int3; 1:"
+                  _ASM_TRAP_OK(1b));
 
     /* Check that the previous breakpoint wasn't logged. */
     if ( !check_nr_entries(1) )
@@ -319,7 +313,6 @@ void test_main(void)
             write_cr4(cr4);
     }
 
-    test_int3_breakpoint();
     test_extable();
     test_exlog();
     test_exec_user();
index 799576400c61b4b2862b7b32c225be21291b6419..236ac5298aa5c4e0025c4b0ed2a4e04381fbb906 100644 (file)
@@ -70,6 +70,8 @@ GLOBAL(label_\insn\()_\type\()_trap)
         /* Fixup from fault label to trap label. */
         _ASM_EXTABLE(label_\insn\()_\type\()_fault,
                      label_\insn\()_\type\()_trap)
+        /* Mark traps as ok. */
+        _ASM_TRAP_OK(label_\insn\()_\type\()_trap)
 
 ENDFUNC(stub_\insn\()_\type)
 .endm