Merge branch 'pm-x86'
* pm-x86: x86/power: Fix 'nosmt' vs hibernation triple fault during resume x86: intel_epb: Do not build when CONFIG_PM is unset
This commit is contained in:
@@ -28,7 +28,10 @@ obj-y += cpuid-deps.o
|
|||||||
obj-$(CONFIG_PROC_FS) += proc.o
|
obj-$(CONFIG_PROC_FS) += proc.o
|
||||||
obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o
|
obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o
|
||||||
|
|
||||||
obj-$(CONFIG_CPU_SUP_INTEL) += intel.o intel_pconfig.o intel_epb.o
|
ifdef CONFIG_CPU_SUP_INTEL
|
||||||
|
obj-y += intel.o intel_pconfig.o
|
||||||
|
obj-$(CONFIG_PM) += intel_epb.o
|
||||||
|
endif
|
||||||
obj-$(CONFIG_CPU_SUP_AMD) += amd.o
|
obj-$(CONFIG_CPU_SUP_AMD) += amd.o
|
||||||
obj-$(CONFIG_CPU_SUP_HYGON) += hygon.o
|
obj-$(CONFIG_CPU_SUP_HYGON) += hygon.o
|
||||||
obj-$(CONFIG_CPU_SUP_CYRIX_32) += cyrix.o
|
obj-$(CONFIG_CPU_SUP_CYRIX_32) += cyrix.o
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ static void intel_epb_restore(void)
|
|||||||
wrmsrl(MSR_IA32_ENERGY_PERF_BIAS, (epb & ~EPB_MASK) | val);
|
wrmsrl(MSR_IA32_ENERGY_PERF_BIAS, (epb & ~EPB_MASK) | val);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
|
||||||
static struct syscore_ops intel_epb_syscore_ops = {
|
static struct syscore_ops intel_epb_syscore_ops = {
|
||||||
.suspend = intel_epb_save,
|
.suspend = intel_epb_save,
|
||||||
.resume = intel_epb_restore,
|
.resume = intel_epb_restore,
|
||||||
@@ -194,25 +193,6 @@ static int intel_epb_offline(unsigned int cpu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void register_intel_ebp_syscore_ops(void)
|
|
||||||
{
|
|
||||||
register_syscore_ops(&intel_epb_syscore_ops);
|
|
||||||
}
|
|
||||||
#else /* !CONFIG_PM */
|
|
||||||
static int intel_epb_online(unsigned int cpu)
|
|
||||||
{
|
|
||||||
intel_epb_restore();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int intel_epb_offline(unsigned int cpu)
|
|
||||||
{
|
|
||||||
return intel_epb_save();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void register_intel_ebp_syscore_ops(void) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static __init int intel_epb_init(void)
|
static __init int intel_epb_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -226,7 +206,7 @@ static __init int intel_epb_init(void)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_out_online;
|
goto err_out_online;
|
||||||
|
|
||||||
register_intel_ebp_syscore_ops();
|
register_syscore_ops(&intel_epb_syscore_ops);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_out_online:
|
err_out_online:
|
||||||
|
|||||||
@@ -299,7 +299,17 @@ int hibernate_resume_nonboot_cpu_disable(void)
|
|||||||
* address in its instruction pointer may not be possible to resolve
|
* address in its instruction pointer may not be possible to resolve
|
||||||
* any more at that point (the page tables used by it previously may
|
* any more at that point (the page tables used by it previously may
|
||||||
* have been overwritten by hibernate image data).
|
* have been overwritten by hibernate image data).
|
||||||
|
*
|
||||||
|
* First, make sure that we wake up all the potentially disabled SMT
|
||||||
|
* threads which have been initially brought up and then put into
|
||||||
|
* mwait/cpuidle sleep.
|
||||||
|
* Those will be put to proper (not interfering with hibernation
|
||||||
|
* resume) sleep afterwards, and the resumed kernel will decide itself
|
||||||
|
* what to do with them.
|
||||||
*/
|
*/
|
||||||
|
ret = cpuhp_smt_enable();
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
smp_ops.play_dead = resume_play_dead;
|
smp_ops.play_dead = resume_play_dead;
|
||||||
ret = disable_nonboot_cpus();
|
ret = disable_nonboot_cpus();
|
||||||
smp_ops.play_dead = play_dead;
|
smp_ops.play_dead = play_dead;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <linux/suspend.h>
|
#include <linux/suspend.h>
|
||||||
#include <linux/scatterlist.h>
|
#include <linux/scatterlist.h>
|
||||||
#include <linux/kdebug.h>
|
#include <linux/kdebug.h>
|
||||||
|
#include <linux/cpu.h>
|
||||||
|
|
||||||
#include <crypto/hash.h>
|
#include <crypto/hash.h>
|
||||||
|
|
||||||
@@ -245,3 +246,35 @@ out:
|
|||||||
__flush_tlb_all();
|
__flush_tlb_all();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int arch_resume_nosmt(void)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
/*
|
||||||
|
* We reached this while coming out of hibernation. This means
|
||||||
|
* that SMT siblings are sleeping in hlt, as mwait is not safe
|
||||||
|
* against control transition during resume (see comment in
|
||||||
|
* hibernate_resume_nonboot_cpu_disable()).
|
||||||
|
*
|
||||||
|
* If the resumed kernel has SMT disabled, we have to take all the
|
||||||
|
* SMT siblings out of hlt, and offline them again so that they
|
||||||
|
* end up in mwait proper.
|
||||||
|
*
|
||||||
|
* Called with hotplug disabled.
|
||||||
|
*/
|
||||||
|
cpu_hotplug_enable();
|
||||||
|
if (cpu_smt_control == CPU_SMT_DISABLED ||
|
||||||
|
cpu_smt_control == CPU_SMT_FORCE_DISABLED) {
|
||||||
|
enum cpuhp_smt_control old = cpu_smt_control;
|
||||||
|
|
||||||
|
ret = cpuhp_smt_enable();
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
ret = cpuhp_smt_disable(old);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
cpu_hotplug_disable();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|||||||
@@ -201,10 +201,14 @@ enum cpuhp_smt_control {
|
|||||||
extern enum cpuhp_smt_control cpu_smt_control;
|
extern enum cpuhp_smt_control cpu_smt_control;
|
||||||
extern void cpu_smt_disable(bool force);
|
extern void cpu_smt_disable(bool force);
|
||||||
extern void cpu_smt_check_topology(void);
|
extern void cpu_smt_check_topology(void);
|
||||||
|
extern int cpuhp_smt_enable(void);
|
||||||
|
extern int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval);
|
||||||
#else
|
#else
|
||||||
# define cpu_smt_control (CPU_SMT_NOT_IMPLEMENTED)
|
# define cpu_smt_control (CPU_SMT_NOT_IMPLEMENTED)
|
||||||
static inline void cpu_smt_disable(bool force) { }
|
static inline void cpu_smt_disable(bool force) { }
|
||||||
static inline void cpu_smt_check_topology(void) { }
|
static inline void cpu_smt_check_topology(void) { }
|
||||||
|
static inline int cpuhp_smt_enable(void) { return 0; }
|
||||||
|
static inline int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval) { return 0; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -2061,7 +2061,7 @@ static void cpuhp_online_cpu_device(unsigned int cpu)
|
|||||||
kobject_uevent(&dev->kobj, KOBJ_ONLINE);
|
kobject_uevent(&dev->kobj, KOBJ_ONLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
|
int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
|
||||||
{
|
{
|
||||||
int cpu, ret = 0;
|
int cpu, ret = 0;
|
||||||
|
|
||||||
@@ -2093,7 +2093,7 @@ static int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cpuhp_smt_enable(void)
|
int cpuhp_smt_enable(void)
|
||||||
{
|
{
|
||||||
int cpu, ret = 0;
|
int cpu, ret = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -257,6 +257,11 @@ void swsusp_show_speed(ktime_t start, ktime_t stop,
|
|||||||
(kps % 1000) / 10);
|
(kps % 1000) / 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__weak int arch_resume_nosmt(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create_image - Create a hibernation image.
|
* create_image - Create a hibernation image.
|
||||||
* @platform_mode: Whether or not to use the platform driver.
|
* @platform_mode: Whether or not to use the platform driver.
|
||||||
@@ -324,6 +329,10 @@ static int create_image(int platform_mode)
|
|||||||
Enable_cpus:
|
Enable_cpus:
|
||||||
suspend_enable_secondary_cpus();
|
suspend_enable_secondary_cpus();
|
||||||
|
|
||||||
|
/* Allow architectures to do nosmt-specific post-resume dances */
|
||||||
|
if (!in_suspend)
|
||||||
|
error = arch_resume_nosmt();
|
||||||
|
|
||||||
Platform_finish:
|
Platform_finish:
|
||||||
platform_finish(platform_mode);
|
platform_finish(platform_mode);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user