hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/kernel/power/hibernate.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * kernel/power/hibernate.c - Hibernation (a.k.a suspend-to-disk) support.
34 *
....@@ -6,15 +7,12 @@
67 * Copyright (c) 2004 Pavel Machek <pavel@ucw.cz>
78 * Copyright (c) 2009 Rafael J. Wysocki, Novell Inc.
89 * Copyright (C) 2012 Bojan Smojver <bojan@rexursive.com>
9
- *
10
- * This file is released under the GPLv2.
1110 */
1211
13
-#define pr_fmt(fmt) "PM: " fmt
12
+#define pr_fmt(fmt) "PM: hibernation: " fmt
1413
1514 #include <linux/export.h>
1615 #include <linux/suspend.h>
17
-#include <linux/syscalls.h>
1816 #include <linux/reboot.h>
1917 #include <linux/string.h>
2018 #include <linux/device.h>
....@@ -32,6 +30,7 @@
3230 #include <linux/ctype.h>
3331 #include <linux/genhd.h>
3432 #include <linux/ktime.h>
33
+#include <linux/security.h>
3534 #include <trace/events/power.h>
3635
3736 #include "power.h"
....@@ -68,9 +67,21 @@
6867
6968 static const struct platform_hibernation_ops *hibernation_ops;
7069
70
+static atomic_t hibernate_atomic = ATOMIC_INIT(1);
71
+
72
+bool hibernate_acquire(void)
73
+{
74
+ return atomic_add_unless(&hibernate_atomic, -1, 0);
75
+}
76
+
77
+void hibernate_release(void)
78
+{
79
+ atomic_inc(&hibernate_atomic);
80
+}
81
+
7182 bool hibernation_available(void)
7283 {
73
- return (nohibernate == 0);
84
+ return nohibernate == 0 && !security_locked_down(LOCKDOWN_HIBERNATION);
7485 }
7586
7687 /**
....@@ -107,7 +118,7 @@
107118 #ifdef CONFIG_PM_DEBUG
108119 static void hibernation_debug_sleep(void)
109120 {
110
- pr_info("hibernation debug: Waiting for 5 seconds.\n");
121
+ pr_info("debug: Waiting for 5 seconds.\n");
111122 mdelay(5000);
112123 }
113124
....@@ -130,7 +141,7 @@
130141 static int platform_begin(int platform_mode)
131142 {
132143 return (platform_mode && hibernation_ops) ?
133
- hibernation_ops->begin() : 0;
144
+ hibernation_ops->begin(PMSG_FREEZE) : 0;
134145 }
135146
136147 /**
....@@ -278,7 +289,7 @@
278289
279290 error = dpm_suspend_end(PMSG_FREEZE);
280291 if (error) {
281
- pr_err("Some devices failed to power down, aborting hibernation\n");
292
+ pr_err("Some devices failed to power down, aborting\n");
282293 return error;
283294 }
284295
....@@ -286,7 +297,7 @@
286297 if (error || hibernation_test(TEST_PLATFORM))
287298 goto Platform_finish;
288299
289
- error = disable_nonboot_cpus();
300
+ error = suspend_disable_secondary_cpus();
290301 if (error || hibernation_test(TEST_CPUS))
291302 goto Enable_cpus;
292303
....@@ -296,7 +307,7 @@
296307
297308 error = syscore_suspend();
298309 if (error) {
299
- pr_err("Some system devices failed to power down, aborting hibernation\n");
310
+ pr_err("Some system devices failed to power down, aborting\n");
300311 goto Enable_irqs;
301312 }
302313
....@@ -311,11 +322,11 @@
311322 restore_processor_state();
312323 trace_suspend_resume(TPS("machine_suspend"), PM_EVENT_HIBERNATE, false);
313324 if (error)
314
- pr_err("Error %d creating hibernation image\n", error);
325
+ pr_err("Error %d creating image\n", error);
315326
316327 if (!in_suspend) {
317328 events_check_enabled = false;
318
- clear_free_pages();
329
+ clear_or_poison_free_pages();
319330 }
320331
321332 platform_leave(platform_mode);
....@@ -328,7 +339,7 @@
328339 local_irq_enable();
329340
330341 Enable_cpus:
331
- enable_nonboot_cpus();
342
+ suspend_enable_secondary_cpus();
332343
333344 /* Allow architectures to do nosmt-specific post-resume dances */
334345 if (!in_suspend)
....@@ -426,7 +437,7 @@
426437
427438 int __weak hibernate_resume_nonboot_cpu_disable(void)
428439 {
429
- return disable_nonboot_cpus();
440
+ return suspend_disable_secondary_cpus();
430441 }
431442
432443 /**
....@@ -495,7 +506,7 @@
495506 local_irq_enable();
496507
497508 Enable_cpus:
498
- enable_nonboot_cpus();
509
+ suspend_enable_secondary_cpus();
499510
500511 Cleanup:
501512 platform_restore_cleanup(platform_mode);
....@@ -552,7 +563,7 @@
552563 * hibernation_ops->finish() before saving the image, so we should let
553564 * the firmware know that we're going to enter the sleep state after all
554565 */
555
- error = hibernation_ops->begin();
566
+ error = hibernation_ops->begin(PMSG_HIBERNATE);
556567 if (error)
557568 goto Close;
558569
....@@ -573,7 +584,7 @@
573584 if (error)
574585 goto Platform_finish;
575586
576
- error = disable_nonboot_cpus();
587
+ error = suspend_disable_secondary_cpus();
577588 if (error)
578589 goto Enable_cpus;
579590
....@@ -595,7 +606,7 @@
595606 local_irq_enable();
596607
597608 Enable_cpus:
598
- enable_nonboot_cpus();
609
+ suspend_enable_secondary_cpus();
599610
600611 Platform_finish:
601612 hibernation_ops->finish();
....@@ -626,7 +637,7 @@
626637 int error;
627638
628639 if (hibernation_mode == HIBERNATION_SUSPEND) {
629
- error = suspend_devices_and_enter(PM_SUSPEND_MEM);
640
+ error = suspend_devices_and_enter(mem_sleep_current);
630641 if (error) {
631642 hibernation_mode = hibernation_ops ?
632643 HIBERNATION_PLATFORM :
....@@ -648,7 +659,7 @@
648659 break;
649660 case HIBERNATION_PLATFORM:
650661 hibernation_platform_enter();
651
- /* Fall through */
662
+ fallthrough;
652663 case HIBERNATION_SHUTDOWN:
653664 if (pm_power_off)
654665 kernel_power_off();
....@@ -679,9 +690,9 @@
679690 error = swsusp_read(&flags);
680691 swsusp_close(FMODE_READ | FMODE_EXCL);
681692 if (!error)
682
- hibernation_restore(flags & SF_PLATFORM_MODE);
693
+ error = hibernation_restore(flags & SF_PLATFORM_MODE);
683694
684
- pr_err("Failed to load hibernation image, recovering.\n");
695
+ pr_err("Failed to load image, recovering.\n");
685696 swsusp_free();
686697 free_basic_memory_bitmaps();
687698 Unlock:
....@@ -690,43 +701,33 @@
690701 return error;
691702 }
692703
693
-#ifndef CONFIG_SUSPEND
694
-bool pm_in_action;
695
-#endif
696
-
697704 /**
698705 * hibernate - Carry out system hibernation, including saving the image.
699706 */
700707 int hibernate(void)
701708 {
702
- int error, nr_calls = 0;
703709 bool snapshot_test = false;
710
+ int error;
704711
705712 if (!hibernation_available()) {
706713 pm_pr_dbg("Hibernation not available.\n");
707714 return -EPERM;
708715 }
709716
710
- pm_in_action = true;
711
-
712717 lock_system_sleep();
713718 /* The snapshot device should not be opened while we're running */
714
- if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
719
+ if (!hibernate_acquire()) {
715720 error = -EBUSY;
716721 goto Unlock;
717722 }
718723
719724 pr_info("hibernation entry\n");
720725 pm_prepare_console();
721
- error = __pm_notifier_call_chain(PM_HIBERNATION_PREPARE, -1, &nr_calls);
722
- if (error) {
723
- nr_calls--;
724
- goto Exit;
725
- }
726
+ error = pm_notifier_call_chain_robust(PM_HIBERNATION_PREPARE, PM_POST_HIBERNATION);
727
+ if (error)
728
+ goto Restore;
726729
727
- pr_info("Syncing filesystems ... \n");
728
- ksys_sync();
729
- pr_info("done.\n");
730
+ ksys_sync_helper();
730731
731732 error = freeze_processes();
732733 if (error)
....@@ -752,7 +753,7 @@
752753 else
753754 flags |= SF_CRC32_MODE;
754755
755
- pm_pr_dbg("Writing image.\n");
756
+ pm_pr_dbg("Writing hibernation image.\n");
756757 error = swsusp_write(flags);
757758 swsusp_free();
758759 if (!error) {
....@@ -764,7 +765,7 @@
764765 in_suspend = 0;
765766 pm_restore_gfp_mask();
766767 } else {
767
- pm_pr_dbg("Image restored successfully.\n");
768
+ pm_pr_dbg("Hibernation image restored successfully.\n");
768769 }
769770
770771 Free_bitmaps:
....@@ -782,17 +783,113 @@
782783 /* Don't bother checking whether freezer_test_done is true */
783784 freezer_test_done = false;
784785 Exit:
785
- __pm_notifier_call_chain(PM_POST_HIBERNATION, nr_calls, NULL);
786
+ pm_notifier_call_chain(PM_POST_HIBERNATION);
787
+ Restore:
786788 pm_restore_console();
787
- atomic_inc(&snapshot_device_available);
789
+ hibernate_release();
788790 Unlock:
789791 unlock_system_sleep();
790
- pm_in_action = false;
791792 pr_info("hibernation exit\n");
792793
793794 return error;
794795 }
795796
797
+/**
798
+ * hibernate_quiet_exec - Execute a function with all devices frozen.
799
+ * @func: Function to execute.
800
+ * @data: Data pointer to pass to @func.
801
+ *
802
+ * Return the @func return value or an error code if it cannot be executed.
803
+ */
804
+int hibernate_quiet_exec(int (*func)(void *data), void *data)
805
+{
806
+ int error;
807
+
808
+ lock_system_sleep();
809
+
810
+ if (!hibernate_acquire()) {
811
+ error = -EBUSY;
812
+ goto unlock;
813
+ }
814
+
815
+ pm_prepare_console();
816
+
817
+ error = pm_notifier_call_chain_robust(PM_HIBERNATION_PREPARE, PM_POST_HIBERNATION);
818
+ if (error)
819
+ goto restore;
820
+
821
+ error = freeze_processes();
822
+ if (error)
823
+ goto exit;
824
+
825
+ lock_device_hotplug();
826
+
827
+ pm_suspend_clear_flags();
828
+
829
+ error = platform_begin(true);
830
+ if (error)
831
+ goto thaw;
832
+
833
+ error = freeze_kernel_threads();
834
+ if (error)
835
+ goto thaw;
836
+
837
+ error = dpm_prepare(PMSG_FREEZE);
838
+ if (error)
839
+ goto dpm_complete;
840
+
841
+ suspend_console();
842
+
843
+ error = dpm_suspend(PMSG_FREEZE);
844
+ if (error)
845
+ goto dpm_resume;
846
+
847
+ error = dpm_suspend_end(PMSG_FREEZE);
848
+ if (error)
849
+ goto dpm_resume;
850
+
851
+ error = platform_pre_snapshot(true);
852
+ if (error)
853
+ goto skip;
854
+
855
+ error = func(data);
856
+
857
+skip:
858
+ platform_finish(true);
859
+
860
+ dpm_resume_start(PMSG_THAW);
861
+
862
+dpm_resume:
863
+ dpm_resume(PMSG_THAW);
864
+
865
+ resume_console();
866
+
867
+dpm_complete:
868
+ dpm_complete(PMSG_THAW);
869
+
870
+ thaw_kernel_threads();
871
+
872
+thaw:
873
+ platform_end(true);
874
+
875
+ unlock_device_hotplug();
876
+
877
+ thaw_processes();
878
+
879
+exit:
880
+ pm_notifier_call_chain(PM_POST_HIBERNATION);
881
+
882
+restore:
883
+ pm_restore_console();
884
+
885
+ hibernate_release();
886
+
887
+unlock:
888
+ unlock_system_sleep();
889
+
890
+ return error;
891
+}
892
+EXPORT_SYMBOL_GPL(hibernate_quiet_exec);
796893
797894 /**
798895 * software_resume - Resume from a saved hibernation image.
....@@ -811,7 +908,7 @@
811908 */
812909 static int software_resume(void)
813910 {
814
- int error, nr_calls = 0;
911
+ int error;
815912
816913 /*
817914 * If the user said "noresume".. bail out early.
....@@ -879,7 +976,7 @@
879976 goto Unlock;
880977
881978 /* The snapshot device should not be opened while we're running */
882
- if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
979
+ if (!hibernate_acquire()) {
883980 error = -EBUSY;
884981 swsusp_close(FMODE_READ | FMODE_EXCL);
885982 goto Unlock;
....@@ -887,13 +984,11 @@
887984
888985 pr_info("resume from hibernation\n");
889986 pm_prepare_console();
890
- error = __pm_notifier_call_chain(PM_RESTORE_PREPARE, -1, &nr_calls);
891
- if (error) {
892
- nr_calls--;
893
- goto Close_Finish;
894
- }
987
+ error = pm_notifier_call_chain_robust(PM_RESTORE_PREPARE, PM_POST_RESTORE);
988
+ if (error)
989
+ goto Restore;
895990
896
- pm_pr_dbg("Preparing processes for restore.\n");
991
+ pm_pr_dbg("Preparing processes for hibernation restore.\n");
897992 error = freeze_processes();
898993 if (error)
899994 goto Close_Finish;
....@@ -907,10 +1002,11 @@
9071002 error = load_image_and_restore();
9081003 thaw_processes();
9091004 Finish:
910
- __pm_notifier_call_chain(PM_POST_RESTORE, nr_calls, NULL);
1005
+ pm_notifier_call_chain(PM_POST_RESTORE);
1006
+ Restore:
9111007 pm_restore_console();
912
- pr_info("resume from hibernation failed (%d)\n", error);
913
- atomic_inc(&snapshot_device_available);
1008
+ pr_info("resume failed (%d)\n", error);
1009
+ hibernate_release();
9141010 /* For success case, the suspend path will release the lock */
9151011 Unlock:
9161012 mutex_unlock(&system_transition_mutex);
....@@ -1049,7 +1145,7 @@
10491145 static ssize_t resume_show(struct kobject *kobj, struct kobj_attribute *attr,
10501146 char *buf)
10511147 {
1052
- return sprintf(buf,"%d:%d\n", MAJOR(swsusp_resume_device),
1148
+ return sprintf(buf, "%d:%d\n", MAJOR(swsusp_resume_device),
10531149 MINOR(swsusp_resume_device));
10541150 }
10551151
....@@ -1074,7 +1170,8 @@
10741170 lock_system_sleep();
10751171 swsusp_resume_device = res;
10761172 unlock_system_sleep();
1077
- pm_pr_dbg("Configured resume from disk to %u\n", swsusp_resume_device);
1173
+ pm_pr_dbg("Configured hibernation resume from disk to %u\n",
1174
+ swsusp_resume_device);
10781175 noresume = 0;
10791176 software_resume();
10801177 return n;
....@@ -1148,7 +1245,7 @@
11481245
11491246 power_attr(reserved_size);
11501247
1151
-static struct attribute * g[] = {
1248
+static struct attribute *g[] = {
11521249 &disk_attr.attr,
11531250 &resume_offset_attr.attr,
11541251 &resume_attr.attr,
....@@ -1176,7 +1273,7 @@
11761273 if (noresume)
11771274 return 1;
11781275
1179
- strncpy( resume_file, str, 255 );
1276
+ strncpy(resume_file, str, 255);
11801277 return 1;
11811278 }
11821279
....@@ -1226,7 +1323,7 @@
12261323 int rc = kstrtouint(str, 0, &resume_delay);
12271324
12281325 if (rc)
1229
- return rc;
1326
+ pr_warn("resumedelay: bad option string '%s'\n", str);
12301327 return 1;
12311328 }
12321329