diff options
Diffstat (limited to 'arch/x86/kernel/cpu/common.c')
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 45 |
1 files changed, 32 insertions, 13 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index fb789dd9e691..25581dcb280e 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -124,18 +124,25 @@ static inline int flag_is_changeable_p(u32 flag) | |||
124 | { | 124 | { |
125 | u32 f1, f2; | 125 | u32 f1, f2; |
126 | 126 | ||
127 | asm("pushfl\n\t" | 127 | /* |
128 | "pushfl\n\t" | 128 | * Cyrix and IDT cpus allow disabling of CPUID |
129 | "popl %0\n\t" | 129 | * so the code below may return different results |
130 | "movl %0,%1\n\t" | 130 | * when it is executed before and after enabling |
131 | "xorl %2,%0\n\t" | 131 | * the CPUID. Add "volatile" to not allow gcc to |
132 | "pushl %0\n\t" | 132 | * optimize the subsequent calls to this function. |
133 | "popfl\n\t" | 133 | */ |
134 | "pushfl\n\t" | 134 | asm volatile ("pushfl\n\t" |
135 | "popl %0\n\t" | 135 | "pushfl\n\t" |
136 | "popfl\n\t" | 136 | "popl %0\n\t" |
137 | : "=&r" (f1), "=&r" (f2) | 137 | "movl %0,%1\n\t" |
138 | : "ir" (flag)); | 138 | "xorl %2,%0\n\t" |
139 | "pushl %0\n\t" | ||
140 | "popfl\n\t" | ||
141 | "pushfl\n\t" | ||
142 | "popl %0\n\t" | ||
143 | "popfl\n\t" | ||
144 | : "=&r" (f1), "=&r" (f2) | ||
145 | : "ir" (flag)); | ||
139 | 146 | ||
140 | return ((f1^f2) & flag) != 0; | 147 | return ((f1^f2) & flag) != 0; |
141 | } | 148 | } |
@@ -719,12 +726,24 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
719 | #endif | 726 | #endif |
720 | } | 727 | } |
721 | 728 | ||
729 | #ifdef CONFIG_X86_64 | ||
730 | static void vgetcpu_set_mode(void) | ||
731 | { | ||
732 | if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP)) | ||
733 | vgetcpu_mode = VGETCPU_RDTSCP; | ||
734 | else | ||
735 | vgetcpu_mode = VGETCPU_LSL; | ||
736 | } | ||
737 | #endif | ||
738 | |||
722 | void __init identify_boot_cpu(void) | 739 | void __init identify_boot_cpu(void) |
723 | { | 740 | { |
724 | identify_cpu(&boot_cpu_data); | 741 | identify_cpu(&boot_cpu_data); |
725 | #ifdef CONFIG_X86_32 | 742 | #ifdef CONFIG_X86_32 |
726 | sysenter_setup(); | 743 | sysenter_setup(); |
727 | enable_sep_cpu(); | 744 | enable_sep_cpu(); |
745 | #else | ||
746 | vgetcpu_set_mode(); | ||
728 | #endif | 747 | #endif |
729 | } | 748 | } |
730 | 749 | ||
@@ -797,7 +816,7 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) | |||
797 | else if (c->cpuid_level >= 0) | 816 | else if (c->cpuid_level >= 0) |
798 | vendor = c->x86_vendor_id; | 817 | vendor = c->x86_vendor_id; |
799 | 818 | ||
800 | if (vendor && strncmp(c->x86_model_id, vendor, strlen(vendor))) | 819 | if (vendor && !strstr(c->x86_model_id, vendor)) |
801 | printk(KERN_CONT "%s ", vendor); | 820 | printk(KERN_CONT "%s ", vendor); |
802 | 821 | ||
803 | if (c->x86_model_id[0]) | 822 | if (c->x86_model_id[0]) |