aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/entry_64.S
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-11-11 16:51:52 -0500
committerH. Peter Anvin <hpa@zytor.com>2008-11-11 16:51:52 -0500
commit939b787130bf22887a09d8fd2641a094dcef8c22 (patch)
tree6bdd272bb742bf2916d35c04cb8a6dd24e2dd135 /arch/x86/kernel/entry_64.S
parentb7c6244f13d37592003b46e12500a90e9781ad9d (diff)
x86: 64 bits: shrink and align IRQ stubs
Move the IRQ stub generation to assembly to simplify it and for consistency with 32 bits. Doing it in a C file with asm() statements doesn't help clarity, and it prevents some optimizations. Shrink the IRQ stubs down to just over four bytes per (we fit seven into a 32-byte chunk.) This shrinks the total icache consumption of the IRQ stubs down to an even kilobyte, if all of them are in active use. The downside is that we end up with a double jump, which could have a negative effect on some pipelines. The double jump is always inside the same cacheline on any modern chips. To get the most effect, cache-align the IRQ stubs. This makes the 64-bit code match changes already done to the 32-bit code, and should open up irqinit*.c for unification. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/kernel/entry_64.S')
-rw-r--r--arch/x86/kernel/entry_64.S48
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"
636ENTRY(interrupt)
637 .text
638 .p2align 5
639 .p2align CONFIG_X86_L1_CACHE_SHIFT
640ENTRY(irq_entries_start)
641 INTR_FRAME
642vector=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
6501: 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
658vector=vector+1
659 .endif
660 .endr
6612: jmp common_interrupt
662.endr
663 CFI_ENDPROC
664END(irq_entries_start)
665
666.previous
667END(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
673ENTRY(common_interrupt) 714 .p2align CONFIG_X86_L1_CACHE_SHIFT
715common_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 */