1
The following commit has been merged into the x86/urgent branch of tip:
1
The following commit has been merged into the x86/urgent branch of tip:
2
2
3
Commit-ID: e5f1e8af9c9e151ecd665f6d2e36fb25fec3b110
3
Commit-ID: b578bfe07ae943937a2945a9f6ac4b497f4d4e09
4
Gitweb: https://git.kernel.org/tip/e5f1e8af9c9e151ecd665f6d2e36fb25fec3b110
4
Gitweb: https://git.kernel.org/tip/b578bfe07ae943937a2945a9f6ac4b497f4d4e09
5
Author: Xin Li (Intel) <xin@zytor.com>
5
Author: Xin Li (Intel) <xin@zytor.com>
6
AuthorDate: Tue, 01 Apr 2025 00:57:27 -07:00
6
AuthorDate: Tue, 25 Mar 2025 23:25:40 -07:00
7
Committer: Ingo Molnar <mingo@kernel.org>
7
Committer: Ingo Molnar <mingo@kernel.org>
8
CommitterDate: Tue, 01 Apr 2025 22:29:02 +02:00
8
CommitterDate: Mon, 31 Mar 2025 14:19:35 +02:00
9
9
10
x86/fred: Fix system hang during S4 resume with FRED enabled
10
x86/fred: Fix system hang during S4 resume with FRED enabled
11
11
12
Upon a wakeup from S4, the restore kernel starts and initializes the
12
During an S4 resume, the system first performs a cold power-on. The
13
FRED MSRs as needed from its perspective. It then loads a hibernation
13
kernel image is initially loaded to a random linear address, and the
14
image, including the image kernel, and attempts to load image pages
14
FRED MSRs are initialized. Subsequently, the S4 image is loaded,
15
directly into their original page frames used before hibernation unless
15
and the kernel image is relocated to its original address from before
16
those frames are currently in use. Once all pages are moved to their
16
the S4 suspend. Due to changes in the kernel text and data mappings,
17
original locations, it jumps to a "trampoline" page in the image kernel.
17
the FRED MSRs must be reinitialized with new values.
18
18
19
At this point, the image kernel takes control, but the FRED MSRs still
19
[ mingo: Rephrased & clarified the comments. ]
20
contain values set by the restore kernel, which may differ from those
21
set by the image kernel before hibernation. Therefore, the image kernel
22
must ensure the FRED MSRs have the same values as before hibernation.
23
Since these values depend only on the location of the kernel text and
24
data, they can be recomputed from scratch.
25
20
26
Reported-by: Xi Pardee <xi.pardee@intel.com>
21
Reported-by: Xi Pardee <xi.pardee@intel.com>
27
Reported-by: Todd Brandt <todd.e.brandt@intel.com>
22
Reported-by: Todd Brandt <todd.e.brandt@intel.com>
28
Tested-by: Todd Brandt <todd.e.brandt@intel.com>
29
Suggested-by: H. Peter Anvin (Intel) <hpa@zytor.com>
23
Suggested-by: H. Peter Anvin (Intel) <hpa@zytor.com>
30
Signed-off-by: Xin Li (Intel) <xin@zytor.com>
24
Signed-off-by: Xin Li (Intel) <xin@zytor.com>
31
Signed-off-by: Ingo Molnar <mingo@kernel.org>
25
Signed-off-by: Ingo Molnar <mingo@kernel.org>
32
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
26
Tested-by: Todd Brandt <todd.e.brandt@intel.com>
33
Reviewed-by: H. Peter Anvin (Intel) <hpa@zytor.com>
34
Cc: Andy Lutomirski <luto@kernel.org>
27
Cc: Andy Lutomirski <luto@kernel.org>
35
Cc: Brian Gerst <brgerst@gmail.com>
28
Cc: Brian Gerst <brgerst@gmail.com>
36
Cc: Juergen Gross <jgross@suse.com>
29
Cc: Juergen Gross <jgross@suse.com>
37
Cc: Linus Torvalds <torvalds@linux-foundation.org>
30
Cc: Linus Torvalds <torvalds@linux-foundation.org>
38
Link: https://lore.kernel.org/r/20250401075728.3626147-1-xin@zytor.com
31
Link: https://lore.kernel.org/r/20250326062540.820556-1-xin@zytor.com
39
---
32
---
40
arch/x86/power/cpu.c | 14 ++++++++++++++
33
arch/x86/power/cpu.c | 20 ++++++++++++++++++++
41
1 file changed, 14 insertions(+)
34
1 file changed, 20 insertions(+)
42
35
43
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
36
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
44
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
45
--- a/arch/x86/power/cpu.c
38
--- a/arch/x86/power/cpu.c
46
+++ b/arch/x86/power/cpu.c
39
+++ b/arch/x86/power/cpu.c
...
...
56
     */
49
     */
57
#ifdef CONFIG_X86_64
50
#ifdef CONFIG_X86_64
58
    wrmsrl(MSR_GS_BASE, ctxt->kernelmode_gs_base);
51
    wrmsrl(MSR_GS_BASE, ctxt->kernelmode_gs_base);
59
+
52
+
60
+    /*
53
+    /*
61
+     * Reinitialize FRED to ensure the FRED MSRs contain the same values
54
+     * Restore FRED settings.
62
+     * as before hibernation.
63
+     *
55
+     *
64
+     * Note, the setup of FRED RSPs requires access to percpu data
56
+     * FRED settings can be completely derived from
65
+     * structures. Therefore, FRED reinitialization can only occur after
57
+     * current kernel text and data data mappings, thus
66
+     * the percpu access pointer (i.e., MSR_GS_BASE) is restored.
58
+     * nothing needs to be saved and restored.
59
+     *
60
+     * As such, simply re-initialize FRED to restore the FRED
61
+     * settings. Note that any changes to text and data mappings
62
+     * after S4 resume will generate different FRED configuration
63
+     * values.
64
+     *
65
+     * Also, FRED RSPs setup needs to access per-CPU data structures.
67
+     */
66
+     */
68
+    if (ctxt->cr4 & X86_CR4_FRED) {
67
+    if (ctxt->cr4 & X86_CR4_FRED) {
69
+        cpu_init_fred_exceptions();
68
+        cpu_init_fred_exceptions();
70
+        cpu_init_fred_rsps();
69
+        cpu_init_fred_rsps();
71
+    }
70
+    }
72
#else
71
#else
73
    loadsegment(fs, __KERNEL_PERCPU);
72
    loadsegment(fs, __KERNEL_PERCPU);
74
#endif
73
#endif
diff view generated by jsdifflib