x86: early_idt_handler improvements, 64-bit
It's not too pretty, but I found this made the "PANIC: early exception" messages become much more reliably useful: 1. print the vector number, 2. print the %cs value, 3. handle error-code-pushing vs non-pushing vectors. Signed-off-by: Roland McGrath <roland@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
committed by
Ingo Molnar
parent
d504e39efd
commit
8866cd9dc9
@@ -59,7 +59,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
|
|||||||
zap_identity_mappings();
|
zap_identity_mappings();
|
||||||
|
|
||||||
for (i = 0; i < IDT_ENTRIES; i++)
|
for (i = 0; i < IDT_ENTRIES; i++)
|
||||||
set_intr_gate(i, early_idt_handler);
|
set_intr_gate(i, &early_idt_handlers[i]);
|
||||||
load_idt((const struct desc_ptr *)&idt_descr);
|
load_idt((const struct desc_ptr *)&idt_descr);
|
||||||
|
|
||||||
early_printk("Kernel alive\n");
|
early_printk("Kernel alive\n");
|
||||||
|
@@ -267,14 +267,40 @@ init_rsp:
|
|||||||
bad_address:
|
bad_address:
|
||||||
jmp bad_address
|
jmp bad_address
|
||||||
|
|
||||||
|
.macro early_idt_tramp first, last
|
||||||
|
.ifgt \last-\first
|
||||||
|
early_idt_tramp \first, \last-1
|
||||||
|
.endif
|
||||||
|
movl $\last,%esi
|
||||||
|
jmp early_idt_handler
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.globl early_idt_handlers
|
||||||
|
early_idt_handlers:
|
||||||
|
early_idt_tramp 0, 63
|
||||||
|
early_idt_tramp 64, 127
|
||||||
|
early_idt_tramp 128, 191
|
||||||
|
early_idt_tramp 192, 255
|
||||||
|
|
||||||
ENTRY(early_idt_handler)
|
ENTRY(early_idt_handler)
|
||||||
cmpl $2,early_recursion_flag(%rip)
|
cmpl $2,early_recursion_flag(%rip)
|
||||||
jz 1f
|
jz 1f
|
||||||
incl early_recursion_flag(%rip)
|
incl early_recursion_flag(%rip)
|
||||||
xorl %eax,%eax
|
|
||||||
movq 8(%rsp),%rsi # get rip
|
|
||||||
movq (%rsp),%rdx
|
|
||||||
GET_CR2_INTO_RCX
|
GET_CR2_INTO_RCX
|
||||||
|
movq %rcx,%r9
|
||||||
|
xorl %r8d,%r8d # zero for error code
|
||||||
|
movl %esi,%ecx # get vector number
|
||||||
|
# Test %ecx against mask of vectors that push error code.
|
||||||
|
cmpl $31,%ecx
|
||||||
|
ja 0f
|
||||||
|
movl $1,%eax
|
||||||
|
salq %cl,%rax
|
||||||
|
testl $0x27d00,%eax
|
||||||
|
je 0f
|
||||||
|
popq %r8 # get error code
|
||||||
|
0: movq 0(%rsp),%rcx # get ip
|
||||||
|
movq 8(%rsp),%rdx # get cs
|
||||||
|
xorl %eax,%eax
|
||||||
leaq early_idt_msg(%rip),%rdi
|
leaq early_idt_msg(%rip),%rdi
|
||||||
call early_printk
|
call early_printk
|
||||||
cmpl $2,early_recursion_flag(%rip)
|
cmpl $2,early_recursion_flag(%rip)
|
||||||
@@ -291,7 +317,7 @@ early_recursion_flag:
|
|||||||
.long 0
|
.long 0
|
||||||
|
|
||||||
early_idt_msg:
|
early_idt_msg:
|
||||||
.asciz "PANIC: early exception rip %lx error %lx cr2 %lx\n"
|
.asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
|
||||||
early_idt_ripmsg:
|
early_idt_ripmsg:
|
||||||
.asciz "RIP %s\n"
|
.asciz "RIP %s\n"
|
||||||
|
|
||||||
|
@@ -195,4 +195,10 @@
|
|||||||
#define GDT_ENTRY_TLS_ENTRIES 3
|
#define GDT_ENTRY_TLS_ENTRIES 3
|
||||||
#define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8)
|
#define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8)
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
extern const char early_idt_handlers[IDT_ENTRIES][10];
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user