Skip to content

Commit 567e5a0

Browse files
jonhunterKAGA-KOKO
authored andcommitted
irqchip/gic: Only allow the primary GIC to set the CPU map
The gic_init_bases() function initialises an array that stores the mapping between the GIC and CPUs. This array is a global array that is unconditionally initialised on every call to gic_init_bases(). Although, it is not common for there to be more than one GIC instance, there are some devices that do support nested GIC controllers and gic_init_bases() can be called more than once. A 2nd call to gic_init_bases() will clear the previous CPU mapping and will only setup the mapping again for the CPU calling gic_init_bases(). Fix this by only allowing the CPU map to be configured for the primary GIC. For secondary GICs the CPU map is not relevant because these GICs do not directly route the interrupts to the main CPU(s) but to other GICs or devices. Signed-off-by: Jon Hunter <[email protected]> Reviewed-by: Marc Zyngier <[email protected]> Cc: <[email protected]> Cc: Russell King <[email protected]> Cc: Nicolas Pitre <[email protected]> Cc: Jason Cooper <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Thomas Gleixner <[email protected]>
1 parent 36f024e commit 567e5a0

File tree

1 file changed

+25
-18
lines changed

1 file changed

+25
-18
lines changed

drivers/irqchip/irq-gic.c

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -402,19 +402,26 @@ static void gic_cpu_init(struct gic_chip_data *gic)
402402
int i;
403403

404404
/*
405-
* Get what the GIC says our CPU mask is.
405+
* Setting up the CPU map is only relevant for the primary GIC
406+
* because any nested/secondary GICs do not directly interface
407+
* with the CPU(s).
406408
*/
407-
BUG_ON(cpu >= NR_GIC_CPU_IF);
408-
cpu_mask = gic_get_cpumask(gic);
409-
gic_cpu_map[cpu] = cpu_mask;
409+
if (gic == &gic_data[0]) {
410+
/*
411+
* Get what the GIC says our CPU mask is.
412+
*/
413+
BUG_ON(cpu >= NR_GIC_CPU_IF);
414+
cpu_mask = gic_get_cpumask(gic);
415+
gic_cpu_map[cpu] = cpu_mask;
410416

411-
/*
412-
* Clear our mask from the other map entries in case they're
413-
* still undefined.
414-
*/
415-
for (i = 0; i < NR_GIC_CPU_IF; i++)
416-
if (i != cpu)
417-
gic_cpu_map[i] &= ~cpu_mask;
417+
/*
418+
* Clear our mask from the other map entries in case they're
419+
* still undefined.
420+
*/
421+
for (i = 0; i < NR_GIC_CPU_IF; i++)
422+
if (i != cpu)
423+
gic_cpu_map[i] &= ~cpu_mask;
424+
}
418425

419426
gic_cpu_config(dist_base, NULL);
420427

@@ -925,13 +932,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
925932
gic_set_base_accessor(gic, gic_get_common_base);
926933
}
927934

928-
/*
929-
* Initialize the CPU interface map to all CPUs.
930-
* It will be refined as each CPU probes its ID.
931-
*/
932-
for (i = 0; i < NR_GIC_CPU_IF; i++)
933-
gic_cpu_map[i] = 0xff;
934-
935935
/*
936936
* Find out how many interrupts are supported.
937937
* The GIC only supports up to 1020 interrupt sources.
@@ -977,6 +977,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
977977
return;
978978

979979
if (gic_nr == 0) {
980+
/*
981+
* Initialize the CPU interface map to all CPUs.
982+
* It will be refined as each CPU probes its ID.
983+
* This is only necessary for the primary GIC.
984+
*/
985+
for (i = 0; i < NR_GIC_CPU_IF; i++)
986+
gic_cpu_map[i] = 0xff;
980987
#ifdef CONFIG_SMP
981988
set_smp_cross_call(gic_raise_softirq);
982989
register_cpu_notifier(&gic_cpu_notifier);

0 commit comments

Comments
 (0)