Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-next/vcpu-hotplug' into for-next/core

* for-next/vcpu-hotplug: (21 commits)
: arm64 support for virtual CPU hotplug (ACPI)
irqchip/gic-v3: Fix 'broken_rdists' unused warning when !SMP and !ACPI
arm64: Kconfig: Fix dependencies to enable ACPI_HOTPLUG_CPU
cpumask: Add enabled cpumask for present CPUs that can be brought online
arm64: document virtual CPU hotplug's expectations
arm64: Kconfig: Enable hotplug CPU on arm64 if ACPI_PROCESSOR is enabled.
arm64: arch_register_cpu() variant to check if an ACPI handle is now available.
arm64: psci: Ignore DENIED CPUs
irqchip/gic-v3: Add support for ACPI's disabled but 'online capable' CPUs
irqchip/gic-v3: Don't return errors from gic_acpi_match_gicc()
arm64: acpi: Harden get_cpu_for_acpi_id() against missing CPU entry
arm64: acpi: Move get_cpu_for_acpi_id() to a header
ACPI: Add post_eject to struct acpi_scan_handler for cpu hotplug
ACPI: scan: switch to flags for acpi_scan_check_and_detach()
ACPI: processor: Register deferred CPUs from acpi_processor_get_info()
ACPI: processor: Add acpi_get_processor_handle() helper
ACPI: processor: Move checks and availability of acpi_processor earlier
ACPI: processor: Fix memory leaks in error paths of processor_add()
ACPI: processor: Return an error if acpi_processor_get_info() fails in processor_add()
ACPI: processor: Drop duplicated check on _STA (enabled + present)
cpu: Do not warn on arch_register_cpu() returning -EPROBE_DEFER
...

+406 -137
+6
Documentation/ABI/testing/sysfs-devices-system-cpu
··· 694 694 (RO) indicates whether or not the kernel directly supports 695 695 modifying the crash elfcorehdr for CPU hot un/plug and/or 696 696 on/offline changes. 697 + 698 + What: /sys/devices/system/cpu/enabled 699 + Date: Nov 2022 700 + Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> 701 + Description: 702 + (RO) the list of CPUs that can be brought online.
+79
Documentation/arch/arm64/cpu-hotplug.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + .. _cpuhp_index: 3 + 4 + ==================== 5 + CPU Hotplug and ACPI 6 + ==================== 7 + 8 + CPU hotplug in the arm64 world is commonly used to describe the kernel taking 9 + CPUs online/offline using PSCI. This document is about ACPI firmware allowing 10 + CPUs that were not available during boot to be added to the system later. 11 + 12 + ``possible`` and ``present`` refer to the state of the CPU as seen by linux. 13 + 14 + 15 + CPU Hotplug on physical systems - CPUs not present at boot 16 + ---------------------------------------------------------- 17 + 18 + Physical systems need to mark a CPU that is ``possible`` but not ``present`` as 19 + being ``present``. An example would be a dual socket machine, where the package 20 + in one of the sockets can be replaced while the system is running. 21 + 22 + This is not supported. 23 + 24 + In the arm64 world CPUs are not a single device but a slice of the system. 25 + There are no systems that support the physical addition (or removal) of CPUs 26 + while the system is running, and ACPI is not able to sufficiently describe 27 + them. 28 + 29 + e.g. New CPUs come with new caches, but the platform's cache toplogy is 30 + described in a static table, the PPTT. How caches are shared between CPUs is 31 + not discoverable, and must be described by firmware. 32 + 33 + e.g. The GIC redistributor for each CPU must be accessed by the driver during 34 + boot to discover the system wide supported features. ACPI's MADT GICC 35 + structures can describe a redistributor associated with a disabled CPU, but 36 + can't describe whether the redistributor is accessible, only that it is not 37 + 'always on'. 38 + 39 + arm64's ACPI tables assume that everything described is ``present``. 40 + 41 + 42 + CPU Hotplug on virtual systems - CPUs not enabled at boot 43 + --------------------------------------------------------- 44 + 45 + Virtual systems have the advantage that all the properties the system will 46 + ever have can be described at boot. There are no power-domain considerations 47 + as such devices are emulated. 48 + 49 + CPU Hotplug on virtual systems is supported. It is distinct from physical 50 + CPU Hotplug as all resources are described as ``present``, but CPUs may be 51 + marked as disabled by firmware. Only the CPU's online/offline behaviour is 52 + influenced by firmware. An example is where a virtual machine boots with a 53 + single CPU, and additional CPUs are added once a cloud orchestrator deploys 54 + the workload. 55 + 56 + For a virtual machine, the VMM (e.g. Qemu) plays the part of firmware. 57 + 58 + Virtual hotplug is implemented as a firmware policy affecting which CPUs can be 59 + brought online. Firmware can enforce its policy via PSCI's return codes. e.g. 60 + ``DENIED``. 61 + 62 + The ACPI tables must describe all the resources of the virtual machine. CPUs 63 + that firmware wishes to disable either from boot (or later) should not be 64 + ``enabled`` in the MADT GICC structures, but should have the ``online capable`` 65 + bit set, to indicate they can be enabled later. The boot CPU must be marked as 66 + ``enabled``. The 'always on' GICR structure must be used to describe the 67 + redistributors. 68 + 69 + CPUs described as ``online capable`` but not ``enabled`` can be set to enabled 70 + by the DSDT's Processor object's _STA method. On virtual systems the _STA method 71 + must always report the CPU as ``present``. Changes to the firmware policy can 72 + be notified to the OS via device-check or eject-request. 73 + 74 + CPUs described as ``enabled`` in the static table, should not have their _STA 75 + modified dynamically by firmware. Soft-restart features such as kexec will 76 + re-read the static properties of the system from these static tables, and 77 + may malfunction if these no longer describe the running system. Linux will 78 + re-discover the dynamic properties of the system from the _STA method later 79 + during boot.
+1
Documentation/arch/arm64/index.rst
··· 13 13 asymmetric-32bit 14 14 booting 15 15 cpu-feature-registers 16 + cpu-hotplug 16 17 elf_hwcaps 17 18 hugetlbpage 18 19 kdump
+1
arch/arm64/Kconfig
··· 5 5 select ACPI_CCA_REQUIRED if ACPI 6 6 select ACPI_GENERIC_GSI if ACPI 7 7 select ACPI_GTDT if ACPI 8 + select ACPI_HOTPLUG_CPU if ACPI_PROCESSOR && HOTPLUG_CPU 8 9 select ACPI_IORT if ACPI 9 10 select ACPI_REDUCED_HARDWARE_ONLY if ACPI 10 11 select ACPI_MCFG if (ACPI && PCI)
+12
arch/arm64/include/asm/acpi.h
··· 119 119 return acpi_cpu_get_madt_gicc(cpu)->uid; 120 120 } 121 121 122 + static inline int get_cpu_for_acpi_id(u32 uid) 123 + { 124 + int cpu; 125 + 126 + for (cpu = 0; cpu < nr_cpu_ids; cpu++) 127 + if (acpi_cpu_get_madt_gicc(cpu) && 128 + uid == get_acpi_id_for_cpu(cpu)) 129 + return cpu; 130 + 131 + return -EINVAL; 132 + } 133 + 122 134 static inline void arch_fix_phys_package_id(int num, u32 slot) { } 123 135 void __init acpi_init_cpus(void); 124 136 int apei_claim_sea(struct pt_regs *regs);
+22
arch/arm64/kernel/acpi.c
··· 30 30 #include <linux/pgtable.h> 31 31 32 32 #include <acpi/ghes.h> 33 + #include <acpi/processor.h> 33 34 #include <asm/cputype.h> 34 35 #include <asm/cpu_ops.h> 35 36 #include <asm/daifflags.h> ··· 439 438 { 440 439 memblock_mark_nomap(addr, size); 441 440 } 441 + 442 + #ifdef CONFIG_ACPI_HOTPLUG_CPU 443 + int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 apci_id, 444 + int *pcpu) 445 + { 446 + /* If an error code is passed in this stub can't fix it */ 447 + if (*pcpu < 0) { 448 + pr_warn_once("Unable to map CPU to valid ID\n"); 449 + return *pcpu; 450 + } 451 + 452 + return 0; 453 + } 454 + EXPORT_SYMBOL(acpi_map_cpu); 455 + 456 + int acpi_unmap_cpu(int cpu) 457 + { 458 + return 0; 459 + } 460 + EXPORT_SYMBOL(acpi_unmap_cpu); 461 + #endif /* CONFIG_ACPI_HOTPLUG_CPU */
-11
arch/arm64/kernel/acpi_numa.c
··· 34 34 return acpi_early_node_map[cpu]; 35 35 } 36 36 37 - static inline int get_cpu_for_acpi_id(u32 uid) 38 - { 39 - int cpu; 40 - 41 - for (cpu = 0; cpu < nr_cpu_ids; cpu++) 42 - if (uid == get_acpi_id_for_cpu(cpu)) 43 - return cpu; 44 - 45 - return -EINVAL; 46 - } 47 - 48 37 static int __init acpi_parse_gicc_pxm(union acpi_subtable_headers *header, 49 38 const unsigned long end) 50 39 {
+1 -1
arch/arm64/kernel/psci.c
··· 40 40 { 41 41 phys_addr_t pa_secondary_entry = __pa_symbol(secondary_entry); 42 42 int err = psci_ops.cpu_on(cpu_logical_map(cpu), pa_secondary_entry); 43 - if (err) 43 + if (err && err != -EPERM) 44 44 pr_err("failed to boot CPU%d (%d)\n", cpu, err); 45 45 46 46 return err;
+57 -2
arch/arm64/kernel/smp.c
··· 129 129 /* Now bring the CPU into our world */ 130 130 ret = boot_secondary(cpu, idle); 131 131 if (ret) { 132 - pr_err("CPU%u: failed to boot: %d\n", cpu, ret); 132 + if (ret != -EPERM) 133 + pr_err("CPU%u: failed to boot: %d\n", cpu, ret); 133 134 return ret; 134 135 } 135 136 ··· 508 507 static bool bootcpu_valid __initdata; 509 508 static unsigned int cpu_count = 1; 510 509 510 + int arch_register_cpu(int cpu) 511 + { 512 + acpi_handle acpi_handle = acpi_get_processor_handle(cpu); 513 + struct cpu *c = &per_cpu(cpu_devices, cpu); 514 + 515 + if (!acpi_disabled && !acpi_handle && 516 + IS_ENABLED(CONFIG_ACPI_HOTPLUG_CPU)) 517 + return -EPROBE_DEFER; 518 + 519 + #ifdef CONFIG_ACPI_HOTPLUG_CPU 520 + /* For now block anything that looks like physical CPU Hotplug */ 521 + if (invalid_logical_cpuid(cpu) || !cpu_present(cpu)) { 522 + pr_err_once("Changing CPU present bit is not supported\n"); 523 + return -ENODEV; 524 + } 525 + #endif 526 + 527 + /* 528 + * Availability of the acpi handle is sufficient to establish 529 + * that _STA has aleady been checked. No need to recheck here. 530 + */ 531 + c->hotpluggable = arch_cpu_is_hotpluggable(cpu); 532 + 533 + return register_cpu(c, cpu); 534 + } 535 + 536 + #ifdef CONFIG_ACPI_HOTPLUG_CPU 537 + void arch_unregister_cpu(int cpu) 538 + { 539 + acpi_handle acpi_handle = acpi_get_processor_handle(cpu); 540 + struct cpu *c = &per_cpu(cpu_devices, cpu); 541 + acpi_status status; 542 + unsigned long long sta; 543 + 544 + if (!acpi_handle) { 545 + pr_err_once("Removing a CPU without associated ACPI handle\n"); 546 + return; 547 + } 548 + 549 + status = acpi_evaluate_integer(acpi_handle, "_STA", NULL, &sta); 550 + if (ACPI_FAILURE(status)) 551 + return; 552 + 553 + /* For now do not allow anything that looks like physical CPU HP */ 554 + if (cpu_present(cpu) && !(sta & ACPI_STA_DEVICE_PRESENT)) { 555 + pr_err_once("Changing CPU present bit is not supported\n"); 556 + return; 557 + } 558 + 559 + unregister_cpu(c); 560 + } 561 + #endif /* CONFIG_ACPI_HOTPLUG_CPU */ 562 + 511 563 #ifdef CONFIG_ACPI 512 564 static struct acpi_madt_generic_interrupt cpu_madt_gicc[NR_CPUS]; 513 565 ··· 581 527 { 582 528 u64 hwid = processor->arm_mpidr; 583 529 584 - if (!acpi_gicc_is_usable(processor)) { 530 + if (!(processor->flags & 531 + (ACPI_MADT_ENABLED | ACPI_MADT_GICC_ONLINE_CAPABLE))) { 585 532 pr_debug("skipping disabled CPU entry with 0x%llx MPIDR\n", hwid); 586 533 return; 587 534 }
+83 -62
drivers/acpi/acpi_processor.c
··· 35 35 struct acpi_processor_errata errata __read_mostly; 36 36 EXPORT_SYMBOL_GPL(errata); 37 37 38 + acpi_handle acpi_get_processor_handle(int cpu) 39 + { 40 + struct acpi_processor *pr; 41 + 42 + pr = per_cpu(processors, cpu); 43 + if (pr) 44 + return pr->handle; 45 + 46 + return NULL; 47 + } 48 + 38 49 static int acpi_processor_errata_piix4(struct pci_dev *dev) 39 50 { 40 51 u8 value1 = 0; ··· 194 183 #endif /* CONFIG_X86 */ 195 184 196 185 /* Initialization */ 197 - #ifdef CONFIG_ACPI_HOTPLUG_CPU 198 - static int acpi_processor_hotadd_init(struct acpi_processor *pr) 186 + static DEFINE_PER_CPU(void *, processor_device_array); 187 + 188 + static int acpi_processor_set_per_cpu(struct acpi_processor *pr, 189 + struct acpi_device *device) 199 190 { 200 - unsigned long long sta; 201 - acpi_status status; 191 + BUG_ON(pr->id >= nr_cpu_ids); 192 + 193 + /* 194 + * Buggy BIOS check. 195 + * ACPI id of processors can be reported wrongly by the BIOS. 196 + * Don't trust it blindly 197 + */ 198 + if (per_cpu(processor_device_array, pr->id) != NULL && 199 + per_cpu(processor_device_array, pr->id) != device) { 200 + dev_warn(&device->dev, 201 + "BIOS reported wrong ACPI id %d for the processor\n", 202 + pr->id); 203 + return -EINVAL; 204 + } 205 + /* 206 + * processor_device_array is not cleared on errors to allow buggy BIOS 207 + * checks. 208 + */ 209 + per_cpu(processor_device_array, pr->id) = device; 210 + per_cpu(processors, pr->id) = pr; 211 + 212 + return 0; 213 + } 214 + 215 + #ifdef CONFIG_ACPI_HOTPLUG_CPU 216 + static int acpi_processor_hotadd_init(struct acpi_processor *pr, 217 + struct acpi_device *device) 218 + { 202 219 int ret; 203 220 204 221 if (invalid_phys_cpuid(pr->phys_id)) 205 - return -ENODEV; 206 - 207 - status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta); 208 - if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT)) 209 222 return -ENODEV; 210 223 211 224 cpu_maps_update_begin(); ··· 239 204 if (ret) 240 205 goto out; 241 206 242 - ret = arch_register_cpu(pr->id); 207 + ret = acpi_processor_set_per_cpu(pr, device); 243 208 if (ret) { 244 209 acpi_unmap_cpu(pr->id); 245 210 goto out; 246 211 } 247 212 213 + ret = arch_register_cpu(pr->id); 214 + if (ret) { 215 + /* Leave the processor device array in place to detect buggy bios */ 216 + per_cpu(processors, pr->id) = NULL; 217 + acpi_unmap_cpu(pr->id); 218 + goto out; 219 + } 220 + 248 221 /* 249 - * CPU got hot-added, but cpu_data is not initialized yet. Set a flag 250 - * to delay cpu_idle/throttling initialization and do it when the CPU 251 - * gets online for the first time. 222 + * CPU got hot-added, but cpu_data is not initialized yet. Do 223 + * cpu_idle/throttling initialization when the CPU gets online for 224 + * the first time. 252 225 */ 253 226 pr_info("CPU%d has been hot-added\n", pr->id); 254 - pr->flags.need_hotplug_init = 1; 255 227 256 228 out: 257 229 cpus_write_unlock(); ··· 266 224 return ret; 267 225 } 268 226 #else 269 - static inline int acpi_processor_hotadd_init(struct acpi_processor *pr) 227 + static inline int acpi_processor_hotadd_init(struct acpi_processor *pr, 228 + struct acpi_device *device) 270 229 { 271 230 return -ENODEV; 272 231 } ··· 282 239 acpi_status status = AE_OK; 283 240 static int cpu0_initialized; 284 241 unsigned long long value; 242 + int ret; 285 243 286 244 acpi_processor_errata(); 287 245 ··· 359 315 } 360 316 361 317 /* 362 - * Extra Processor objects may be enumerated on MP systems with 363 - * less than the max # of CPUs. They should be ignored _iff 364 - * they are physically not present. 365 - * 366 - * NOTE: Even if the processor has a cpuid, it may not be present 367 - * because cpuid <-> apicid mapping is persistent now. 318 + * This code is not called unless we know the CPU is present and 319 + * enabled. The two paths are: 320 + * a) Initially present CPUs on architectures that do not defer 321 + * their arch_register_cpu() calls until this point. 322 + * b) Hotplugged CPUs (enabled bit in _STA has transitioned from not 323 + * enabled to enabled) 368 324 */ 369 - if (invalid_logical_cpuid(pr->id) || !cpu_present(pr->id)) { 370 - int ret = acpi_processor_hotadd_init(pr); 371 - 372 - if (ret) 373 - return ret; 374 - } 325 + if (!get_cpu_device(pr->id)) 326 + ret = acpi_processor_hotadd_init(pr, device); 327 + else 328 + ret = acpi_processor_set_per_cpu(pr, device); 329 + if (ret) 330 + return ret; 375 331 376 332 /* 377 333 * On some boxes several processors use the same processor bus id. ··· 416 372 * (cpu_data(cpu)) values, like CPU feature flags, family, model, etc. 417 373 * Such things have to be put in and set up by the processor driver's .probe(). 418 374 */ 419 - static DEFINE_PER_CPU(void *, processor_device_array); 420 - 421 375 static int acpi_processor_add(struct acpi_device *device, 422 376 const struct acpi_device_id *id) 423 377 { ··· 442 400 443 401 result = acpi_processor_get_info(device); 444 402 if (result) /* Processor is not physically present or unavailable */ 445 - return 0; 446 - 447 - BUG_ON(pr->id >= nr_cpu_ids); 448 - 449 - /* 450 - * Buggy BIOS check. 451 - * ACPI id of processors can be reported wrongly by the BIOS. 452 - * Don't trust it blindly 453 - */ 454 - if (per_cpu(processor_device_array, pr->id) != NULL && 455 - per_cpu(processor_device_array, pr->id) != device) { 456 - dev_warn(&device->dev, 457 - "BIOS reported wrong ACPI id %d for the processor\n", 458 - pr->id); 459 - /* Give up, but do not abort the namespace scan. */ 460 - goto err; 461 - } 462 - /* 463 - * processor_device_array is not cleared on errors to allow buggy BIOS 464 - * checks. 465 - */ 466 - per_cpu(processor_device_array, pr->id) = device; 467 - per_cpu(processors, pr->id) = pr; 403 + goto err_clear_driver_data; 468 404 469 405 dev = get_cpu_device(pr->id); 470 406 if (!dev) { 471 407 result = -ENODEV; 472 - goto err; 408 + goto err_clear_per_cpu; 473 409 } 474 410 475 411 result = acpi_bind_one(dev, device); 476 412 if (result) 477 - goto err; 413 + goto err_clear_per_cpu; 478 414 479 415 pr->dev = dev; 480 416 ··· 463 443 dev_err(dev, "Processor driver could not be attached\n"); 464 444 acpi_unbind_one(dev); 465 445 466 - err: 467 - free_cpumask_var(pr->throttling.shared_cpu_map); 468 - device->driver_data = NULL; 446 + err_clear_per_cpu: 469 447 per_cpu(processors, pr->id) = NULL; 448 + err_clear_driver_data: 449 + device->driver_data = NULL; 450 + free_cpumask_var(pr->throttling.shared_cpu_map); 470 451 err_free_pr: 471 452 kfree(pr); 472 453 return result; ··· 475 454 476 455 #ifdef CONFIG_ACPI_HOTPLUG_CPU 477 456 /* Removal */ 478 - static void acpi_processor_remove(struct acpi_device *device) 457 + static void acpi_processor_post_eject(struct acpi_device *device) 479 458 { 480 459 struct acpi_processor *pr; 481 460 ··· 497 476 device_release_driver(pr->dev); 498 477 acpi_unbind_one(pr->dev); 499 478 500 - /* Clean up. */ 501 - per_cpu(processor_device_array, pr->id) = NULL; 502 - per_cpu(processors, pr->id) = NULL; 503 - 504 479 cpu_maps_update_begin(); 505 480 cpus_write_lock(); 506 481 507 482 /* Remove the CPU. */ 508 483 arch_unregister_cpu(pr->id); 509 484 acpi_unmap_cpu(pr->id); 485 + 486 + /* Clean up. */ 487 + per_cpu(processor_device_array, pr->id) = NULL; 488 + per_cpu(processors, pr->id) = NULL; 510 489 511 490 cpus_write_unlock(); 512 491 cpu_maps_update_done(); ··· 643 622 .ids = processor_device_ids, 644 623 .attach = acpi_processor_add, 645 624 #ifdef CONFIG_ACPI_HOTPLUG_CPU 646 - .detach = acpi_processor_remove, 625 + .post_eject = acpi_processor_post_eject, 647 626 #endif 648 627 .hotplug = { 649 628 .enabled = true,
+2 -1
drivers/acpi/processor_core.c
··· 90 90 struct acpi_madt_generic_interrupt *gicc = 91 91 container_of(entry, struct acpi_madt_generic_interrupt, header); 92 92 93 - if (!acpi_gicc_is_usable(gicc)) 93 + if (!(gicc->flags & 94 + (ACPI_MADT_ENABLED | ACPI_MADT_GICC_ONLINE_CAPABLE))) 94 95 return -ENODEV; 95 96 96 97 /* device_declaration means Device object in DSDT, in the
+12 -31
drivers/acpi/processor_driver.c
··· 33 33 MODULE_DESCRIPTION("ACPI Processor Driver"); 34 34 MODULE_LICENSE("GPL"); 35 35 36 - static int acpi_processor_start(struct device *dev); 37 36 static int acpi_processor_stop(struct device *dev); 38 37 39 38 static const struct acpi_device_id processor_device_ids[] = { ··· 46 47 .name = "processor", 47 48 .bus = &cpu_subsys, 48 49 .acpi_match_table = processor_device_ids, 49 - .probe = acpi_processor_start, 50 50 .remove = acpi_processor_stop, 51 51 }; 52 52 ··· 113 115 * CPU got physically hotplugged and onlined for the first time: 114 116 * Initialize missing things. 115 117 */ 116 - if (pr->flags.need_hotplug_init) { 118 + if (!pr->flags.previously_online) { 117 119 int ret; 118 120 119 - pr_info("Will online and init hotplugged CPU: %d\n", 120 - pr->id); 121 - pr->flags.need_hotplug_init = 0; 122 121 ret = __acpi_processor_start(device); 123 122 WARN(ret, "Failed to start CPU: %d\n", pr->id); 124 123 } else { ··· 162 167 if (!pr) 163 168 return -ENODEV; 164 169 165 - if (pr->flags.need_hotplug_init) 166 - return 0; 167 - 168 170 result = acpi_cppc_processor_probe(pr); 169 171 if (result && !IS_ENABLED(CONFIG_ACPI_CPU_FREQ_PSS)) 170 172 dev_dbg(&device->dev, "CPPC data invalid or not present\n"); ··· 177 185 178 186 status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, 179 187 acpi_processor_notify, device); 180 - if (ACPI_SUCCESS(status)) 181 - return 0; 188 + if (!ACPI_SUCCESS(status)) { 189 + result = -ENODEV; 190 + goto err_thermal_exit; 191 + } 192 + pr->flags.previously_online = 1; 182 193 183 - result = -ENODEV; 194 + return 0; 195 + 196 + err_thermal_exit: 184 197 acpi_processor_thermal_exit(pr, device); 185 - 186 198 err_power_exit: 187 199 acpi_processor_power_exit(pr); 188 200 return result; 189 - } 190 - 191 - static int acpi_processor_start(struct device *dev) 192 - { 193 - struct acpi_device *device = ACPI_COMPANION(dev); 194 - int ret; 195 - 196 - if (!device) 197 - return -ENODEV; 198 - 199 - /* Protect against concurrent CPU hotplug operations */ 200 - cpu_hotplug_disable(); 201 - ret = __acpi_processor_start(device); 202 - cpu_hotplug_enable(); 203 - return ret; 204 201 } 205 202 206 203 static int acpi_processor_stop(struct device *dev) ··· 260 279 if (result < 0) 261 280 return result; 262 281 263 - result = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, 264 - "acpi/cpu-drv:online", 265 - acpi_soft_cpu_online, NULL); 282 + result = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, 283 + "acpi/cpu-drv:online", 284 + acpi_soft_cpu_online, NULL); 266 285 if (result < 0) 267 286 goto err; 268 287 hp_online = result;
+39 -8
drivers/acpi/scan.c
··· 243 243 return 0; 244 244 } 245 245 246 - static int acpi_scan_check_and_detach(struct acpi_device *adev, void *check) 246 + #define ACPI_SCAN_CHECK_FLAG_STATUS BIT(0) 247 + #define ACPI_SCAN_CHECK_FLAG_EJECT BIT(1) 248 + 249 + static int acpi_scan_check_and_detach(struct acpi_device *adev, void *p) 247 250 { 248 251 struct acpi_scan_handler *handler = adev->handler; 252 + uintptr_t flags = (uintptr_t)p; 249 253 250 - acpi_dev_for_each_child_reverse(adev, acpi_scan_check_and_detach, check); 254 + acpi_dev_for_each_child_reverse(adev, acpi_scan_check_and_detach, p); 251 255 252 - if (check) { 256 + if (flags & ACPI_SCAN_CHECK_FLAG_STATUS) { 253 257 acpi_bus_get_status(adev); 254 258 /* 255 259 * Skip devices that are still there and take the enabled ··· 273 269 if (handler) { 274 270 if (handler->detach) 275 271 handler->detach(adev); 276 - 277 - adev->handler = NULL; 278 272 } else { 279 273 device_release_driver(&adev->dev); 280 274 } ··· 282 280 */ 283 281 acpi_device_set_power(adev, ACPI_STATE_D3_COLD); 284 282 adev->flags.initialized = false; 283 + 284 + /* For eject this is deferred to acpi_bus_post_eject() */ 285 + if (!(flags & ACPI_SCAN_CHECK_FLAG_EJECT)) { 286 + adev->handler = NULL; 287 + acpi_device_clear_enumerated(adev); 288 + } 289 + return 0; 290 + } 291 + 292 + static int acpi_bus_post_eject(struct acpi_device *adev, void *not_used) 293 + { 294 + struct acpi_scan_handler *handler = adev->handler; 295 + 296 + acpi_dev_for_each_child_reverse(adev, acpi_bus_post_eject, NULL); 297 + 298 + if (handler) { 299 + if (handler->post_eject) 300 + handler->post_eject(adev); 301 + 302 + adev->handler = NULL; 303 + } 304 + 285 305 acpi_device_clear_enumerated(adev); 286 306 287 307 return 0; ··· 311 287 312 288 static void acpi_scan_check_subtree(struct acpi_device *adev) 313 289 { 314 - acpi_scan_check_and_detach(adev, (void *)true); 290 + uintptr_t flags = ACPI_SCAN_CHECK_FLAG_STATUS; 291 + 292 + acpi_scan_check_and_detach(adev, (void *)flags); 315 293 } 316 294 317 295 static int acpi_scan_hot_remove(struct acpi_device *device) ··· 321 295 acpi_handle handle = device->handle; 322 296 unsigned long long sta; 323 297 acpi_status status; 298 + uintptr_t flags = ACPI_SCAN_CHECK_FLAG_EJECT; 324 299 325 300 if (device->handler && device->handler->hotplug.demand_offline) { 326 301 if (!acpi_scan_is_offline(device, true)) ··· 334 307 335 308 acpi_handle_debug(handle, "Ejecting\n"); 336 309 337 - acpi_bus_trim(device); 310 + acpi_scan_check_and_detach(device, (void *)flags); 338 311 339 312 acpi_evaluate_lck(handle, 0); 340 313 /* ··· 357 330 } else if (sta & ACPI_STA_DEVICE_ENABLED) { 358 331 acpi_handle_warn(handle, 359 332 "Eject incomplete - status 0x%llx\n", sta); 333 + } else { 334 + acpi_bus_post_eject(device, NULL); 360 335 } 361 336 362 337 return 0; ··· 2625 2596 */ 2626 2597 void acpi_bus_trim(struct acpi_device *adev) 2627 2598 { 2628 - acpi_scan_check_and_detach(adev, NULL); 2599 + uintptr_t flags = 0; 2600 + 2601 + acpi_scan_check_and_detach(adev, (void *)flags); 2629 2602 } 2630 2603 EXPORT_SYMBOL_GPL(acpi_bus_trim); 2631 2604
+11 -1
drivers/base/cpu.c
··· 95 95 { 96 96 int logical_cpu = cpu->dev.id; 97 97 98 + set_cpu_enabled(logical_cpu, false); 98 99 unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu)); 99 100 100 101 device_unregister(&cpu->dev); ··· 274 273 } 275 274 static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL); 276 275 276 + static ssize_t print_cpus_enabled(struct device *dev, 277 + struct device_attribute *attr, char *buf) 278 + { 279 + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(cpu_enabled_mask)); 280 + } 281 + static DEVICE_ATTR(enabled, 0444, print_cpus_enabled, NULL); 282 + 277 283 static ssize_t print_cpus_isolated(struct device *dev, 278 284 struct device_attribute *attr, char *buf) 279 285 { ··· 421 413 register_cpu_under_node(num, cpu_to_node(num)); 422 414 dev_pm_qos_expose_latency_limit(&cpu->dev, 423 415 PM_QOS_RESUME_LATENCY_NO_CONSTRAINT); 416 + set_cpu_enabled(num, true); 424 417 425 418 return 0; 426 419 } ··· 503 494 &cpu_attrs[2].attr.attr, 504 495 &dev_attr_kernel_max.attr, 505 496 &dev_attr_offline.attr, 497 + &dev_attr_enabled.attr, 506 498 &dev_attr_isolated.attr, 507 499 #ifdef CONFIG_NO_HZ_FULL 508 500 &dev_attr_nohz_full.attr, ··· 568 558 569 559 for_each_present_cpu(i) { 570 560 ret = arch_register_cpu(i); 571 - if (ret) 561 + if (ret && ret != -EPROBE_DEFER) 572 562 pr_warn("register_cpu %d failed (%d)\n", i, ret); 573 563 } 574 564 }
+43 -14
drivers/irqchip/irq-gic-v3.c
··· 47 47 48 48 #define GIC_IRQ_TYPE_PARTITION (GIC_IRQ_TYPE_LPI + 1) 49 49 50 + static struct cpumask broken_rdists __read_mostly __maybe_unused; 51 + 50 52 struct redist_region { 51 53 void __iomem *redist_base; 52 54 phys_addr_t phys_base; ··· 1319 1317 #define MPIDR_TO_SGI_RS(mpidr) (MPIDR_RS(mpidr) << ICC_SGI1R_RS_SHIFT) 1320 1318 #define MPIDR_TO_SGI_CLUSTER_ID(mpidr) ((mpidr) & ~0xFUL) 1321 1319 1320 + /* 1321 + * gic_starting_cpu() is called after the last point where cpuhp is allowed 1322 + * to fail. So pre check for problems earlier. 1323 + */ 1324 + static int gic_check_rdist(unsigned int cpu) 1325 + { 1326 + if (cpumask_test_cpu(cpu, &broken_rdists)) 1327 + return -EINVAL; 1328 + 1329 + return 0; 1330 + } 1331 + 1322 1332 static int gic_starting_cpu(unsigned int cpu) 1323 1333 { 1324 1334 gic_cpu_init(); ··· 1421 1407 .param_count = 1, 1422 1408 }; 1423 1409 int base_sgi; 1410 + 1411 + cpuhp_setup_state_nocalls(CPUHP_BP_PREPARE_DYN, 1412 + "irqchip/arm/gicv3:checkrdist", 1413 + gic_check_rdist, NULL); 1424 1414 1425 1415 cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING, 1426 1416 "irqchip/arm/gicv3:starting", ··· 2378 2360 u32 size = reg == GIC_PIDR2_ARCH_GICv4 ? SZ_64K * 4 : SZ_64K * 2; 2379 2361 void __iomem *redist_base; 2380 2362 2381 - if (!acpi_gicc_is_usable(gicc)) 2363 + /* Neither enabled or online capable means it doesn't exist, skip it */ 2364 + if (!(gicc->flags & (ACPI_MADT_ENABLED | ACPI_MADT_GICC_ONLINE_CAPABLE))) 2382 2365 return 0; 2366 + 2367 + /* 2368 + * Capable but disabled CPUs can be brought online later. What about 2369 + * the redistributor? ACPI doesn't want to say! 2370 + * Virtual hotplug systems can use the MADT's "always-on" GICR entries. 2371 + * Otherwise, prevent such CPUs from being brought online. 2372 + */ 2373 + if (!(gicc->flags & ACPI_MADT_ENABLED)) { 2374 + int cpu = get_cpu_for_acpi_id(gicc->uid); 2375 + 2376 + pr_warn("CPU %u's redistributor is inaccessible: this CPU can't be brought online\n", cpu); 2377 + if (cpu >= 0) 2378 + cpumask_set_cpu(cpu, &broken_rdists); 2379 + return 0; 2380 + } 2383 2381 2384 2382 redist_base = ioremap(gicc->gicr_base_address, size); 2385 2383 if (!redist_base) ··· 2442 2408 2443 2409 /* 2444 2410 * If GICC is enabled and has valid gicr base address, then it means 2445 - * GICR base is presented via GICC 2411 + * GICR base is presented via GICC. The redistributor is only known to 2412 + * be accessible if the GICC is marked as enabled. If this bit is not 2413 + * set, we'd need to add the redistributor at runtime, which isn't 2414 + * supported. 2446 2415 */ 2447 - if (acpi_gicc_is_usable(gicc) && gicc->gicr_base_address) { 2416 + if (gicc->flags & ACPI_MADT_ENABLED && gicc->gicr_base_address) 2448 2417 acpi_data.enabled_rdists++; 2449 - return 0; 2450 - } 2451 2418 2452 - /* 2453 - * It's perfectly valid firmware can pass disabled GICC entry, driver 2454 - * should not treat as errors, skip the entry instead of probe fail. 2455 - */ 2456 - if (!acpi_gicc_is_usable(gicc)) 2457 - return 0; 2458 - 2459 - return -ENODEV; 2419 + return 0; 2460 2420 } 2461 2421 2462 2422 static int __init gic_acpi_count_gicr_regions(void) ··· 2506 2478 int maint_irq_mode; 2507 2479 static int first_madt = true; 2508 2480 2509 - if (!acpi_gicc_is_usable(gicc)) 2481 + if (!(gicc->flags & 2482 + (ACPI_MADT_ENABLED | ACPI_MADT_GICC_ONLINE_CAPABLE))) 2510 2483 return 0; 2511 2484 2512 2485 maint_irq_mode = (gicc->flags & ACPI_MADT_VGIC_IRQ_MODE) ?
+1
include/acpi/acpi_bus.h
··· 134 134 bool (*match)(const char *idstr, const struct acpi_device_id **matchid); 135 135 int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id); 136 136 void (*detach)(struct acpi_device *dev); 137 + void (*post_eject)(struct acpi_device *dev); 137 138 void (*bind)(struct device *phys_dev); 138 139 void (*unbind)(struct device *phys_dev); 139 140 struct acpi_hotplug_profile hotplug;
+1 -1
include/acpi/processor.h
··· 217 217 u8 has_lpi:1; 218 218 u8 power_setup_done:1; 219 219 u8 bm_rld_set:1; 220 - u8 need_hotplug_init:1; 220 + u8 previously_online:1; 221 221 }; 222 222 223 223 struct acpi_processor {
+7 -5
include/linux/acpi.h
··· 237 237 int acpi_parse_mcfg (struct acpi_table_header *header); 238 238 void acpi_table_print_madt_entry (struct acpi_subtable_header *madt); 239 239 240 - static inline bool acpi_gicc_is_usable(struct acpi_madt_generic_interrupt *gicc) 241 - { 242 - return gicc->flags & ACPI_MADT_ENABLED; 243 - } 244 - 245 240 #if defined(CONFIG_X86) || defined(CONFIG_LOONGARCH) 246 241 void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa); 247 242 #else ··· 298 303 int *pcpu); 299 304 int acpi_unmap_cpu(int cpu); 300 305 #endif /* CONFIG_ACPI_HOTPLUG_CPU */ 306 + 307 + acpi_handle acpi_get_processor_handle(int cpu); 301 308 302 309 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC 303 310 int acpi_get_ioapic_id(acpi_handle handle, u32 gsi_base, u64 *phys_addr); ··· 1071 1074 static inline bool acpi_sleep_state_supported(u8 sleep_state) 1072 1075 { 1073 1076 return false; 1077 + } 1078 + 1079 + static inline acpi_handle acpi_get_processor_handle(int cpu) 1080 + { 1081 + return NULL; 1074 1082 } 1075 1083 1076 1084 #endif /* !CONFIG_ACPI */
+25
include/linux/cpumask.h
··· 93 93 * 94 94 * cpu_possible_mask- has bit 'cpu' set iff cpu is populatable 95 95 * cpu_present_mask - has bit 'cpu' set iff cpu is populated 96 + * cpu_enabled_mask - has bit 'cpu' set iff cpu can be brought online 96 97 * cpu_online_mask - has bit 'cpu' set iff cpu available to scheduler 97 98 * cpu_active_mask - has bit 'cpu' set iff cpu available to migration 98 99 * ··· 126 125 127 126 extern struct cpumask __cpu_possible_mask; 128 127 extern struct cpumask __cpu_online_mask; 128 + extern struct cpumask __cpu_enabled_mask; 129 129 extern struct cpumask __cpu_present_mask; 130 130 extern struct cpumask __cpu_active_mask; 131 131 extern struct cpumask __cpu_dying_mask; 132 132 #define cpu_possible_mask ((const struct cpumask *)&__cpu_possible_mask) 133 133 #define cpu_online_mask ((const struct cpumask *)&__cpu_online_mask) 134 + #define cpu_enabled_mask ((const struct cpumask *)&__cpu_enabled_mask) 134 135 #define cpu_present_mask ((const struct cpumask *)&__cpu_present_mask) 135 136 #define cpu_active_mask ((const struct cpumask *)&__cpu_active_mask) 136 137 #define cpu_dying_mask ((const struct cpumask *)&__cpu_dying_mask) ··· 1078 1075 #else 1079 1076 #define for_each_possible_cpu(cpu) for_each_cpu((cpu), cpu_possible_mask) 1080 1077 #define for_each_online_cpu(cpu) for_each_cpu((cpu), cpu_online_mask) 1078 + #define for_each_enabled_cpu(cpu) for_each_cpu((cpu), cpu_enabled_mask) 1081 1079 #define for_each_present_cpu(cpu) for_each_cpu((cpu), cpu_present_mask) 1082 1080 #endif 1083 1081 ··· 1094 1090 cpumask_set_cpu(cpu, &__cpu_possible_mask); 1095 1091 else 1096 1092 cpumask_clear_cpu(cpu, &__cpu_possible_mask); 1093 + } 1094 + 1095 + static inline void 1096 + set_cpu_enabled(unsigned int cpu, bool can_be_onlined) 1097 + { 1098 + if (can_be_onlined) 1099 + cpumask_set_cpu(cpu, &__cpu_enabled_mask); 1100 + else 1101 + cpumask_clear_cpu(cpu, &__cpu_enabled_mask); 1097 1102 } 1098 1103 1099 1104 static inline void ··· 1186 1173 return raw_atomic_read(&__num_online_cpus); 1187 1174 } 1188 1175 #define num_possible_cpus() cpumask_weight(cpu_possible_mask) 1176 + #define num_enabled_cpus() cpumask_weight(cpu_enabled_mask) 1189 1177 #define num_present_cpus() cpumask_weight(cpu_present_mask) 1190 1178 #define num_active_cpus() cpumask_weight(cpu_active_mask) 1191 1179 1192 1180 static inline bool cpu_online(unsigned int cpu) 1193 1181 { 1194 1182 return cpumask_test_cpu(cpu, cpu_online_mask); 1183 + } 1184 + 1185 + static inline bool cpu_enabled(unsigned int cpu) 1186 + { 1187 + return cpumask_test_cpu(cpu, cpu_enabled_mask); 1195 1188 } 1196 1189 1197 1190 static inline bool cpu_possible(unsigned int cpu) ··· 1224 1205 1225 1206 #define num_online_cpus() 1U 1226 1207 #define num_possible_cpus() 1U 1208 + #define num_enabled_cpus() 1U 1227 1209 #define num_present_cpus() 1U 1228 1210 #define num_active_cpus() 1U 1229 1211 ··· 1234 1214 } 1235 1215 1236 1216 static inline bool cpu_possible(unsigned int cpu) 1217 + { 1218 + return cpu == 0; 1219 + } 1220 + 1221 + static inline bool cpu_enabled(unsigned int cpu) 1237 1222 { 1238 1223 return cpu == 0; 1239 1224 }
+3
kernel/cpu.c
··· 3069 3069 struct cpumask __cpu_online_mask __read_mostly; 3070 3070 EXPORT_SYMBOL(__cpu_online_mask); 3071 3071 3072 + struct cpumask __cpu_enabled_mask __read_mostly; 3073 + EXPORT_SYMBOL(__cpu_enabled_mask); 3074 + 3072 3075 struct cpumask __cpu_present_mask __read_mostly; 3073 3076 EXPORT_SYMBOL(__cpu_present_mask); 3074 3077