mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 08:38:45 +02:00 
			
		
		
		
	kernel/reboot: Change registration order of legacy power-off handler
We're unconditionally registering sys-off handler for the legacy
pm_power_off() callback, this causes problem for platforms that don't
use power-off handlers at all and should be halted. Now reboot syscall
assumes that there is a power-off handler installed and tries to power
off system instead of halting it.
To fix the trouble, move the handler's registration to the reboot syscall
and check the pm_power_off() presence.
Fixes: 0e2110d2e9 ("kernel/reboot: Add kernel_can_power_off()")
Reported-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
			
			
This commit is contained in:
		
							parent
							
								
									cfd6d63e59
								
							
						
					
					
						commit
						da007f171f
					
				
					 1 changed files with 17 additions and 16 deletions
				
			
		|  | @ -569,22 +569,6 @@ static int legacy_pm_power_off(struct sys_off_data *data) | |||
| 	return NOTIFY_DONE; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Register sys-off handlers for legacy PM callbacks. This allows legacy | ||||
|  * PM callbacks co-exist with the new sys-off API. | ||||
|  * | ||||
|  * TODO: Remove legacy handlers once all legacy PM users will be switched | ||||
|  *       to the sys-off based APIs. | ||||
|  */ | ||||
| static int __init legacy_pm_init(void) | ||||
| { | ||||
| 	register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_DEFAULT, | ||||
| 				 legacy_pm_power_off, NULL); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| core_initcall(legacy_pm_init); | ||||
| 
 | ||||
| static void do_kernel_power_off_prepare(void) | ||||
| { | ||||
| 	blocking_notifier_call_chain(&power_off_prep_handler_list, 0, NULL); | ||||
|  | @ -646,6 +630,7 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, | |||
| 		void __user *, arg) | ||||
| { | ||||
| 	struct pid_namespace *pid_ns = task_active_pid_ns(current); | ||||
| 	struct sys_off_handler *sys_off = NULL; | ||||
| 	char buffer[256]; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
|  | @ -670,6 +655,21 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, | |||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Register sys-off handlers for legacy PM callback. This allows | ||||
| 	 * legacy PM callbacks temporary co-exist with the new sys-off API. | ||||
| 	 * | ||||
| 	 * TODO: Remove legacy handlers once all legacy PM users will be | ||||
| 	 *       switched to the sys-off based APIs. | ||||
| 	 */ | ||||
| 	if (pm_power_off) { | ||||
| 		sys_off = register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, | ||||
| 						   SYS_OFF_PRIO_DEFAULT, | ||||
| 						   legacy_pm_power_off, NULL); | ||||
| 		if (IS_ERR(sys_off)) | ||||
| 			return PTR_ERR(sys_off); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Instead of trying to make the power_off code look like
 | ||||
| 	 * halt when pm_power_off is not set do it the easy way. | ||||
| 	 */ | ||||
|  | @ -727,6 +727,7 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, | |||
| 		break; | ||||
| 	} | ||||
| 	mutex_unlock(&system_transition_mutex); | ||||
| 	unregister_sys_off_handler(sys_off); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Dmitry Osipenko
						Dmitry Osipenko