[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [tip:x86/asm] x86/head: Move early exception panic code into early_fixup_exception()



Commit-ID:  0e861fbb5bda79b871341ef2a9a8059765cbe8a4
Gitweb:     http://git.kernel.org/tip/0e861fbb5bda79b871341ef2a9a8059765cbe8a4
Author:     Andy Lutomirski <luto@xxxxxxxxxx>
AuthorDate: Sat, 2 Apr 2016 07:01:34 -0700
Committer:  Ingo Molnar <mingo@xxxxxxxxxx>
CommitDate: Wed, 13 Apr 2016 11:37:44 +0200

x86/head: Move early exception panic code into early_fixup_exception()

This removes a bunch of assembly and adds some C code instead.  It
changes the actual printouts on both 32-bit and 64-bit kernels, but
they still seem okay.

Tested-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>
Signed-off-by: Andy Lutomirski <luto@xxxxxxxxxx>
Acked-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Cc: Arjan van de Ven <arjan@xxxxxxxxxxxxxxx>
Cc: Borislav Petkov <bp@xxxxxxxxx>
Cc: KVM list <kvm@xxxxxxxxxxxxxxx>
Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx>
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Cc: xen-devel <Xen-devel@xxxxxxxxxxxxx>
Link: 
http://lkml.kernel.org/r/4085070316fc3ab29538d3fcfe282648d1d4ee2e.1459605520.git.luto@xxxxxxxxxx
Signed-off-by: Ingo Molnar <mingo@xxxxxxxxxx>
---
 arch/x86/include/asm/uaccess.h |  2 +-
 arch/x86/kernel/head_32.S      | 49 +++++-------------------------------------
 arch/x86/kernel/head_64.S      | 45 ++------------------------------------
 arch/x86/mm/extable.c          | 29 ++++++++++++++++++++-----
 4 files changed, 32 insertions(+), 93 deletions(-)

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index b6fb311..d794fd1 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -110,7 +110,7 @@ struct exception_table_entry {
 
 extern int fixup_exception(struct pt_regs *regs, int trapnr);
 extern bool ex_has_fault_handler(unsigned long ip);
-extern int early_fixup_exception(struct pt_regs *regs, int trapnr);
+extern void early_fixup_exception(struct pt_regs *regs, int trapnr);
 
 /*
  * These are the main single-value transfer routines.  They automatically
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 184291c..6770865 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -561,8 +561,6 @@ early_idt_handler_common:
         */
        cld
 
-       cmpl $2,%ss:early_recursion_flag
-       je hlt_loop
        incl %ss:early_recursion_flag
 
        /* The vector number is in pt_regs->gs */
@@ -594,13 +592,8 @@ early_idt_handler_common:
        movw    %gs, PT_GS(%esp)
        movw    $0, PT_GS+2(%esp)
 
-       cmpl $(__KERNEL_CS),PT_CS(%esp)
-       jne 10f
-
        movl    %esp, %eax      /* args are pt_regs (EAX), trapnr (EDX) */
        call    early_fixup_exception
-       andl    %eax,%eax
-       jz      10f             /* Exception wasn't fixed up */
 
        popl    %ebx            /* pt_regs->bx */
        popl    %ecx            /* pt_regs->cx */
@@ -616,29 +609,6 @@ early_idt_handler_common:
        decl    %ss:early_recursion_flag
        addl    $4, %esp        /* pop pt_regs->orig_ax */
        iret
-
-10:
-#ifdef CONFIG_PRINTK
-       xorl %eax,%eax
-       movw %ax,PT_FS+2(%esp)  /* clean up the segment values on some cpus */
-       movw %ax,PT_DS+2(%esp)
-       movw %ax,PT_ES+2(%esp)
-       leal  40(%esp),%eax
-       pushl %eax              /* %esp before the exception */
-       pushl %ebx
-       pushl %ebp
-       pushl %esi
-       pushl %edi
-       movl %cr2,%eax
-       pushl %eax
-       pushl (20+6*4)(%esp)    /* trapno */
-       pushl $fault_msg
-       call printk
-#endif
-       call dump_stack
-hlt_loop:
-       hlt
-       jmp hlt_loop
 ENDPROC(early_idt_handler_common)
 
 /* This is the default interrupt "handler" :-) */
@@ -674,10 +644,14 @@ ignore_int:
        popl %eax
 #endif
        iret
+
+hlt_loop:
+       hlt
+       jmp hlt_loop
 ENDPROC(ignore_int)
 __INITDATA
        .align 4
-early_recursion_flag:
+GLOBAL(early_recursion_flag)
        .long 0
 
 __REFDATA
@@ -742,19 +716,6 @@ __INITRODATA
 int_msg:
        .asciz "Unknown interrupt or fault at: %p %p %p\n"
 
-fault_msg:
-/* fault info: */
-       .ascii "BUG: Int %d: CR2 %p\n"
-/* regs pushed in early_idt_handler: */
-       .ascii "     EDI %p  ESI %p  EBP %p  EBX %p\n"
-       .ascii "     ESP %p   ES %p   DS %p\n"
-       .ascii "     EDX %p  ECX %p  EAX %p\n"
-/* fault frame: */
-       .ascii "     vec %p  err %p  EIP %p   CS %p  flg %p\n"
-       .ascii "Stack: %p %p %p %p %p %p %p %p\n"
-       .ascii "       %p %p %p %p %p %p %p %p\n"
-       .asciz "       %p %p %p %p %p %p %p %p\n"
-
 #include "../../x86/xen/xen-head.S"
 
 /*
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 2308437..3de91a7 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -351,8 +351,6 @@ early_idt_handler_common:
         */
        cld
 
-       cmpl $2,early_recursion_flag(%rip)
-       jz  1f
        incl early_recursion_flag(%rip)
 
        /* The vector number is currently in the pt_regs->di slot. */
@@ -373,9 +371,6 @@ early_idt_handler_common:
        pushq %r14                              /* pt_regs->r14 */
        pushq %r15                              /* pt_regs->r15 */
 
-       cmpl $__KERNEL_CS,CS(%rsp)
-       jne 11f
-
        cmpq $14,%rsi           /* Page fault? */
        jnz 10f
        GET_CR2_INTO(%rdi)      /* Can clobber any volatile register if pv */
@@ -386,37 +381,8 @@ early_idt_handler_common:
 10:
        movq %rsp,%rdi          /* RDI = pt_regs; RSI is already trapnr */
        call early_fixup_exception
-       andl %eax,%eax
-       jnz 20f                 # Found an exception entry
-
-11:
-#ifdef CONFIG_EARLY_PRINTK
-       /*
-        * On paravirt kernels, GET_CR2_INTO clobbers callee-clobbered regs.
-        * We only care about RSI, so we need to save it.
-        */
-       movq %rsi,%rbx          /* Save vector number */
-       GET_CR2_INTO(%r9)
-       movq ORIG_RAX(%rsp),%r8 /* error code */
-       movq %rbx,%rsi          /* vector number */
-       movq CS(%rsp),%rdx
-       movq RIP(%rsp),%rcx
-       xorl %eax,%eax
-       leaq early_idt_msg(%rip),%rdi
-       call early_printk
-       cmpl $2,early_recursion_flag(%rip)
-       jz  1f
-       call dump_stack
-#ifdef CONFIG_KALLSYMS 
-       leaq early_idt_ripmsg(%rip),%rdi
-       movq RIP(%rsp),%rsi     # %rip again
-       call __print_symbol
-#endif
-#endif /* EARLY_PRINTK */
-1:     hlt
-       jmp 1b
 
-20:    /* Exception table entry found or page table generated */
+20:
        decl early_recursion_flag(%rip)
        jmp restore_regs_and_iret
 ENDPROC(early_idt_handler_common)
@@ -424,16 +390,9 @@ ENDPROC(early_idt_handler_common)
        __INITDATA
 
        .balign 4
-early_recursion_flag:
+GLOBAL(early_recursion_flag)
        .long 0
 
-#ifdef CONFIG_EARLY_PRINTK
-early_idt_msg:
-       .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
-early_idt_ripmsg:
-       .asciz "RIP %s\n"
-#endif /* CONFIG_EARLY_PRINTK */
-
 #define NEXT_PAGE(name) \
        .balign PAGE_SIZE; \
 GLOBAL(name)
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
index 4be0419..da442f3 100644
--- a/arch/x86/mm/extable.c
+++ b/arch/x86/mm/extable.c
@@ -83,8 +83,10 @@ int fixup_exception(struct pt_regs *regs, int trapnr)
        return handler(e, regs, trapnr);
 }
 
+extern unsigned int early_recursion_flag;
+
 /* Restricted version used during very early boot */
-int __init early_fixup_exception(struct pt_regs *regs, int trapnr)
+void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 {
        const struct exception_table_entry *e;
        unsigned long new_ip;
@@ -92,19 +94,36 @@ int __init early_fixup_exception(struct pt_regs *regs, int 
trapnr)
 
        /* Ignore early NMIs. */
        if (trapnr == X86_TRAP_NMI)
-               return 1;
+               return;
+
+       if (early_recursion_flag > 2)
+               goto halt_loop;
+
+       if (regs->cs != __KERNEL_CS)
+               goto fail;
 
        e = search_exception_tables(regs->ip);
        if (!e)
-               return 0;
+               goto fail;
 
        new_ip  = ex_fixup_addr(e);
        handler = ex_fixup_handler(e);
 
        /* special handling not supported during early boot */
        if (handler != ex_handler_default)
-               return 0;
+               goto fail;
 
        regs->ip = new_ip;
-       return 1;
+       return;
+
+fail:
+       early_printk("PANIC: early exception 0x%02x IP %lx:%lx error %lx cr2 
0x%lx\n",
+                    (unsigned)trapnr, (unsigned long)regs->cs, regs->ip,
+                    regs->orig_ax, read_cr2());
+
+       show_regs(regs);
+
+halt_loop:
+       while (true)
+               halt();
 }

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.