mirror of
https://github.com/torvalds/linux.git
synced 2024-12-29 22:31:32 +00:00
7ee18d6779
My previous attempt to fix a couple of bugs in __restore_processor_context():5b06bbcfc2
("x86/power: Fix some ordering bugs in __restore_processor_context()") ... introduced yet another bug, breaking suspend-resume. Rather than trying to come up with a minimal fix, let's try to clean it up for real. This patch fixes quite a few things: - The old code saved a nonsensical subset of segment registers. The only registers that need to be saved are those that contain userspace state or those that can't be trivially restored without percpu access working. (On x86_32, we can restore percpu access by writing __KERNEL_PERCPU to %fs. On x86_64, it's easier to save and restore the kernel's GSBASE.) With this patch, we restore hardcoded values to the kernel state where applicable and explicitly restore the user state after fixing all the descriptor tables. - We used to use an unholy mix of inline asm and C helpers for segment register access. Let's get rid of the inline asm. This fixes the reported s2ram hangs and make the code all around more logical. Analyzed-by: Linus Torvalds <torvalds@linux-foundation.org> Reported-by: Jarkko Nikula <jarkko.nikula@linux.intel.com> Reported-by: Pavel Machek <pavel@ucw.cz> Tested-by: Jarkko Nikula <jarkko.nikula@linux.intel.com> Tested-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Andy Lutomirski <luto@kernel.org> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Thomas Gleixner <tglx@linutronix.de> Cc: Borislav Petkov <bpetkov@suse.de> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rafael J. Wysocki <rjw@rjwysocki.net> Cc: Zhang Rui <rui.zhang@intel.com> Fixes:5b06bbcfc2
("x86/power: Fix some ordering bugs in __restore_processor_context()") Link: http://lkml.kernel.org/r/398ee68e5c0f766425a7b746becfc810840770ff.1513286253.git.luto@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
36 lines
822 B
C
36 lines
822 B
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright 2001-2002 Pavel Machek <pavel@suse.cz>
|
|
* Based on code
|
|
* Copyright 2001 Patrick Mochel <mochel@osdl.org>
|
|
*/
|
|
#ifndef _ASM_X86_SUSPEND_32_H
|
|
#define _ASM_X86_SUSPEND_32_H
|
|
|
|
#include <asm/desc.h>
|
|
#include <asm/fpu/api.h>
|
|
|
|
/* image of the saved processor state */
|
|
struct saved_context {
|
|
/*
|
|
* On x86_32, all segment registers, with the possible exception of
|
|
* gs, are saved at kernel entry in pt_regs.
|
|
*/
|
|
#ifdef CONFIG_X86_32_LAZY_GS
|
|
u16 gs;
|
|
#endif
|
|
unsigned long cr0, cr2, cr3, cr4;
|
|
u64 misc_enable;
|
|
bool misc_enable_saved;
|
|
struct saved_msrs saved_msrs;
|
|
struct desc_ptr gdt_desc;
|
|
struct desc_ptr idt;
|
|
u16 ldt;
|
|
u16 tss;
|
|
unsigned long tr;
|
|
unsigned long safety;
|
|
unsigned long return_address;
|
|
} __attribute__((packed));
|
|
|
|
#endif /* _ASM_X86_SUSPEND_32_H */
|