aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/hw_irq.h6
-rw-r--r--arch/x86/include/asm/irq.h4
-rw-r--r--arch/x86/kernel/apic/vector.c51
-rw-r--r--arch/x86/kernel/irq.c37
-rw-r--r--arch/x86/kernel/irq_32.c9
-rw-r--r--arch/x86/kernel/irq_64.c9
-rw-r--r--arch/x86/kernel/irqinit.c4
-rw-r--r--arch/x86/lguest/boot.c4
8 files changed, 58 insertions, 66 deletions
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index 62bb8d23b826..1e3408e88604 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -182,10 +182,10 @@ extern char irq_entries_start[];
182#define trace_irq_entries_start irq_entries_start 182#define trace_irq_entries_start irq_entries_start
183#endif 183#endif
184 184
185#define VECTOR_UNUSED (-1) 185#define VECTOR_UNUSED NULL
186#define VECTOR_RETRIGGERED (-2) 186#define VECTOR_RETRIGGERED ((void *)~0UL)
187 187
188typedef int vector_irq_t[NR_VECTORS]; 188typedef struct irq_desc* vector_irq_t[NR_VECTORS];
189DECLARE_PER_CPU(vector_irq_t, vector_irq); 189DECLARE_PER_CPU(vector_irq_t, vector_irq);
190 190
191#endif /* !ASSEMBLY_ */ 191#endif /* !ASSEMBLY_ */
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index 8008d06581c7..881b4768644a 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -36,7 +36,9 @@ extern void kvm_set_posted_intr_wakeup_handler(void (*handler)(void));
36 36
37extern void (*x86_platform_ipi_callback)(void); 37extern void (*x86_platform_ipi_callback)(void);
38extern void native_init_IRQ(void); 38extern void native_init_IRQ(void);
39extern bool handle_irq(unsigned irq, struct pt_regs *regs); 39
40struct irq_desc;
41extern bool handle_irq(struct irq_desc *desc, struct pt_regs *regs);
40 42
41extern __visible unsigned int do_IRQ(struct pt_regs *regs); 43extern __visible unsigned int do_IRQ(struct pt_regs *regs);
42 44
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 9a6d11258684..200b5a5d6b79 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -169,7 +169,7 @@ next:
169 goto next; 169 goto next;
170 170
171 for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask) { 171 for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask) {
172 if (per_cpu(vector_irq, new_cpu)[vector] > VECTOR_UNUSED) 172 if (!IS_ERR_OR_NULL(per_cpu(vector_irq, new_cpu)[vector]))
173 goto next; 173 goto next;
174 } 174 }
175 /* Found one! */ 175 /* Found one! */
@@ -181,7 +181,7 @@ next:
181 cpumask_intersects(d->old_domain, cpu_online_mask); 181 cpumask_intersects(d->old_domain, cpu_online_mask);
182 } 182 }
183 for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask) 183 for_each_cpu_and(new_cpu, vector_cpumask, cpu_online_mask)
184 per_cpu(vector_irq, new_cpu)[vector] = irq; 184 per_cpu(vector_irq, new_cpu)[vector] = irq_to_desc(irq);
185 d->cfg.vector = vector; 185 d->cfg.vector = vector;
186 cpumask_copy(d->domain, vector_cpumask); 186 cpumask_copy(d->domain, vector_cpumask);
187 err = 0; 187 err = 0;
@@ -223,8 +223,9 @@ static int assign_irq_vector_policy(int irq, int node,
223 223
224static void clear_irq_vector(int irq, struct apic_chip_data *data) 224static void clear_irq_vector(int irq, struct apic_chip_data *data)
225{ 225{
226 int cpu, vector; 226 struct irq_desc *desc;
227 unsigned long flags; 227 unsigned long flags;
228 int cpu, vector;
228 229
229 raw_spin_lock_irqsave(&vector_lock, flags); 230 raw_spin_lock_irqsave(&vector_lock, flags);
230 BUG_ON(!data->cfg.vector); 231 BUG_ON(!data->cfg.vector);
@@ -241,10 +242,11 @@ static void clear_irq_vector(int irq, struct apic_chip_data *data)
241 return; 242 return;
242 } 243 }
243 244
245 desc = irq_to_desc(irq);
244 for_each_cpu_and(cpu, data->old_domain, cpu_online_mask) { 246 for_each_cpu_and(cpu, data->old_domain, cpu_online_mask) {
245 for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; 247 for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS;
246 vector++) { 248 vector++) {
247 if (per_cpu(vector_irq, cpu)[vector] != irq) 249 if (per_cpu(vector_irq, cpu)[vector] != desc)
248 continue; 250 continue;
249 per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED; 251 per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED;
250 break; 252 break;
@@ -402,30 +404,30 @@ int __init arch_early_irq_init(void)
402 return arch_early_ioapic_init(); 404 return arch_early_ioapic_init();
403} 405}
404 406
407/* Initialize vector_irq on a new cpu */
405static void __setup_vector_irq(int cpu) 408static void __setup_vector_irq(int cpu)
406{ 409{
407 /* Initialize vector_irq on a new cpu */
408 int irq, vector;
409 struct apic_chip_data *data; 410 struct apic_chip_data *data;
411 struct irq_desc *desc;
412 int irq, vector;
410 413
411 /* Mark the inuse vectors */ 414 /* Mark the inuse vectors */
412 for_each_active_irq(irq) { 415 for_each_irq_desc(irq, desc) {
413 data = apic_chip_data(irq_get_irq_data(irq)); 416 struct irq_data *idata = irq_desc_get_irq_data(desc);
414 if (!data)
415 continue;
416 417
417 if (!cpumask_test_cpu(cpu, data->domain)) 418 data = apic_chip_data(idata);
419 if (!data || !cpumask_test_cpu(cpu, data->domain))
418 continue; 420 continue;
419 vector = data->cfg.vector; 421 vector = data->cfg.vector;
420 per_cpu(vector_irq, cpu)[vector] = irq; 422 per_cpu(vector_irq, cpu)[vector] = desc;
421 } 423 }
422 /* Mark the free vectors */ 424 /* Mark the free vectors */
423 for (vector = 0; vector < NR_VECTORS; ++vector) { 425 for (vector = 0; vector < NR_VECTORS; ++vector) {
424 irq = per_cpu(vector_irq, cpu)[vector]; 426 desc = per_cpu(vector_irq, cpu)[vector];
425 if (irq <= VECTOR_UNUSED) 427 if (IS_ERR_OR_NULL(desc))
426 continue; 428 continue;
427 429
428 data = apic_chip_data(irq_get_irq_data(irq)); 430 data = apic_chip_data(irq_desc_get_irq_data(desc));
429 if (!cpumask_test_cpu(cpu, data->domain)) 431 if (!cpumask_test_cpu(cpu, data->domain))
430 per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED; 432 per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED;
431 } 433 }
@@ -447,7 +449,7 @@ void setup_vector_irq(int cpu)
447 * legacy vector to irq mapping: 449 * legacy vector to irq mapping:
448 */ 450 */
449 for (irq = 0; irq < nr_legacy_irqs(); irq++) 451 for (irq = 0; irq < nr_legacy_irqs(); irq++)
450 per_cpu(vector_irq, cpu)[ISA_IRQ_VECTOR(irq)] = irq; 452 per_cpu(vector_irq, cpu)[ISA_IRQ_VECTOR(irq)] = irq_to_desc(irq);
451 453
452 __setup_vector_irq(cpu); 454 __setup_vector_irq(cpu);
453} 455}
@@ -543,19 +545,13 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void)
543 545
544 me = smp_processor_id(); 546 me = smp_processor_id();
545 for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { 547 for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
546 int irq;
547 unsigned int irr;
548 struct irq_desc *desc;
549 struct apic_chip_data *data; 548 struct apic_chip_data *data;
549 struct irq_desc *desc;
550 unsigned int irr;
550 551
551 retry: 552 retry:
552 irq = __this_cpu_read(vector_irq[vector]); 553 desc = __this_cpu_read(vector_irq[vector]);
553 554 if (IS_ERR_OR_NULL(desc))
554 if (irq <= VECTOR_UNUSED)
555 continue;
556
557 desc = irq_to_desc(irq);
558 if (!desc)
559 continue; 555 continue;
560 556
561 if (!raw_spin_trylock(&desc->lock)) { 557 if (!raw_spin_trylock(&desc->lock)) {
@@ -565,9 +561,10 @@ asmlinkage __visible void smp_irq_move_cleanup_interrupt(void)
565 goto retry; 561 goto retry;
566 } 562 }
567 563
568 data = apic_chip_data(&desc->irq_data); 564 data = apic_chip_data(irq_desc_get_irq_data(desc));
569 if (!data) 565 if (!data)
570 goto unlock; 566 goto unlock;
567
571 /* 568 /*
572 * Check if the irq migration is in progress. If so, we 569 * Check if the irq migration is in progress. If so, we
573 * haven't received the cleanup request yet for this irq. 570 * haven't received the cleanup request yet for this irq.
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 140950fb9902..e010847583d7 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -211,22 +211,21 @@ u64 arch_irq_stat(void)
211__visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs) 211__visible unsigned int __irq_ent