aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/msr-index.h2
-rw-r--r--arch/x86/kernel/process.c32
2 files changed, 26 insertions, 8 deletions
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 1cd58cdbc03f..4604e6a54d36 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -105,6 +105,8 @@
105#define MSR_AMD64_PATCH_LEVEL 0x0000008b 105#define MSR_AMD64_PATCH_LEVEL 0x0000008b
106#define MSR_AMD64_NB_CFG 0xc001001f 106#define MSR_AMD64_NB_CFG 0xc001001f
107#define MSR_AMD64_PATCH_LOADER 0xc0010020 107#define MSR_AMD64_PATCH_LOADER 0xc0010020
108#define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140
109#define MSR_AMD64_OSVW_STATUS 0xc0010141
108#define MSR_AMD64_IBSFETCHCTL 0xc0011030 110#define MSR_AMD64_IBSFETCHCTL 0xc0011030
109#define MSR_AMD64_IBSFETCHLINAD 0xc0011031 111#define MSR_AMD64_IBSFETCHLINAD 0xc0011031
110#define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032 112#define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index c9b3522b6b46..999c8a6a4e7a 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -519,21 +519,37 @@ static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c)
519} 519}
520 520
521/* 521/*
522 * Check for AMD CPUs, which have potentially C1E support 522 * Check for AMD CPUs, where APIC timer interrupt does not wake up CPU from C1e.
523 * For more information see
524 * - Erratum #400 for NPT family 0xf and family 0x10 CPUs
525 * - Erratum #365 for family 0x11 (not affected because C1e not in use)
523 */ 526 */
524static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c) 527static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c)
525{ 528{
529 u64 val;
526 if (c->x86_vendor != X86_VENDOR_AMD) 530 if (c->x86_vendor != X86_VENDOR_AMD)
527 return 0; 531 goto no_c1e_idle;
528
529 if (c->x86 < 0x0F)
530 return 0;
531 532
532 /* Family 0x0f models < rev F do not have C1E */ 533 /* Family 0x0f models < rev F do not have C1E */
533 if (c->x86 == 0x0f && c->x86_model < 0x40) 534 if (c->x86 == 0x0F && c->x86_model >= 0x40)
534 return 0; 535 return 1;
535 536
536 return 1; 537 if (c->x86 == 0x10) {
538 /*
539 * check OSVW bit for CPUs that are not affected
540 * by erratum #400
541 */
542 rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, val);
543 if (val >= 2) {
544 rdmsrl(MSR_AMD64_OSVW_STATUS, val);
545 if (!(val & BIT(1)))
546 goto no_c1e_idle;
547 }
548 return 1;
549 }
550
551no_c1e_idle:
552 return 0;
537} 553}
538 554
539static cpumask_var_t c1e_mask; 555static cpumask_var_t c1e_mask;