Skip to content

Commit 723edbd

Browse files
xinli-intelKAGA-KOKO
authored andcommitted
x86/fred: Set SS to __KERNEL_DS when enabling FRED
SS is initialized to NULL during boot time and not explicitly set to __KERNEL_DS. With FRED enabled, if a kernel event is delivered before a CPU goes to user level for the first time, its SS is NULL thus NULL is pushed into the SS field of the FRED stack frame. But before ERETS is executed, the CPU may context switch to another task and go to user level. Then when the CPU comes back to kernel mode, SS is changed to __KERNEL_DS. Later when ERETS is executed to return from the kernel event handler, a #GP fault is generated because SS doesn't match the SS saved in the FRED stack frame. Initialize SS to __KERNEL_DS when enabling FRED to prevent that. Note, IRET doesn't check if SS matches the SS saved in its stack frame, thus IDT doesn't have this problem. For IDT it doesn't matter whether SS is set to __KERNEL_DS or not, because it's set to NULL upon interrupt or exception delivery and __KERNEL_DS upon SYSCALL. Thus it's pointless to initialize SS for IDT. Signed-off-by: Xin Li (Intel) <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/all/[email protected]
1 parent a97756c commit 723edbd

File tree

1 file changed

+14
-0
lines changed

1 file changed

+14
-0
lines changed

arch/x86/kernel/fred.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,20 @@ void cpu_init_fred_exceptions(void)
2626
/* When FRED is enabled by default, remove this log message */
2727
pr_info("Initialize FRED on CPU%d\n", smp_processor_id());
2828

29+
/*
30+
* If a kernel event is delivered before a CPU goes to user level for
31+
* the first time, its SS is NULL thus NULL is pushed into the SS field
32+
* of the FRED stack frame. But before ERETS is executed, the CPU may
33+
* context switch to another task and go to user level. Then when the
34+
* CPU comes back to kernel mode, SS is changed to __KERNEL_DS. Later
35+
* when ERETS is executed to return from the kernel event handler, a #GP
36+
* fault is generated because SS doesn't match the SS saved in the FRED
37+
* stack frame.
38+
*
39+
* Initialize SS to __KERNEL_DS when enabling FRED to avoid such #GPs.
40+
*/
41+
loadsegment(ss, __KERNEL_DS);
42+
2943
wrmsrl(MSR_IA32_FRED_CONFIG,
3044
/* Reserve for CALL emulation */
3145
FRED_CONFIG_REDZONE |

0 commit comments

Comments
 (0)