diff options
Diffstat (limited to 'arch/x86/kernel/head_32.S')
-rw-r--r-- | arch/x86/kernel/head_32.S | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index d031bad9e07e..53eeb226657c 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -478,21 +478,22 @@ is486: | |||
478 | __INIT | 478 | __INIT |
479 | setup_once: | 479 | setup_once: |
480 | /* | 480 | /* |
481 | * Set up a idt with 256 entries pointing to ignore_int, | 481 | * Set up a idt with 256 interrupt gates that push zero if there |
482 | * interrupt gates. It doesn't actually load idt - that needs | 482 | * is no error code and then jump to early_idt_handler_common. |
483 | * to be done on each CPU. Interrupts are enabled elsewhere, | 483 | * It doesn't actually load the idt - that needs to be done on |
484 | * when we can be relatively sure everything is ok. | 484 | * each CPU. Interrupts are enabled elsewhere, when we can be |
485 | * relatively sure everything is ok. | ||
485 | */ | 486 | */ |
486 | 487 | ||
487 | movl $idt_table,%edi | 488 | movl $idt_table,%edi |
488 | movl $early_idt_handlers,%eax | 489 | movl $early_idt_handler_array,%eax |
489 | movl $NUM_EXCEPTION_VECTORS,%ecx | 490 | movl $NUM_EXCEPTION_VECTORS,%ecx |
490 | 1: | 491 | 1: |
491 | movl %eax,(%edi) | 492 | movl %eax,(%edi) |
492 | movl %eax,4(%edi) | 493 | movl %eax,4(%edi) |
493 | /* interrupt gate, dpl=0, present */ | 494 | /* interrupt gate, dpl=0, present */ |
494 | movl $(0x8E000000 + __KERNEL_CS),2(%edi) | 495 | movl $(0x8E000000 + __KERNEL_CS),2(%edi) |
495 | addl $9,%eax | 496 | addl $EARLY_IDT_HANDLER_SIZE,%eax |
496 | addl $8,%edi | 497 | addl $8,%edi |
497 | loop 1b | 498 | loop 1b |
498 | 499 | ||
@@ -524,26 +525,28 @@ setup_once: | |||
524 | andl $0,setup_once_ref /* Once is enough, thanks */ | 525 | andl $0,setup_once_ref /* Once is enough, thanks */ |
525 | ret | 526 | ret |
526 | 527 | ||
527 | ENTRY(early_idt_handlers) | 528 | ENTRY(early_idt_handler_array) |
528 | # 36(%esp) %eflags | 529 | # 36(%esp) %eflags |
529 | # 32(%esp) %cs | 530 | # 32(%esp) %cs |
530 | # 28(%esp) %eip | 531 | # 28(%esp) %eip |
531 | # 24(%rsp) error code | 532 | # 24(%rsp) error code |
532 | i = 0 | 533 | i = 0 |
533 | .rept NUM_EXCEPTION_VECTORS | 534 | .rept NUM_EXCEPTION_VECTORS |
534 | .if (EXCEPTION_ERRCODE_MASK >> i) & 1 | 535 | .ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1 |
535 | ASM_NOP2 | ||
536 | .else | ||
537 | pushl $0 # Dummy error code, to make stack frame uniform | 536 | pushl $0 # Dummy error code, to make stack frame uniform |
538 | .endif | 537 | .endif |
539 | pushl $i # 20(%esp) Vector number | 538 | pushl $i # 20(%esp) Vector number |
540 | jmp early_idt_handler | 539 | jmp early_idt_handler_common |
541 | i = i + 1 | 540 | i = i + 1 |
541 | .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc | ||
542 | .endr | 542 | .endr |
543 | ENDPROC(early_idt_handlers) | 543 | ENDPROC(early_idt_handler_array) |
544 | 544 | ||
545 | /* This is global to keep gas from relaxing the jumps */ | 545 | early_idt_handler_common: |
546 | ENTRY(early_idt_handler) | 546 | /* |
547 | * The stack is the hardware frame, an error code or zero, and the | ||
548 | * vector number. | ||
549 | */ | ||
547 | cld | 550 | cld |
548 | 551 | ||
549 | cmpl $2,(%esp) # X86_TRAP_NMI | 552 | cmpl $2,(%esp) # X86_TRAP_NMI |
@@ -603,7 +606,7 @@ ex_entry: | |||
603 | is_nmi: | 606 | is_nmi: |
604 | addl $8,%esp /* drop vector number and error code */ | 607 | addl $8,%esp /* drop vector number and error code */ |
605 | iret | 608 | iret |
606 | ENDPROC(early_idt_handler) | 609 | ENDPROC(early_idt_handler_common) |
607 | 610 | ||
608 | /* This is the default interrupt "handler" :-) */ | 611 | /* This is the default interrupt "handler" :-) */ |
609 | ALIGN | 612 | ALIGN |