aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJan Beulich <JBeulich@suse.com>2014-11-03 03:39:43 -0500
committerThomas Gleixner <tglx@linutronix.de>2014-12-16 08:08:14 -0500
commit2414e021ac8d588f1b09f64891f69a3e26feadf1 (patch)
treeb74763cf043cd03720f371141a0a77c3baf6369f /arch
parente10679825924580845c4825deaaddf5331ff627c (diff)
x86: Avoid building unused IRQ entry stubs
When X86_LOCAL_APIC (i.e. unconditionally on x86-64), first_system_vector will never end up being higher than LOCAL_TIMER_VECTOR (0xef), and hence building stubs for vectors 0xef...0xff is pointlessly reducing code density. Deal with this at build time already. Taking into consideration that X86_64 implies X86_LOCAL_APIC, also simplify (and hence make easier to read and more consistent with the change done here) some #if-s in arch/x86/kernel/irqinit.c. While we could further improve the packing of the IRQ entry stubs (the four ones now left in the last set could be fit into the four padding bytes each of the final four sets have) this doesn't seem to provide any real benefit: Both irq_entries_start and common_interrupt getting cache line aligned, eliminating the 30th set would just produce 32 bytes of padding between the 29th and common_interrupt. [ tglx: Folded lguest fix from Dan Carpenter ] Signed-off-by: Jan Beulich <jbeulich@suse.com> Cc: Dan Carpenter <dan.carpenter@oracle.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: lguest@lists.ozlabs.org Cc: Rusty Russell <rusty@rustcorp.com.au> Link: http://lkml.kernel.org/r/54574D5F0200007800044389@mail.emea.novell.com Link: http://lkml.kernel.org/r/20141115185718.GB6530@mwanda Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/hw_irq.h3
-rw-r--r--arch/x86/include/asm/irq_vectors.h6
-rw-r--r--arch/x86/kernel/apic/apic.c22
-rw-r--r--arch/x86/kernel/entry_32.S4
-rw-r--r--arch/x86/kernel/entry_64.S4
-rw-r--r--arch/x86/kernel/irqinit.c13
-rw-r--r--arch/x86/lguest/boot.c2
7 files changed, 34 insertions, 20 deletions
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index fa5d1e768ba3..8dbe237bd806 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -189,7 +189,8 @@ extern __visible void smp_call_function_single_interrupt(struct pt_regs *);
189extern __visible void smp_invalidate_interrupt(struct pt_regs *); 189extern __visible void smp_invalidate_interrupt(struct pt_regs *);
190#endif 190#endif
191 191
192extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void); 192extern void (*__initconst interrupt[FIRST_SYSTEM_VECTOR
193 - FIRST_EXTERNAL_VECTOR])(void);
193#ifdef CONFIG_TRACING 194#ifdef CONFIG_TRACING
194#define trace_interrupt interrupt 195#define trace_interrupt interrupt
195#endif 196#endif
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index 5702d7e3111d..666c89ec4bd7 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -126,6 +126,12 @@
126 126
127#define NR_VECTORS 256 127#define NR_VECTORS 256
128 128
129#ifdef CONFIG_X86_LOCAL_APIC
130#define FIRST_SYSTEM_VECTOR LOCAL_TIMER_VECTOR
131#else
132#define FIRST_SYSTEM_VECTOR NR_VECTORS
133#endif
134
129#define FPU_IRQ 13 135#define FPU_IRQ 13
130 136
131#define FIRST_VM86_IRQ 3 137#define FIRST_VM86_IRQ 3
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index ba6cc041edb1..29b5b18afa27 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -196,7 +196,7 @@ static int disable_apic_timer __initdata;
196int local_apic_timer_c2_ok; 196int local_apic_timer_c2_ok;
197EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); 197EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
198 198
199int first_system_vector = 0xfe; 199int first_system_vector = FIRST_SYSTEM_VECTOR;
200 200
201/* 201/*
202 * Debug level, exported for io_apic.c 202 * Debug level, exported for io_apic.c
@@ -1930,7 +1930,7 @@ int __init APIC_init_uniprocessor(void)
1930/* 1930/*
1931 * This interrupt should _never_ happen with our APIC/SMP architecture 1931 * This interrupt should _never_ happen with our APIC/SMP architecture
1932 */ 1932 */
1933static inline void __smp_spurious_interrupt(void) 1933static inline void __smp_spurious_interrupt(u8 vector)
1934{ 1934{
1935 u32 v; 1935 u32 v;
1936 1936
@@ -1939,30 +1939,32 @@ static inline void __smp_spurious_interrupt(void)
1939 * if it is a vectored one. Just in case... 1939 * if it is a vectored one. Just in case...
1940 * Spurious interrupts should not be ACKed. 1940 * Spurious interrupts should not be ACKed.
1941 */ 1941 */
1942 v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1)); 1942 v = apic_read(APIC_ISR + ((vector & ~0x1f) >> 1));
1943 if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f))) 1943 if (v & (1 << (vector & 0x1f)))
1944 ack_APIC_irq(); 1944 ack_APIC_irq();
1945 1945
1946 inc_irq_stat(irq_spurious_count); 1946 inc_irq_stat(irq_spurious_count);
1947 1947
1948 /* see sw-dev-man vol 3, chapter 7.4.13.5 */ 1948 /* see sw-dev-man vol 3, chapter 7.4.13.5 */
1949 pr_info("spurious APIC interrupt on CPU#%d, " 1949 pr_info("spurious APIC interrupt through vector %02x on CPU#%d, "
1950 "should never happen.\n", smp_processor_id()); 1950 "should never happen.\n", vector, smp_processor_id());
1951} 1951}
1952 1952
1953__visible void smp_spurious_interrupt(struct pt_regs *regs) 1953__visible void smp_spurious_interrupt(struct pt_regs *regs)
1954{ 1954{
1955 entering_irq(); 1955 entering_irq();
1956 __smp_spurious_interrupt(); 1956 __smp_spurious_interrupt(~regs->orig_ax);
1957 exiting_irq(); 1957 exiting_irq();
1958} 1958}
1959 1959
1960__visible void smp_trace_spurious_interrupt(struct pt_regs *regs) 1960__visible void smp_trace_spurious_interrupt(struct pt_regs *regs)
1961{ 1961{
1962 u8 vector = ~regs->orig_ax;
1963
1962 entering_irq(); 1964 entering_irq();
1963 trace_spurious_apic_entry(SPURIOUS_APIC_VECTOR); 1965 trace_spurious_apic_entry(vector);
1964 __smp_spurious_interrupt(); 1966 __smp_spurious_interrupt(vector);
1965 trace_spurious_apic_exit(SPURIOUS_APIC_VECTOR); 1967 trace_spurious_apic_exit(vector);
1966 exiting_irq(); 1968 exiting_irq();
1967} 1969}
1968 1970
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 344b63f18d14..1ea4488bbb90 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -732,10 +732,10 @@ ENTRY(interrupt)
732ENTRY(irq_entries_start) 732ENTRY(irq_entries_start)
733 RING0_INT_FRAME 733 RING0_INT_FRAME
734vector=FIRST_EXTERNAL_VECTOR 734vector=FIRST_EXTERNAL_VECTOR
735.rept (NR_VECTORS-FIRST_EXTERNAL_VECTOR+6)/7 735.rept (FIRST_SYSTEM_VECTOR-FIRST_EXTERNAL_VECTOR+6)/7
736 .balign 32 736 .balign 32
737 .rept 7 737 .rept 7
738 .if vector < NR_VECTORS 738 .if vector < FIRST_SYSTEM_VECTOR
739 .if vector <> FIRST_EXTERNAL_VECTOR 739 .if vector <> FIRST_EXTERNAL_VECTOR
740 CFI_ADJUST_CFA_OFFSET -4 740 CFI_ADJUST_CFA_OFFSET -4
741 .endif 741 .endif
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index c0226ab54106..e61c14aa1ef9 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -712,10 +712,10 @@ ENTRY(interrupt)
712ENTRY(irq_entries_start) 712ENTRY(irq_entries_start)
713 INTR_FRAME 713 INTR_FRAME
714vector=FIRST_EXTERNAL_VECTOR 714vector=FIRST_EXTERNAL_VECTOR
715.rept (NR_VECTORS-FIRST_EXTERNAL_VECTOR+6)/7 715.rept (FIRST_SYSTEM_VECTOR-FIRST_EXTERNAL_VECTOR+6)/7
716 .balign 32 716 .balign 32
717 .rept 7 717 .rept 7
718 .if vector < NR_VECTORS 718 .if vector < FIRST_SYSTEM_VECTOR
719 .if vector <> FIRST_EXTERNAL_VECTOR 719 .if vector <> FIRST_EXTERNAL_VECTOR
720 CFI_ADJUST_CFA_OFFSET -8 720 CFI_ADJUST_CFA_OFFSET -8
721 .endif 721 .endif
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index 4de73ee78361..fa893087fb51 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -124,7 +124,6 @@ void setup_vector_irq(int cpu)
124static void __init smp_intr_init(void) 124static void __init smp_intr_init(void)
125{ 125{
126#ifdef CONFIG_SMP 126#ifdef CONFIG_SMP
127#if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
128 /* 127 /*
129 * The reschedule interrupt is a CPU-to-CPU reschedule-helper 128 * The reschedule interrupt is a CPU-to-CPU reschedule-helper
130 * IPI, driven by wakeup. 129 * IPI, driven by wakeup.
@@ -144,7 +143,6 @@ static void __init smp_intr_init(void)
144 143
145 /* IPI used for rebooting/stopping */ 144 /* IPI used for rebooting/stopping */
146 alloc_intr_gate(REBOOT_VECTOR, reboot_interrupt); 145 alloc_intr_gate(REBOOT_VECTOR, reboot_interrupt);
147#endif
148#endif /* CONFIG_SMP */ 146#endif /* CONFIG_SMP */
149} 147}
150 148
@@ -159,7 +157,7 @@ static void __init apic_intr_init(void)
159 alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt); 157 alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
160#endif 158#endif
161 159
162#if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC) 160#ifdef CONFIG_X86_LOCAL_APIC
163 /* self generated IPI for local APIC timer */ 161 /* self generated IPI for local APIC timer */
164 alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); 162 alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
165 163
@@ -197,10 +195,17 @@ void __init native_init_IRQ(void)
197 * 'special' SMP interrupts) 195 * 'special' SMP interrupts)
198 */ 196 */
199 i = FIRST_EXTERNAL_VECTOR; 197 i = FIRST_EXTERNAL_VECTOR;
200 for_each_clear_bit_from(i, used_vectors, NR_VECTORS) { 198#ifndef CONFIG_X86_LOCAL_APIC
199#define first_system_vector NR_VECTORS
200#endif
201 for_each_clear_bit_from(i, used_vectors, first_system_vector) {
201 /* IA32_SYSCALL_VECTOR could be used in trap_init already. */ 202 /* IA32_SYSCALL_VECTOR could be used in trap_init already. */
202 set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]); 203 set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]);
203 } 204 }
205#ifdef CONFIG_X86_LOCAL_APIC
206 for_each_clear_bit_from(i, used_vectors, NR_VECTORS)
207 set_intr_gate(i, spurious_interrupt);
208#endif
204 209
205 if (!acpi_ioapic && !of_ioapic && nr_legacy_irqs()) 210 if (!acpi_ioapic && !of_ioapic && nr_legacy_irqs())
206 setup_irq(2, &irq2); 211 setup_irq(2, &irq2);
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index aae94132bc24..c1c1544b8485 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -841,7 +841,7 @@ static void __init lguest_init_IRQ(void)
841{ 841{
842 unsigned int i; 842 unsigned int i;
843 843
844 for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) { 844 for (i = FIRST_EXTERNAL_VECTOR; i < FIRST_SYSTEM_VECTOR; i++) {
845 /* Some systems map "vectors" to interrupts weirdly. Not us! */ 845 /* Some systems map "vectors" to interrupts weirdly. Not us! */
846 __this_cpu_write(vector_irq[i], i - FIRST_EXTERNAL_VECTOR); 846 __this_cpu_write(vector_irq[i], i - FIRST_EXTERNAL_VECTOR);
847 if (i != SYSCALL_VECTOR) 847 if (i != SYSCALL_VECTOR)