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

cpu/hotplug: Add support for declaring CPU offlining not supported

The ACPI MADT mailbox wakeup method doesn't allow to offline a CPU after
it has been woken up.

Currently, offlining is prevented based on the confidential computing attribute
which is set for Intel TDX. But TDX is not the only possible user of the wake up
method. The MADT wakeup can be implemented outside of a confidential computing
environment. Offline support is a property of the wakeup method, not the CoCo
implementation.

Introduce cpu_hotplug_disable_offlining() that can be called to indicate that
CPU offlining should be disabled.

This function is going to replace CC_ATTR_HOTPLUG_DISABLED for ACPI MADT wakeup
method.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Tao Liu <ltao@redhat.com>
Link: https://lore.kernel.org/r/20240614095904.1345461-4-kirill.shutemov@linux.intel.com

authored by

Kirill A. Shutemov and committed by
Borislav Petkov (AMD)
1037e4c5 24dd05da

+14 -1
+2
include/linux/cpuhplock.h
··· 21 21 void cpus_read_unlock(void); 22 22 int cpus_read_trylock(void); 23 23 void lockdep_assert_cpus_held(void); 24 + void cpu_hotplug_disable_offlining(void); 24 25 void cpu_hotplug_disable(void); 25 26 void cpu_hotplug_enable(void); 26 27 void clear_tasks_mm_cpumask(int cpu); ··· 37 36 static inline void cpus_read_unlock(void) { } 38 37 static inline int cpus_read_trylock(void) { return true; } 39 38 static inline void lockdep_assert_cpus_held(void) { } 39 + static inline void cpu_hotplug_disable_offlining(void) { } 40 40 static inline void cpu_hotplug_disable(void) { } 41 41 static inline void cpu_hotplug_enable(void) { } 42 42 static inline int remove_cpu(unsigned int cpu) { return -EPERM; }
+12 -1
kernel/cpu.c
··· 483 483 484 484 DEFINE_STATIC_PERCPU_RWSEM(cpu_hotplug_lock); 485 485 486 + static bool cpu_hotplug_offline_disabled __ro_after_init; 487 + 486 488 void cpus_read_lock(void) 487 489 { 488 490 percpu_down_read(&cpu_hotplug_lock); ··· 542 540 static void lockdep_release_cpus_lock(void) 543 541 { 544 542 rwsem_release(&cpu_hotplug_lock.dep_map, _THIS_IP_); 543 + } 544 + 545 + /* Declare CPU offlining not supported */ 546 + void cpu_hotplug_disable_offlining(void) 547 + { 548 + cpu_maps_update_begin(); 549 + cpu_hotplug_offline_disabled = true; 550 + cpu_maps_update_done(); 545 551 } 546 552 547 553 /* ··· 1481 1471 * If the platform does not support hotplug, report it explicitly to 1482 1472 * differentiate it from a transient offlining failure. 1483 1473 */ 1484 - if (cc_platform_has(CC_ATTR_HOTPLUG_DISABLED)) 1474 + if (cc_platform_has(CC_ATTR_HOTPLUG_DISABLED) || 1475 + cpu_hotplug_offline_disabled) 1485 1476 return -EOPNOTSUPP; 1486 1477 if (cpu_hotplug_disabled) 1487 1478 return -EBUSY;