|
44 | 44 |
|
45 | 45 | #define GIC_IRQ_TYPE_PARTITION (GIC_IRQ_TYPE_LPI + 1)
|
46 | 46 |
|
| 47 | +static struct cpumask broken_rdists __read_mostly; |
| 48 | + |
47 | 49 | struct redist_region {
|
48 | 50 | void __iomem *redist_base;
|
49 | 51 | phys_addr_t phys_base;
|
@@ -1293,6 +1295,18 @@ static void gic_cpu_init(void)
|
1293 | 1295 | #define MPIDR_TO_SGI_RS(mpidr) (MPIDR_RS(mpidr) << ICC_SGI1R_RS_SHIFT)
|
1294 | 1296 | #define MPIDR_TO_SGI_CLUSTER_ID(mpidr) ((mpidr) & ~0xFUL)
|
1295 | 1297 |
|
| 1298 | +/* |
| 1299 | + * gic_starting_cpu() is called after the last point where cpuhp is allowed |
| 1300 | + * to fail. So pre check for problems earlier. |
| 1301 | + */ |
| 1302 | +static int gic_check_rdist(unsigned int cpu) |
| 1303 | +{ |
| 1304 | + if (cpumask_test_cpu(cpu, &broken_rdists)) |
| 1305 | + return -EINVAL; |
| 1306 | + |
| 1307 | + return 0; |
| 1308 | +} |
| 1309 | + |
1296 | 1310 | static int gic_starting_cpu(unsigned int cpu)
|
1297 | 1311 | {
|
1298 | 1312 | gic_cpu_init();
|
@@ -1384,6 +1398,10 @@ static void __init gic_smp_init(void)
|
1384 | 1398 | };
|
1385 | 1399 | int base_sgi;
|
1386 | 1400 |
|
| 1401 | + cpuhp_setup_state_nocalls(CPUHP_BP_PREPARE_DYN, |
| 1402 | + "irqchip/arm/gicv3:checkrdist", |
| 1403 | + gic_check_rdist, NULL); |
| 1404 | + |
1387 | 1405 | cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING,
|
1388 | 1406 | "irqchip/arm/gicv3:starting",
|
1389 | 1407 | gic_starting_cpu, NULL);
|
@@ -2365,8 +2383,24 @@ gic_acpi_parse_madt_gicc(union acpi_subtable_headers *header,
|
2365 | 2383 | u32 size = reg == GIC_PIDR2_ARCH_GICv4 ? SZ_64K * 4 : SZ_64K * 2;
|
2366 | 2384 | void __iomem *redist_base;
|
2367 | 2385 |
|
2368 |
| - if (!acpi_gicc_is_usable(gicc)) |
| 2386 | + /* Neither enabled or online capable means it doesn't exist, skip it */ |
| 2387 | + if (!(gicc->flags & (ACPI_MADT_ENABLED | ACPI_MADT_GICC_ONLINE_CAPABLE))) |
| 2388 | + return 0; |
| 2389 | + |
| 2390 | + /* |
| 2391 | + * Capable but disabled CPUs can be brought online later. What about |
| 2392 | + * the redistributor? ACPI doesn't want to say! |
| 2393 | + * Virtual hotplug systems can use the MADT's "always-on" GICR entries. |
| 2394 | + * Otherwise, prevent such CPUs from being brought online. |
| 2395 | + */ |
| 2396 | + if (!(gicc->flags & ACPI_MADT_ENABLED)) { |
| 2397 | + int cpu = get_cpu_for_acpi_id(gicc->uid); |
| 2398 | + |
| 2399 | + pr_warn("CPU %u's redistributor is inaccessible: this CPU can't be brought online\n", cpu); |
| 2400 | + if (cpu >= 0) |
| 2401 | + cpumask_set_cpu(cpu, &broken_rdists); |
2369 | 2402 | return 0;
|
| 2403 | + } |
2370 | 2404 |
|
2371 | 2405 | redist_base = ioremap(gicc->gicr_base_address, size);
|
2372 | 2406 | if (!redist_base)
|
@@ -2413,9 +2447,12 @@ static int __init gic_acpi_match_gicc(union acpi_subtable_headers *header,
|
2413 | 2447 |
|
2414 | 2448 | /*
|
2415 | 2449 | * If GICC is enabled and has valid gicr base address, then it means
|
2416 |
| - * GICR base is presented via GICC |
| 2450 | + * GICR base is presented via GICC. The redistributor is only known to |
| 2451 | + * be accessible if the GICC is marked as enabled. If this bit is not |
| 2452 | + * set, we'd need to add the redistributor at runtime, which isn't |
| 2453 | + * supported. |
2417 | 2454 | */
|
2418 |
| - if (acpi_gicc_is_usable(gicc) && gicc->gicr_base_address) |
| 2455 | + if (gicc->flags & ACPI_MADT_ENABLED && gicc->gicr_base_address) |
2419 | 2456 | acpi_data.enabled_rdists++;
|
2420 | 2457 |
|
2421 | 2458 | return 0;
|
@@ -2474,7 +2511,8 @@ static int __init gic_acpi_parse_virt_madt_gicc(union acpi_subtable_headers *hea
|
2474 | 2511 | int maint_irq_mode;
|
2475 | 2512 | static int first_madt = true;
|
2476 | 2513 |
|
2477 |
| - if (!acpi_gicc_is_usable(gicc)) |
| 2514 | + if (!(gicc->flags & |
| 2515 | + (ACPI_MADT_ENABLED | ACPI_MADT_GICC_ONLINE_CAPABLE))) |
2478 | 2516 | return 0;
|
2479 | 2517 |
|
2480 | 2518 | maint_irq_mode = (gicc->flags & ACPI_MADT_VGIC_IRQ_MODE) ?
|
|
0 commit comments