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.
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);
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");
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");
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();
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) )
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) )
write_cr4(cr4);
}
- test_int3_breakpoint();
test_extable();
test_exlog();
test_exec_user();