mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
x86/S3: Drop {save,restore}_rest_processor_state() completely
There is no need to save/restore FS/GS/XCR0 state. It will be handled suitably on the context switch away from the idle. The CR4 restoration in restore_rest_processor_state() was actually fighting later code in enter_state() which tried to keep CR4.MCE clear until everything was set up. Delete the intermediate restoration, and defer final restoration until after MCE is reconfigured. Restoring PAT can be done earlier, and ideally before paging is enabled. By moving it into the trampoline during the setup for 64bit, the call can be dropped from cpu_init(). The EFI path boot path doesn't disable paging, so make the adjustment when switching onto Xen's pagetables. The only remaing piece of restoration is load_system_tables(), so suspend.c can be deleted in its entirety. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
46d8f69d46
commit
4304ff420e
7 files changed
+12
-60
No files matched your search
@@ -1,4 +1,4 @@
|
||||
obj-y += cpufreq/
|
||||
|
||||
obj-y += lib.o power.o suspend.o cpu_idle.o cpuidle_menu.o
|
||||
obj-y += lib.o power.o cpu_idle.o cpuidle_menu.o
|
||||
obj-bin-y += boot.init.o wakeup_prot.o
|
||||
@@ -195,7 +195,6 @@ static int enter_state(u32 state)
|
||||
unsigned long flags;
|
||||
int error;
|
||||
struct cpu_info *ci;
|
||||
unsigned long cr4;
|
||||
|
||||
if ( (state <= ACPI_STATE_S0) || (state > ACPI_S_STATES_MAX) )
|
||||
return -EINVAL;
|
||||
@@ -270,15 +269,15 @@ static int enter_state(u32 state)
|
||||
|
||||
system_state = SYS_STATE_resume;
|
||||
|
||||
/* Restore CR4 and EFER from cached values. */
|
||||
cr4 = read_cr4();
|
||||
write_cr4(cr4 & ~X86_CR4_MCE);
|
||||
/* Restore EFER from cached value. */
|
||||
write_efer(read_efer());
|
||||
|
||||
device_power_up(SAVED_ALL);
|
||||
|
||||
mcheck_init(&boot_cpu_data, false);
|
||||
write_cr4(cr4);
|
||||
|
||||
/* Restore CR4 from cached value, now MCE is set up. */
|
||||
write_cr4(read_cr4());
|
||||
|
||||
printk(XENLOG_INFO "Finishing wakeup from ACPI S%d state.\n", state);
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Portions are:
|
||||
* Copyright (c) 2002 Pavel Machek <pavel@suse.cz>
|
||||
* Copyright (c) 2001 Patrick Mochel <mochel@osdl.org>
|
||||
*/
|
||||
|
||||
#include <xen/acpi.h>
|
||||
#include <xen/smp.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/debugreg.h>
|
||||
#include <asm/hvm/hvm.h>
|
||||
#include <asm/hvm/support.h>
|
||||
#include <asm/i387.h>
|
||||
#include <asm/xstate.h>
|
||||
#include <xen/hypercall.h>
|
||||
|
||||
static unsigned long saved_fs_base, saved_gs_base, saved_kernel_gs_base;
|
||||
static uint64_t saved_xcr0;
|
||||
|
||||
void save_rest_processor_state(void)
|
||||
{
|
||||
saved_fs_base = rdfsbase();
|
||||
saved_gs_base = rdgsbase();
|
||||
rdmsrl(MSR_SHADOW_GS_BASE, saved_kernel_gs_base);
|
||||
|
||||
if ( cpu_has_xsave )
|
||||
saved_xcr0 = get_xcr0();
|
||||
}
|
||||
|
||||
|
||||
void restore_rest_processor_state(void)
|
||||
{
|
||||
load_system_tables();
|
||||
|
||||
/* Restore full CR4 (inc MCE) now that the IDT is in place. */
|
||||
write_cr4(mmu_cr4_features);
|
||||
|
||||
wrfsbase(saved_fs_base);
|
||||
wrgsbase(saved_gs_base);
|
||||
wrmsrl(MSR_SHADOW_GS_BASE, saved_kernel_gs_base);
|
||||
|
||||
if ( cpu_has_xsave && !set_xcr0(saved_xcr0) )
|
||||
BUG();
|
||||
|
||||
wrmsrl(MSR_IA32_CR_PAT, XEN_MSR_PAT);
|
||||
|
||||
mtrr_bp_restore();
|
||||
}
|
||||
@@ -15,8 +15,6 @@ ENTRY(do_suspend_lowlevel)
|
||||
mov %cr0, %rax
|
||||
mov %rax, saved_cr0(%rip)
|
||||
|
||||
call save_rest_processor_state
|
||||
|
||||
/* enter sleep state physically */
|
||||
mov $3, %edi
|
||||
call acpi_enter_sleep_state
|
||||
@@ -51,7 +49,7 @@ ENTRY(s3_resume)
|
||||
lretq
|
||||
1:
|
||||
|
||||
call restore_rest_processor_state
|
||||
call load_system_tables
|
||||
|
||||
.Lsuspend_err:
|
||||
pop %r15
|
||||
|
||||
@@ -91,6 +91,11 @@ trampoline_protmode_entry:
|
||||
and %edi,%edx
|
||||
wrmsr
|
||||
1:
|
||||
/* Set up PAT before enabling paging. */
|
||||
mov $XEN_MSR_PAT & 0xffffffff, %eax
|
||||
mov $XEN_MSR_PAT >> 32, %edx
|
||||
mov $MSR_IA32_CR_PAT, %ecx
|
||||
wrmsr
|
||||
|
||||
/* Set up EFER (Extended Feature Enable Register). */
|
||||
movl $MSR_EFER,%ecx
|
||||
|
||||
@@ -790,8 +790,6 @@ void cpu_init(void)
|
||||
if (opt_cpu_info)
|
||||
printk("Initializing CPU#%d\n", cpu);
|
||||
|
||||
wrmsrl(MSR_IA32_CR_PAT, XEN_MSR_PAT);
|
||||
|
||||
/* Install correct page table. */
|
||||
write_ptbase(current);
|
||||
|
||||
|
||||
@@ -242,6 +242,7 @@ static void __init noreturn efi_arch_post_exit_boot(void)
|
||||
if ( cpu_has_nx )
|
||||
efer |= EFER_NX;
|
||||
wrmsrl(MSR_EFER, efer);
|
||||
wrmsrl(MSR_IA32_CR_PAT, XEN_MSR_PAT);
|
||||
write_cr0(X86_CR0_PE | X86_CR0_MP | X86_CR0_ET | X86_CR0_NE | X86_CR0_WP |
|
||||
X86_CR0_AM | X86_CR0_PG);
|
||||
asm volatile ( "mov %[cr4], %%cr4\n\t"
|
||||
|
||||