diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/msr-index.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/process.c | 32 |
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 | */ |
524 | static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c) | 527 | static 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 | |||
551 | no_c1e_idle: | ||
552 | return 0; | ||
537 | } | 553 | } |
538 | 554 | ||
539 | static cpumask_var_t c1e_mask; | 555 | static cpumask_var_t c1e_mask; |