x86/fred: Set SS to __KERNEL_DS when enabling FRED
authorXin Li (Intel) <xin@zytor.com>
Fri, 16 Aug 2024 10:43:16 +0000 (03:43 -0700)
committerThomas Gleixner <tglx@linutronix.de>
Sun, 25 Aug 2024 14:24:52 +0000 (16:24 +0200)
commit723edbd2ca5fb4c78ac4a5644511c63895fd1c57
tree77d6a0cd8b8910e584f852bef67e50c872ec1248
parenta97756cbec448032f84b5bbfe4e101478d1e01e0
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) <xin@zytor.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20240816104316.2276968-1-xin@zytor.com
arch/x86/kernel/fred.c