diff options
| -rw-r--r-- | arch/x86/include/asm/hw_irq.h | 6 | ||||
| -rw-r--r-- | arch/x86/include/asm/irq.h | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/vector.c | 51 | ||||
| -rw-r--r-- | arch/x86/kernel/irq.c | 37 | ||||
| -rw-r--r-- | arch/x86/kernel/irq_32.c | 9 | ||||
| -rw-r--r-- | arch/x86/kernel/irq_64.c | 9 | ||||
| -rw-r--r-- | arch/x86/kernel/irqinit.c | 4 | ||||
| -rw-r--r-- | arch/x86/lguest/boot.c | 4 |
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 | ||
| 188 | typedef int vector_irq_t[NR_VECTORS]; | 188 | typedef struct irq_desc* vector_irq_t[NR_VECTORS]; |
| 189 | DECLARE_PER_CPU(vector_irq_t, vector_irq); | 189 | DECLARE_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 | ||
| 37 | extern void (*x86_platform_ipi_callback)(void); | 37 | extern void (*x86_platform_ipi_callback)(void); |
| 38 | extern void native_init_IRQ(void); | 38 | extern void native_init_IRQ(void); |
| 39 | extern bool handle_irq(unsigned irq, struct pt_regs *regs); | 39 | |
| 40 | struct irq_desc; | ||
| 41 | extern bool handle_irq(struct irq_desc *desc, struct pt_regs *regs); | ||
| 40 | 42 | ||
| 41 | extern __visible unsigned int do_IRQ(struct pt_regs *regs); | 43 | extern __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 | ||
| 224 | static void clear_irq_vector(int irq, struct apic_chip_data *data) | 224 | static 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 */ | ||
| 405 | static void __setup_vector_irq(int cpu) | 408 | static 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 |
