diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index db1378c6ff26..7e4bafaedd7f 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -274,6 +274,19 @@ static void notrace __restore_processor_state(struct saved_context *ctxt) /* Needed by apm.c */ void notrace restore_processor_state(void) { +#ifdef __clang__ + // The following code snippet is copied from __restore_processor_state. + // Its purpose is to prepare GS segment before the function is called. + // Since the function is compiled with SCS on, it will use GS at its + // entry. + // TODO: Hack to be removed later when compiler bug is fixed. +#ifdef CONFIG_X86_64 + wrmsrl(MSR_GS_BASE, saved_context.kernelmode_gs_base); +#else + loadsegment(fs, __KERNEL_PERCPU); + loadsegment(gs, __KERNEL_STACK_CANARY); +#endif +#endif __restore_processor_state(&saved_context); } #ifdef CONFIG_X86_32