diff options
Diffstat (limited to 'arch/x86/kernel/cpu')
-rw-r--r-- | arch/x86/kernel/cpu/amd.c | 5 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/centaur.c | 272 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel.c | 10 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/microcode/amd_early.c | 43 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mtrr/generic.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 11 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.h | 1 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel.c | 11 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_uncore.c | 10 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_p6.c | 48 |
11 files changed, 96 insertions, 326 deletions
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index d3153e281d72..c67ffa686064 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -767,10 +767,7 @@ static unsigned int amd_size_cache(struct cpuinfo_x86 *c, unsigned int size) | |||
767 | 767 | ||
768 | static void cpu_set_tlb_flushall_shift(struct cpuinfo_x86 *c) | 768 | static void cpu_set_tlb_flushall_shift(struct cpuinfo_x86 *c) |
769 | { | 769 | { |
770 | tlb_flushall_shift = 5; | 770 | tlb_flushall_shift = 6; |
771 | |||
772 | if (c->x86 <= 0x11) | ||
773 | tlb_flushall_shift = 4; | ||
774 | } | 771 | } |
775 | 772 | ||
776 | static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c) | 773 | static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c) |
diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c index 8779edab684e..d8fba5c15fbd 100644 --- a/arch/x86/kernel/cpu/centaur.c +++ b/arch/x86/kernel/cpu/centaur.c | |||
@@ -8,236 +8,6 @@ | |||
8 | 8 | ||
9 | #include "cpu.h" | 9 | #include "cpu.h" |
10 | 10 | ||
11 | #ifdef CONFIG_X86_OOSTORE | ||
12 | |||
13 | static u32 power2(u32 x) | ||
14 | { | ||
15 | u32 s = 1; | ||
16 | |||
17 | while (s <= x) | ||
18 | s <<= 1; | ||
19 | |||
20 | return s >>= 1; | ||
21 | } | ||
22 | |||
23 | |||
24 | /* | ||
25 | * Set up an actual MCR | ||
26 | */ | ||
27 | static void centaur_mcr_insert(int reg, u32 base, u32 size, int key) | ||
28 | { | ||
29 | u32 lo, hi; | ||
30 | |||
31 | hi = base & ~0xFFF; | ||
32 | lo = ~(size-1); /* Size is a power of 2 so this makes a mask */ | ||
33 | lo &= ~0xFFF; /* Remove the ctrl value bits */ | ||
34 | lo |= key; /* Attribute we wish to set */ | ||
35 | wrmsr(reg+MSR_IDT_MCR0, lo, hi); | ||
36 | mtrr_centaur_report_mcr(reg, lo, hi); /* Tell the mtrr driver */ | ||
37 | } | ||
38 | |||
39 | /* | ||
40 | * Figure what we can cover with MCR's | ||
41 | * | ||
42 | * Shortcut: We know you can't put 4Gig of RAM on a winchip | ||
43 | */ | ||
44 | static u32 ramtop(void) | ||
45 | { | ||
46 | u32 clip = 0xFFFFFFFFUL; | ||
47 | u32 top = 0; | ||
48 | int i; | ||
49 | |||
50 | for (i = 0; i < e820.nr_map; i++) { | ||
51 | unsigned long start, end; | ||
52 | |||
53 | if (e820.map[i].addr > 0xFFFFFFFFUL) | ||
54 | continue; | ||
55 | /* | ||
56 | * Don't MCR over reserved space. Ignore the ISA hole | ||
57 | * we frob around that catastrophe already | ||
58 | */ | ||
59 | if (e820.map[i].type == E820_RESERVED) { | ||
60 | if (e820.map[i].addr >= 0x100000UL && | ||
61 | e820.map[i].addr < clip) | ||
62 | clip = e820.map[i].addr; | ||
63 | continue; | ||
64 | } | ||
65 | start = e820.map[i].addr; | ||
66 | end = e820.map[i].addr + e820.map[i].size; | ||
67 | if (start >= end) | ||
68 | continue; | ||
69 | if (end > top) | ||
70 | top = end; | ||
71 | } | ||
72 | /* | ||
73 | * Everything below 'top' should be RAM except for the ISA hole. | ||
74 | * Because of the limited MCR's we want to map NV/ACPI into our | ||
75 | * MCR range for gunk in RAM | ||
76 | * | ||
77 | * Clip might cause us to MCR insufficient RAM but that is an | ||
78 | * acceptable failure mode and should only bite obscure boxes with | ||
79 | * a VESA hole at 15Mb | ||
80 | * | ||
81 | * The second case Clip sometimes kicks in is when the EBDA is marked | ||
82 | * as reserved. Again we fail safe with reasonable results | ||
83 | */ | ||
84 | if (top > clip) | ||
85 | top = clip; | ||
86 | |||
87 | return top; | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * Compute a set of MCR's to give maximum coverage | ||
92 | */ | ||
93 | static int centaur_mcr_compute(int nr, int key) | ||
94 | { | ||
95 | u32 mem = ramtop(); | ||
96 | u32 root = power2(mem); | ||
97 | u32 base = root; | ||
98 | u32 top = root; | ||
99 | u32 floor = 0; | ||
100 | int ct = 0; | ||
101 | |||
102 | while (ct < nr) { | ||
103 | u32 fspace = 0; | ||
104 | u32 high; | ||
105 | u32 low; | ||
106 | |||
107 | /* | ||
108 | * Find the largest block we will fill going upwards | ||
109 | */ | ||
110 | high = power2(mem-top); | ||
111 | |||
112 | /* | ||
113 | * Find the largest block we will fill going downwards | ||
114 | */ | ||
115 | low = base/2; | ||
116 | |||
117 | /* | ||
118 | * Don't fill below 1Mb going downwards as there | ||
119 | * is an ISA hole in the way. | ||
120 | */ | ||
121 | if (base <= 1024*1024) | ||
122 | low = 0; | ||
123 | |||
124 | /* | ||
125 | * See how much space we could cover by filling below | ||
126 | * the ISA hole | ||
127 | */ | ||
128 | |||
129 | if (floor == 0) | ||
130 | fspace = 512*1024; | ||
131 | else if (floor == 512*1024) | ||
132 | fspace = 128*1024; | ||
133 | |||
134 | /* And forget ROM space */ | ||
135 | |||
136 | /* | ||
137 | * Now install the largest coverage we get | ||
138 | */ | ||
139 | if (fspace > high && fspace > low) { | ||
140 | centaur_mcr_insert(ct, floor, fspace, key); | ||
141 | floor += fspace; | ||
142 | } else if (high > low) { | ||
143 | centaur_mcr_insert(ct, top, high, key); | ||
144 | top += high; | ||
145 | } else if (low > 0) { | ||
146 | base -= low; | ||
147 | centaur_mcr_insert(ct, base, low, key); | ||
148 | } else | ||
149 | break; | ||
150 | ct++; | ||
151 | } | ||
152 | /* | ||
153 | * We loaded ct values. We now need to set the mask. The caller | ||
154 | * must do this bit. | ||
155 | */ | ||
156 | return ct; | ||
157 | } | ||
158 | |||
159 | static void centaur_create_optimal_mcr(void) | ||
160 | { | ||
161 | int used; | ||
162 | int i; | ||
163 | |||
164 | /* | ||
165 | * Allocate up to 6 mcrs to mark as much of ram as possible | ||
166 | * as write combining and weak write ordered. | ||
167 | * | ||
168 | * To experiment with: Linux never uses stack operations for | ||
169 | * mmio spaces so we could globally enable stack operation wc | ||
170 | * | ||
171 | * Load the registers with type 31 - full write combining, all | ||
172 | * writes weakly ordered. | ||
173 | */ | ||
174 | used = centaur_mcr_compute(6, 31); | ||
175 | |||
176 | /* | ||
177 | * Wipe unused MCRs | ||
178 | */ | ||
179 | for (i = used; i < 8; i++) | ||
180 | wrmsr(MSR_IDT_MCR0+i, 0, 0); | ||
181 | } | ||
182 | |||
183 | static void winchip2_create_optimal_mcr(void) | ||
184 | { | ||
185 | u32 lo, hi; | ||
186 | int used; | ||
187 | int i; | ||
188 | |||
189 | /* | ||
190 | * Allocate up to 6 mcrs to mark as much of ram as possible | ||
191 | * as write combining, weak store ordered. | ||
192 | * | ||
193 | * Load the registers with type 25 | ||
194 | * 8 - weak write ordering | ||
195 | * 16 - weak read ordering | ||
196 | * 1 - write combining | ||
197 | */ | ||
198 | used = centaur_mcr_compute(6, 25); | ||
199 | |||
200 | /* | ||
201 | * Mark the registers we are using. | ||
202 | */ | ||
203 | rdmsr(MSR_IDT_MCR_CTRL, lo, hi); | ||
204 | for (i = 0; i < used; i++) | ||
205 | lo |= 1<<(9+i); | ||
206 | wrmsr(MSR_IDT_MCR_CTRL, lo, hi); | ||
207 | |||
208 | /* | ||
209 | * Wipe unused MCRs | ||
210 | */ | ||
211 | |||
212 | for (i = used; i < 8; i++) | ||
213 | wrmsr(MSR_IDT_MCR0+i, 0, 0); | ||
214 | } | ||
215 | |||
216 | /* | ||
217 | * Handle the MCR key on the Winchip 2. | ||
218 | */ | ||
219 | static void winchip2_unprotect_mcr(void) | ||
220 | { | ||
221 | u32 lo, hi; | ||
222 | u32 key; | ||
223 | |||
224 | rdmsr(MSR_IDT_MCR_CTRL, lo, hi); | ||
225 | lo &= ~0x1C0; /* blank bits 8-6 */ | ||
226 | key = (lo>>17) & 7; | ||
227 | lo |= key<<6; /* replace with unlock key */ | ||
228 | wrmsr(MSR_IDT_MCR_CTRL, lo, hi); | ||
229 | } | ||
230 | |||
231 | static void winchip2_protect_mcr(void) | ||
232 | { | ||
233 | u32 lo, hi; | ||
234 | |||
235 | rdmsr(MSR_IDT_MCR_CTRL, lo, hi); | ||
236 | lo &= ~0x1C0; /* blank bits 8-6 */ | ||
237 | wrmsr(MSR_IDT_MCR_CTRL, lo, hi); | ||
238 | } | ||
239 | #endif /* CONFIG_X86_OOSTORE */ | ||
240 | |||
241 | #define ACE_PRESENT (1 << 6) | 11 | #define ACE_PRESENT (1 << 6) |
242 | #define ACE_ENABLED (1 << 7) | 12 | #define ACE_ENABLED (1 << 7) |
243 | #define ACE_FCR (1 << 28) /* MSR_VIA_FCR */ | 13 | #define ACE_FCR (1 << 28) /* MSR_VIA_FCR */ |
@@ -362,20 +132,6 @@ static void init_centaur(struct cpuinfo_x86 *c) | |||
362 | fcr_clr = DPDC; | 132 | fcr_clr = DPDC; |
363 | printk(KERN_NOTICE "Disabling bugged TSC.\n"); | 133 | printk(KERN_NOTICE "Disabling bugged TSC.\n"); |
364 | clear_cpu_cap(c, X86_FEATURE_TSC); | 134 | clear_cpu_cap(c, X86_FEATURE_TSC); |
365 | #ifdef CONFIG_X86_OOSTORE | ||
366 | centaur_create_optimal_mcr(); | ||
367 | /* | ||
368 | * Enable: | ||
369 | * write combining on non-stack, non-string | ||
370 | * write combining on string, all types | ||
371 | * weak write ordering | ||
372 | * | ||
373 | * The C6 original lacks weak read order | ||
374 | * | ||
375 | * Note 0x120 is write only on Winchip 1 | ||
376 | */ | ||
377 | wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0); | ||
378 | #endif | ||
379 | break; | 135 | break; |
380 | case 8: | 136 | case 8: |
381 | switch (c->x86_mask) { | 137 | switch (c->x86_mask) { |
@@ -392,40 +148,12 @@ static void init_centaur(struct cpuinfo_x86 *c) | |||
392 | fcr_set = ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK| | 148 | fcr_set = ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK| |
393 | E2MMX|EAMD3D; | 149 | E2MMX|EAMD3D; |
394 | fcr_clr = DPDC; | 150 | fcr_clr = DPDC; |
395 | #ifdef CONFIG_X86_OOSTORE | ||
396 | winchip2_unprotect_mcr(); | ||
397 | winchip2_create_optimal_mcr(); | ||
398 | rdmsr(MSR_IDT_MCR_CTRL, lo, hi); | ||
399 | /* | ||
400 | * Enable: | ||
401 | * write combining on non-stack, non-string | ||
402 | * write combining on string, all types | ||
403 | * weak write ordering | ||
404 | */ | ||
405 | lo |= 31; | ||
406 | wrmsr(MSR_IDT_MCR_CTRL, lo, hi); | ||
407 | winchip2_protect_mcr(); | ||
408 | #endif | ||
409 | break; | 151 | break; |
410 | case 9: | 152 | case 9: |
411 | name = "3"; | 153 | name = "3"; |
412 | fcr_set = ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK| | 154 | fcr_set = ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK| |
413 | E2MMX|EAMD3D; | 155 | E2MMX|EAMD3D; |
414 | fcr_clr = DPDC; | 156 | fcr_clr = DPDC; |
415 | #ifdef CONFIG_X86_OOSTORE | ||
416 | winchip2_unprotect_mcr(); | ||
417 | winchip2_create_optimal_mcr(); | ||
418 | rdmsr(MSR_IDT_MCR_CTRL, lo, hi); | ||
419 | /* | ||
420 | * Enable: | ||
421 | * write combining on non-stack, non-string | ||
422 | * write combining on string, all types | ||
423 | * weak write ordering | ||
424 | */ | ||
425 | lo |= 31; | ||
426 | wrmsr(MSR_IDT_MCR_CTRL, lo, hi); | ||
427 | winchip2_protect_mcr(); | ||
428 | #endif | ||
429 | break; | 157 | break; |
430 | default: | 158 | default: |
431 | name = "??"; | 159 | name = "??"; |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 24b6fd10625a..8e28bf2fc3ef 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -284,8 +284,13 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c) | |||
284 | raw_local_save_flags(eflags); | 284 | raw_local_save_flags(eflags); |
285 | BUG_ON(eflags & X86_EFLAGS_AC); | 285 | BUG_ON(eflags & X86_EFLAGS_AC); |
286 | 286 | ||
287 | if (cpu_has(c, X86_FEATURE_SMAP)) | 287 | if (cpu_has(c, X86_FEATURE_SMAP)) { |
288 | #ifdef CONFIG_X86_SMAP | ||
288 | set_in_cr4(X86_CR4_SMAP); | 289 | set_in_cr4(X86_CR4_SMAP); |
290 | #else | ||
291 | clear_in_cr4(X86_CR4_SMAP); | ||
292 | #endif | ||
293 | } | ||
289 | } | 294 | } |
290 | 295 | ||
291 | /* | 296 | /* |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 3db61c644e44..5cd9bfabd645 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -640,21 +640,17 @@ static void intel_tlb_flushall_shift_set(struct cpuinfo_x86 *c) | |||
640 | case 0x61d: /* six-core 45 nm xeon "Dunnington" */ | 640 | case 0x61d: /* six-core 45 nm xeon "Dunnington" */ |
641 | tlb_flushall_shift = -1; | 641 | tlb_flushall_shift = -1; |
642 | break; | 642 | break; |
643 | case 0x63a: /* Ivybridge */ | ||
644 | tlb_flushall_shift = 2; | ||
645 | break; | ||
643 | case 0x61a: /* 45 nm nehalem, "Bloomfield" */ | 646 | case 0x61a: /* 45 nm nehalem, "Bloomfield" */ |
644 | case 0x61e: /* 45 nm nehalem, "Lynnfield" */ | 647 | case 0x61e: /* 45 nm nehalem, "Lynnfield" */ |
645 | case 0x625: /* 32 nm nehalem, "Clarkdale" */ | 648 | case 0x625: /* 32 nm nehalem, "Clarkdale" */ |
646 | case 0x62c: /* 32 nm nehalem, "Gulftown" */ | 649 | case 0x62c: /* 32 nm nehalem, "Gulftown" */ |
647 | case 0x62e: /* 45 nm nehalem-ex, "Beckton" */ | 650 | case 0x62e: /* 45 nm nehalem-ex, "Beckton" */ |
648 | case 0x62f: /* 32 nm Xeon E7 */ | 651 | case 0x62f: /* 32 nm Xeon E7 */ |
649 | tlb_flushall_shift = 6; | ||
650 | break; | ||
651 | case 0x62a: /* SandyBridge */ | 652 | case 0x62a: /* SandyBridge */ |
652 | case 0x62d: /* SandyBridge, "Romely-EP" */ | 653 | case 0x62d: /* SandyBridge, "Romely-EP" */ |
653 | tlb_flushall_shift = 5; | ||
654 | break; | ||
655 | case 0x63a: /* Ivybridge */ | ||
656 | tlb_flushall_shift = 1; | ||
657 | break; | ||
658 | default: | 654 | default: |
659 | tlb_flushall_shift = 6; | 655 | tlb_flushall_shift = 6; |
660 | } | 656 | } |
diff --git a/arch/x86/kernel/cpu/microcode/amd_early.c b/arch/x86/kernel/cpu/microcode/amd_early.c index 8384c0fa206f..617a9e284245 100644 --- a/arch/x86/kernel/cpu/microcode/amd_early.c +++ b/arch/x86/kernel/cpu/microcode/amd_early.c | |||
@@ -285,6 +285,15 @@ static void __init collect_cpu_sig_on_bsp(void *arg) | |||
285 | 285 | ||
286 | uci->cpu_sig.sig = cpuid_eax(0x00000001); | 286 | uci->cpu_sig.sig = cpuid_eax(0x00000001); |
287 | } | 287 | } |
288 | |||
289 | static void __init get_bsp_sig(void) | ||
290 | { | ||
291 | unsigned int bsp = boot_cpu_data.cpu_index; | ||
292 | struct ucode_cpu_info *uci = ucode_cpu_info + bsp; | ||
293 | |||
294 | if (!uci->cpu_sig.sig) | ||
295 | smp_call_function_single(bsp, collect_cpu_sig_on_bsp, NULL, 1); | ||
296 | } | ||
288 | #else | 297 | #else |
289 | void load_ucode_amd_ap(void) | 298 | void load_ucode_amd_ap(void) |
290 | { | 299 | { |
@@ -337,31 +346,37 @@ void load_ucode_amd_ap(void) | |||
337 | 346 | ||
338 | int __init save_microcode_in_initrd_amd(void) | 347 | int __init save_microcode_in_initrd_amd(void) |
339 | { | 348 | { |
349 | unsigned long cont; | ||
340 | enum ucode_state ret; | 350 | enum ucode_state ret; |
341 | u32 eax; | 351 | u32 eax; |
342 | 352 | ||
343 | #ifdef CONFIG_X86_32 | 353 | if (!container) |
344 | unsigned int bsp = boot_cpu_data.cpu_index; | 354 | return -EINVAL; |
345 | struct ucode_cpu_info *uci = ucode_cpu_info + bsp; | ||
346 | |||
347 | if (!uci->cpu_sig.sig) | ||
348 | smp_call_function_single(bsp, collect_cpu_sig_on_bsp, NULL, 1); | ||
349 | 355 | ||
356 | #ifdef CONFIG_X86_32 | ||
357 | get_bsp_sig(); | ||
358 | cont = (unsigned long)container; | ||
359 | #else | ||
350 | /* | 360 | /* |
351 | * Take into account the fact that the ramdisk might get relocated | 361 | * We need the physical address of the container for both bitness since |
352 | * and therefore we need to recompute the container's position in | 362 | * boot_params.hdr.ramdisk_image is a physical address. |
353 | * virtual memory space. | ||
354 | */ | 363 | */ |
355 | container = (u8 *)(__va((u32)relocated_ramdisk) + | 364 | cont = __pa(container); |
356 | ((u32)container - boot_params.hdr.ramdisk_image)); | ||
357 | #endif | 365 | #endif |
366 | |||
367 | /* | ||
368 | * Take into account the fact that the ramdisk might get relocated and | ||
369 | * therefore we need to recompute the container's position in virtual | ||
370 | * memory space. | ||
371 | */ | ||
372 | if (relocated_ramdisk) | ||
373 | container = (u8 *)(__va(relocated_ramdisk) + | ||
374 | (cont - boot_params.hdr.ramdisk_image)); | ||
375 | |||
358 | if (ucode_new_rev) | 376 | if (ucode_new_rev) |
359 | pr_info("microcode: updated early to new patch_level=0x%08x\n", | 377 | pr_info("microcode: updated early to new patch_level=0x%08x\n", |
360 | ucode_new_rev); | 378 | ucode_new_rev); |
361 | 379 | ||
362 | if (!container) | ||
363 | return -EINVAL; | ||
364 | |||
365 | eax = cpuid_eax(0x00000001); | 380 | eax = cpuid_eax(0x00000001); |
366 | eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); | 381 | eax = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); |
367 | 382 | ||
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index ce2d0a2c3e4f..0e25a1bc5ab5 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c | |||
@@ -683,7 +683,7 @@ static void prepare_set(void) __acquires(set_atomicity_lock) | |||
683 | } | 683 | } |
684 | 684 | ||
685 | /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */ | 685 | /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */ |
686 | count_vm_event(NR_TLB_LOCAL_FLUSH_ALL); | 686 | count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL); |
687 | __flush_tlb(); | 687 | __flush_tlb(); |
688 | 688 | ||
689 | /* Save MTRR state */ | 689 | /* Save MTRR state */ |
@@ -697,7 +697,7 @@ static void prepare_set(void) __acquires(set_atomicity_lock) | |||
697 | static void post_set(void) __releases(set_atomicity_lock) | 697 | static void post_set(void) __releases(set_atomicity_lock) |
698 | { | 698 | { |
699 | /* Flush TLBs (no need to flush caches - they are disabled) */ | 699 | /* Flush TLBs (no need to flush caches - they are disabled) */ |
700 | count_vm_event(NR_TLB_LOCAL_FLUSH_ALL); | 700 | count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL); |
701 | __flush_tlb(); | 701 | __flush_tlb(); |
702 | 702 | ||
703 | /* Intel (P6) standard MTRRs */ | 703 | /* Intel (P6) standard MTRRs */ |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index b88645191fe5..79f9f848bee4 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -1192,6 +1192,9 @@ static void x86_pmu_del(struct perf_event *event, int flags) | |||
1192 | for (i = 0; i < cpuc->n_events; i++) { | 1192 | for (i = 0; i < cpuc->n_events; i++) { |
1193 | if (event == cpuc->event_list[i]) { | 1193 | if (event == cpuc->event_list[i]) { |
1194 | 1194 | ||
1195 | if (i >= cpuc->n_events - cpuc->n_added) | ||
1196 | --cpuc->n_added; | ||
1197 | |||
1195 | if (x86_pmu.put_event_constraints) | 1198 | if (x86_pmu.put_event_constraints) |
1196 | x86_pmu.put_event_constraints(cpuc, event); | 1199 | x86_pmu.put_event_constraints(cpuc, event); |
1197 | 1200 | ||
@@ -1521,6 +1524,8 @@ static int __init init_hw_perf_events(void) | |||
1521 | 1524 | ||
1522 | pr_cont("%s PMU driver.\n", x86_pmu.name); | 1525 | pr_cont("%s PMU driver.\n", x86_pmu.name); |
1523 | 1526 | ||
1527 | x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */ | ||
1528 | |||
1524 | for (quirk = x86_pmu.quirks; quirk; quirk = quirk->next) | 1529 | for (quirk = x86_pmu.quirks; quirk; quirk = quirk->next) |
1525 | quirk->func(); | 1530 | quirk->func(); |
1526 | 1531 | ||
@@ -1534,7 +1539,6 @@ static int __init init_hw_perf_events(void) | |||
1534 | __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1, | 1539 | __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1, |
1535 | 0, x86_pmu.num_counters, 0, 0); | 1540 | 0, x86_pmu.num_counters, 0, 0); |
1536 | 1541 | ||
1537 | x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */ | ||
1538 | x86_pmu_format_group.attrs = x86_pmu.format_attrs; | 1542 | x86_pmu_format_group.attrs = x86_pmu.format_attrs; |
1539 | 1543 | ||
1540 | if (x86_pmu.event_attrs) | 1544 | if (x86_pmu.event_attrs) |
@@ -1820,9 +1824,12 @@ static ssize_t set_attr_rdpmc(struct device *cdev, | |||
1820 | if (ret) | 1824 | if (ret) |
1821 | return ret; | 1825 | return ret; |
1822 | 1826 | ||
1827 | if (x86_pmu.attr_rdpmc_broken) | ||
1828 | return -ENOTSUPP; | ||
1829 | |||
1823 | if (!!val != !!x86_pmu.attr_rdpmc) { | 1830 | if (!!val != !!x86_pmu.attr_rdpmc) { |
1824 | x86_pmu.attr_rdpmc = !!val; | 1831 | x86_pmu.attr_rdpmc = !!val; |
1825 | smp_call_function(change_rdpmc, (void *)val, 1); | 1832 | on_each_cpu(change_rdpmc, (void *)val, 1); |
1826 | } | 1833 | } |
1827 | 1834 | ||
1828 | return count; | 1835 | return count; |
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index c1a861829d81..4972c244d0bc 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h | |||
@@ -409,6 +409,7 @@ struct x86_pmu { | |||
409 | /* | 409 | /* |
410 | * sysfs attrs | 410 | * sysfs attrs |
411 | */ | 411 | */ |
412 | int attr_rdpmc_broken; | ||
412 | int attr_rdpmc; | 413 | int attr_rdpmc; |
413 | struct attribute **format_attrs; | 414 | struct attribute **format_attrs; |
414 | struct attribute **event_attrs; | 415 | struct attribute **event_attrs; |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 0fa4f242f050..aa333d966886 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -1361,10 +1361,8 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) | |||
1361 | intel_pmu_disable_all(); | 1361 | intel_pmu_disable_all(); |
1362 | handled = intel_pmu_drain_bts_buffer(); | 1362 | handled = intel_pmu_drain_bts_buffer(); |
1363 | status = intel_pmu_get_status(); | 1363 | status = intel_pmu_get_status(); |
1364 | if (!status) { | 1364 | if (!status) |
1365 | intel_pmu_enable_all(0); | 1365 | goto done; |
1366 | return handled; | ||
1367 | } | ||
1368 | 1366 | ||
1369 | loops = 0; | 1367 | loops = 0; |
1370 | again: | 1368 | again: |
@@ -2310,10 +2308,7 @@ __init int intel_pmu_init(void) | |||
2310 | if (version > 1) | 2308 | if (version > 1) |
2311 | x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3); | 2309 | x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3); |
2312 | 2310 | ||
2313 | /* | 2311 | if (boot_cpu_has(X86_FEATURE_PDCM)) { |
2314 | * v2 and above have a perf capabilities MSR | ||
2315 | */ | ||
2316 | if (version > 1) { | ||
2317 | u64 capabilities; | 2312 | u64 capabilities; |
2318 | 2313 | ||
2319 | rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities); | 2314 | rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities); |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 29c248799ced..c88f7f4b03ee 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c | |||
@@ -501,8 +501,11 @@ static struct extra_reg snbep_uncore_cbox_extra_regs[] = { | |||
501 | SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN, | 501 | SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN, |
502 | SNBEP_CBO_PMON_CTL_TID_EN, 0x1), | 502 | SNBEP_CBO_PMON_CTL_TID_EN, 0x1), |
503 | SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4), | 503 | SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4), |
504 | SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0x6), | ||
504 | SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4), | 505 | SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4), |
506 | SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0x6), | ||
505 | SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4), | 507 | SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4), |
508 | SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0x6), | ||
506 | SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x6), | 509 | SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x6), |
507 | SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x8), | 510 | SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x8), |
508 | SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x8), | 511 | SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x8), |
@@ -1178,10 +1181,15 @@ static struct extra_reg ivt_uncore_cbox_extra_regs[] = { | |||
1178 | SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN, | 1181 | SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN, |
1179 | SNBEP_CBO_PMON_CTL_TID_EN, 0x1), | 1182 | SNBEP_CBO_PMON_CTL_TID_EN, 0x1), |
1180 | SNBEP_CBO_EVENT_EXTRA_REG(0x1031, 0x10ff, 0x2), | 1183 | SNBEP_CBO_EVENT_EXTRA_REG(0x1031, 0x10ff, 0x2), |
1184 | SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4), | ||
1185 | SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0xc), | ||
1186 | SNBEP_CBO_EVENT_EXTRA_REG(0x5134, 0xffff, 0xc), | ||
1181 | SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4), | 1187 | SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4), |
1188 | SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0xc), | ||
1182 | SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4), | 1189 | SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4), |
1190 | SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0xc), | ||
1183 | SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4), | 1191 | SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4), |
1184 | SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0xc), | 1192 | SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0xc), |
1185 | SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x10), | 1193 | SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x10), |
1186 | SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10), | 1194 | SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10), |
1187 | SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10), | 1195 | SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10), |
diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index b1e2fe115323..7c1a0c07b607 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c | |||
@@ -231,31 +231,49 @@ static __initconst const struct x86_pmu p6_pmu = { | |||
231 | 231 | ||
232 | }; | 232 | }; |
233 | 233 | ||
234 | static __init void p6_pmu_rdpmc_quirk(void) | ||
235 | { | ||
236 | if (boot_cpu_data.x86_mask < 9) { | ||
237 | /* | ||
238 | * PPro erratum 26; fixed in stepping 9 and above. | ||
239 | */ | ||
240 | pr_warn("Userspace RDPMC support disabled due to a CPU erratum\n"); | ||
241 | x86_pmu.attr_rdpmc_broken = 1; | ||
242 | x86_pmu.attr_rdpmc = 0; | ||
243 | } | ||
244 | } | ||
245 | |||
234 | __init int p6_pmu_init(void) | 246 | __init int p6_pmu_init(void) |
235 | { | 247 | { |
248 | x86_pmu = p6_pmu; | ||
249 | |||
236 | switch (boot_cpu_data.x86_model) { | 250 | switch (boot_cpu_data.x86_model) { |
237 | case 1: | 251 | case 1: /* Pentium Pro */ |
238 | case 3: /* Pentium Pro */ | 252 | x86_add_quirk(p6_pmu_rdpmc_quirk); |
239 | case 5: | 253 | break; |
240 | case 6: /* Pentium II */ | 254 | |
241 | case 7: | 255 | case 3: /* Pentium II - Klamath */ |
242 | case 8: | 256 | case 5: /* Pentium II - Deschutes */ |
243 | case 11: /* Pentium III */ | 257 | case 6: /* Pentium II - Mendocino */ |
244 | case 9: | ||
245 | case 13: | ||
246 | /* Pentium M */ | ||
247 | break; | 258 | break; |
259 | |||
260 | case 7: /* Pentium III - Katmai */ | ||
261 | case 8: /* Pentium III - Coppermine */ | ||
262 | case 10: /* Pentium III Xeon */ | ||
263 | case 11: /* Pentium III - Tualatin */ | ||
264 | break; | ||
265 | |||
266 | case 9: /* Pentium M - Banias */ | ||
267 | case 13: /* Pentium M - Dothan */ | ||
268 | break; | ||
269 | |||
248 | default: | 270 | default: |
249 | pr_cont("unsupported p6 CPU model %d ", | 271 | pr_cont("unsupported p6 CPU model %d ", boot_cpu_data.x86_model); |
250 | boot_cpu_data.x86_model); | ||
251 | return -ENODEV; | 272 | return -ENODEV; |
252 | } | 273 | } |
253 | 274 | ||
254 | x86_pmu = p6_pmu; | ||
255 | |||
256 | memcpy(hw_cache_event_ids, p6_hw_cache_event_ids, | 275 | memcpy(hw_cache_event_ids, p6_hw_cache_event_ids, |
257 | sizeof(hw_cache_event_ids)); | 276 | sizeof(hw_cache_event_ids)); |
258 | 277 | ||
259 | |||
260 | return 0; | 278 | return 0; |
261 | } | 279 | } |