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 |