diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/process.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index b3078f4ce25b..fe415ba606e0 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -122,19 +122,31 @@ static void poll_idle(void) | |||
122 | * | 122 | * |
123 | * idle=mwait overrides this decision and forces the usage of mwait. | 123 | * idle=mwait overrides this decision and forces the usage of mwait. |
124 | */ | 124 | */ |
125 | |||
126 | #define MWAIT_INFO 0x05 | ||
127 | #define MWAIT_ECX_EXTENDED_INFO 0x01 | ||
128 | #define MWAIT_EDX_C1 0xf0 | ||
129 | |||
125 | static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c) | 130 | static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c) |
126 | { | 131 | { |
132 | u32 eax, ebx, ecx, edx; | ||
133 | |||
127 | if (force_mwait) | 134 | if (force_mwait) |
128 | return 1; | 135 | return 1; |
129 | 136 | ||
130 | if (c->x86_vendor == X86_VENDOR_AMD) { | 137 | if (c->cpuid_level < MWAIT_INFO) |
131 | switch(c->x86) { | 138 | return 0; |
132 | case 0x10: | 139 | |
133 | case 0x11: | 140 | cpuid(MWAIT_INFO, &eax, &ebx, &ecx, &edx); |
134 | return 0; | 141 | /* Check, whether EDX has extended info about MWAIT */ |
135 | } | 142 | if (!(ecx & MWAIT_ECX_EXTENDED_INFO)) |
136 | } | 143 | return 1; |
137 | return 1; | 144 | |
145 | /* | ||
146 | * edx enumeratios MONITOR/MWAIT extensions. Check, whether | ||
147 | * C1 supports MWAIT | ||
148 | */ | ||
149 | return (edx & MWAIT_EDX_C1); | ||
138 | } | 150 | } |
139 | 151 | ||
140 | void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) | 152 | void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) |