diff options
Diffstat (limited to 'arch/x86/kernel/entry_64.S')
-rw-r--r-- | arch/x86/kernel/entry_64.S | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index b86f332c96a6..9b2aeaac9a6b 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -627,6 +627,46 @@ END(stub_rt_sigreturn) | |||
627 | vector already pushed) */ | 627 | vector already pushed) */ |
628 | #define XCPT_FRAME _frame ORIG_RAX | 628 | #define XCPT_FRAME _frame ORIG_RAX |
629 | 629 | ||
630 | /* | ||
631 | * Build the entry stubs and pointer table with some assembler magic. | ||
632 | * We pack 7 stubs into a single 32-byte chunk, which will fit in a | ||
633 | * single cache line on all modern x86 implementations. | ||
634 | */ | ||
635 | .section .init.rodata,"a" | ||
636 | ENTRY(interrupt) | ||
637 | .text | ||
638 | .p2align 5 | ||
639 | .p2align CONFIG_X86_L1_CACHE_SHIFT | ||
640 | ENTRY(irq_entries_start) | ||
641 | INTR_FRAME | ||
642 | vector=FIRST_EXTERNAL_VECTOR | ||
643 | .rept (NR_VECTORS-FIRST_EXTERNAL_VECTOR+6)/7 | ||
644 | .balign 32 | ||
645 | .rept 7 | ||
646 | .if vector < NR_VECTORS | ||
647 | .if vector != FIRST_EXTERNAL_VECTOR | ||
648 | CFI_ADJUST_CFA_OFFSET -8 | ||
649 | .endif | ||
650 | 1: pushq $(~vector+0x80) /* Note: always in signed byte range */ | ||
651 | CFI_ADJUST_CFA_OFFSET 8 | ||
652 | .if ((vector-FIRST_EXTERNAL_VECTOR)%7) != 6 | ||
653 | jmp 2f | ||
654 | .endif | ||
655 | .previous | ||
656 | .quad 1b | ||
657 | .text | ||
658 | vector=vector+1 | ||
659 | .endif | ||
660 | .endr | ||
661 | 2: jmp common_interrupt | ||
662 | .endr | ||
663 | CFI_ENDPROC | ||
664 | END(irq_entries_start) | ||
665 | |||
666 | .previous | ||
667 | END(interrupt) | ||
668 | .previous | ||
669 | |||
630 | /* | 670 | /* |
631 | * Interrupt entry/exit. | 671 | * Interrupt entry/exit. |
632 | * | 672 | * |
@@ -635,11 +675,12 @@ END(stub_rt_sigreturn) | |||
635 | * Entry runs with interrupts off. | 675 | * Entry runs with interrupts off. |
636 | */ | 676 | */ |
637 | 677 | ||
638 | /* 0(%rsp): interrupt number */ | 678 | /* 0(%rsp): ~(interrupt number)+0x80 */ |
639 | .macro interrupt func | 679 | .macro interrupt func |
680 | addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */ | ||
640 | cld | 681 | cld |
641 | SAVE_ARGS | 682 | SAVE_ARGS |
642 | leaq -ARGOFFSET(%rsp),%rdi # arg1 for handler | 683 | leaq -ARGOFFSET(%rsp),%rdi /* arg1 for handler */ |
643 | pushq %rbp | 684 | pushq %rbp |
644 | /* | 685 | /* |
645 | * Save rbp twice: One is for marking the stack frame, as usual, and the | 686 | * Save rbp twice: One is for marking the stack frame, as usual, and the |
@@ -670,7 +711,8 @@ END(stub_rt_sigreturn) | |||
670 | call \func | 711 | call \func |
671 | .endm | 712 | .endm |
672 | 713 | ||
673 | ENTRY(common_interrupt) | 714 | .p2align CONFIG_X86_L1_CACHE_SHIFT |
715 | common_interrupt: | ||
674 | XCPT_FRAME | 716 | XCPT_FRAME |
675 | interrupt do_IRQ | 717 | interrupt do_IRQ |
676 | /* 0(%rsp): oldrsp-ARGOFFSET */ | 718 | /* 0(%rsp): oldrsp-ARGOFFSET */ |