aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLaura Abbott <labbott@fedoraproject.org>2015-07-20 17:47:58 -0400
committerIngo Molnar <mingo@kernel.org>2015-07-21 01:51:38 -0400
commitb51ef52df71cb28e9d90cd1d48b79bf19f0bab06 (patch)
treeb2f6d97f1f5b4e6a743d8e278d3f3a176b69735c /arch
parent9d634c410b07be7bf637ea03362d3ff132088fe3 (diff)
x86/cpu: Restore MSR_IA32_ENERGY_PERF_BIAS after resume
MSR_IA32_ENERGY_PERF_BIAS is lost after suspend/resume: x86_energy_perf_policy -r before cpu0: 0x0000000000000006 cpu1: 0x0000000000000006 cpu2: 0x0000000000000006 cpu3: 0x0000000000000006 cpu4: 0x0000000000000006 cpu5: 0x0000000000000006 cpu6: 0x0000000000000006 cpu7: 0x0000000000000006 after cpu0: 0x0000000000000000 cpu1: 0x0000000000000006 cpu2: 0x0000000000000006 cpu3: 0x0000000000000006 cpu4: 0x0000000000000006 cpu5: 0x0000000000000006 cpu6: 0x0000000000000006 cpu7: 0x0000000000000006 Resulting in inconsistent energy policy settings across CPUs. This register is set via init_intel() at bootup. During resume, the secondary CPUs are brought online again and init_intel() is callled which re-initializes the register. The boot CPU however never reinitializes the register. Add a syscore callback to reinitialize the register for the boot CPU. Signed-off-by: Laura Abbott <labbott@fedoraproject.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Borislav Petkov <bp@alien8.de> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/1437428878-4105-1-git-send-email-labbott@fedoraproject.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/cpu/common.c18
-rw-r--r--arch/x86/kernel/cpu/cpu.h1
-rw-r--r--arch/x86/kernel/cpu/intel.c47
3 files changed, 51 insertions, 15 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 922c5e0cea4c..fa95bb8829ce 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -13,6 +13,7 @@
13#include <linux/kgdb.h> 13#include <linux/kgdb.h>
14#include <linux/smp.h> 14#include <linux/smp.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/syscore_ops.h>
16 17
17#include <asm/stackprotector.h> 18#include <asm/stackprotector.h>
18#include <asm/perf_event.h> 19#include <asm/perf_event.h>
@@ -1488,3 +1489,20 @@ inline bool __static_cpu_has_safe(u16 bit)
1488 return boot_cpu_has(bit); 1489 return boot_cpu_has(bit);
1489} 1490}
1490EXPORT_SYMBOL_GPL(__static_cpu_has_safe); 1491EXPORT_SYMBOL_GPL(__static_cpu_has_safe);
1492
1493static void bsp_resume(void)
1494{
1495 if (this_cpu->c_bsp_resume)
1496 this_cpu->c_bsp_resume(&boot_cpu_data);
1497}
1498
1499static struct syscore_ops cpu_syscore_ops = {
1500 .resume = bsp_resume,
1501};
1502
1503static int __init init_cpu_syscore(void)
1504{
1505 register_syscore_ops(&cpu_syscore_ops);
1506 return 0;
1507}
1508core_initcall(init_cpu_syscore);
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
index c37dc37e8317..2584265d4745 100644
--- a/arch/x86/kernel/cpu/cpu.h
+++ b/arch/x86/kernel/cpu/cpu.h
@@ -13,6 +13,7 @@ struct cpu_dev {
13 void (*c_init)(struct cpuinfo_x86 *); 13 void (*c_init)(struct cpuinfo_x86 *);
14 void (*c_identify)(struct cpuinfo_x86 *); 14 void (*c_identify)(struct cpuinfo_x86 *);
15 void (*c_detect_tlb)(struct cpuinfo_x86 *); 15 void (*c_detect_tlb)(struct cpuinfo_x86 *);
16 void (*c_bsp_resume)(struct cpuinfo_x86 *);
16 int c_x86_vendor; 17 int c_x86_vendor;
17#ifdef CONFIG_X86_32 18#ifdef CONFIG_X86_32
18 /* Optional vendor specific routine to obtain the cache size. */ 19 /* Optional vendor specific routine to obtain the cache size. */
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 50163fa9034f..98a13db5f4be 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -371,6 +371,36 @@ static void detect_vmx_virtcap(struct cpuinfo_x86 *c)
371 } 371 }
372} 372}
373 373
374static void init_intel_energy_perf(struct cpuinfo_x86 *c)
375{
376 u64 epb;
377
378 /*
379 * Initialize MSR_IA32_ENERGY_PERF_BIAS if not already initialized.
380 * (x86_energy_perf_policy(8) is available to change it at run-time.)
381 */
382 if (!cpu_has(c, X86_FEATURE_EPB))
383 return;
384
385 rdmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb);
386 if ((epb & 0xF) != ENERGY_PERF_BIAS_PERFORMANCE)
387 return;
388
389 pr_warn_once("ENERGY_PERF_BIAS: Set to 'normal', was 'performance'\n");
390 pr_warn_once("ENERGY_PERF_BIAS: View and update with x86_energy_perf_policy(8)\n");
391 epb = (epb & ~0xF) | ENERGY_PERF_BIAS_NORMAL;
392 wrmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb);
393}
394
395static void intel_bsp_resume(struct cpuinfo_x86 *c)
396{
397 /*
398 * MSR_IA32_ENERGY_PERF_BIAS is lost across suspend/resume,
399 * so reinitialize it properly like during bootup:
400 */
401 init_intel_energy_perf(c);
402}
403
374static void init_intel(struct cpuinfo_x86 *c) 404static void init_intel(struct cpuinfo_x86 *c)
375{ 405{
376 unsigned int l2 = 0; 406 unsigned int l2 = 0;
@@ -478,21 +508,7 @@ static void init_intel(struct cpuinfo_x86 *c)
478 if (cpu_has(c, X86_FEATURE_VMX)) 508 if (cpu_has(c, X86_FEATURE_VMX))
479 detect_vmx_virtcap(c); 509 detect_vmx_virtcap(c);
480 510
481 /* 511 init_intel_energy_perf(c);
482 * Initialize MSR_IA32_ENERGY_PERF_BIAS if BIOS did not.
483 * x86_energy_perf_policy(8) is available to change it at run-time
484 */
485 if (cpu_has(c, X86_FEATURE_EPB)) {
486 u64 epb;
487
488 rdmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb);
489 if ((epb & 0xF) == ENERGY_PERF_BIAS_PERFORMANCE) {
490 pr_warn_once("ENERGY_PERF_BIAS: Set to 'normal', was 'performance'\n");
491 pr_warn_once("ENERGY_PERF_BIAS: View and update with x86_energy_perf_policy(8)\n");
492 epb = (epb & ~0xF) | ENERGY_PERF_BIAS_NORMAL;
493 wrmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb);
494 }
495 }
496} 512}
497 513
498#ifdef CONFIG_X86_32 514#ifdef CONFIG_X86_32
@@ -747,6 +763,7 @@ static const struct cpu_dev intel_cpu_dev = {
747 .c_detect_tlb = intel_detect_tlb, 763 .c_detect_tlb = intel_detect_tlb,
748 .c_early_init = early_init_intel, 764 .c_early_init = early_init_intel,
749 .c_init = init_intel, 765 .c_init = init_intel,
766 .c_bsp_resume = intel_bsp_resume,
750 .c_x86_vendor = X86_VENDOR_INTEL, 767 .c_x86_vendor = X86_VENDOR_INTEL,
751}; 768};
752 769