diff options
author | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-04-02 00:08:05 -0500 |
---|---|---|
committer | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-04-02 00:08:05 -0500 |
commit | 95d465fd750897ab32462a6702fbfe1b122cbbc0 (patch) | |
tree | 65c38b2f11c51bb6932e44dd6c92f15b0091abfe /arch/i386/kernel | |
parent | 642fde17dceceb56c7ba2762733ac688666ae657 (diff) | |
parent | 683aa4012f53b2ada0f430487e05d37b0d94e90a (diff) |
Manual merge with Linus.
Conflicts:
arch/powerpc/kernel/setup-common.c
drivers/input/keyboard/hil_kbd.c
drivers/input/mouse/hil_ptr.c
Diffstat (limited to 'arch/i386/kernel')
55 files changed, 1421 insertions, 790 deletions
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 65656c033d70..5b9ed21216cf 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile | |||
@@ -7,7 +7,7 @@ extra-y := head.o init_task.o vmlinux.lds | |||
7 | obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ | 7 | obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ |
8 | ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ | 8 | ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ |
9 | pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \ | 9 | pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \ |
10 | quirks.o i8237.o topology.o | 10 | quirks.o i8237.o topology.o alternative.o |
11 | 11 | ||
12 | obj-y += cpu/ | 12 | obj-y += cpu/ |
13 | obj-y += timers/ | 13 | obj-y += timers/ |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index f1a21945963d..033066176b3e 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -668,10 +668,10 @@ unsigned long __init acpi_find_rsdp(void) | |||
668 | unsigned long rsdp_phys = 0; | 668 | unsigned long rsdp_phys = 0; |
669 | 669 | ||
670 | if (efi_enabled) { | 670 | if (efi_enabled) { |
671 | if (efi.acpi20) | 671 | if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) |
672 | return __pa(efi.acpi20); | 672 | return efi.acpi20; |
673 | else if (efi.acpi) | 673 | else if (efi.acpi != EFI_INVALID_TABLE_ADDR) |
674 | return __pa(efi.acpi); | 674 | return efi.acpi; |
675 | } | 675 | } |
676 | /* | 676 | /* |
677 | * Scan memory looking for the RSDP signature. First search EBDA (low | 677 | * Scan memory looking for the RSDP signature. First search EBDA (low |
diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c new file mode 100644 index 000000000000..5cbd6f99fb2a --- /dev/null +++ b/arch/i386/kernel/alternative.c | |||
@@ -0,0 +1,321 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/spinlock.h> | ||
3 | #include <linux/list.h> | ||
4 | #include <asm/alternative.h> | ||
5 | #include <asm/sections.h> | ||
6 | |||
7 | #define DEBUG 0 | ||
8 | #if DEBUG | ||
9 | # define DPRINTK(fmt, args...) printk(fmt, args) | ||
10 | #else | ||
11 | # define DPRINTK(fmt, args...) | ||
12 | #endif | ||
13 | |||
14 | /* Use inline assembly to define this because the nops are defined | ||
15 | as inline assembly strings in the include files and we cannot | ||
16 | get them easily into strings. */ | ||
17 | asm("\t.data\nintelnops: " | ||
18 | GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6 | ||
19 | GENERIC_NOP7 GENERIC_NOP8); | ||
20 | asm("\t.data\nk8nops: " | ||
21 | K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 | ||
22 | K8_NOP7 K8_NOP8); | ||
23 | asm("\t.data\nk7nops: " | ||
24 | K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6 | ||
25 | K7_NOP7 K7_NOP8); | ||
26 | |||
27 | extern unsigned char intelnops[], k8nops[], k7nops[]; | ||
28 | static unsigned char *intel_nops[ASM_NOP_MAX+1] = { | ||
29 | NULL, | ||
30 | intelnops, | ||
31 | intelnops + 1, | ||
32 | intelnops + 1 + 2, | ||
33 | intelnops + 1 + 2 + 3, | ||
34 | intelnops + 1 + 2 + 3 + 4, | ||
35 | intelnops + 1 + 2 + 3 + 4 + 5, | ||
36 | intelnops + 1 + 2 + 3 + 4 + 5 + 6, | ||
37 | intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7, | ||
38 | }; | ||
39 | static unsigned char *k8_nops[ASM_NOP_MAX+1] = { | ||
40 | NULL, | ||
41 | k8nops, | ||
42 | k8nops + 1, | ||
43 | k8nops + 1 + 2, | ||
44 | k8nops + 1 + 2 + 3, | ||
45 | k8nops + 1 + 2 + 3 + 4, | ||
46 | k8nops + 1 + 2 + 3 + 4 + 5, | ||
47 | k8nops + 1 + 2 + 3 + 4 + 5 + 6, | ||
48 | k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, | ||
49 | }; | ||
50 | static unsigned char *k7_nops[ASM_NOP_MAX+1] = { | ||
51 | NULL, | ||
52 | k7nops, | ||
53 | k7nops + 1, | ||
54 | k7nops + 1 + 2, | ||
55 | k7nops + 1 + 2 + 3, | ||
56 | k7nops + 1 + 2 + 3 + 4, | ||
57 | k7nops + 1 + 2 + 3 + 4 + 5, | ||
58 | k7nops + 1 + 2 + 3 + 4 + 5 + 6, | ||
59 | k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, | ||
60 | }; | ||
61 | static struct nop { | ||
62 | int cpuid; | ||
63 | unsigned char **noptable; | ||
64 | } noptypes[] = { | ||
65 | { X86_FEATURE_K8, k8_nops }, | ||
66 | { X86_FEATURE_K7, k7_nops }, | ||
67 | { -1, NULL } | ||
68 | }; | ||
69 | |||
70 | |||
71 | extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; | ||
72 | extern struct alt_instr __smp_alt_instructions[], __smp_alt_instructions_end[]; | ||
73 | extern u8 *__smp_locks[], *__smp_locks_end[]; | ||
74 | |||
75 | extern u8 __smp_alt_begin[], __smp_alt_end[]; | ||
76 | |||
77 | |||
78 | static unsigned char** find_nop_table(void) | ||
79 | { | ||
80 | unsigned char **noptable = intel_nops; | ||
81 | int i; | ||
82 | |||
83 | for (i = 0; noptypes[i].cpuid >= 0; i++) { | ||
84 | if (boot_cpu_has(noptypes[i].cpuid)) { | ||
85 | noptable = noptypes[i].noptable; | ||
86 | break; | ||
87 | } | ||
88 | } | ||
89 | return noptable; | ||
90 | } | ||
91 | |||
92 | /* Replace instructions with better alternatives for this CPU type. | ||
93 | This runs before SMP is initialized to avoid SMP problems with | ||
94 | self modifying code. This implies that assymetric systems where | ||
95 | APs have less capabilities than the boot processor are not handled. | ||
96 | Tough. Make sure you disable such features by hand. */ | ||
97 | |||
98 | void apply_alternatives(struct alt_instr *start, struct alt_instr *end) | ||
99 | { | ||
100 | unsigned char **noptable = find_nop_table(); | ||
101 | struct alt_instr *a; | ||
102 | int diff, i, k; | ||
103 | |||
104 | DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end); | ||
105 | for (a = start; a < end; a++) { | ||
106 | BUG_ON(a->replacementlen > a->instrlen); | ||
107 | if (!boot_cpu_has(a->cpuid)) | ||
108 | continue; | ||
109 | memcpy(a->instr, a->replacement, a->replacementlen); | ||
110 | diff = a->instrlen - a->replacementlen; | ||
111 | /* Pad the rest with nops */ | ||
112 | for (i = a->replacementlen; diff > 0; diff -= k, i += k) { | ||
113 | k = diff; | ||
114 | if (k > ASM_NOP_MAX) | ||
115 | k = ASM_NOP_MAX; | ||
116 | memcpy(a->instr + i, noptable[k], k); | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | |||
121 | static void alternatives_smp_save(struct alt_instr *start, struct alt_instr *end) | ||
122 | { | ||
123 | struct alt_instr *a; | ||
124 | |||
125 | DPRINTK("%s: alt table %p-%p\n", __FUNCTION__, start, end); | ||
126 | for (a = start; a < end; a++) { | ||
127 | memcpy(a->replacement + a->replacementlen, | ||
128 | a->instr, | ||
129 | a->instrlen); | ||
130 | } | ||
131 | } | ||
132 | |||
133 | static void alternatives_smp_apply(struct alt_instr *start, struct alt_instr *end) | ||
134 | { | ||
135 | struct alt_instr *a; | ||
136 | |||
137 | for (a = start; a < end; a++) { | ||
138 | memcpy(a->instr, | ||
139 | a->replacement + a->replacementlen, | ||
140 | a->instrlen); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) | ||
145 | { | ||
146 | u8 **ptr; | ||
147 | |||
148 | for (ptr = start; ptr < end; ptr++) { | ||
149 | if (*ptr < text) | ||
150 | continue; | ||
151 | if (*ptr > text_end) | ||
152 | continue; | ||
153 | **ptr = 0xf0; /* lock prefix */ | ||
154 | }; | ||
155 | } | ||
156 | |||
157 | static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end) | ||
158 | { | ||
159 | unsigned char **noptable = find_nop_table(); | ||
160 | u8 **ptr; | ||
161 | |||
162 | for (ptr = start; ptr < end; ptr++) { | ||
163 | if (*ptr < text) | ||
164 | continue; | ||
165 | if (*ptr > text_end) | ||
166 | continue; | ||
167 | **ptr = noptable[1][0]; | ||
168 | }; | ||
169 | } | ||
170 | |||
171 | struct smp_alt_module { | ||
172 | /* what is this ??? */ | ||
173 | struct module *mod; | ||
174 | char *name; | ||
175 | |||
176 | /* ptrs to lock prefixes */ | ||
177 | u8 **locks; | ||
178 | u8 **locks_end; | ||
179 | |||
180 | /* .text segment, needed to avoid patching init code ;) */ | ||
181 | u8 *text; | ||
182 | u8 *text_end; | ||
183 | |||
184 | struct list_head next; | ||
185 | }; | ||
186 | static LIST_HEAD(smp_alt_modules); | ||
187 | static DEFINE_SPINLOCK(smp_alt); | ||
188 | |||
189 | static int smp_alt_once = 0; | ||
190 | static int __init bootonly(char *str) | ||
191 | { | ||
192 | smp_alt_once = 1; | ||
193 | return 1; | ||
194 | } | ||
195 | __setup("smp-alt-boot", bootonly); | ||
196 | |||
197 | void alternatives_smp_module_add(struct module *mod, char *name, | ||
198 | void *locks, void *locks_end, | ||
199 | void *text, void *text_end) | ||
200 | { | ||
201 | struct smp_alt_module *smp; | ||
202 | unsigned long flags; | ||
203 | |||
204 | if (smp_alt_once) { | ||
205 | if (boot_cpu_has(X86_FEATURE_UP)) | ||
206 | alternatives_smp_unlock(locks, locks_end, | ||
207 | text, text_end); | ||
208 | return; | ||
209 | } | ||
210 | |||
211 | smp = kzalloc(sizeof(*smp), GFP_KERNEL); | ||
212 | if (NULL == smp) | ||
213 | return; /* we'll run the (safe but slow) SMP code then ... */ | ||
214 | |||
215 | smp->mod = mod; | ||
216 | smp->name = name; | ||
217 | smp->locks = locks; | ||
218 | smp->locks_end = locks_end; | ||
219 | smp->text = text; | ||
220 | smp->text_end = text_end; | ||
221 | DPRINTK("%s: locks %p -> %p, text %p -> %p, name %s\n", | ||
222 | __FUNCTION__, smp->locks, smp->locks_end, | ||
223 | smp->text, smp->text_end, smp->name); | ||
224 | |||
225 | spin_lock_irqsave(&smp_alt, flags); | ||
226 | list_add_tail(&smp->next, &smp_alt_modules); | ||
227 | if (boot_cpu_has(X86_FEATURE_UP)) | ||
228 | alternatives_smp_unlock(smp->locks, smp->locks_end, | ||
229 | smp->text, smp->text_end); | ||
230 | spin_unlock_irqrestore(&smp_alt, flags); | ||
231 | } | ||
232 | |||
233 | void alternatives_smp_module_del(struct module *mod) | ||
234 | { | ||
235 | struct smp_alt_module *item; | ||
236 | unsigned long flags; | ||
237 | |||
238 | if (smp_alt_once) | ||
239 | return; | ||
240 | |||
241 | spin_lock_irqsave(&smp_alt, flags); | ||
242 | list_for_each_entry(item, &smp_alt_modules, next) { | ||
243 | if (mod != item->mod) | ||
244 | continue; | ||
245 | list_del(&item->next); | ||
246 | spin_unlock_irqrestore(&smp_alt, flags); | ||
247 | DPRINTK("%s: %s\n", __FUNCTION__, item->name); | ||
248 | kfree(item); | ||
249 | return; | ||
250 | } | ||
251 | spin_unlock_irqrestore(&smp_alt, flags); | ||
252 | } | ||
253 | |||
254 | void alternatives_smp_switch(int smp) | ||
255 | { | ||
256 | struct smp_alt_module *mod; | ||
257 | unsigned long flags; | ||
258 | |||
259 | if (smp_alt_once) | ||
260 | return; | ||
261 | BUG_ON(!smp && (num_online_cpus() > 1)); | ||
262 | |||
263 | spin_lock_irqsave(&smp_alt, flags); | ||
264 | if (smp) { | ||
265 | printk(KERN_INFO "SMP alternatives: switching to SMP code\n"); | ||
266 | clear_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); | ||
267 | clear_bit(X86_FEATURE_UP, cpu_data[0].x86_capability); | ||
268 | alternatives_smp_apply(__smp_alt_instructions, | ||
269 | __smp_alt_instructions_end); | ||
270 | list_for_each_entry(mod, &smp_alt_modules, next) | ||
271 | alternatives_smp_lock(mod->locks, mod->locks_end, | ||
272 | mod->text, mod->text_end); | ||
273 | } else { | ||
274 | printk(KERN_INFO "SMP alternatives: switching to UP code\n"); | ||
275 | set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); | ||
276 | set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability); | ||
277 | apply_alternatives(__smp_alt_instructions, | ||
278 | __smp_alt_instructions_end); | ||
279 | list_for_each_entry(mod, &smp_alt_modules, next) | ||
280 | alternatives_smp_unlock(mod->locks, mod->locks_end, | ||
281 | mod->text, mod->text_end); | ||
282 | } | ||
283 | spin_unlock_irqrestore(&smp_alt, flags); | ||
284 | } | ||
285 | |||
286 | void __init alternative_instructions(void) | ||
287 | { | ||
288 | apply_alternatives(__alt_instructions, __alt_instructions_end); | ||
289 | |||
290 | /* switch to patch-once-at-boottime-only mode and free the | ||
291 | * tables in case we know the number of CPUs will never ever | ||
292 | * change */ | ||
293 | #ifdef CONFIG_HOTPLUG_CPU | ||
294 | if (num_possible_cpus() < 2) | ||
295 | smp_alt_once = 1; | ||
296 | #else | ||
297 | smp_alt_once = 1; | ||
298 | #endif | ||
299 | |||
300 | if (smp_alt_once) { | ||
301 | if (1 == num_possible_cpus()) { | ||
302 | printk(KERN_INFO "SMP alternatives: switching to UP code\n"); | ||
303 | set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); | ||
304 | set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability); | ||
305 | apply_alternatives(__smp_alt_instructions, | ||
306 | __smp_alt_instructions_end); | ||
307 | alternatives_smp_unlock(__smp_locks, __smp_locks_end, | ||
308 | _text, _etext); | ||
309 | } | ||
310 | free_init_pages("SMP alternatives", | ||
311 | (unsigned long)__smp_alt_begin, | ||
312 | (unsigned long)__smp_alt_end); | ||
313 | } else { | ||
314 | alternatives_smp_save(__smp_alt_instructions, | ||
315 | __smp_alt_instructions_end); | ||
316 | alternatives_smp_module_add(NULL, "core kernel", | ||
317 | __smp_locks, __smp_locks_end, | ||
318 | _text, _etext); | ||
319 | alternatives_smp_switch(0); | ||
320 | } | ||
321 | } | ||
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index f39e09ef64ec..6273bf74c203 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <asm/i8253.h> | 38 | #include <asm/i8253.h> |
39 | 39 | ||
40 | #include <mach_apic.h> | 40 | #include <mach_apic.h> |
41 | #include <mach_apicdef.h> | ||
41 | #include <mach_ipi.h> | 42 | #include <mach_ipi.h> |
42 | 43 | ||
43 | #include "io_ports.h" | 44 | #include "io_ports.h" |
@@ -414,6 +415,7 @@ void __init init_bsp_APIC(void) | |||
414 | void __devinit setup_local_APIC(void) | 415 | void __devinit setup_local_APIC(void) |
415 | { | 416 | { |
416 | unsigned long oldvalue, value, ver, maxlvt; | 417 | unsigned long oldvalue, value, ver, maxlvt; |
418 | int i, j; | ||
417 | 419 | ||
418 | /* Pound the ESR really hard over the head with a big hammer - mbligh */ | 420 | /* Pound the ESR really hard over the head with a big hammer - mbligh */ |
419 | if (esr_disable) { | 421 | if (esr_disable) { |
@@ -451,6 +453,25 @@ void __devinit setup_local_APIC(void) | |||
451 | apic_write_around(APIC_TASKPRI, value); | 453 | apic_write_around(APIC_TASKPRI, value); |
452 | 454 | ||
453 | /* | 455 | /* |
456 | * After a crash, we no longer service the interrupts and a pending | ||
457 | * interrupt from previous kernel might still have ISR bit set. | ||
458 | * | ||
459 | * Most probably by now CPU has serviced that pending interrupt and | ||
460 | * it might not have done the ack_APIC_irq() because it thought, | ||
461 | * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it | ||
462 | * does not clear the ISR bit and cpu thinks it has already serivced | ||
463 | * the interrupt. Hence a vector might get locked. It was noticed | ||
464 | * for timer irq (vector 0x31). Issue an extra EOI to clear ISR. | ||
465 | */ | ||
466 | for (i = APIC_ISR_NR - 1; i >= 0; i--) { | ||
467 | value = apic_read(APIC_ISR + i*0x10); | ||
468 | for (j = 31; j >= 0; j--) { | ||
469 | if (value & (1<<j)) | ||
470 | ack_APIC_irq(); | ||
471 | } | ||
472 | } | ||
473 | |||
474 | /* | ||
454 | * Now that we are all set up, enable the APIC | 475 | * Now that we are all set up, enable the APIC |
455 | */ | 476 | */ |
456 | value = apic_read(APIC_SPIV); | 477 | value = apic_read(APIC_SPIV); |
@@ -570,16 +591,18 @@ void __devinit setup_local_APIC(void) | |||
570 | */ | 591 | */ |
571 | void lapic_shutdown(void) | 592 | void lapic_shutdown(void) |
572 | { | 593 | { |
594 | unsigned long flags; | ||
595 | |||
573 | if (!cpu_has_apic) | 596 | if (!cpu_has_apic) |
574 | return; | 597 | return; |
575 | 598 | ||
576 | local_irq_disable(); | 599 | local_irq_save(flags); |
577 | clear_local_APIC(); | 600 | clear_local_APIC(); |
578 | 601 | ||
579 | if (enabled_via_apicbase) | 602 | if (enabled_via_apicbase) |
580 | disable_local_APIC(); | 603 | disable_local_APIC(); |
581 | 604 | ||
582 | local_irq_enable(); | 605 | local_irq_restore(flags); |
583 | } | 606 | } |
584 | 607 | ||
585 | #ifdef CONFIG_PM | 608 | #ifdef CONFIG_PM |
@@ -729,7 +752,7 @@ static int __init apic_set_verbosity(char *str) | |||
729 | printk(KERN_WARNING "APIC Verbosity level %s not recognised" | 752 | printk(KERN_WARNING "APIC Verbosity level %s not recognised" |
730 | " use apic=verbose or apic=debug\n", str); | 753 | " use apic=verbose or apic=debug\n", str); |
731 | 754 | ||
732 | return 0; | 755 | return 1; |
733 | } | 756 | } |
734 | 757 | ||
735 | __setup("apic=", apic_set_verbosity); | 758 | __setup("apic=", apic_set_verbosity); |
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 05312a8abb8b..da30a374dd4e 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c | |||
@@ -824,8 +824,6 @@ static void apm_do_busy(void) | |||
824 | 824 | ||
825 | static void (*original_pm_idle)(void); | 825 | static void (*original_pm_idle)(void); |
826 | 826 | ||
827 | extern void default_idle(void); | ||
828 | |||
829 | /** | 827 | /** |
830 | * apm_cpu_idle - cpu idling for APM capable Linux | 828 | * apm_cpu_idle - cpu idling for APM capable Linux |
831 | * | 829 | * |
diff --git a/arch/i386/kernel/cpu/centaur.c b/arch/i386/kernel/cpu/centaur.c index f52669ecb93f..bd75629dd262 100644 --- a/arch/i386/kernel/cpu/centaur.c +++ b/arch/i386/kernel/cpu/centaur.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <asm/processor.h> | 4 | #include <asm/processor.h> |
5 | #include <asm/msr.h> | 5 | #include <asm/msr.h> |
6 | #include <asm/e820.h> | 6 | #include <asm/e820.h> |
7 | #include <asm/mtrr.h> | ||
7 | #include "cpu.h" | 8 | #include "cpu.h" |
8 | 9 | ||
9 | #ifdef CONFIG_X86_OOSTORE | 10 | #ifdef CONFIG_X86_OOSTORE |
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index e6bd095ae108..a06a49075f10 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c | |||
@@ -25,9 +25,10 @@ EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr); | |||
25 | DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); | 25 | DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); |
26 | EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); | 26 | EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); |
27 | 27 | ||
28 | static int cachesize_override __devinitdata = -1; | 28 | static int cachesize_override __cpuinitdata = -1; |
29 | static int disable_x86_fxsr __devinitdata = 0; | 29 | static int disable_x86_fxsr __cpuinitdata; |
30 | static int disable_x86_serial_nr __devinitdata = 1; | 30 | static int disable_x86_serial_nr __cpuinitdata = 1; |
31 | static int disable_x86_sep __cpuinitdata; | ||
31 | 32 | ||
32 | struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; | 33 | struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; |
33 | 34 | ||
@@ -59,7 +60,7 @@ static int __init cachesize_setup(char *str) | |||
59 | } | 60 | } |
60 | __setup("cachesize=", cachesize_setup); | 61 | __setup("cachesize=", cachesize_setup); |
61 | 62 | ||
62 | int __devinit get_model_name(struct cpuinfo_x86 *c) | 63 | int __cpuinit get_model_name(struct cpuinfo_x86 *c) |
63 | { | 64 | { |
64 | unsigned int *v; | 65 | unsigned int *v; |
65 | char *p, *q; | 66 | char *p, *q; |
@@ -89,7 +90,7 @@ int __devinit get_model_name(struct cpuinfo_x86 *c) | |||
89 | } | 90 | } |
90 | 91 | ||
91 | 92 | ||
92 | void __devinit display_cacheinfo(struct cpuinfo_x86 *c) | 93 | void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) |
93 | { | 94 | { |
94 | unsigned int n, dummy, ecx, edx, l2size; | 95 | unsigned int n, dummy, ecx, edx, l2size; |
95 | 96 | ||
@@ -130,7 +131,7 @@ void __devinit display_cacheinfo(struct cpuinfo_x86 *c) | |||
130 | /* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used */ | 131 | /* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used */ |
131 | 132 | ||
132 | /* Look up CPU names by table lookup. */ | 133 | /* Look up CPU names by table lookup. */ |
133 | static char __devinit *table_lookup_model(struct cpuinfo_x86 *c) | 134 | static char __cpuinit *table_lookup_model(struct cpuinfo_x86 *c) |
134 | { | 135 | { |
135 | struct cpu_model_info *info; | 136 | struct cpu_model_info *info; |
136 | 137 | ||
@@ -151,7 +152,7 @@ static char __devinit *table_lookup_model(struct cpuinfo_x86 *c) | |||
151 | } | 152 | } |
152 | 153 | ||
153 | 154 | ||
154 | static void __devinit get_cpu_vendor(struct cpuinfo_x86 *c, int early) | 155 | static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c, int early) |
155 | { | 156 | { |
156 | char *v = c->x86_vendor_id; | 157 | char *v = c->x86_vendor_id; |
157 | int i; | 158 | int i; |
@@ -187,6 +188,14 @@ static int __init x86_fxsr_setup(char * s) | |||
187 | __setup("nofxsr", x86_fxsr_setup); | 188 | __setup("nofxsr", x86_fxsr_setup); |
188 | 189 | ||
189 | 190 | ||
191 | static int __init x86_sep_setup(char * s) | ||
192 | { | ||
193 | disable_x86_sep = 1; | ||
194 | return 1; | ||
195 | } | ||
196 | __setup("nosep", x86_sep_setup); | ||
197 | |||
198 | |||
190 | /* Standard macro to see if a specific flag is changeable */ | 199 | /* Standard macro to see if a specific flag is changeable */ |
191 | static inline int flag_is_changeable_p(u32 flag) | 200 | static inline int flag_is_changeable_p(u32 flag) |
192 | { | 201 | { |
@@ -210,7 +219,7 @@ static inline int flag_is_changeable_p(u32 flag) | |||
210 | 219 | ||
211 | 220 | ||
212 | /* Probe for the CPUID instruction */ | 221 | /* Probe for the CPUID instruction */ |
213 | static int __devinit have_cpuid_p(void) | 222 | static int __cpuinit have_cpuid_p(void) |
214 | { | 223 | { |
215 | return flag_is_changeable_p(X86_EFLAGS_ID); | 224 | return flag_is_changeable_p(X86_EFLAGS_ID); |
216 | } | 225 | } |
@@ -254,10 +263,10 @@ static void __init early_cpu_detect(void) | |||
254 | } | 263 | } |
255 | } | 264 | } |
256 | 265 | ||
257 | void __devinit generic_identify(struct cpuinfo_x86 * c) | 266 | void __cpuinit generic_identify(struct cpuinfo_x86 * c) |
258 | { | 267 | { |
259 | u32 tfms, xlvl; | 268 | u32 tfms, xlvl; |
260 | int junk; | 269 | int ebx; |
261 | 270 | ||
262 | if (have_cpuid_p()) { | 271 | if (have_cpuid_p()) { |
263 | /* Get vendor name */ | 272 | /* Get vendor name */ |
@@ -273,7 +282,7 @@ void __devinit generic_identify(struct cpuinfo_x86 * c) | |||
273 | /* Intel-defined flags: level 0x00000001 */ | 282 | /* Intel-defined flags: level 0x00000001 */ |
274 | if ( c->cpuid_level >= 0x00000001 ) { | 283 | if ( c->cpuid_level >= 0x00000001 ) { |
275 | u32 capability, excap; | 284 | u32 capability, excap; |
276 | cpuid(0x00000001, &tfms, &junk, &excap, &capability); | 285 | cpuid(0x00000001, &tfms, &ebx, &excap, &capability); |
277 | c->x86_capability[0] = capability; | 286 | c->x86_capability[0] = capability; |
278 | c->x86_capability[4] = excap; | 287 | c->x86_capability[4] = excap; |
279 | c->x86 = (tfms >> 8) & 15; | 288 | c->x86 = (tfms >> 8) & 15; |
@@ -283,6 +292,11 @@ void __devinit generic_identify(struct cpuinfo_x86 * c) | |||
283 | if (c->x86 >= 0x6) | 292 | if (c->x86 >= 0x6) |
284 | c->x86_model += ((tfms >> 16) & 0xF) << 4; | 293 | c->x86_model += ((tfms >> 16) & 0xF) << 4; |
285 | c->x86_mask = tfms & 15; | 294 | c->x86_mask = tfms & 15; |
295 | #ifdef CONFIG_SMP | ||
296 | c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0); | ||
297 | #else | ||
298 | c->apicid = (ebx >> 24) & 0xFF; | ||
299 | #endif | ||
286 | } else { | 300 | } else { |
287 | /* Have CPUID level 0 only - unheard of */ | 301 | /* Have CPUID level 0 only - unheard of */ |
288 | c->x86 = 4; | 302 | c->x86 = 4; |
@@ -307,7 +321,7 @@ void __devinit generic_identify(struct cpuinfo_x86 * c) | |||
307 | #endif | 321 | #endif |
308 | } | 322 | } |
309 | 323 | ||
310 | static void __devinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c) | 324 | static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c) |
311 | { | 325 | { |
312 | if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr ) { | 326 | if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr ) { |
313 | /* Disable processor serial number */ | 327 | /* Disable processor serial number */ |
@@ -335,7 +349,7 @@ __setup("serialnumber", x86_serial_nr_setup); | |||
335 | /* | 349 | /* |
336 | * This does the hard work of actually picking apart the CPU stuff... | 350 | * This does the hard work of actually picking apart the CPU stuff... |
337 | */ | 351 | */ |
338 | void __devinit identify_cpu(struct cpuinfo_x86 *c) | 352 | void __cpuinit identify_cpu(struct cpuinfo_x86 *c) |
339 | { | 353 | { |
340 | int i; | 354 | int i; |
341 | 355 | ||
@@ -405,6 +419,10 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c) | |||
405 | clear_bit(X86_FEATURE_XMM, c->x86_capability); | 419 | clear_bit(X86_FEATURE_XMM, c->x86_capability); |
406 | } | 420 | } |
407 | 421 | ||
422 | /* SEP disabled? */ | ||
423 | if (disable_x86_sep) | ||
424 | clear_bit(X86_FEATURE_SEP, c->x86_capability); | ||
425 | |||
408 | if (disable_pse) | 426 | if (disable_pse) |
409 | clear_bit(X86_FEATURE_PSE, c->x86_capability); | 427 | clear_bit(X86_FEATURE_PSE, c->x86_capability); |
410 | 428 | ||
@@ -417,7 +435,7 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c) | |||
417 | else | 435 | else |
418 | /* Last resort... */ | 436 | /* Last resort... */ |
419 | sprintf(c->x86_model_id, "%02x/%02x", | 437 | sprintf(c->x86_model_id, "%02x/%02x", |
420 | c->x86_vendor, c->x86_model); | 438 | c->x86, c->x86_model); |
421 | } | 439 | } |
422 | 440 | ||
423 | /* Now the feature flags better reflect actual CPU features! */ | 441 | /* Now the feature flags better reflect actual CPU features! */ |
@@ -453,7 +471,7 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c) | |||
453 | } | 471 | } |
454 | 472 | ||
455 | #ifdef CONFIG_X86_HT | 473 | #ifdef CONFIG_X86_HT |
456 | void __devinit detect_ht(struct cpuinfo_x86 *c) | 474 | void __cpuinit detect_ht(struct cpuinfo_x86 *c) |
457 | { | 475 | { |
458 | u32 eax, ebx, ecx, edx; | 476 | u32 eax, ebx, ecx, edx; |
459 | int index_msb, core_bits; | 477 | int index_msb, core_bits; |
@@ -461,7 +479,6 @@ void __devinit detect_ht(struct cpuinfo_x86 *c) | |||
461 | 479 | ||
462 | cpuid(1, &eax, &ebx, &ecx, &edx); | 480 | cpuid(1, &eax, &ebx, &ecx, &edx); |
463 | 481 | ||
464 | c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0); | ||
465 | 482 | ||
466 | if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) | 483 | if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) |
467 | return; | 484 | return; |
@@ -500,7 +517,7 @@ void __devinit detect_ht(struct cpuinfo_x86 *c) | |||
500 | } | 517 | } |
501 | #endif | 518 | #endif |
502 | 519 | ||
503 | void __devinit print_cpu_info(struct cpuinfo_x86 *c) | 520 | void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) |
504 | { | 521 | { |
505 | char *vendor = NULL; | 522 | char *vendor = NULL; |
506 | 523 | ||
@@ -523,7 +540,7 @@ void __devinit print_cpu_info(struct cpuinfo_x86 *c) | |||
523 | printk("\n"); | 540 | printk("\n"); |
524 | } | 541 | } |
525 | 542 | ||
526 | cpumask_t cpu_initialized __devinitdata = CPU_MASK_NONE; | 543 | cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; |
527 | 544 | ||
528 | /* This is hacky. :) | 545 | /* This is hacky. :) |
529 | * We're emulating future behavior. | 546 | * We're emulating future behavior. |
@@ -570,7 +587,7 @@ void __init early_cpu_init(void) | |||
570 | * and IDT. We reload them nevertheless, this function acts as a | 587 | * and IDT. We reload them nevertheless, this function acts as a |
571 | * 'CPU state barrier', nothing should get across. | 588 | * 'CPU state barrier', nothing should get across. |
572 | */ | 589 | */ |
573 | void __devinit cpu_init(void) | 590 | void __cpuinit cpu_init(void) |
574 | { | 591 | { |
575 | int cpu = smp_processor_id(); | 592 | int cpu = smp_processor_id(); |
576 | struct tss_struct * t = &per_cpu(init_tss, cpu); | 593 | struct tss_struct * t = &per_cpu(init_tss, cpu); |
@@ -670,7 +687,7 @@ void __devinit cpu_init(void) | |||
670 | } | 687 | } |
671 | 688 | ||
672 | #ifdef CONFIG_HOTPLUG_CPU | 689 | #ifdef CONFIG_HOTPLUG_CPU |
673 | void __devinit cpu_uninit(void) | 690 | void __cpuinit cpu_uninit(void) |
674 | { | 691 | { |
675 | int cpu = raw_smp_processor_id(); | 692 | int cpu = raw_smp_processor_id(); |
676 | cpu_clear(cpu, cpu_initialized); | 693 | cpu_clear(cpu, cpu_initialized); |
diff --git a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig index 26892d2099b0..e44a4c6a4fe5 100644 --- a/arch/i386/kernel/cpu/cpufreq/Kconfig +++ b/arch/i386/kernel/cpu/cpufreq/Kconfig | |||
@@ -96,7 +96,6 @@ config X86_POWERNOW_K8_ACPI | |||
96 | 96 | ||
97 | config X86_GX_SUSPMOD | 97 | config X86_GX_SUSPMOD |
98 | tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation" | 98 | tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation" |
99 | depends on PCI | ||
100 | help | 99 | help |
101 | This add the CPUFreq driver for NatSemi Geode processors which | 100 | This add the CPUFreq driver for NatSemi Geode processors which |
102 | support suspend modulation. | 101 | support suspend modulation. |
@@ -115,9 +114,9 @@ config X86_SPEEDSTEP_CENTRINO | |||
115 | you also need to say Y to "Use ACPI tables to decode..." below | 114 | you also need to say Y to "Use ACPI tables to decode..." below |
116 | [which might imply enabling ACPI] if you want to use this driver | 115 | [which might imply enabling ACPI] if you want to use this driver |
117 | on non-Banias CPUs. | 116 | on non-Banias CPUs. |
118 | 117 | ||
119 | For details, take a look at <file:Documentation/cpu-freq/>. | 118 | For details, take a look at <file:Documentation/cpu-freq/>. |
120 | 119 | ||
121 | If in doubt, say N. | 120 | If in doubt, say N. |
122 | 121 | ||
123 | config X86_SPEEDSTEP_CENTRINO_ACPI | 122 | config X86_SPEEDSTEP_CENTRINO_ACPI |
@@ -148,7 +147,7 @@ config X86_SPEEDSTEP_ICH | |||
148 | help | 147 | help |
149 | This adds the CPUFreq driver for certain mobile Intel Pentium III | 148 | This adds the CPUFreq driver for certain mobile Intel Pentium III |
150 | (Coppermine), all mobile Intel Pentium III-M (Tualatin) and all | 149 | (Coppermine), all mobile Intel Pentium III-M (Tualatin) and all |
151 | mobile Intel Pentium 4 P4-M on systems which have an Intel ICH2, | 150 | mobile Intel Pentium 4 P4-M on systems which have an Intel ICH2, |
152 | ICH3 or ICH4 southbridge. | 151 | ICH3 or ICH4 southbridge. |
153 | 152 | ||
154 | For details, take a look at <file:Documentation/cpu-freq/>. | 153 | For details, take a look at <file:Documentation/cpu-freq/>. |
@@ -161,7 +160,7 @@ config X86_SPEEDSTEP_SMI | |||
161 | depends on EXPERIMENTAL | 160 | depends on EXPERIMENTAL |
162 | help | 161 | help |
163 | This adds the CPUFreq driver for certain mobile Intel Pentium III | 162 | This adds the CPUFreq driver for certain mobile Intel Pentium III |
164 | (Coppermine), all mobile Intel Pentium III-M (Tualatin) | 163 | (Coppermine), all mobile Intel Pentium III-M (Tualatin) |
165 | on systems which have an Intel 440BX/ZX/MX southbridge. | 164 | on systems which have an Intel 440BX/ZX/MX southbridge. |
166 | 165 | ||
167 | For details, take a look at <file:Documentation/cpu-freq/>. | 166 | For details, take a look at <file:Documentation/cpu-freq/>. |
@@ -203,9 +202,10 @@ config X86_LONGRUN | |||
203 | config X86_LONGHAUL | 202 | config X86_LONGHAUL |
204 | tristate "VIA Cyrix III Longhaul" | 203 | tristate "VIA Cyrix III Longhaul" |
205 | select CPU_FREQ_TABLE | 204 | select CPU_FREQ_TABLE |
205 | depends on BROKEN | ||
206 | help | 206 | help |
207 | This adds the CPUFreq driver for VIA Samuel/CyrixIII, | 207 | This adds the CPUFreq driver for VIA Samuel/CyrixIII, |
208 | VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T | 208 | VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T |
209 | processors. | 209 | processors. |
210 | 210 | ||
211 | For details, take a look at <file:Documentation/cpu-freq/>. | 211 | For details, take a look at <file:Documentation/cpu-freq/>. |
@@ -215,11 +215,11 @@ config X86_LONGHAUL | |||
215 | comment "shared options" | 215 | comment "shared options" |
216 | 216 | ||
217 | config X86_ACPI_CPUFREQ_PROC_INTF | 217 | config X86_ACPI_CPUFREQ_PROC_INTF |
218 | bool "/proc/acpi/processor/../performance interface (deprecated)" | 218 | bool "/proc/acpi/processor/../performance interface (deprecated)" |
219 | depends on PROC_FS | 219 | depends on PROC_FS |
220 | depends on X86_ACPI_CPUFREQ || X86_SPEEDSTEP_CENTRINO_ACPI || X86_POWERNOW_K7_ACPI || X86_POWERNOW_K8_ACPI | 220 | depends on X86_ACPI_CPUFREQ || X86_SPEEDSTEP_CENTRINO_ACPI || X86_POWERNOW_K7_ACPI || X86_POWERNOW_K8_ACPI |
221 | help | 221 | help |
222 | This enables the deprecated /proc/acpi/processor/../performance | 222 | This enables the deprecated /proc/acpi/processor/../performance |
223 | interface. While it is helpful for debugging, the generic, | 223 | interface. While it is helpful for debugging, the generic, |
224 | cross-architecture cpufreq interfaces should be used. | 224 | cross-architecture cpufreq interfaces should be used. |
225 | 225 | ||
@@ -233,9 +233,9 @@ config X86_SPEEDSTEP_RELAXED_CAP_CHECK | |||
233 | bool "Relaxed speedstep capability checks" | 233 | bool "Relaxed speedstep capability checks" |
234 | depends on (X86_SPEEDSTEP_SMI || X86_SPEEDSTEP_ICH) | 234 | depends on (X86_SPEEDSTEP_SMI || X86_SPEEDSTEP_ICH) |
235 | help | 235 | help |
236 | Don't perform all checks for a speedstep capable system which would | 236 | Don't perform all checks for a speedstep capable system which would |
237 | normally be done. Some ancient or strange systems, though speedstep | 237 | normally be done. Some ancient or strange systems, though speedstep |
238 | capable, don't always indicate that they are speedstep capable. This | 238 | capable, don't always indicate that they are speedstep capable. This |
239 | option lets the probing code bypass some of those checks if the | 239 | option lets the probing code bypass some of those checks if the |
240 | parameter "relaxed_check=1" is passed to the module. | 240 | parameter "relaxed_check=1" is passed to the module. |
241 | 241 | ||
diff --git a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c index 2b62dee35c6c..f275e0d4aee5 100644 --- a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c +++ b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c | |||
@@ -39,7 +39,7 @@ static struct pci_dev *nforce2_chipset_dev; | |||
39 | static int fid = 0; | 39 | static int fid = 0; |
40 | 40 | ||
41 | /* min_fsb, max_fsb: | 41 | /* min_fsb, max_fsb: |
42 | * minimum and maximum FSB (= FSB at boot time) | 42 | * minimum and maximum FSB (= FSB at boot time) |
43 | */ | 43 | */ |
44 | static int min_fsb = 0; | 44 | static int min_fsb = 0; |
45 | static int max_fsb = 0; | 45 | static int max_fsb = 0; |
@@ -57,10 +57,10 @@ MODULE_PARM_DESC(min_fsb, | |||
57 | 57 | ||
58 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "cpufreq-nforce2", msg) | 58 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "cpufreq-nforce2", msg) |
59 | 59 | ||
60 | /* | 60 | /** |
61 | * nforce2_calc_fsb - calculate FSB | 61 | * nforce2_calc_fsb - calculate FSB |
62 | * @pll: PLL value | 62 | * @pll: PLL value |
63 | * | 63 | * |
64 | * Calculates FSB from PLL value | 64 | * Calculates FSB from PLL value |
65 | */ | 65 | */ |
66 | static int nforce2_calc_fsb(int pll) | 66 | static int nforce2_calc_fsb(int pll) |
@@ -76,10 +76,10 @@ static int nforce2_calc_fsb(int pll) | |||
76 | return 0; | 76 | return 0; |
77 | } | 77 | } |
78 | 78 | ||
79 | /* | 79 | /** |
80 | * nforce2_calc_pll - calculate PLL value | 80 | * nforce2_calc_pll - calculate PLL value |
81 | * @fsb: FSB | 81 | * @fsb: FSB |
82 | * | 82 | * |
83 | * Calculate PLL value for given FSB | 83 | * Calculate PLL value for given FSB |
84 | */ | 84 | */ |
85 | static int nforce2_calc_pll(unsigned int fsb) | 85 | static int nforce2_calc_pll(unsigned int fsb) |
@@ -106,10 +106,10 @@ static int nforce2_calc_pll(unsigned int fsb) | |||
106 | return NFORCE2_PLL(mul, div); | 106 | return NFORCE2_PLL(mul, div); |
107 | } | 107 | } |
108 | 108 | ||
109 | /* | 109 | /** |
110 | * nforce2_write_pll - write PLL value to chipset | 110 | * nforce2_write_pll - write PLL value to chipset |
111 | * @pll: PLL value | 111 | * @pll: PLL value |
112 | * | 112 | * |
113 | * Writes new FSB PLL value to chipset | 113 | * Writes new FSB PLL value to chipset |
114 | */ | 114 | */ |
115 | static void nforce2_write_pll(int pll) | 115 | static void nforce2_write_pll(int pll) |
@@ -121,15 +121,13 @@ static void nforce2_write_pll(int pll) | |||
121 | pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLADR, temp); | 121 | pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLADR, temp); |
122 | 122 | ||
123 | /* Now write the value in all 64 registers */ | 123 | /* Now write the value in all 64 registers */ |
124 | for (temp = 0; temp <= 0x3f; temp++) { | 124 | for (temp = 0; temp <= 0x3f; temp++) |
125 | pci_write_config_dword(nforce2_chipset_dev, | 125 | pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLREG, pll); |
126 | NFORCE2_PLLREG, pll); | ||
127 | } | ||
128 | 126 | ||
129 | return; | 127 | return; |
130 | } | 128 | } |
131 | 129 | ||
132 | /* | 130 | /** |
133 | * nforce2_fsb_read - Read FSB | 131 | * nforce2_fsb_read - Read FSB |
134 | * | 132 | * |
135 | * Read FSB from chipset | 133 | * Read FSB from chipset |
@@ -140,39 +138,32 @@ static unsigned int nforce2_fsb_read(int bootfsb) | |||
140 | struct pci_dev *nforce2_sub5; | 138 | struct pci_dev *nforce2_sub5; |
141 | u32 fsb, temp = 0; | 139 | u32 fsb, temp = 0; |
142 | 140 | ||
143 | |||
144 | /* Get chipset boot FSB from subdevice 5 (FSB at boot-time) */ | 141 | /* Get chipset boot FSB from subdevice 5 (FSB at boot-time) */ |
145 | nforce2_sub5 = pci_get_subsys(PCI_VENDOR_ID_NVIDIA, | 142 | nforce2_sub5 = pci_get_subsys(PCI_VENDOR_ID_NVIDIA, |
146 | 0x01EF, | 143 | 0x01EF,PCI_ANY_ID,PCI_ANY_ID,NULL); |
147 | PCI_ANY_ID, | ||
148 | PCI_ANY_ID, | ||
149 | NULL); | ||
150 | |||
151 | if (!nforce2_sub5) | 144 | if (!nforce2_sub5) |
152 | return 0; | 145 | return 0; |
153 | 146 | ||
154 | pci_read_config_dword(nforce2_sub5, NFORCE2_BOOTFSB, &fsb); | 147 | pci_read_config_dword(nforce2_sub5, NFORCE2_BOOTFSB, &fsb); |
155 | fsb /= 1000000; | 148 | fsb /= 1000000; |
156 | 149 | ||
157 | /* Check if PLL register is already set */ | 150 | /* Check if PLL register is already set */ |
158 | pci_read_config_byte(nforce2_chipset_dev, | 151 | pci_read_config_byte(nforce2_chipset_dev,NFORCE2_PLLENABLE, (u8 *)&temp); |
159 | NFORCE2_PLLENABLE, (u8 *)&temp); | 152 | |
160 | |||
161 | if(bootfsb || !temp) | 153 | if(bootfsb || !temp) |
162 | return fsb; | 154 | return fsb; |
163 | 155 | ||
164 | /* Use PLL register FSB value */ | 156 | /* Use PLL register FSB value */ |
165 | pci_read_config_dword(nforce2_chipset_dev, | 157 | pci_read_config_dword(nforce2_chipset_dev,NFORCE2_PLLREG, &temp); |
166 | NFORCE2_PLLREG, &temp); | ||
167 | fsb = nforce2_calc_fsb(temp); | 158 | fsb = nforce2_calc_fsb(temp); |
168 | 159 | ||
169 | return fsb; | 160 | return fsb; |
170 | } | 161 | } |
171 | 162 | ||
172 | /* | 163 | /** |
173 | * nforce2_set_fsb - set new FSB | 164 | * nforce2_set_fsb - set new FSB |
174 | * @fsb: New FSB | 165 | * @fsb: New FSB |
175 | * | 166 | * |
176 | * Sets new FSB | 167 | * Sets new FSB |
177 | */ | 168 | */ |
178 | static int nforce2_set_fsb(unsigned int fsb) | 169 | static int nforce2_set_fsb(unsigned int fsb) |
@@ -186,7 +177,7 @@ static int nforce2_set_fsb(unsigned int fsb) | |||
186 | printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb); | 177 | printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb); |
187 | return -EINVAL; | 178 | return -EINVAL; |
188 | } | 179 | } |
189 | 180 | ||
190 | tfsb = nforce2_fsb_read(0); | 181 | tfsb = nforce2_fsb_read(0); |
191 | if (!tfsb) { | 182 | if (!tfsb) { |
192 | printk(KERN_ERR "cpufreq: Error while reading the FSB\n"); | 183 | printk(KERN_ERR "cpufreq: Error while reading the FSB\n"); |
@@ -194,8 +185,7 @@ static int nforce2_set_fsb(unsigned int fsb) | |||
194 | } | 185 | } |
195 | 186 | ||
196 | /* First write? Then set actual value */ | 187 | /* First write? Then set actual value */ |
197 | pci_read_config_byte(nforce2_chipset_dev, | 188 | pci_read_config_byte(nforce2_chipset_dev,NFORCE2_PLLENABLE, (u8 *)&temp); |
198 | NFORCE2_PLLENABLE, (u8 *)&temp); | ||
199 | if (!temp) { | 189 | if (!temp) { |
200 | pll = nforce2_calc_pll(tfsb); | 190 | pll = nforce2_calc_pll(tfsb); |
201 | 191 | ||
@@ -223,7 +213,7 @@ static int nforce2_set_fsb(unsigned int fsb) | |||
223 | /* Calculate the PLL reg. value */ | 213 | /* Calculate the PLL reg. value */ |
224 | if ((pll = nforce2_calc_pll(tfsb)) == -1) | 214 | if ((pll = nforce2_calc_pll(tfsb)) == -1) |
225 | return -EINVAL; | 215 | return -EINVAL; |
226 | 216 | ||
227 | nforce2_write_pll(pll); | 217 | nforce2_write_pll(pll); |
228 | #ifdef NFORCE2_DELAY | 218 | #ifdef NFORCE2_DELAY |
229 | mdelay(NFORCE2_DELAY); | 219 | mdelay(NFORCE2_DELAY); |
@@ -239,7 +229,7 @@ static int nforce2_set_fsb(unsigned int fsb) | |||
239 | /** | 229 | /** |
240 | * nforce2_get - get the CPU frequency | 230 | * nforce2_get - get the CPU frequency |
241 | * @cpu: CPU number | 231 | * @cpu: CPU number |
242 | * | 232 | * |
243 | * Returns the CPU frequency | 233 | * Returns the CPU frequency |
244 | */ | 234 | */ |
245 | static unsigned int nforce2_get(unsigned int cpu) | 235 | static unsigned int nforce2_get(unsigned int cpu) |
@@ -354,10 +344,10 @@ static int nforce2_cpu_init(struct cpufreq_policy *policy) | |||
354 | 344 | ||
355 | printk(KERN_INFO "cpufreq: FSB currently at %i MHz, FID %d.%d\n", fsb, | 345 | printk(KERN_INFO "cpufreq: FSB currently at %i MHz, FID %d.%d\n", fsb, |
356 | fid / 10, fid % 10); | 346 | fid / 10, fid % 10); |
357 | 347 | ||
358 | /* Set maximum FSB to FSB at boot time */ | 348 | /* Set maximum FSB to FSB at boot time */ |
359 | max_fsb = nforce2_fsb_read(1); | 349 | max_fsb = nforce2_fsb_read(1); |
360 | 350 | ||
361 | if(!max_fsb) | 351 | if(!max_fsb) |
362 | return -EIO; | 352 | return -EIO; |
363 | 353 | ||
@@ -398,17 +388,15 @@ static struct cpufreq_driver nforce2_driver = { | |||
398 | * nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic | 388 | * nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic |
399 | * | 389 | * |
400 | * Detects nForce2 A2 and C1 stepping | 390 | * Detects nForce2 A2 and C1 stepping |
401 | * | 391 | * |
402 | */ | 392 | */ |
403 | static unsigned int nforce2_detect_chipset(void) | 393 | static unsigned int nforce2_detect_chipset(void) |
404 | { | 394 | { |
405 | u8 revision; | 395 | u8 revision; |
406 | 396 | ||
407 | nforce2_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA, | 397 | nforce2_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA, |
408 | PCI_DEVICE_ID_NVIDIA_NFORCE2, | 398 | PCI_DEVICE_ID_NVIDIA_NFORCE2, |
409 | PCI_ANY_ID, | 399 | PCI_ANY_ID, PCI_ANY_ID, NULL); |
410 | PCI_ANY_ID, | ||
411 | NULL); | ||
412 | 400 | ||
413 | if (nforce2_chipset_dev == NULL) | 401 | if (nforce2_chipset_dev == NULL) |
414 | return -ENODEV; | 402 | return -ENODEV; |
diff --git a/arch/i386/kernel/cpu/cpufreq/elanfreq.c b/arch/i386/kernel/cpu/cpufreq/elanfreq.c index 3f7caa4ae6d6..f317276afa7a 100644 --- a/arch/i386/kernel/cpu/cpufreq/elanfreq.c +++ b/arch/i386/kernel/cpu/cpufreq/elanfreq.c | |||
@@ -1,16 +1,16 @@ | |||
1 | /* | 1 | /* |
2 | * elanfreq: cpufreq driver for the AMD ELAN family | 2 | * elanfreq: cpufreq driver for the AMD ELAN family |
3 | * | 3 | * |
4 | * (c) Copyright 2002 Robert Schwebel <r.schwebel@pengutronix.de> | 4 | * (c) Copyright 2002 Robert Schwebel <r.schwebel@pengutronix.de> |
5 | * | 5 | * |
6 | * Parts of this code are (c) Sven Geggus <sven@geggus.net> | 6 | * Parts of this code are (c) Sven Geggus <sven@geggus.net> |
7 | * | 7 | * |
8 | * All Rights Reserved. | 8 | * All Rights Reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
11 | * modify it under the terms of the GNU General Public License | 11 | * modify it under the terms of the GNU General Public License |
12 | * as published by the Free Software Foundation; either version | 12 | * as published by the Free Software Foundation; either version |
13 | * 2 of the License, or (at your option) any later version. | 13 | * 2 of the License, or (at your option) any later version. |
14 | * | 14 | * |
15 | * 2002-02-13: - initial revision for 2.4.18-pre9 by Robert Schwebel | 15 | * 2002-02-13: - initial revision for 2.4.18-pre9 by Robert Schwebel |
16 | * | 16 | * |
@@ -28,7 +28,7 @@ | |||
28 | #include <asm/timex.h> | 28 | #include <asm/timex.h> |
29 | #include <asm/io.h> | 29 | #include <asm/io.h> |
30 | 30 | ||
31 | #define REG_CSCIR 0x22 /* Chip Setup and Control Index Register */ | 31 | #define REG_CSCIR 0x22 /* Chip Setup and Control Index Register */ |
32 | #define REG_CSCDR 0x23 /* Chip Setup and Control Data Register */ | 32 | #define REG_CSCDR 0x23 /* Chip Setup and Control Data Register */ |
33 | 33 | ||
34 | /* Module parameter */ | 34 | /* Module parameter */ |
@@ -41,7 +41,7 @@ struct s_elan_multiplier { | |||
41 | }; | 41 | }; |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * It is important that the frequencies | 44 | * It is important that the frequencies |
45 | * are listed in ascending order here! | 45 | * are listed in ascending order here! |
46 | */ | 46 | */ |
47 | struct s_elan_multiplier elan_multiplier[] = { | 47 | struct s_elan_multiplier elan_multiplier[] = { |
@@ -72,78 +72,79 @@ static struct cpufreq_frequency_table elanfreq_table[] = { | |||
72 | * elanfreq_get_cpu_frequency: determine current cpu speed | 72 | * elanfreq_get_cpu_frequency: determine current cpu speed |
73 | * | 73 | * |
74 | * Finds out at which frequency the CPU of the Elan SOC runs | 74 | * Finds out at which frequency the CPU of the Elan SOC runs |
75 | * at the moment. Frequencies from 1 to 33 MHz are generated | 75 | * at the moment. Frequencies from 1 to 33 MHz are generated |
76 | * the normal way, 66 and 99 MHz are called "Hyperspeed Mode" | 76 | * the normal way, 66 and 99 MHz are called "Hyperspeed Mode" |
77 | * and have the rest of the chip running with 33 MHz. | 77 | * and have the rest of the chip running with 33 MHz. |
78 | */ | 78 | */ |
79 | 79 | ||
80 | static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu) | 80 | static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu) |
81 | { | 81 | { |
82 | u8 clockspeed_reg; /* Clock Speed Register */ | 82 | u8 clockspeed_reg; /* Clock Speed Register */ |
83 | 83 | ||
84 | local_irq_disable(); | 84 | local_irq_disable(); |
85 | outb_p(0x80,REG_CSCIR); | 85 | outb_p(0x80,REG_CSCIR); |
86 | clockspeed_reg = inb_p(REG_CSCDR); | 86 | clockspeed_reg = inb_p(REG_CSCDR); |
87 | local_irq_enable(); | 87 | local_irq_enable(); |
88 | 88 | ||
89 | if ((clockspeed_reg & 0xE0) == 0xE0) { return 0; } | 89 | if ((clockspeed_reg & 0xE0) == 0xE0) |
90 | return 0; | ||
90 | 91 | ||
91 | /* Are we in CPU clock multiplied mode (66/99 MHz)? */ | 92 | /* Are we in CPU clock multiplied mode (66/99 MHz)? */ |
92 | if ((clockspeed_reg & 0xE0) == 0xC0) { | 93 | if ((clockspeed_reg & 0xE0) == 0xC0) { |
93 | if ((clockspeed_reg & 0x01) == 0) { | 94 | if ((clockspeed_reg & 0x01) == 0) |
94 | return 66000; | 95 | return 66000; |
95 | } else { | 96 | else |
96 | return 99000; | 97 | return 99000; |
97 | } | 98 | } |
98 | } | ||
99 | 99 | ||
100 | /* 33 MHz is not 32 MHz... */ | 100 | /* 33 MHz is not 32 MHz... */ |
101 | if ((clockspeed_reg & 0xE0)==0xA0) | 101 | if ((clockspeed_reg & 0xE0)==0xA0) |
102 | return 33000; | 102 | return 33000; |
103 | 103 | ||
104 | return ((1<<((clockspeed_reg & 0xE0) >> 5)) * 1000); | 104 | return ((1<<((clockspeed_reg & 0xE0) >> 5)) * 1000); |
105 | } | 105 | } |
106 | 106 | ||
107 | 107 | ||
108 | /** | 108 | /** |
109 | * elanfreq_set_cpu_frequency: Change the CPU core frequency | 109 | * elanfreq_set_cpu_frequency: Change the CPU core frequency |
110 | * @cpu: cpu number | 110 | * @cpu: cpu number |
111 | * @freq: frequency in kHz | 111 | * @freq: frequency in kHz |
112 | * | 112 | * |
113 | * This function takes a frequency value and changes the CPU frequency | 113 | * This function takes a frequency value and changes the CPU frequency |
114 | * according to this. Note that the frequency has to be checked by | 114 | * according to this. Note that the frequency has to be checked by |
115 | * elanfreq_validatespeed() for correctness! | 115 | * elanfreq_validatespeed() for correctness! |
116 | * | 116 | * |
117 | * There is no return value. | 117 | * There is no return value. |
118 | */ | 118 | */ |
119 | 119 | ||
120 | static void elanfreq_set_cpu_state (unsigned int state) { | 120 | static void elanfreq_set_cpu_state (unsigned int state) |
121 | 121 | { | |
122 | struct cpufreq_freqs freqs; | 122 | struct cpufreq_freqs freqs; |
123 | 123 | ||
124 | freqs.old = elanfreq_get_cpu_frequency(0); | 124 | freqs.old = elanfreq_get_cpu_frequency(0); |
125 | freqs.new = elan_multiplier[state].clock; | 125 | freqs.new = elan_multiplier[state].clock; |
126 | freqs.cpu = 0; /* elanfreq.c is UP only driver */ | 126 | freqs.cpu = 0; /* elanfreq.c is UP only driver */ |
127 | 127 | ||
128 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 128 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); |
129 | 129 | ||
130 | printk(KERN_INFO "elanfreq: attempting to set frequency to %i kHz\n",elan_multiplier[state].clock); | 130 | printk(KERN_INFO "elanfreq: attempting to set frequency to %i kHz\n", |
131 | elan_multiplier[state].clock); | ||
131 | 132 | ||
132 | 133 | ||
133 | /* | 134 | /* |
134 | * Access to the Elan's internal registers is indexed via | 135 | * Access to the Elan's internal registers is indexed via |
135 | * 0x22: Chip Setup & Control Register Index Register (CSCI) | 136 | * 0x22: Chip Setup & Control Register Index Register (CSCI) |
136 | * 0x23: Chip Setup & Control Register Data Register (CSCD) | 137 | * 0x23: Chip Setup & Control Register Data Register (CSCD) |
137 | * | 138 | * |
138 | */ | 139 | */ |
139 | 140 | ||
140 | /* | 141 | /* |
141 | * 0x40 is the Power Management Unit's Force Mode Register. | 142 | * 0x40 is the Power Management Unit's Force Mode Register. |
142 | * Bit 6 enables Hyperspeed Mode (66/100 MHz core frequency) | 143 | * Bit 6 enables Hyperspeed Mode (66/100 MHz core frequency) |
143 | */ | 144 | */ |
144 | 145 | ||
145 | local_irq_disable(); | 146 | local_irq_disable(); |
146 | outb_p(0x40,REG_CSCIR); /* Disable hyperspeed mode */ | 147 | outb_p(0x40,REG_CSCIR); /* Disable hyperspeed mode */ |
147 | outb_p(0x00,REG_CSCDR); | 148 | outb_p(0x00,REG_CSCDR); |
148 | local_irq_enable(); /* wait till internal pipelines and */ | 149 | local_irq_enable(); /* wait till internal pipelines and */ |
149 | udelay(1000); /* buffers have cleaned up */ | 150 | udelay(1000); /* buffers have cleaned up */ |
@@ -166,10 +167,10 @@ static void elanfreq_set_cpu_state (unsigned int state) { | |||
166 | 167 | ||
167 | /** | 168 | /** |
168 | * elanfreq_validatespeed: test if frequency range is valid | 169 | * elanfreq_validatespeed: test if frequency range is valid |
169 | * @policy: the policy to validate | 170 | * @policy: the policy to validate |
170 | * | 171 | * |
171 | * This function checks if a given frequency range in kHz is valid | 172 | * This function checks if a given frequency range in kHz is valid |
172 | * for the hardware supported by the driver. | 173 | * for the hardware supported by the driver. |
173 | */ | 174 | */ |
174 | 175 | ||
175 | static int elanfreq_verify (struct cpufreq_policy *policy) | 176 | static int elanfreq_verify (struct cpufreq_policy *policy) |
@@ -177,11 +178,11 @@ static int elanfreq_verify (struct cpufreq_policy *policy) | |||
177 | return cpufreq_frequency_table_verify(policy, &elanfreq_table[0]); | 178 | return cpufreq_frequency_table_verify(policy, &elanfreq_table[0]); |
178 | } | 179 | } |
179 | 180 | ||
180 | static int elanfreq_target (struct cpufreq_policy *policy, | 181 | static int elanfreq_target (struct cpufreq_policy *policy, |
181 | unsigned int target_freq, | 182 | unsigned int target_freq, |
182 | unsigned int relation) | 183 | unsigned int relation) |
183 | { | 184 | { |
184 | unsigned int newstate = 0; | 185 | unsigned int newstate = 0; |
185 | 186 | ||
186 | if (cpufreq_frequency_table_target(policy, &elanfreq_table[0], target_freq, relation, &newstate)) | 187 | if (cpufreq_frequency_table_target(policy, &elanfreq_table[0], target_freq, relation, &newstate)) |
187 | return -EINVAL; | 188 | return -EINVAL; |
@@ -212,7 +213,7 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy) | |||
212 | max_freq = elanfreq_get_cpu_frequency(0); | 213 | max_freq = elanfreq_get_cpu_frequency(0); |
213 | 214 | ||
214 | /* table init */ | 215 | /* table init */ |
215 | for (i=0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) { | 216 | for (i=0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) { |
216 | if (elanfreq_table[i].frequency > max_freq) | 217 | if (elanfreq_table[i].frequency > max_freq) |
217 | elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 218 | elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID; |
218 | } | 219 | } |
@@ -226,8 +227,7 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy) | |||
226 | if (result) | 227 | if (result) |
227 | return (result); | 228 | return (result); |
228 | 229 | ||
229 | cpufreq_frequency_table_get_attr(elanfreq_table, policy->cpu); | 230 | cpufreq_frequency_table_get_attr(elanfreq_table, policy->cpu); |
230 | |||
231 | return 0; | 231 | return 0; |
232 | } | 232 | } |
233 | 233 | ||
@@ -268,9 +268,9 @@ static struct freq_attr* elanfreq_attr[] = { | |||
268 | 268 | ||
269 | 269 | ||
270 | static struct cpufreq_driver elanfreq_driver = { | 270 | static struct cpufreq_driver elanfreq_driver = { |
271 | .get = elanfreq_get_cpu_frequency, | 271 | .get = elanfreq_get_cpu_frequency, |
272 | .verify = elanfreq_verify, | 272 | .verify = elanfreq_verify, |
273 | .target = elanfreq_target, | 273 | .target = elanfreq_target, |
274 | .init = elanfreq_cpu_init, | 274 | .init = elanfreq_cpu_init, |
275 | .exit = elanfreq_cpu_exit, | 275 | .exit = elanfreq_cpu_exit, |
276 | .name = "elanfreq", | 276 | .name = "elanfreq", |
@@ -279,23 +279,21 @@ static struct cpufreq_driver elanfreq_driver = { | |||
279 | }; | 279 | }; |
280 | 280 | ||
281 | 281 | ||
282 | static int __init elanfreq_init(void) | 282 | static int __init elanfreq_init(void) |
283 | { | 283 | { |
284 | struct cpuinfo_x86 *c = cpu_data; | 284 | struct cpuinfo_x86 *c = cpu_data; |
285 | 285 | ||
286 | /* Test if we have the right hardware */ | 286 | /* Test if we have the right hardware */ |
287 | if ((c->x86_vendor != X86_VENDOR_AMD) || | 287 | if ((c->x86_vendor != X86_VENDOR_AMD) || |
288 | (c->x86 != 4) || (c->x86_model!=10)) | 288 | (c->x86 != 4) || (c->x86_model!=10)) { |
289 | { | ||
290 | printk(KERN_INFO "elanfreq: error: no Elan processor found!\n"); | 289 | printk(KERN_INFO "elanfreq: error: no Elan processor found!\n"); |
291 | return -ENODEV; | 290 | return -ENODEV; |
292 | } | 291 | } |
293 | |||
294 | return cpufreq_register_driver(&elanfreq_driver); | 292 | return cpufreq_register_driver(&elanfreq_driver); |
295 | } | 293 | } |
296 | 294 | ||
297 | 295 | ||
298 | static void __exit elanfreq_exit(void) | 296 | static void __exit elanfreq_exit(void) |
299 | { | 297 | { |
300 | cpufreq_unregister_driver(&elanfreq_driver); | 298 | cpufreq_unregister_driver(&elanfreq_driver); |
301 | } | 299 | } |
@@ -309,4 +307,3 @@ MODULE_DESCRIPTION("cpufreq driver for AMD's Elan CPUs"); | |||
309 | 307 | ||
310 | module_init(elanfreq_init); | 308 | module_init(elanfreq_init); |
311 | module_exit(elanfreq_exit); | 309 | module_exit(elanfreq_exit); |
312 | |||
diff --git a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c index e86ea486c311..92afa3bc84f1 100644 --- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c +++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c | |||
@@ -6,12 +6,12 @@ | |||
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License | 8 | * modify it under the terms of the GNU General Public License |
9 | * version 2 as published by the Free Software Foundation | 9 | * version 2 as published by the Free Software Foundation |
10 | * | 10 | * |
11 | * The author(s) of this software shall not be held liable for damages | 11 | * The author(s) of this software shall not be held liable for damages |
12 | * of any nature resulting due to the use of this software. This | 12 | * of any nature resulting due to the use of this software. This |
13 | * software is provided AS-IS with no warranties. | 13 | * software is provided AS-IS with no warranties. |
14 | * | 14 | * |
15 | * Theoritical note: | 15 | * Theoritical note: |
16 | * | 16 | * |
17 | * (see Geode(tm) CS5530 manual (rev.4.1) page.56) | 17 | * (see Geode(tm) CS5530 manual (rev.4.1) page.56) |
@@ -21,18 +21,18 @@ | |||
21 | * | 21 | * |
22 | * Suspend Modulation works by asserting and de-asserting the SUSP# pin | 22 | * Suspend Modulation works by asserting and de-asserting the SUSP# pin |
23 | * to CPU(GX1/GXLV) for configurable durations. When asserting SUSP# | 23 | * to CPU(GX1/GXLV) for configurable durations. When asserting SUSP# |
24 | * the CPU enters an idle state. GX1 stops its core clock when SUSP# is | 24 | * the CPU enters an idle state. GX1 stops its core clock when SUSP# is |
25 | * asserted then power consumption is reduced. | 25 | * asserted then power consumption is reduced. |
26 | * | 26 | * |
27 | * Suspend Modulation's OFF/ON duration are configurable | 27 | * Suspend Modulation's OFF/ON duration are configurable |
28 | * with 'Suspend Modulation OFF Count Register' | 28 | * with 'Suspend Modulation OFF Count Register' |
29 | * and 'Suspend Modulation ON Count Register'. | 29 | * and 'Suspend Modulation ON Count Register'. |
30 | * These registers are 8bit counters that represent the number of | 30 | * These registers are 8bit counters that represent the number of |
31 | * 32us intervals which the SUSP# pin is asserted(ON)/de-asserted(OFF) | 31 | * 32us intervals which the SUSP# pin is asserted(ON)/de-asserted(OFF) |
32 | * to the processor. | 32 | * to the processor. |
33 | * | 33 | * |
34 | * These counters define a ratio which is the effective frequency | 34 | * These counters define a ratio which is the effective frequency |
35 | * of operation of the system. | 35 | * of operation of the system. |
36 | * | 36 | * |
37 | * OFF Count | 37 | * OFF Count |
38 | * F_eff = Fgx * ---------------------- | 38 | * F_eff = Fgx * ---------------------- |
@@ -40,24 +40,24 @@ | |||
40 | * | 40 | * |
41 | * 0 <= On Count, Off Count <= 255 | 41 | * 0 <= On Count, Off Count <= 255 |
42 | * | 42 | * |
43 | * From these limits, we can get register values | 43 | * From these limits, we can get register values |
44 | * | 44 | * |
45 | * off_duration + on_duration <= MAX_DURATION | 45 | * off_duration + on_duration <= MAX_DURATION |
46 | * on_duration = off_duration * (stock_freq - freq) / freq | 46 | * on_duration = off_duration * (stock_freq - freq) / freq |
47 | * | 47 | * |
48 | * off_duration = (freq * DURATION) / stock_freq | 48 | * off_duration = (freq * DURATION) / stock_freq |
49 | * on_duration = DURATION - off_duration | 49 | * on_duration = DURATION - off_duration |
50 | * | 50 | * |
51 | * | 51 | * |
52 | *--------------------------------------------------------------------------- | 52 | *--------------------------------------------------------------------------- |
53 | * | 53 | * |
54 | * ChangeLog: | 54 | * ChangeLog: |
55 | * Dec. 12, 2003 Hiroshi Miura <miura@da-cha.org> | 55 | * Dec. 12, 2003 Hiroshi Miura <miura@da-cha.org> |
56 | * - fix on/off register mistake | 56 | * - fix on/off register mistake |
57 | * - fix cpu_khz calc when it stops cpu modulation. | 57 | * - fix cpu_khz calc when it stops cpu modulation. |
58 | * | 58 | * |
59 | * Dec. 11, 2002 Hiroshi Miura <miura@da-cha.org> | 59 | * Dec. 11, 2002 Hiroshi Miura <miura@da-cha.org> |
60 | * - rewrite for Cyrix MediaGX Cx5510/5520 and | 60 | * - rewrite for Cyrix MediaGX Cx5510/5520 and |
61 | * NatSemi Geode Cs5530(A). | 61 | * NatSemi Geode Cs5530(A). |
62 | * | 62 | * |
63 | * Jul. ??, 2002 Zwane Mwaikambo <zwane@commfireservices.com> | 63 | * Jul. ??, 2002 Zwane Mwaikambo <zwane@commfireservices.com> |
@@ -74,40 +74,40 @@ | |||
74 | ************************************************************************/ | 74 | ************************************************************************/ |
75 | 75 | ||
76 | #include <linux/kernel.h> | 76 | #include <linux/kernel.h> |
77 | #include <linux/module.h> | 77 | #include <linux/module.h> |
78 | #include <linux/init.h> | 78 | #include <linux/init.h> |
79 | #include <linux/smp.h> | 79 | #include <linux/smp.h> |
80 | #include <linux/cpufreq.h> | 80 | #include <linux/cpufreq.h> |
81 | #include <linux/pci.h> | 81 | #include <linux/pci.h> |
82 | #include <asm/processor.h> | 82 | #include <asm/processor.h> |
83 | #include <asm/errno.h> | 83 | #include <asm/errno.h> |
84 | 84 | ||
85 | /* PCI config registers, all at F0 */ | 85 | /* PCI config registers, all at F0 */ |
86 | #define PCI_PMER1 0x80 /* power management enable register 1 */ | 86 | #define PCI_PMER1 0x80 /* power management enable register 1 */ |
87 | #define PCI_PMER2 0x81 /* power management enable register 2 */ | 87 | #define PCI_PMER2 0x81 /* power management enable register 2 */ |
88 | #define PCI_PMER3 0x82 /* power management enable register 3 */ | 88 | #define PCI_PMER3 0x82 /* power management enable register 3 */ |
89 | #define PCI_IRQTC 0x8c /* irq speedup timer counter register:typical 2 to 4ms */ | 89 | #define PCI_IRQTC 0x8c /* irq speedup timer counter register:typical 2 to 4ms */ |
90 | #define PCI_VIDTC 0x8d /* video speedup timer counter register: typical 50 to 100ms */ | 90 | #define PCI_VIDTC 0x8d /* video speedup timer counter register: typical 50 to 100ms */ |
91 | #define PCI_MODOFF 0x94 /* suspend modulation OFF counter register, 1 = 32us */ | 91 | #define PCI_MODOFF 0x94 /* suspend modulation OFF counter register, 1 = 32us */ |
92 | #define PCI_MODON 0x95 /* suspend modulation ON counter register */ | 92 | #define PCI_MODON 0x95 /* suspend modulation ON counter register */ |
93 | #define PCI_SUSCFG 0x96 /* suspend configuration register */ | 93 | #define PCI_SUSCFG 0x96 /* suspend configuration register */ |
94 | 94 | ||
95 | /* PMER1 bits */ | 95 | /* PMER1 bits */ |
96 | #define GPM (1<<0) /* global power management */ | 96 | #define GPM (1<<0) /* global power management */ |
97 | #define GIT (1<<1) /* globally enable PM device idle timers */ | 97 | #define GIT (1<<1) /* globally enable PM device idle timers */ |
98 | #define GTR (1<<2) /* globally enable IO traps */ | 98 | #define GTR (1<<2) /* globally enable IO traps */ |
99 | #define IRQ_SPDUP (1<<3) /* disable clock throttle during interrupt handling */ | 99 | #define IRQ_SPDUP (1<<3) /* disable clock throttle during interrupt handling */ |
100 | #define VID_SPDUP (1<<4) /* disable clock throttle during vga video handling */ | 100 | #define VID_SPDUP (1<<4) /* disable clock throttle during vga video handling */ |
101 | 101 | ||
102 | /* SUSCFG bits */ | 102 | /* SUSCFG bits */ |
103 | #define SUSMOD (1<<0) /* enable/disable suspend modulation */ | 103 | #define SUSMOD (1<<0) /* enable/disable suspend modulation */ |
104 | /* the belows support only with cs5530 (after rev.1.2)/cs5530A */ | 104 | /* the belows support only with cs5530 (after rev.1.2)/cs5530A */ |
105 | #define SMISPDUP (1<<1) /* select how SMI re-enable suspend modulation: */ | 105 | #define SMISPDUP (1<<1) /* select how SMI re-enable suspend modulation: */ |
106 | /* IRQTC timer or read SMI speedup disable reg.(F1BAR[08-09h]) */ | 106 | /* IRQTC timer or read SMI speedup disable reg.(F1BAR[08-09h]) */ |
107 | #define SUSCFG (1<<2) /* enable powering down a GXLV processor. "Special 3Volt Suspend" mode */ | 107 | #define SUSCFG (1<<2) /* enable powering down a GXLV processor. "Special 3Volt Suspend" mode */ |
108 | /* the belows support only with cs5530A */ | 108 | /* the belows support only with cs5530A */ |
109 | #define PWRSVE_ISA (1<<3) /* stop ISA clock */ | 109 | #define PWRSVE_ISA (1<<3) /* stop ISA clock */ |
110 | #define PWRSVE (1<<4) /* active idle */ | 110 | #define PWRSVE (1<<4) /* active idle */ |
111 | 111 | ||
112 | struct gxfreq_params { | 112 | struct gxfreq_params { |
113 | u8 on_duration; | 113 | u8 on_duration; |
@@ -128,7 +128,7 @@ module_param (pci_busclk, int, 0444); | |||
128 | 128 | ||
129 | /* maximum duration for which the cpu may be suspended | 129 | /* maximum duration for which the cpu may be suspended |
130 | * (32us * MAX_DURATION). If no parameter is given, this defaults | 130 | * (32us * MAX_DURATION). If no parameter is given, this defaults |
131 | * to 255. | 131 | * to 255. |
132 | * Note that this leads to a maximum of 8 ms(!) where the CPU clock | 132 | * Note that this leads to a maximum of 8 ms(!) where the CPU clock |
133 | * is suspended -- processing power is just 0.39% of what it used to be, | 133 | * is suspended -- processing power is just 0.39% of what it used to be, |
134 | * though. 781.25 kHz(!) for a 200 MHz processor -- wow. */ | 134 | * though. 781.25 kHz(!) for a 200 MHz processor -- wow. */ |
@@ -144,17 +144,17 @@ module_param (max_duration, int, 0444); | |||
144 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "gx-suspmod", msg) | 144 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "gx-suspmod", msg) |
145 | 145 | ||
146 | /** | 146 | /** |
147 | * we can detect a core multipiler from dir0_lsb | 147 | * we can detect a core multipiler from dir0_lsb |
148 | * from GX1 datasheet p.56, | 148 | * from GX1 datasheet p.56, |
149 | * MULT[3:0]: | 149 | * MULT[3:0]: |
150 | * 0000 = SYSCLK multiplied by 4 (test only) | 150 | * 0000 = SYSCLK multiplied by 4 (test only) |
151 | * 0001 = SYSCLK multiplied by 10 | 151 | * 0001 = SYSCLK multiplied by 10 |
152 | * 0010 = SYSCLK multiplied by 4 | 152 | * 0010 = SYSCLK multiplied by 4 |
153 | * 0011 = SYSCLK multiplied by 6 | 153 | * 0011 = SYSCLK multiplied by 6 |
154 | * 0100 = SYSCLK multiplied by 9 | 154 | * 0100 = SYSCLK multiplied by 9 |
155 | * 0101 = SYSCLK multiplied by 5 | 155 | * 0101 = SYSCLK multiplied by 5 |
156 | * 0110 = SYSCLK multiplied by 7 | 156 | * 0110 = SYSCLK multiplied by 7 |
157 | * 0111 = SYSCLK multiplied by 8 | 157 | * 0111 = SYSCLK multiplied by 8 |
158 | * of 33.3MHz | 158 | * of 33.3MHz |
159 | **/ | 159 | **/ |
160 | static int gx_freq_mult[16] = { | 160 | static int gx_freq_mult[16] = { |
@@ -164,17 +164,17 @@ static int gx_freq_mult[16] = { | |||
164 | 164 | ||
165 | 165 | ||
166 | /**************************************************************** | 166 | /**************************************************************** |
167 | * Low Level chipset interface * | 167 | * Low Level chipset interface * |
168 | ****************************************************************/ | 168 | ****************************************************************/ |
169 | static struct pci_device_id gx_chipset_tbl[] __initdata = { | 169 | static struct pci_device_id gx_chipset_tbl[] __initdata = { |
170 | { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, PCI_ANY_ID, PCI_ANY_ID }, | 170 | { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, PCI_ANY_ID, PCI_ANY_ID }, |
171 | { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, PCI_ANY_ID, PCI_ANY_ID }, | 171 | { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, PCI_ANY_ID, PCI_ANY_ID }, |
172 | { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, PCI_ANY_ID, PCI_ANY_ID }, | 172 | { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, PCI_ANY_ID, PCI_ANY_ID }, |
173 | { 0, }, | 173 | { 0, }, |
174 | }; | 174 | }; |
175 | 175 | ||
176 | /** | 176 | /** |
177 | * gx_detect_chipset: | 177 | * gx_detect_chipset: |
178 | * | 178 | * |
179 | **/ | 179 | **/ |
180 | static __init struct pci_dev *gx_detect_chipset(void) | 180 | static __init struct pci_dev *gx_detect_chipset(void) |
@@ -182,17 +182,16 @@ static __init struct pci_dev *gx_detect_chipset(void) | |||
182 | struct pci_dev *gx_pci = NULL; | 182 | struct pci_dev *gx_pci = NULL; |
183 | 183 | ||
184 | /* check if CPU is a MediaGX or a Geode. */ | 184 | /* check if CPU is a MediaGX or a Geode. */ |
185 | if ((current_cpu_data.x86_vendor != X86_VENDOR_NSC) && | 185 | if ((current_cpu_data.x86_vendor != X86_VENDOR_NSC) && |
186 | (current_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) { | 186 | (current_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) { |
187 | dprintk("error: no MediaGX/Geode processor found!\n"); | 187 | dprintk("error: no MediaGX/Geode processor found!\n"); |
188 | return NULL; | 188 | return NULL; |
189 | } | 189 | } |
190 | 190 | ||
191 | /* detect which companion chip is used */ | 191 | /* detect which companion chip is used */ |
192 | while ((gx_pci = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) { | 192 | while ((gx_pci = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) { |
193 | if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) { | 193 | if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) |
194 | return gx_pci; | 194 | return gx_pci; |
195 | } | ||
196 | } | 195 | } |
197 | 196 | ||
198 | dprintk("error: no supported chipset found!\n"); | 197 | dprintk("error: no supported chipset found!\n"); |
@@ -200,24 +199,24 @@ static __init struct pci_dev *gx_detect_chipset(void) | |||
200 | } | 199 | } |
201 | 200 | ||
202 | /** | 201 | /** |
203 | * gx_get_cpuspeed: | 202 | * gx_get_cpuspeed: |
204 | * | 203 | * |
205 | * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi Geode CPU runs. | 204 | * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi Geode CPU runs. |
206 | */ | 205 | */ |
207 | static unsigned int gx_get_cpuspeed(unsigned int cpu) | 206 | static unsigned int gx_get_cpuspeed(unsigned int cpu) |
208 | { | 207 | { |
209 | if ((gx_params->pci_suscfg & SUSMOD) == 0) | 208 | if ((gx_params->pci_suscfg & SUSMOD) == 0) |
210 | return stock_freq; | 209 | return stock_freq; |
211 | 210 | ||
212 | return (stock_freq * gx_params->off_duration) | 211 | return (stock_freq * gx_params->off_duration) |
213 | / (gx_params->on_duration + gx_params->off_duration); | 212 | / (gx_params->on_duration + gx_params->off_duration); |
214 | } | 213 | } |
215 | 214 | ||
216 | /** | 215 | /** |
217 | * gx_validate_speed: | 216 | * gx_validate_speed: |
218 | * determine current cpu speed | 217 | * determine current cpu speed |
219 | * | 218 | * |
220 | **/ | 219 | **/ |
221 | 220 | ||
222 | static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, u8 *off_duration) | 221 | static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, u8 *off_duration) |
223 | { | 222 | { |
@@ -230,7 +229,7 @@ static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, u8 *off | |||
230 | *on_duration=0; | 229 | *on_duration=0; |
231 | 230 | ||
232 | for (i=max_duration; i>0; i--) { | 231 | for (i=max_duration; i>0; i--) { |
233 | tmp_off = ((khz * i) / stock_freq) & 0xff; | 232 | tmp_off = ((khz * i) / stock_freq) & 0xff; |
234 | tmp_on = i - tmp_off; | 233 | tmp_on = i - tmp_off; |
235 | tmp_freq = (stock_freq * tmp_off) / i; | 234 | tmp_freq = (stock_freq * tmp_off) / i; |
236 | /* if this relation is closer to khz, use this. If it's equal, | 235 | /* if this relation is closer to khz, use this. If it's equal, |
@@ -247,18 +246,17 @@ static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, u8 *off | |||
247 | 246 | ||
248 | 247 | ||
249 | /** | 248 | /** |
250 | * gx_set_cpuspeed: | 249 | * gx_set_cpuspeed: |
251 | * set cpu speed in khz. | 250 | * set cpu speed in khz. |
252 | **/ | 251 | **/ |
253 | 252 | ||
254 | static void gx_set_cpuspeed(unsigned int khz) | 253 | static void gx_set_cpuspeed(unsigned int khz) |
255 | { | 254 | { |
256 | u8 suscfg, pmer1; | 255 | u8 suscfg, pmer1; |
257 | unsigned int new_khz; | 256 | unsigned int new_khz; |
258 | unsigned long flags; | 257 | unsigned long flags; |
259 | struct cpufreq_freqs freqs; | 258 | struct cpufreq_freqs freqs; |
260 | 259 | ||
261 | |||
262 | freqs.cpu = 0; | 260 | freqs.cpu = 0; |
263 | freqs.old = gx_get_cpuspeed(0); | 261 | freqs.old = gx_get_cpuspeed(0); |
264 | 262 | ||
@@ -303,18 +301,18 @@ static void gx_set_cpuspeed(unsigned int khz) | |||
303 | pci_write_config_byte(gx_params->cs55x0, PCI_MODOFF, gx_params->off_duration); | 301 | pci_write_config_byte(gx_params->cs55x0, PCI_MODOFF, gx_params->off_duration); |
304 | pci_write_config_byte(gx_params->cs55x0, PCI_MODON, gx_params->on_duration); | 302 | pci_write_config_byte(gx_params->cs55x0, PCI_MODON, gx_params->on_duration); |
305 | 303 | ||
306 | pci_write_config_byte(gx_params->cs55x0, PCI_SUSCFG, suscfg); | 304 | pci_write_config_byte(gx_params->cs55x0, PCI_SUSCFG, suscfg); |
307 | pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &suscfg); | 305 | pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &suscfg); |
308 | 306 | ||
309 | local_irq_restore(flags); | 307 | local_irq_restore(flags); |
310 | 308 | ||
311 | gx_params->pci_suscfg = suscfg; | 309 | gx_params->pci_suscfg = suscfg; |
312 | 310 | ||
313 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 311 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); |
314 | 312 | ||
315 | dprintk("suspend modulation w/ duration of ON:%d us, OFF:%d us\n", | 313 | dprintk("suspend modulation w/ duration of ON:%d us, OFF:%d us\n", |
316 | gx_params->on_duration * 32, gx_params->off_duration * 32); | 314 | gx_params->on_duration * 32, gx_params->off_duration * 32); |
317 | dprintk("suspend modulation w/ clock speed: %d kHz.\n", freqs.new); | 315 | dprintk("suspend modulation w/ clock speed: %d kHz.\n", freqs.new); |
318 | } | 316 | } |
319 | 317 | ||
320 | /**************************************************************** | 318 | /**************************************************************** |
@@ -322,10 +320,10 @@ static void gx_set_cpuspeed(unsigned int khz) | |||
322 | ****************************************************************/ | 320 | ****************************************************************/ |
323 | 321 | ||
324 | /* | 322 | /* |
325 | * cpufreq_gx_verify: test if frequency range is valid | 323 | * cpufreq_gx_verify: test if frequency range is valid |
326 | * | 324 | * |
327 | * This function checks if a given frequency range in kHz is valid | 325 | * This function checks if a given frequency range in kHz is valid |
328 | * for the hardware supported by the driver. | 326 | * for the hardware supported by the driver. |
329 | */ | 327 | */ |
330 | 328 | ||
331 | static int cpufreq_gx_verify(struct cpufreq_policy *policy) | 329 | static int cpufreq_gx_verify(struct cpufreq_policy *policy) |
@@ -333,8 +331,8 @@ static int cpufreq_gx_verify(struct cpufreq_policy *policy) | |||
333 | unsigned int tmp_freq = 0; | 331 | unsigned int tmp_freq = 0; |
334 | u8 tmp1, tmp2; | 332 | u8 tmp1, tmp2; |
335 | 333 | ||
336 | if (!stock_freq || !policy) | 334 | if (!stock_freq || !policy) |
337 | return -EINVAL; | 335 | return -EINVAL; |
338 | 336 | ||
339 | policy->cpu = 0; | 337 | policy->cpu = 0; |
340 | cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); | 338 | cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); |
@@ -342,14 +340,14 @@ static int cpufreq_gx_verify(struct cpufreq_policy *policy) | |||
342 | /* it needs to be assured that at least one supported frequency is | 340 | /* it needs to be assured that at least one supported frequency is |
343 | * within policy->min and policy->max. If it is not, policy->max | 341 | * within policy->min and policy->max. If it is not, policy->max |
344 | * needs to be increased until one freuqency is supported. | 342 | * needs to be increased until one freuqency is supported. |
345 | * policy->min may not be decreased, though. This way we guarantee a | 343 | * policy->min may not be decreased, though. This way we guarantee a |
346 | * specific processing capacity. | 344 | * specific processing capacity. |
347 | */ | 345 | */ |
348 | tmp_freq = gx_validate_speed(policy->min, &tmp1, &tmp2); | 346 | tmp_freq = gx_validate_speed(policy->min, &tmp1, &tmp2); |
349 | if (tmp_freq < policy->min) | 347 | if (tmp_freq < policy->min) |
350 | tmp_freq += stock_freq / max_duration; | 348 | tmp_freq += stock_freq / max_duration; |
351 | policy->min = tmp_freq; | 349 | policy->min = tmp_freq; |
352 | if (policy->min > policy->max) | 350 | if (policy->min > policy->max) |
353 | policy->max = tmp_freq; | 351 | policy->max = tmp_freq; |
354 | tmp_freq = gx_validate_speed(policy->max, &tmp1, &tmp2); | 352 | tmp_freq = gx_validate_speed(policy->max, &tmp1, &tmp2); |
355 | if (tmp_freq > policy->max) | 353 | if (tmp_freq > policy->max) |
@@ -358,12 +356,12 @@ static int cpufreq_gx_verify(struct cpufreq_policy *policy) | |||
358 | if (policy->max < policy->min) | 356 | if (policy->max < policy->min) |
359 | policy->max = policy->min; | 357 | policy->max = policy->min; |
360 | cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); | 358 | cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq); |
361 | 359 | ||
362 | return 0; | 360 | return 0; |
363 | } | 361 | } |
364 | 362 | ||
365 | /* | 363 | /* |
366 | * cpufreq_gx_target: | 364 | * cpufreq_gx_target: |
367 | * | 365 | * |
368 | */ | 366 | */ |
369 | static int cpufreq_gx_target(struct cpufreq_policy *policy, | 367 | static int cpufreq_gx_target(struct cpufreq_policy *policy, |
@@ -373,8 +371,8 @@ static int cpufreq_gx_target(struct cpufreq_policy *policy, | |||
373 | u8 tmp1, tmp2; | 371 | u8 tmp1, tmp2; |
374 | unsigned int tmp_freq; | 372 | unsigned int tmp_freq; |
375 | 373 | ||
376 | if (!stock_freq || !policy) | 374 | if (!stock_freq || !policy) |
377 | return -EINVAL; | 375 | return -EINVAL; |
378 | 376 | ||
379 | policy->cpu = 0; | 377 | policy->cpu = 0; |
380 | 378 | ||
@@ -431,7 +429,7 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy) | |||
431 | return 0; | 429 | return 0; |
432 | } | 430 | } |
433 | 431 | ||
434 | /* | 432 | /* |
435 | * cpufreq_gx_init: | 433 | * cpufreq_gx_init: |
436 | * MediaGX/Geode GX initialize cpufreq driver | 434 | * MediaGX/Geode GX initialize cpufreq driver |
437 | */ | 435 | */ |
@@ -452,7 +450,7 @@ static int __init cpufreq_gx_init(void) | |||
452 | u32 class_rev; | 450 | u32 class_rev; |
453 | 451 | ||
454 | /* Test if we have the right hardware */ | 452 | /* Test if we have the right hardware */ |
455 | if ((gx_pci = gx_detect_chipset()) == NULL) | 453 | if ((gx_pci = gx_detect_chipset()) == NULL) |
456 | return -ENODEV; | 454 | return -ENODEV; |
457 | 455 | ||
458 | /* check whether module parameters are sane */ | 456 | /* check whether module parameters are sane */ |
@@ -461,10 +459,9 @@ static int __init cpufreq_gx_init(void) | |||
461 | 459 | ||
462 | dprintk("geode suspend modulation available.\n"); | 460 | dprintk("geode suspend modulation available.\n"); |
463 | 461 | ||
464 | params = kmalloc(sizeof(struct gxfreq_params), GFP_KERNEL); | 462 | params = kzalloc(sizeof(struct gxfreq_params), GFP_KERNEL); |
465 | if (params == NULL) | 463 | if (params == NULL) |
466 | return -ENOMEM; | 464 | return -ENOMEM; |
467 | memset(params, 0, sizeof(struct gxfreq_params)); | ||
468 | 465 | ||
469 | params->cs55x0 = gx_pci; | 466 | params->cs55x0 = gx_pci; |
470 | gx_params = params; | 467 | gx_params = params; |
@@ -478,7 +475,7 @@ static int __init cpufreq_gx_init(void) | |||
478 | pci_read_config_dword(params->cs55x0, PCI_CLASS_REVISION, &class_rev); | 475 | pci_read_config_dword(params->cs55x0, PCI_CLASS_REVISION, &class_rev); |
479 | params->pci_rev = class_rev && 0xff; | 476 | params->pci_rev = class_rev && 0xff; |
480 | 477 | ||
481 | if ((ret = cpufreq_register_driver(&gx_suspmod_driver))) { | 478 | if ((ret = cpufreq_register_driver(&gx_suspmod_driver))) { |
482 | kfree(params); | 479 | kfree(params); |
483 | return ret; /* register error! */ | 480 | return ret; /* register error! */ |
484 | } | 481 | } |
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.h b/arch/i386/kernel/cpu/cpufreq/longhaul.h index 2a495c162ec7..d3a95d77ee85 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.h +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.h | |||
@@ -234,7 +234,7 @@ static int __initdata ezrat_eblcr[32] = { | |||
234 | 234 | ||
235 | /* | 235 | /* |
236 | * VIA C3 Nehemiah */ | 236 | * VIA C3 Nehemiah */ |
237 | 237 | ||
238 | static int __initdata nehemiah_a_clock_ratio[32] = { | 238 | static int __initdata nehemiah_a_clock_ratio[32] = { |
239 | 100, /* 0000 -> 10.0x */ | 239 | 100, /* 0000 -> 10.0x */ |
240 | 160, /* 0001 -> 16.0x */ | 240 | 160, /* 0001 -> 16.0x */ |
@@ -446,7 +446,7 @@ static int __initdata nehemiah_c_eblcr[32] = { | |||
446 | /* end of table */ | 446 | /* end of table */ |
447 | }; | 447 | }; |
448 | 448 | ||
449 | /* | 449 | /* |
450 | * Voltage scales. Div/Mod by 1000 to get actual voltage. | 450 | * Voltage scales. Div/Mod by 1000 to get actual voltage. |
451 | * Which scale to use depends on the VRM type in use. | 451 | * Which scale to use depends on the VRM type in use. |
452 | */ | 452 | */ |
diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c index cc73a7ae34bc..ab6504efd801 100644 --- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c | |||
@@ -14,7 +14,7 @@ | |||
14 | * The author(s) of this software shall not be held liable for damages | 14 | * The author(s) of this software shall not be held liable for damages |
15 | * of any nature resulting due to the use of this software. This | 15 | * of any nature resulting due to the use of this software. This |
16 | * software is provided AS-IS with no warranties. | 16 | * software is provided AS-IS with no warranties. |
17 | * | 17 | * |
18 | * Date Errata Description | 18 | * Date Errata Description |
19 | * 20020525 N44, O17 12.5% or 25% DC causes lockup | 19 | * 20020525 N44, O17 12.5% or 25% DC causes lockup |
20 | * | 20 | * |
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | #include <linux/config.h> | 23 | #include <linux/config.h> |
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/smp.h> | 27 | #include <linux/smp.h> |
28 | #include <linux/cpufreq.h> | 28 | #include <linux/cpufreq.h> |
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/cpumask.h> | 30 | #include <linux/cpumask.h> |
31 | #include <linux/sched.h> /* current / set_cpus_allowed() */ | 31 | #include <linux/sched.h> /* current / set_cpus_allowed() */ |
32 | 32 | ||
33 | #include <asm/processor.h> | 33 | #include <asm/processor.h> |
34 | #include <asm/msr.h> | 34 | #include <asm/msr.h> |
35 | #include <asm/timex.h> | 35 | #include <asm/timex.h> |
36 | 36 | ||
@@ -79,7 +79,7 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) | |||
79 | } else { | 79 | } else { |
80 | dprintk("CPU#%d setting duty cycle to %d%%\n", | 80 | dprintk("CPU#%d setting duty cycle to %d%%\n", |
81 | cpu, ((125 * newstate) / 10)); | 81 | cpu, ((125 * newstate) / 10)); |
82 | /* bits 63 - 5 : reserved | 82 | /* bits 63 - 5 : reserved |
83 | * bit 4 : enable/disable | 83 | * bit 4 : enable/disable |
84 | * bits 3-1 : duty cycle | 84 | * bits 3-1 : duty cycle |
85 | * bit 0 : reserved | 85 | * bit 0 : reserved |
@@ -132,7 +132,7 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy, | |||
132 | } | 132 | } |
133 | 133 | ||
134 | /* run on each logical CPU, see section 13.15.3 of IA32 Intel Architecture Software | 134 | /* run on each logical CPU, see section 13.15.3 of IA32 Intel Architecture Software |
135 | * Developer's Manual, Volume 3 | 135 | * Developer's Manual, Volume 3 |
136 | */ | 136 | */ |
137 | cpus_allowed = current->cpus_allowed; | 137 | cpus_allowed = current->cpus_allowed; |
138 | 138 | ||
@@ -206,7 +206,7 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c) | |||
206 | return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_P4D); | 206 | return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_P4D); |
207 | } | 207 | } |
208 | 208 | ||
209 | 209 | ||
210 | 210 | ||
211 | static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) | 211 | static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) |
212 | { | 212 | { |
@@ -234,7 +234,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) | |||
234 | dprintk("has errata -- disabling frequencies lower than 2ghz\n"); | 234 | dprintk("has errata -- disabling frequencies lower than 2ghz\n"); |
235 | break; | 235 | break; |
236 | } | 236 | } |
237 | 237 | ||
238 | /* get max frequency */ | 238 | /* get max frequency */ |
239 | stock_freq = cpufreq_p4_get_frequency(c); | 239 | stock_freq = cpufreq_p4_get_frequency(c); |
240 | if (!stock_freq) | 240 | if (!stock_freq) |
@@ -244,13 +244,13 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) | |||
244 | for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) { | 244 | for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) { |
245 | if ((i<2) && (has_N44_O17_errata[policy->cpu])) | 245 | if ((i<2) && (has_N44_O17_errata[policy->cpu])) |
246 | p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 246 | p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; |
247 | else if (has_N60_errata[policy->cpu] && p4clockmod_table[i].frequency < 2000000) | 247 | else if (has_N60_errata[policy->cpu] && ((stock_freq * i)/8) < 2000000) |
248 | p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 248 | p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; |
249 | else | 249 | else |
250 | p4clockmod_table[i].frequency = (stock_freq * i)/8; | 250 | p4clockmod_table[i].frequency = (stock_freq * i)/8; |
251 | } | 251 | } |
252 | cpufreq_frequency_table_get_attr(p4clockmod_table, policy->cpu); | 252 | cpufreq_frequency_table_get_attr(p4clockmod_table, policy->cpu); |
253 | 253 | ||
254 | /* cpuinfo and default policy values */ | 254 | /* cpuinfo and default policy values */ |
255 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | 255 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; |
256 | policy->cpuinfo.transition_latency = 1000000; /* assumed */ | 256 | policy->cpuinfo.transition_latency = 1000000; /* assumed */ |
@@ -262,7 +262,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) | |||
262 | 262 | ||
263 | static int cpufreq_p4_cpu_exit(struct cpufreq_policy *policy) | 263 | static int cpufreq_p4_cpu_exit(struct cpufreq_policy *policy) |
264 | { | 264 | { |
265 | cpufreq_frequency_table_put_attr(policy->cpu); | 265 | cpufreq_frequency_table_put_attr(policy->cpu); |
266 | return 0; | 266 | return 0; |
267 | } | 267 | } |
268 | 268 | ||
@@ -298,7 +298,7 @@ static struct freq_attr* p4clockmod_attr[] = { | |||
298 | }; | 298 | }; |
299 | 299 | ||
300 | static struct cpufreq_driver p4clockmod_driver = { | 300 | static struct cpufreq_driver p4clockmod_driver = { |
301 | .verify = cpufreq_p4_verify, | 301 | .verify = cpufreq_p4_verify, |
302 | .target = cpufreq_p4_target, | 302 | .target = cpufreq_p4_target, |
303 | .init = cpufreq_p4_cpu_init, | 303 | .init = cpufreq_p4_cpu_init, |
304 | .exit = cpufreq_p4_cpu_exit, | 304 | .exit = cpufreq_p4_cpu_exit, |
@@ -310,12 +310,12 @@ static struct cpufreq_driver p4clockmod_driver = { | |||
310 | 310 | ||
311 | 311 | ||
312 | static int __init cpufreq_p4_init(void) | 312 | static int __init cpufreq_p4_init(void) |
313 | { | 313 | { |
314 | struct cpuinfo_x86 *c = cpu_data; | 314 | struct cpuinfo_x86 *c = cpu_data; |
315 | int ret; | 315 | int ret; |
316 | 316 | ||
317 | /* | 317 | /* |
318 | * THERM_CONTROL is architectural for IA32 now, so | 318 | * THERM_CONTROL is architectural for IA32 now, so |
319 | * we can rely on the capability checks | 319 | * we can rely on the capability checks |
320 | */ | 320 | */ |
321 | if (c->x86_vendor != X86_VENDOR_INTEL) | 321 | if (c->x86_vendor != X86_VENDOR_INTEL) |
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c index 222f8cfe3c57..f89524051e4a 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c | |||
@@ -8,7 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/cpufreq.h> | 13 | #include <linux/cpufreq.h> |
14 | #include <linux/ioport.h> | 14 | #include <linux/ioport.h> |
@@ -50,7 +50,7 @@ static int powernow_k6_get_cpu_multiplier(void) | |||
50 | { | 50 | { |
51 | u64 invalue = 0; | 51 | u64 invalue = 0; |
52 | u32 msrval; | 52 | u32 msrval; |
53 | 53 | ||
54 | msrval = POWERNOW_IOPORT + 0x1; | 54 | msrval = POWERNOW_IOPORT + 0x1; |
55 | wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ | 55 | wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ |
56 | invalue=inl(POWERNOW_IOPORT + 0x8); | 56 | invalue=inl(POWERNOW_IOPORT + 0x8); |
@@ -81,7 +81,7 @@ static void powernow_k6_set_state (unsigned int best_i) | |||
81 | freqs.old = busfreq * powernow_k6_get_cpu_multiplier(); | 81 | freqs.old = busfreq * powernow_k6_get_cpu_multiplier(); |
82 | freqs.new = busfreq * clock_ratio[best_i].index; | 82 | freqs.new = busfreq * clock_ratio[best_i].index; |
83 | freqs.cpu = 0; /* powernow-k6.c is UP only driver */ | 83 | freqs.cpu = 0; /* powernow-k6.c is UP only driver */ |
84 | 84 | ||
85 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 85 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); |
86 | 86 | ||
87 | /* we now need to transform best_i to the BVC format, see AMD#23446 */ | 87 | /* we now need to transform best_i to the BVC format, see AMD#23446 */ |
@@ -152,7 +152,7 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy) | |||
152 | busfreq = cpu_khz / max_multiplier; | 152 | busfreq = cpu_khz / max_multiplier; |
153 | 153 | ||
154 | /* table init */ | 154 | /* table init */ |
155 | for (i=0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { | 155 | for (i=0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { |
156 | if (clock_ratio[i].index > max_multiplier) | 156 | if (clock_ratio[i].index > max_multiplier) |
157 | clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID; | 157 | clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID; |
158 | else | 158 | else |
@@ -182,7 +182,7 @@ static int powernow_k6_cpu_exit(struct cpufreq_policy *policy) | |||
182 | powernow_k6_set_state(i); | 182 | powernow_k6_set_state(i); |
183 | } | 183 | } |
184 | cpufreq_frequency_table_put_attr(policy->cpu); | 184 | cpufreq_frequency_table_put_attr(policy->cpu); |
185 | return 0; | 185 | return 0; |
186 | } | 186 | } |
187 | 187 | ||
188 | static unsigned int powernow_k6_get(unsigned int cpu) | 188 | static unsigned int powernow_k6_get(unsigned int cpu) |
@@ -196,8 +196,8 @@ static struct freq_attr* powernow_k6_attr[] = { | |||
196 | }; | 196 | }; |
197 | 197 | ||
198 | static struct cpufreq_driver powernow_k6_driver = { | 198 | static struct cpufreq_driver powernow_k6_driver = { |
199 | .verify = powernow_k6_verify, | 199 | .verify = powernow_k6_verify, |
200 | .target = powernow_k6_target, | 200 | .target = powernow_k6_target, |
201 | .init = powernow_k6_cpu_init, | 201 | .init = powernow_k6_cpu_init, |
202 | .exit = powernow_k6_cpu_exit, | 202 | .exit = powernow_k6_cpu_exit, |
203 | .get = powernow_k6_get, | 203 | .get = powernow_k6_get, |
@@ -215,7 +215,7 @@ static struct cpufreq_driver powernow_k6_driver = { | |||
215 | * on success. | 215 | * on success. |
216 | */ | 216 | */ |
217 | static int __init powernow_k6_init(void) | 217 | static int __init powernow_k6_init(void) |
218 | { | 218 | { |
219 | struct cpuinfo_x86 *c = cpu_data; | 219 | struct cpuinfo_x86 *c = cpu_data; |
220 | 220 | ||
221 | if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) || | 221 | if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) || |
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c index edcd626001da..2bf4237cb94e 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c | |||
@@ -199,8 +199,8 @@ static int get_ranges (unsigned char *pst) | |||
199 | powernow_table[j].index |= (vid << 8); /* upper 8 bits */ | 199 | powernow_table[j].index |= (vid << 8); /* upper 8 bits */ |
200 | 200 | ||
201 | dprintk (" FID: 0x%x (%d.%dx [%dMHz]) " | 201 | dprintk (" FID: 0x%x (%d.%dx [%dMHz]) " |
202 | "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, | 202 | "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, |
203 | fid_codes[fid] % 10, speed/1000, vid, | 203 | fid_codes[fid] % 10, speed/1000, vid, |
204 | mobile_vid_table[vid]/1000, | 204 | mobile_vid_table[vid]/1000, |
205 | mobile_vid_table[vid]%1000); | 205 | mobile_vid_table[vid]%1000); |
206 | } | 206 | } |
@@ -368,8 +368,8 @@ static int powernow_acpi_init(void) | |||
368 | } | 368 | } |
369 | 369 | ||
370 | dprintk (" FID: 0x%x (%d.%dx [%dMHz]) " | 370 | dprintk (" FID: 0x%x (%d.%dx [%dMHz]) " |
371 | "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, | 371 | "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, |
372 | fid_codes[fid] % 10, speed/1000, vid, | 372 | fid_codes[fid] % 10, speed/1000, vid, |
373 | mobile_vid_table[vid]/1000, | 373 | mobile_vid_table[vid]/1000, |
374 | mobile_vid_table[vid]%1000); | 374 | mobile_vid_table[vid]%1000); |
375 | 375 | ||
@@ -460,7 +460,7 @@ static int powernow_decode_bios (int maxfid, int startvid) | |||
460 | (maxfid==pst->maxfid) && (startvid==pst->startvid)) | 460 | (maxfid==pst->maxfid) && (startvid==pst->startvid)) |
461 | { | 461 | { |
462 | dprintk ("PST:%d (@%p)\n", i, pst); | 462 | dprintk ("PST:%d (@%p)\n", i, pst); |
463 | dprintk (" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n", | 463 | dprintk (" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n", |
464 | pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid); | 464 | pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid); |
465 | 465 | ||
466 | ret = get_ranges ((char *) pst + sizeof (struct pst_s)); | 466 | ret = get_ranges ((char *) pst + sizeof (struct pst_s)); |
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index e11a09207ec8..712a26bd4457 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -40,21 +40,22 @@ | |||
40 | 40 | ||
41 | #ifdef CONFIG_X86_POWERNOW_K8_ACPI | 41 | #ifdef CONFIG_X86_POWERNOW_K8_ACPI |
42 | #include <linux/acpi.h> | 42 | #include <linux/acpi.h> |
43 | #include <linux/mutex.h> | ||
43 | #include <acpi/processor.h> | 44 | #include <acpi/processor.h> |
44 | #endif | 45 | #endif |
45 | 46 | ||
46 | #define PFX "powernow-k8: " | 47 | #define PFX "powernow-k8: " |
47 | #define BFX PFX "BIOS error: " | 48 | #define BFX PFX "BIOS error: " |
48 | #define VERSION "version 1.60.0" | 49 | #define VERSION "version 1.60.1" |
49 | #include "powernow-k8.h" | 50 | #include "powernow-k8.h" |
50 | 51 | ||
51 | /* serialize freq changes */ | 52 | /* serialize freq changes */ |
52 | static DECLARE_MUTEX(fidvid_sem); | 53 | static DEFINE_MUTEX(fidvid_mutex); |
53 | 54 | ||
54 | static struct powernow_k8_data *powernow_data[NR_CPUS]; | 55 | static struct powernow_k8_data *powernow_data[NR_CPUS]; |
55 | 56 | ||
56 | #ifndef CONFIG_SMP | 57 | #ifndef CONFIG_SMP |
57 | static cpumask_t cpu_core_map[1]; | 58 | static cpumask_t cpu_core_map[1] = { CPU_MASK_ALL }; |
58 | #endif | 59 | #endif |
59 | 60 | ||
60 | /* Return a frequency in MHz, given an input fid */ | 61 | /* Return a frequency in MHz, given an input fid */ |
@@ -83,11 +84,10 @@ static u32 find_millivolts_from_vid(struct powernow_k8_data *data, u32 vid) | |||
83 | */ | 84 | */ |
84 | static u32 convert_fid_to_vco_fid(u32 fid) | 85 | static u32 convert_fid_to_vco_fid(u32 fid) |
85 | { | 86 | { |
86 | if (fid < HI_FID_TABLE_BOTTOM) { | 87 | if (fid < HI_FID_TABLE_BOTTOM) |
87 | return 8 + (2 * fid); | 88 | return 8 + (2 * fid); |
88 | } else { | 89 | else |
89 | return fid; | 90 | return fid; |
90 | } | ||
91 | } | 91 | } |
92 | 92 | ||
93 | /* | 93 | /* |
@@ -177,7 +177,7 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid) | |||
177 | if (i++ > 100) { | 177 | if (i++ > 100) { |
178 | printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n"); | 178 | printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n"); |
179 | return 1; | 179 | return 1; |
180 | } | 180 | } |
181 | } while (query_current_values_with_pending_wait(data)); | 181 | } while (query_current_values_with_pending_wait(data)); |
182 | 182 | ||
183 | count_off_irt(data); | 183 | count_off_irt(data); |
@@ -474,8 +474,10 @@ static int check_supported_cpu(unsigned int cpu) | |||
474 | goto out; | 474 | goto out; |
475 | 475 | ||
476 | eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); | 476 | eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); |
477 | if ((eax & CPUID_XFAM) != CPUID_XFAM_K8) | ||
478 | goto out; | ||
479 | |||
477 | if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || | 480 | if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || |
478 | ((eax & CPUID_XFAM) != CPUID_XFAM_K8) || | ||
479 | ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) { | 481 | ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) { |
480 | printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax); | 482 | printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax); |
481 | goto out; | 483 | goto out; |
@@ -780,9 +782,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
780 | /* verify only 1 entry from the lo frequency table */ | 782 | /* verify only 1 entry from the lo frequency table */ |
781 | if (fid < HI_FID_TABLE_BOTTOM) { | 783 | if (fid < HI_FID_TABLE_BOTTOM) { |
782 | if (cntlofreq) { | 784 | if (cntlofreq) { |
783 | /* if both entries are the same, ignore this | 785 | /* if both entries are the same, ignore this one ... */ |
784 | * one... | ||
785 | */ | ||
786 | if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) || | 786 | if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) || |
787 | (powernow_table[i].index != powernow_table[cntlofreq].index)) { | 787 | (powernow_table[i].index != powernow_table[cntlofreq].index)) { |
788 | printk(KERN_ERR PFX "Too many lo freq table entries\n"); | 788 | printk(KERN_ERR PFX "Too many lo freq table entries\n"); |
@@ -854,7 +854,7 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde | |||
854 | dprintk("cpu %d transition to index %u\n", smp_processor_id(), index); | 854 | dprintk("cpu %d transition to index %u\n", smp_processor_id(), index); |
855 | 855 | ||
856 | /* fid are the lower 8 bits of the index we stored into | 856 | /* fid are the lower 8 bits of the index we stored into |
857 | * the cpufreq frequency table in find_psb_table, vid are | 857 | * the cpufreq frequency table in find_psb_table, vid are |
858 | * the upper 8 bits. | 858 | * the upper 8 bits. |
859 | */ | 859 | */ |
860 | 860 | ||
@@ -909,7 +909,6 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
909 | u32 checkvid = data->currvid; | 909 | u32 checkvid = data->currvid; |
910 | unsigned int newstate; | 910 | unsigned int newstate; |
911 | int ret = -EIO; | 911 | int ret = -EIO; |
912 | int i; | ||
913 | 912 | ||
914 | /* only run on specific CPU from here on */ | 913 | /* only run on specific CPU from here on */ |
915 | oldmask = current->cpus_allowed; | 914 | oldmask = current->cpus_allowed; |
@@ -945,23 +944,17 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
945 | if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate)) | 944 | if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate)) |
946 | goto err_out; | 945 | goto err_out; |
947 | 946 | ||
948 | down(&fidvid_sem); | 947 | mutex_lock(&fidvid_mutex); |
949 | 948 | ||
950 | powernow_k8_acpi_pst_values(data, newstate); | 949 | powernow_k8_acpi_pst_values(data, newstate); |
951 | 950 | ||
952 | if (transition_frequency(data, newstate)) { | 951 | if (transition_frequency(data, newstate)) { |
953 | printk(KERN_ERR PFX "transition frequency failed\n"); | 952 | printk(KERN_ERR PFX "transition frequency failed\n"); |
954 | ret = 1; | 953 | ret = 1; |
955 | up(&fidvid_sem); | 954 | mutex_unlock(&fidvid_mutex); |
956 | goto err_out; | 955 | goto err_out; |
957 | } | 956 | } |
958 | 957 | mutex_unlock(&fidvid_mutex); | |
959 | /* Update all the fid/vids of our siblings */ | ||
960 | for_each_cpu_mask(i, cpu_core_map[pol->cpu]) { | ||
961 | powernow_data[i]->currvid = data->currvid; | ||
962 | powernow_data[i]->currfid = data->currfid; | ||
963 | } | ||
964 | up(&fidvid_sem); | ||
965 | 958 | ||
966 | pol->cur = find_khz_freq_from_fid(data->currfid); | 959 | pol->cur = find_khz_freq_from_fid(data->currfid); |
967 | ret = 0; | 960 | ret = 0; |
@@ -1048,7 +1041,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1048 | pol->governor = CPUFREQ_DEFAULT_GOVERNOR; | 1041 | pol->governor = CPUFREQ_DEFAULT_GOVERNOR; |
1049 | pol->cpus = cpu_core_map[pol->cpu]; | 1042 | pol->cpus = cpu_core_map[pol->cpu]; |
1050 | 1043 | ||
1051 | /* Take a crude guess here. | 1044 | /* Take a crude guess here. |
1052 | * That guess was in microseconds, so multiply with 1000 */ | 1045 | * That guess was in microseconds, so multiply with 1000 */ |
1053 | pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US) | 1046 | pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US) |
1054 | + (3 * (1 << data->irt) * 10)) * 1000; | 1047 | + (3 * (1 << data->irt) * 10)) * 1000; |
@@ -1070,9 +1063,8 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1070 | printk("cpu_init done, current fid 0x%x, vid 0x%x\n", | 1063 | printk("cpu_init done, current fid 0x%x, vid 0x%x\n", |
1071 | data->currfid, data->currvid); | 1064 | data->currfid, data->currvid); |
1072 | 1065 | ||
1073 | for_each_cpu_mask(i, cpu_core_map[pol->cpu]) { | 1066 | for_each_cpu_mask(i, cpu_core_map[pol->cpu]) |
1074 | powernow_data[i] = data; | 1067 | powernow_data[i] = data; |
1075 | } | ||
1076 | 1068 | ||
1077 | return 0; | 1069 | return 0; |
1078 | 1070 | ||
@@ -1103,10 +1095,15 @@ static int __devexit powernowk8_cpu_exit (struct cpufreq_policy *pol) | |||
1103 | 1095 | ||
1104 | static unsigned int powernowk8_get (unsigned int cpu) | 1096 | static unsigned int powernowk8_get (unsigned int cpu) |
1105 | { | 1097 | { |
1106 | struct powernow_k8_data *data = powernow_data[cpu]; | 1098 | struct powernow_k8_data *data; |
1107 | cpumask_t oldmask = current->cpus_allowed; | 1099 | cpumask_t oldmask = current->cpus_allowed; |
1108 | unsigned int khz = 0; | 1100 | unsigned int khz = 0; |
1109 | 1101 | ||
1102 | data = powernow_data[first_cpu(cpu_core_map[cpu])]; | ||
1103 | |||
1104 | if (!data) | ||
1105 | return -EINVAL; | ||
1106 | |||
1110 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 1107 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); |
1111 | if (smp_processor_id() != cpu) { | 1108 | if (smp_processor_id() != cpu) { |
1112 | printk(KERN_ERR PFX "limiting to CPU %d failed in powernowk8_get\n", cpu); | 1109 | printk(KERN_ERR PFX "limiting to CPU %d failed in powernowk8_get\n", cpu); |
@@ -1145,16 +1142,14 @@ static int __cpuinit powernowk8_init(void) | |||
1145 | { | 1142 | { |
1146 | unsigned int i, supported_cpus = 0; | 1143 | unsigned int i, supported_cpus = 0; |
1147 | 1144 | ||
1148 | for (i=0; i<NR_CPUS; i++) { | 1145 | for_each_online_cpu(i) { |
1149 | if (!cpu_online(i)) | ||
1150 | continue; | ||
1151 | if (check_supported_cpu(i)) | 1146 | if (check_supported_cpu(i)) |
1152 | supported_cpus++; | 1147 | supported_cpus++; |
1153 | } | 1148 | } |
1154 | 1149 | ||
1155 | if (supported_cpus == num_online_cpus()) { | 1150 | if (supported_cpus == num_online_cpus()) { |
1156 | printk(KERN_INFO PFX "Found %d AMD Athlon 64 / Opteron processors (" VERSION ")\n", | 1151 | printk(KERN_INFO PFX "Found %d AMD Athlon 64 / Opteron " |
1157 | supported_cpus); | 1152 | "processors (" VERSION ")\n", supported_cpus); |
1158 | return cpufreq_register_driver(&cpufreq_amd64_driver); | 1153 | return cpufreq_register_driver(&cpufreq_amd64_driver); |
1159 | } | 1154 | } |
1160 | 1155 | ||
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h index d0de37d58e9a..79a7c5c87edc 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h | |||
@@ -63,7 +63,7 @@ struct powernow_k8_data { | |||
63 | #define MSR_C_LO_VID_SHIFT 8 | 63 | #define MSR_C_LO_VID_SHIFT 8 |
64 | 64 | ||
65 | /* Field definitions within the FID VID High Control MSR : */ | 65 | /* Field definitions within the FID VID High Control MSR : */ |
66 | #define MSR_C_HI_STP_GNT_TO 0x000fffff | 66 | #define MSR_C_HI_STP_GNT_TO 0x000fffff |
67 | 67 | ||
68 | /* Field definitions within the FID VID Low Status MSR : */ | 68 | /* Field definitions within the FID VID Low Status MSR : */ |
69 | #define MSR_S_LO_CHANGE_PENDING 0x80000000 /* cleared when completed */ | 69 | #define MSR_S_LO_CHANGE_PENDING 0x80000000 /* cleared when completed */ |
@@ -123,7 +123,7 @@ struct powernow_k8_data { | |||
123 | * Most values of interest are enocoded in a single field of the _PSS | 123 | * Most values of interest are enocoded in a single field of the _PSS |
124 | * entries: the "control" value. | 124 | * entries: the "control" value. |
125 | */ | 125 | */ |
126 | 126 | ||
127 | #define IRT_SHIFT 30 | 127 | #define IRT_SHIFT 30 |
128 | #define RVO_SHIFT 28 | 128 | #define RVO_SHIFT 28 |
129 | #define EXT_TYPE_SHIFT 27 | 129 | #define EXT_TYPE_SHIFT 27 |
@@ -182,10 +182,6 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid); | |||
182 | 182 | ||
183 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index); | 183 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index); |
184 | 184 | ||
185 | #ifndef for_each_cpu_mask | ||
186 | #define for_each_cpu_mask(i,mask) for (i=0;i<1;i++) | ||
187 | #endif | ||
188 | |||
189 | #ifdef CONFIG_SMP | 185 | #ifdef CONFIG_SMP |
190 | static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[]) | 186 | static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[]) |
191 | { | 187 | { |
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index c173c0fa117a..b0ff9075708c 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | |||
@@ -479,15 +479,13 @@ static int centrino_cpu_init(struct cpufreq_policy *policy) | |||
479 | unsigned l, h; | 479 | unsigned l, h; |
480 | int ret; | 480 | int ret; |
481 | int i; | 481 | int i; |
482 | struct cpuinfo_x86 *c = &cpu_data[policy->cpu]; | ||
483 | 482 | ||
484 | /* Only Intel makes Enhanced Speedstep-capable CPUs */ | 483 | /* Only Intel makes Enhanced Speedstep-capable CPUs */ |
485 | if (cpu->x86_vendor != X86_VENDOR_INTEL || !cpu_has(cpu, X86_FEATURE_EST)) | 484 | if (cpu->x86_vendor != X86_VENDOR_INTEL || !cpu_has(cpu, X86_FEATURE_EST)) |
486 | return -ENODEV; | 485 | return -ENODEV; |
487 | 486 | ||
488 | if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { | 487 | if (cpu_has(cpu, X86_FEATURE_CONSTANT_TSC)) |
489 | centrino_driver.flags |= CPUFREQ_CONST_LOOPS; | 488 | centrino_driver.flags |= CPUFREQ_CONST_LOOPS; |
490 | } | ||
491 | 489 | ||
492 | if (centrino_cpu_init_acpi(policy)) { | 490 | if (centrino_cpu_init_acpi(policy)) { |
493 | if (policy->cpu != 0) | 491 | if (policy->cpu != 0) |
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c index 7c47005a1805..4f46cac155c4 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c | |||
@@ -9,7 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/moduleparam.h> | 13 | #include <linux/moduleparam.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/cpufreq.h> | 15 | #include <linux/cpufreq.h> |
@@ -36,8 +36,8 @@ static unsigned int pentium3_get_frequency (unsigned int processor) | |||
36 | /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */ | 36 | /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */ |
37 | struct { | 37 | struct { |
38 | unsigned int ratio; /* Frequency Multiplier (x10) */ | 38 | unsigned int ratio; /* Frequency Multiplier (x10) */ |
39 | u8 bitmap; /* power on configuration bits | 39 | u8 bitmap; /* power on configuration bits |
40 | [27, 25:22] (in MSR 0x2a) */ | 40 | [27, 25:22] (in MSR 0x2a) */ |
41 | } msr_decode_mult [] = { | 41 | } msr_decode_mult [] = { |
42 | { 30, 0x01 }, | 42 | { 30, 0x01 }, |
43 | { 35, 0x05 }, | 43 | { 35, 0x05 }, |
@@ -58,9 +58,9 @@ static unsigned int pentium3_get_frequency (unsigned int processor) | |||
58 | 58 | ||
59 | /* PIII(-M) FSB settings: see table b1-b of 24547206.pdf */ | 59 | /* PIII(-M) FSB settings: see table b1-b of 24547206.pdf */ |
60 | struct { | 60 | struct { |
61 | unsigned int value; /* Front Side Bus speed in MHz */ | 61 | unsigned int value; /* Front Side Bus speed in MHz */ |
62 | u8 bitmap; /* power on configuration bits [18: 19] | 62 | u8 bitmap; /* power on configuration bits [18: 19] |
63 | (in MSR 0x2a) */ | 63 | (in MSR 0x2a) */ |
64 | } msr_decode_fsb [] = { | 64 | } msr_decode_fsb [] = { |
65 | { 66, 0x0 }, | 65 | { 66, 0x0 }, |
66 | { 100, 0x2 }, | 66 | { 100, 0x2 }, |
@@ -68,8 +68,8 @@ static unsigned int pentium3_get_frequency (unsigned int processor) | |||
68 | { 0, 0xff} | 68 | { 0, 0xff} |
69 | }; | 69 | }; |
70 | 70 | ||
71 | u32 msr_lo, msr_tmp; | 71 | u32 msr_lo, msr_tmp; |
72 | int i = 0, j = 0; | 72 | int i = 0, j = 0; |
73 | 73 | ||
74 | /* read MSR 0x2a - we only need the low 32 bits */ | 74 | /* read MSR 0x2a - we only need the low 32 bits */ |
75 | rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp); | 75 | rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp); |
@@ -106,7 +106,7 @@ static unsigned int pentium3_get_frequency (unsigned int processor) | |||
106 | 106 | ||
107 | static unsigned int pentiumM_get_frequency(void) | 107 | static unsigned int pentiumM_get_frequency(void) |
108 | { | 108 | { |
109 | u32 msr_lo, msr_tmp; | 109 | u32 msr_lo, msr_tmp; |
110 | 110 | ||
111 | rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp); | 111 | rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp); |
112 | dprintk("PM - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp); | 112 | dprintk("PM - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp); |
@@ -134,7 +134,7 @@ static unsigned int pentium4_get_frequency(void) | |||
134 | 134 | ||
135 | dprintk("P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi); | 135 | dprintk("P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi); |
136 | 136 | ||
137 | /* decode the FSB: see IA-32 Intel (C) Architecture Software | 137 | /* decode the FSB: see IA-32 Intel (C) Architecture Software |
138 | * Developer's Manual, Volume 3: System Prgramming Guide, | 138 | * Developer's Manual, Volume 3: System Prgramming Guide, |
139 | * revision #12 in Table B-1: MSRs in the Pentium 4 and | 139 | * revision #12 in Table B-1: MSRs in the Pentium 4 and |
140 | * Intel Xeon Processors, on page B-4 and B-5. | 140 | * Intel Xeon Processors, on page B-4 and B-5. |
@@ -170,7 +170,7 @@ static unsigned int pentium4_get_frequency(void) | |||
170 | return (fsb * mult); | 170 | return (fsb * mult); |
171 | } | 171 | } |
172 | 172 | ||
173 | 173 | ||
174 | unsigned int speedstep_get_processor_frequency(unsigned int processor) | 174 | unsigned int speedstep_get_processor_frequency(unsigned int processor) |
175 | { | 175 | { |
176 | switch (processor) { | 176 | switch (processor) { |
@@ -198,11 +198,11 @@ EXPORT_SYMBOL_GPL(speedstep_get_processor_frequency); | |||
198 | unsigned int speedstep_detect_processor (void) | 198 | unsigned int speedstep_detect_processor (void) |
199 | { | 199 | { |
200 | struct cpuinfo_x86 *c = cpu_data; | 200 | struct cpuinfo_x86 *c = cpu_data; |
201 | u32 ebx, msr_lo, msr_hi; | 201 | u32 ebx, msr_lo, msr_hi; |
202 | 202 | ||
203 | dprintk("x86: %x, model: %x\n", c->x86, c->x86_model); | 203 | dprintk("x86: %x, model: %x\n", c->x86, c->x86_model); |
204 | 204 | ||
205 | if ((c->x86_vendor != X86_VENDOR_INTEL) || | 205 | if ((c->x86_vendor != X86_VENDOR_INTEL) || |
206 | ((c->x86 != 6) && (c->x86 != 0xF))) | 206 | ((c->x86 != 6) && (c->x86 != 0xF))) |
207 | return 0; | 207 | return 0; |
208 | 208 | ||
@@ -218,15 +218,15 @@ unsigned int speedstep_detect_processor (void) | |||
218 | dprintk("ebx value is %x, x86_mask is %x\n", ebx, c->x86_mask); | 218 | dprintk("ebx value is %x, x86_mask is %x\n", ebx, c->x86_mask); |
219 | 219 | ||
220 | switch (c->x86_mask) { | 220 | switch (c->x86_mask) { |
221 | case 4: | 221 | case 4: |
222 | /* | 222 | /* |
223 | * B-stepping [M-P4-M] | 223 | * B-stepping [M-P4-M] |
224 | * sample has ebx = 0x0f, production has 0x0e. | 224 | * sample has ebx = 0x0f, production has 0x0e. |
225 | */ | 225 | */ |
226 | if ((ebx == 0x0e) || (ebx == 0x0f)) | 226 | if ((ebx == 0x0e) || (ebx == 0x0f)) |
227 | return SPEEDSTEP_PROCESSOR_P4M; | 227 | return SPEEDSTEP_PROCESSOR_P4M; |
228 | break; | 228 | break; |
229 | case 7: | 229 | case 7: |
230 | /* | 230 | /* |
231 | * C-stepping [M-P4-M] | 231 | * C-stepping [M-P4-M] |
232 | * needs to have ebx=0x0e, else it's a celeron: | 232 | * needs to have ebx=0x0e, else it's a celeron: |
@@ -253,7 +253,7 @@ unsigned int speedstep_detect_processor (void) | |||
253 | * also, M-P4M HTs have ebx=0x8, too | 253 | * also, M-P4M HTs have ebx=0x8, too |
254 | * For now, they are distinguished by the model_id string | 254 | * For now, they are distinguished by the model_id string |
255 | */ | 255 | */ |
256 | if ((ebx == 0x0e) || (strstr(c->x86_model_id,"Mobile Intel(R) Pentium(R) 4") != NULL)) | 256 | if ((ebx == 0x0e) || (strstr(c->x86_model_id,"Mobile Intel(R) Pentium(R) 4") != NULL)) |
257 | return SPEEDSTEP_PROCESSOR_P4M; | 257 | return SPEEDSTEP_PROCESSOR_P4M; |
258 | break; | 258 | break; |
259 | default: | 259 | default: |
@@ -264,8 +264,7 @@ unsigned int speedstep_detect_processor (void) | |||
264 | 264 | ||
265 | switch (c->x86_model) { | 265 | switch (c->x86_model) { |
266 | case 0x0B: /* Intel PIII [Tualatin] */ | 266 | case 0x0B: /* Intel PIII [Tualatin] */ |
267 | /* cpuid_ebx(1) is 0x04 for desktop PIII, | 267 | /* cpuid_ebx(1) is 0x04 for desktop PIII, 0x06 for mobile PIII-M */ |
268 | 0x06 for mobile PIII-M */ | ||
269 | ebx = cpuid_ebx(0x00000001); | 268 | ebx = cpuid_ebx(0x00000001); |
270 | dprintk("ebx is %x\n", ebx); | 269 | dprintk("ebx is %x\n", ebx); |
271 | 270 | ||
@@ -275,9 +274,8 @@ unsigned int speedstep_detect_processor (void) | |||
275 | return 0; | 274 | return 0; |
276 | 275 | ||
277 | /* So far all PIII-M processors support SpeedStep. See | 276 | /* So far all PIII-M processors support SpeedStep. See |
278 | * Intel's 24540640.pdf of June 2003 | 277 | * Intel's 24540640.pdf of June 2003 |
279 | */ | 278 | */ |
280 | |||
281 | return SPEEDSTEP_PROCESSOR_PIII_T; | 279 | return SPEEDSTEP_PROCESSOR_PIII_T; |
282 | 280 | ||
283 | case 0x08: /* Intel PIII [Coppermine] */ | 281 | case 0x08: /* Intel PIII [Coppermine] */ |
@@ -399,7 +397,7 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
399 | } | 397 | } |
400 | } | 398 | } |
401 | 399 | ||
402 | out: | 400 | out: |
403 | local_irq_restore(flags); | 401 | local_irq_restore(flags); |
404 | return (ret); | 402 | return (ret); |
405 | } | 403 | } |
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h index 6a727fd3a77e..b735429c50b4 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h | |||
@@ -14,7 +14,7 @@ | |||
14 | 14 | ||
15 | #define SPEEDSTEP_PROCESSOR_PIII_C_EARLY 0x00000001 /* Coppermine core */ | 15 | #define SPEEDSTEP_PROCESSOR_PIII_C_EARLY 0x00000001 /* Coppermine core */ |
16 | #define SPEEDSTEP_PROCESSOR_PIII_C 0x00000002 /* Coppermine core */ | 16 | #define SPEEDSTEP_PROCESSOR_PIII_C 0x00000002 /* Coppermine core */ |
17 | #define SPEEDSTEP_PROCESSOR_PIII_T 0x00000003 /* Tualatin core */ | 17 | #define SPEEDSTEP_PROCESSOR_PIII_T 0x00000003 /* Tualatin core */ |
18 | #define SPEEDSTEP_PROCESSOR_P4M 0x00000004 /* P4-M */ | 18 | #define SPEEDSTEP_PROCESSOR_P4M 0x00000004 /* P4-M */ |
19 | 19 | ||
20 | /* the following processors are not speedstep-capable and are not auto-detected | 20 | /* the following processors are not speedstep-capable and are not auto-detected |
@@ -25,8 +25,8 @@ | |||
25 | 25 | ||
26 | /* speedstep states -- only two of them */ | 26 | /* speedstep states -- only two of them */ |
27 | 27 | ||
28 | #define SPEEDSTEP_HIGH 0x00000000 | 28 | #define SPEEDSTEP_HIGH 0x00000000 |
29 | #define SPEEDSTEP_LOW 0x00000001 | 29 | #define SPEEDSTEP_LOW 0x00000001 |
30 | 30 | ||
31 | 31 | ||
32 | /* detect a speedstep-capable processor */ | 32 | /* detect a speedstep-capable processor */ |
@@ -36,13 +36,13 @@ extern unsigned int speedstep_detect_processor (void); | |||
36 | extern unsigned int speedstep_get_processor_frequency(unsigned int processor); | 36 | extern unsigned int speedstep_get_processor_frequency(unsigned int processor); |
37 | 37 | ||
38 | 38 | ||
39 | /* detect the low and high speeds of the processor. The callback | 39 | /* detect the low and high speeds of the processor. The callback |
40 | * set_state"'s first argument is either SPEEDSTEP_HIGH or | 40 | * set_state"'s first argument is either SPEEDSTEP_HIGH or |
41 | * SPEEDSTEP_LOW; the second argument is zero so that no | 41 | * SPEEDSTEP_LOW; the second argument is zero so that no |
42 | * cpufreq_notify_transition calls are initiated. | 42 | * cpufreq_notify_transition calls are initiated. |
43 | */ | 43 | */ |
44 | extern unsigned int speedstep_get_freqs(unsigned int processor, | 44 | extern unsigned int speedstep_get_freqs(unsigned int processor, |
45 | unsigned int *low_speed, | 45 | unsigned int *low_speed, |
46 | unsigned int *high_speed, | 46 | unsigned int *high_speed, |
47 | unsigned int *transition_latency, | 47 | unsigned int *transition_latency, |
48 | void (*set_state) (unsigned int state)); | 48 | void (*set_state) (unsigned int state)); |
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c index 28cc5d524afc..c28333d53646 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c | |||
@@ -13,8 +13,8 @@ | |||
13 | *********************************************************************/ | 13 | *********************************************************************/ |
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/moduleparam.h> | 17 | #include <linux/moduleparam.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/cpufreq.h> | 19 | #include <linux/cpufreq.h> |
20 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
@@ -28,21 +28,21 @@ | |||
28 | * | 28 | * |
29 | * These parameters are got from IST-SMI BIOS call. | 29 | * These parameters are got from IST-SMI BIOS call. |
30 | * If user gives it, these are used. | 30 | * If user gives it, these are used. |
31 | * | 31 | * |
32 | */ | 32 | */ |
33 | static int smi_port = 0; | 33 | static int smi_port = 0; |
34 | static int smi_cmd = 0; | 34 | static int smi_cmd = 0; |
35 | static unsigned int smi_sig = 0; | 35 | static unsigned int smi_sig = 0; |
36 | 36 | ||
37 | /* info about the processor */ | 37 | /* info about the processor */ |
38 | static unsigned int speedstep_processor = 0; | 38 | static unsigned int speedstep_processor = 0; |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * There are only two frequency states for each processor. Values | 41 | * There are only two frequency states for each processor. Values |
42 | * are in kHz for the time being. | 42 | * are in kHz for the time being. |
43 | */ | 43 | */ |
44 | static struct cpufreq_frequency_table speedstep_freqs[] = { | 44 | static struct cpufreq_frequency_table speedstep_freqs[] = { |
45 | {SPEEDSTEP_HIGH, 0}, | 45 | {SPEEDSTEP_HIGH, 0}, |
46 | {SPEEDSTEP_LOW, 0}, | 46 | {SPEEDSTEP_LOW, 0}, |
47 | {0, CPUFREQ_TABLE_END}, | 47 | {0, CPUFREQ_TABLE_END}, |
48 | }; | 48 | }; |
@@ -75,7 +75,9 @@ static int speedstep_smi_ownership (void) | |||
75 | __asm__ __volatile__( | 75 | __asm__ __volatile__( |
76 | "out %%al, (%%dx)\n" | 76 | "out %%al, (%%dx)\n" |
77 | : "=D" (result) | 77 | : "=D" (result) |
78 | : "a" (command), "b" (function), "c" (0), "d" (smi_port), "D" (0), "S" (magic) | 78 | : "a" (command), "b" (function), "c" (0), "d" (smi_port), |
79 | "D" (0), "S" (magic) | ||
80 | : "memory" | ||
79 | ); | 81 | ); |
80 | 82 | ||
81 | dprintk("result is %x\n", result); | 83 | dprintk("result is %x\n", result); |
@@ -123,7 +125,7 @@ static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high) | |||
123 | *low = low_mhz * 1000; | 125 | *low = low_mhz * 1000; |
124 | 126 | ||
125 | return result; | 127 | return result; |
126 | } | 128 | } |
127 | 129 | ||
128 | /** | 130 | /** |
129 | * speedstep_get_state - set the SpeedStep state | 131 | * speedstep_get_state - set the SpeedStep state |
@@ -204,7 +206,7 @@ static void speedstep_set_state (unsigned int state) | |||
204 | * speedstep_target - set a new CPUFreq policy | 206 | * speedstep_target - set a new CPUFreq policy |
205 | * @policy: new policy | 207 | * @policy: new policy |
206 | * @target_freq: new freq | 208 | * @target_freq: new freq |
207 | * @relation: | 209 | * @relation: |
208 | * | 210 | * |
209 | * Sets a new CPUFreq policy/freq. | 211 | * Sets a new CPUFreq policy/freq. |
210 | */ | 212 | */ |
@@ -283,7 +285,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) | |||
283 | state = speedstep_get_state(); | 285 | state = speedstep_get_state(); |
284 | speed = speedstep_freqs[state].frequency; | 286 | speed = speedstep_freqs[state].frequency; |
285 | 287 | ||
286 | dprintk("currently at %s speed setting - %i MHz\n", | 288 | dprintk("currently at %s speed setting - %i MHz\n", |
287 | (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high", | 289 | (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high", |
288 | (speed / 1000)); | 290 | (speed / 1000)); |
289 | 291 | ||
@@ -296,7 +298,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) | |||
296 | if (result) | 298 | if (result) |
297 | return (result); | 299 | return (result); |
298 | 300 | ||
299 | cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu); | 301 | cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu); |
300 | 302 | ||
301 | return 0; | 303 | return 0; |
302 | } | 304 | } |
@@ -332,8 +334,8 @@ static struct freq_attr* speedstep_attr[] = { | |||
332 | 334 | ||
333 | static struct cpufreq_driver speedstep_driver = { | 335 | static struct cpufreq_driver speedstep_driver = { |
334 | .name = "speedstep-smi", | 336 | .name = "speedstep-smi", |
335 | .verify = speedstep_verify, | 337 | .verify = speedstep_verify, |
336 | .target = speedstep_target, | 338 | .target = speedstep_target, |
337 | .init = speedstep_cpu_init, | 339 | .init = speedstep_cpu_init, |
338 | .exit = speedstep_cpu_exit, | 340 | .exit = speedstep_cpu_exit, |
339 | .get = speedstep_get, | 341 | .get = speedstep_get, |
@@ -370,13 +372,12 @@ static int __init speedstep_init(void) | |||
370 | return -ENODEV; | 372 | return -ENODEV; |
371 | } | 373 | } |
372 | 374 | ||
373 | dprintk("signature:0x%.8lx, command:0x%.8lx, event:0x%.8lx, perf_level:0x%.8lx.\n", | 375 | dprintk("signature:0x%.8lx, command:0x%.8lx, event:0x%.8lx, perf_level:0x%.8lx.\n", |
374 | ist_info.signature, ist_info.command, ist_info.event, ist_info.perf_level); | 376 | ist_info.signature, ist_info.command, ist_info.event, ist_info.perf_level); |
375 | 377 | ||
376 | 378 | /* Error if no IST-SMI BIOS or no PARM | |
377 | /* Error if no IST-SMI BIOS or no PARM | ||
378 | sig= 'ISGE' aka 'Intel Speedstep Gate E' */ | 379 | sig= 'ISGE' aka 'Intel Speedstep Gate E' */ |
379 | if ((ist_info.signature != 0x47534943) && ( | 380 | if ((ist_info.signature != 0x47534943) && ( |
380 | (smi_port == 0) || (smi_cmd == 0))) | 381 | (smi_port == 0) || (smi_cmd == 0))) |
381 | return -ENODEV; | 382 | return -ENODEV; |
382 | 383 | ||
@@ -386,17 +387,15 @@ static int __init speedstep_init(void) | |||
386 | smi_sig = ist_info.signature; | 387 | smi_sig = ist_info.signature; |
387 | 388 | ||
388 | /* setup smi_port from MODLULE_PARM or BIOS */ | 389 | /* setup smi_port from MODLULE_PARM or BIOS */ |
389 | if ((smi_port > 0xff) || (smi_port < 0)) { | 390 | if ((smi_port > 0xff) || (smi_port < 0)) |
390 | return -EINVAL; | 391 | return -EINVAL; |
391 | } else if (smi_port == 0) { | 392 | else if (smi_port == 0) |
392 | smi_port = ist_info.command & 0xff; | 393 | smi_port = ist_info.command & 0xff; |
393 | } | ||
394 | 394 | ||
395 | if ((smi_cmd > 0xff) || (smi_cmd < 0)) { | 395 | if ((smi_cmd > 0xff) || (smi_cmd < 0)) |
396 | return -EINVAL; | 396 | return -EINVAL; |
397 | } else if (smi_cmd == 0) { | 397 | else if (smi_cmd == 0) |
398 | smi_cmd = (ist_info.command >> 16) & 0xff; | 398 | smi_cmd = (ist_info.command >> 16) & 0xff; |
399 | } | ||
400 | 399 | ||
401 | return cpufreq_register_driver(&speedstep_driver); | 400 | return cpufreq_register_driver(&speedstep_driver); |
402 | } | 401 | } |
diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c index 8c0120186b9f..5386b29bb5a5 100644 --- a/arch/i386/kernel/cpu/intel.c +++ b/arch/i386/kernel/cpu/intel.c | |||
@@ -29,7 +29,7 @@ extern int trap_init_f00f_bug(void); | |||
29 | struct movsl_mask movsl_mask __read_mostly; | 29 | struct movsl_mask movsl_mask __read_mostly; |
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | void __devinit early_intel_workaround(struct cpuinfo_x86 *c) | 32 | void __cpuinit early_intel_workaround(struct cpuinfo_x86 *c) |
33 | { | 33 | { |
34 | if (c->x86_vendor != X86_VENDOR_INTEL) | 34 | if (c->x86_vendor != X86_VENDOR_INTEL) |
35 | return; | 35 | return; |
@@ -44,7 +44,7 @@ void __devinit early_intel_workaround(struct cpuinfo_x86 *c) | |||
44 | * This is called before we do cpu ident work | 44 | * This is called before we do cpu ident work |
45 | */ | 45 | */ |
46 | 46 | ||
47 | int __devinit ppro_with_ram_bug(void) | 47 | int __cpuinit ppro_with_ram_bug(void) |
48 | { | 48 | { |
49 | /* Uses data from early_cpu_detect now */ | 49 | /* Uses data from early_cpu_detect now */ |
50 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && | 50 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && |
@@ -62,7 +62,7 @@ int __devinit ppro_with_ram_bug(void) | |||
62 | * P4 Xeon errata 037 workaround. | 62 | * P4 Xeon errata 037 workaround. |
63 | * Hardware prefetcher may cause stale data to be loaded into the cache. | 63 | * Hardware prefetcher may cause stale data to be loaded into the cache. |
64 | */ | 64 | */ |
65 | static void __devinit Intel_errata_workarounds(struct cpuinfo_x86 *c) | 65 | static void __cpuinit Intel_errata_workarounds(struct cpuinfo_x86 *c) |
66 | { | 66 | { |
67 | unsigned long lo, hi; | 67 | unsigned long lo, hi; |
68 | 68 | ||
@@ -81,7 +81,7 @@ static void __devinit Intel_errata_workarounds(struct cpuinfo_x86 *c) | |||
81 | /* | 81 | /* |
82 | * find out the number of processor cores on the die | 82 | * find out the number of processor cores on the die |
83 | */ | 83 | */ |
84 | static int __devinit num_cpu_cores(struct cpuinfo_x86 *c) | 84 | static int __cpuinit num_cpu_cores(struct cpuinfo_x86 *c) |
85 | { | 85 | { |
86 | unsigned int eax, ebx, ecx, edx; | 86 | unsigned int eax, ebx, ecx, edx; |
87 | 87 | ||
@@ -96,7 +96,7 @@ static int __devinit num_cpu_cores(struct cpuinfo_x86 *c) | |||
96 | return 1; | 96 | return 1; |
97 | } | 97 | } |
98 | 98 | ||
99 | static void __devinit init_intel(struct cpuinfo_x86 *c) | 99 | static void __cpuinit init_intel(struct cpuinfo_x86 *c) |
100 | { | 100 | { |
101 | unsigned int l2 = 0; | 101 | unsigned int l2 = 0; |
102 | char *p = NULL; | 102 | char *p = NULL; |
@@ -205,7 +205,7 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 * c, unsigned int size) | |||
205 | return size; | 205 | return size; |
206 | } | 206 | } |
207 | 207 | ||
208 | static struct cpu_dev intel_cpu_dev __devinitdata = { | 208 | static struct cpu_dev intel_cpu_dev __cpuinitdata = { |
209 | .c_vendor = "Intel", | 209 | .c_vendor = "Intel", |
210 | .c_ident = { "GenuineIntel" }, | 210 | .c_ident = { "GenuineIntel" }, |
211 | .c_models = { | 211 | .c_models = { |
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index ffe58cee0c48..9df87b03612c 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c | |||
@@ -173,8 +173,12 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) | |||
173 | unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ | 173 | unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ |
174 | unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ | 174 | unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ |
175 | unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ | 175 | unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ |
176 | unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb; | ||
177 | #ifdef CONFIG_SMP | ||
178 | unsigned int cpu = (c == &boot_cpu_data) ? 0 : (c - cpu_data); | ||
179 | #endif | ||
176 | 180 | ||
177 | if (c->cpuid_level > 4) { | 181 | if (c->cpuid_level > 3) { |
178 | static int is_initialized; | 182 | static int is_initialized; |
179 | 183 | ||
180 | if (is_initialized == 0) { | 184 | if (is_initialized == 0) { |
@@ -205,9 +209,15 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) | |||
205 | break; | 209 | break; |
206 | case 2: | 210 | case 2: |
207 | new_l2 = this_leaf.size/1024; | 211 | new_l2 = this_leaf.size/1024; |
212 | num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; | ||
213 | index_msb = get_count_order(num_threads_sharing); | ||
214 | l2_id = c->apicid >> index_msb; | ||
208 | break; | 215 | break; |
209 | case 3: | 216 | case 3: |
210 | new_l3 = this_leaf.size/1024; | 217 | new_l3 = this_leaf.size/1024; |
218 | num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; | ||
219 | index_msb = get_count_order(num_threads_sharing); | ||
220 | l3_id = c->apicid >> index_msb; | ||
211 | break; | 221 | break; |
212 | default: | 222 | default: |
213 | break; | 223 | break; |
@@ -215,11 +225,19 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) | |||
215 | } | 225 | } |
216 | } | 226 | } |
217 | } | 227 | } |
218 | if (c->cpuid_level > 1) { | 228 | /* |
229 | * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for | ||
230 | * trace cache | ||
231 | */ | ||
232 | if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) { | ||
219 | /* supports eax=2 call */ | 233 | /* supports eax=2 call */ |
220 | int i, j, n; | 234 | int i, j, n; |
221 | int regs[4]; | 235 | int regs[4]; |
222 | unsigned char *dp = (unsigned char *)regs; | 236 | unsigned char *dp = (unsigned char *)regs; |
237 | int only_trace = 0; | ||
238 | |||
239 | if (num_cache_leaves != 0 && c->x86 == 15) | ||
240 | only_trace = 1; | ||
223 | 241 | ||
224 | /* Number of times to iterate */ | 242 | /* Number of times to iterate */ |
225 | n = cpuid_eax(2) & 0xFF; | 243 | n = cpuid_eax(2) & 0xFF; |
@@ -241,6 +259,8 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) | |||
241 | while (cache_table[k].descriptor != 0) | 259 | while (cache_table[k].descriptor != 0) |
242 | { | 260 | { |
243 | if (cache_table[k].descriptor == des) { | 261 | if (cache_table[k].descriptor == des) { |
262 | if (only_trace && cache_table[k].cache_type != LVL_TRACE) | ||
263 | break; | ||
244 | switch (cache_table[k].cache_type) { | 264 | switch (cache_table[k].cache_type) { |
245 | case LVL_1_INST: | 265 | case LVL_1_INST: |
246 | l1i += cache_table[k].size; | 266 | l1i += cache_table[k].size; |
@@ -266,34 +286,45 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) | |||
266 | } | 286 | } |
267 | } | 287 | } |
268 | } | 288 | } |
289 | } | ||
269 | 290 | ||
270 | if (new_l1d) | 291 | if (new_l1d) |
271 | l1d = new_l1d; | 292 | l1d = new_l1d; |
272 | 293 | ||
273 | if (new_l1i) | 294 | if (new_l1i) |
274 | l1i = new_l1i; | 295 | l1i = new_l1i; |
275 | 296 | ||
276 | if (new_l2) | 297 | if (new_l2) { |
277 | l2 = new_l2; | 298 | l2 = new_l2; |
299 | #ifdef CONFIG_SMP | ||
300 | cpu_llc_id[cpu] = l2_id; | ||
301 | #endif | ||
302 | } | ||
278 | 303 | ||
279 | if (new_l3) | 304 | if (new_l3) { |
280 | l3 = new_l3; | 305 | l3 = new_l3; |
306 | #ifdef CONFIG_SMP | ||
307 | cpu_llc_id[cpu] = l3_id; | ||
308 | #endif | ||
309 | } | ||
281 | 310 | ||
282 | if ( trace ) | 311 | if (trace) |
283 | printk (KERN_INFO "CPU: Trace cache: %dK uops", trace); | 312 | printk (KERN_INFO "CPU: Trace cache: %dK uops", trace); |
284 | else if ( l1i ) | 313 | else if ( l1i ) |
285 | printk (KERN_INFO "CPU: L1 I cache: %dK", l1i); | 314 | printk (KERN_INFO "CPU: L1 I cache: %dK", l1i); |
286 | if ( l1d ) | ||
287 | printk(", L1 D cache: %dK\n", l1d); | ||
288 | else | ||
289 | printk("\n"); | ||
290 | if ( l2 ) | ||
291 | printk(KERN_INFO "CPU: L2 cache: %dK\n", l2); | ||
292 | if ( l3 ) | ||
293 | printk(KERN_INFO "CPU: L3 cache: %dK\n", l3); | ||
294 | 315 | ||
295 | c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d)); | 316 | if (l1d) |
296 | } | 317 | printk(", L1 D cache: %dK\n", l1d); |
318 | else | ||
319 | printk("\n"); | ||
320 | |||
321 | if (l2) | ||
322 | printk(KERN_INFO "CPU: L2 cache: %dK\n", l2); | ||
323 | |||
324 | if (l3) | ||
325 | printk(KERN_INFO "CPU: L3 cache: %dK\n", l3); | ||
326 | |||
327 | c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d)); | ||
297 | 328 | ||
298 | return l2; | 329 | return l2; |
299 | } | 330 | } |
@@ -330,7 +361,7 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) | |||
330 | } | 361 | } |
331 | } | 362 | } |
332 | } | 363 | } |
333 | static void __devinit cache_remove_shared_cpu_map(unsigned int cpu, int index) | 364 | static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) |
334 | { | 365 | { |
335 | struct _cpuid4_info *this_leaf, *sibling_leaf; | 366 | struct _cpuid4_info *this_leaf, *sibling_leaf; |
336 | int sibling; | 367 | int sibling; |
diff --git a/arch/i386/kernel/cpu/mcheck/mce.c b/arch/i386/kernel/cpu/mcheck/mce.c index 6170af3c271a..afa0888f9a1e 100644 --- a/arch/i386/kernel/cpu/mcheck/mce.c +++ b/arch/i386/kernel/cpu/mcheck/mce.c | |||
@@ -64,13 +64,13 @@ void mcheck_init(struct cpuinfo_x86 *c) | |||
64 | static int __init mcheck_disable(char *str) | 64 | static int __init mcheck_disable(char *str) |
65 | { | 65 | { |
66 | mce_disabled = 1; | 66 | mce_disabled = 1; |
67 | return 0; | 67 | return 1; |
68 | } | 68 | } |
69 | 69 | ||
70 | static int __init mcheck_enable(char *str) | 70 | static int __init mcheck_enable(char *str) |
71 | { | 71 | { |
72 | mce_disabled = -1; | 72 | mce_disabled = -1; |
73 | return 0; | 73 | return 1; |
74 | } | 74 | } |
75 | 75 | ||
76 | __setup("nomce", mcheck_disable); | 76 | __setup("nomce", mcheck_disable); |
diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index 3b4618bed70d..fff90bda4733 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <linux/smp.h> | 37 | #include <linux/smp.h> |
38 | #include <linux/cpu.h> | 38 | #include <linux/cpu.h> |
39 | #include <linux/mutex.h> | ||
39 | 40 | ||
40 | #include <asm/mtrr.h> | 41 | #include <asm/mtrr.h> |
41 | 42 | ||
@@ -47,7 +48,7 @@ | |||
47 | u32 num_var_ranges = 0; | 48 | u32 num_var_ranges = 0; |
48 | 49 | ||
49 | unsigned int *usage_table; | 50 | unsigned int *usage_table; |
50 | static DECLARE_MUTEX(mtrr_sem); | 51 | static DEFINE_MUTEX(mtrr_mutex); |
51 | 52 | ||
52 | u32 size_or_mask, size_and_mask; | 53 | u32 size_or_mask, size_and_mask; |
53 | 54 | ||
@@ -333,7 +334,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, | |||
333 | /* No CPU hotplug when we change MTRR entries */ | 334 | /* No CPU hotplug when we change MTRR entries */ |
334 | lock_cpu_hotplug(); | 335 | lock_cpu_hotplug(); |
335 | /* Search for existing MTRR */ | 336 | /* Search for existing MTRR */ |
336 | down(&mtrr_sem); | 337 | mutex_lock(&mtrr_mutex); |
337 | for (i = 0; i < num_var_ranges; ++i) { | 338 | for (i = 0; i < num_var_ranges; ++i) { |
338 | mtrr_if->get(i, &lbase, &lsize, <ype); | 339 | mtrr_if->get(i, &lbase, &lsize, <ype); |
339 | if (base >= lbase + lsize) | 340 | if (base >= lbase + lsize) |
@@ -371,7 +372,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, | |||
371 | printk(KERN_INFO "mtrr: no more MTRRs available\n"); | 372 | printk(KERN_INFO "mtrr: no more MTRRs available\n"); |
372 | error = i; | 373 | error = i; |
373 | out: | 374 | out: |
374 | up(&mtrr_sem); | 375 | mutex_unlock(&mtrr_mutex); |
375 | unlock_cpu_hotplug(); | 376 | unlock_cpu_hotplug(); |
376 | return error; | 377 | return error; |
377 | } | 378 | } |
@@ -464,7 +465,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) | |||
464 | max = num_var_ranges; | 465 | max = num_var_ranges; |
465 | /* No CPU hotplug when we change MTRR entries */ | 466 | /* No CPU hotplug when we change MTRR entries */ |
466 | lock_cpu_hotplug(); | 467 | lock_cpu_hotplug(); |
467 | down(&mtrr_sem); | 468 | mutex_lock(&mtrr_mutex); |
468 | if (reg < 0) { | 469 | if (reg < 0) { |
469 | /* Search for existing MTRR */ | 470 | /* Search for existing MTRR */ |
470 | for (i = 0; i < max; ++i) { | 471 | for (i = 0; i < max; ++i) { |
@@ -503,7 +504,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) | |||
503 | set_mtrr(reg, 0, 0, 0); | 504 | set_mtrr(reg, 0, 0, 0); |
504 | error = reg; | 505 | error = reg; |
505 | out: | 506 | out: |
506 | up(&mtrr_sem); | 507 | mutex_unlock(&mtrr_mutex); |
507 | unlock_cpu_hotplug(); | 508 | unlock_cpu_hotplug(); |
508 | return error; | 509 | return error; |
509 | } | 510 | } |
@@ -685,7 +686,7 @@ void mtrr_ap_init(void) | |||
685 | if (!mtrr_if || !use_intel()) | 686 | if (!mtrr_if || !use_intel()) |
686 | return; | 687 | return; |
687 | /* | 688 | /* |
688 | * Ideally we should hold mtrr_sem here to avoid mtrr entries changed, | 689 | * Ideally we should hold mtrr_mutex here to avoid mtrr entries changed, |
689 | * but this routine will be called in cpu boot time, holding the lock | 690 | * but this routine will be called in cpu boot time, holding the lock |
690 | * breaks it. This routine is called in two cases: 1.very earily time | 691 | * breaks it. This routine is called in two cases: 1.very earily time |
691 | * of software resume, when there absolutely isn't mtrr entry changes; | 692 | * of software resume, when there absolutely isn't mtrr entry changes; |
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c index 89a85af33d28..f94cdb7aca50 100644 --- a/arch/i386/kernel/cpu/proc.c +++ b/arch/i386/kernel/cpu/proc.c | |||
@@ -40,12 +40,12 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
40 | /* Other (Linux-defined) */ | 40 | /* Other (Linux-defined) */ |
41 | "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr", | 41 | "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr", |
42 | NULL, NULL, NULL, NULL, | 42 | NULL, NULL, NULL, NULL, |
43 | "constant_tsc", NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 43 | "constant_tsc", "up", NULL, NULL, NULL, NULL, NULL, NULL, |
44 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 44 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
45 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 45 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
46 | 46 | ||
47 | /* Intel-defined (#2) */ | 47 | /* Intel-defined (#2) */ |
48 | "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", NULL, "est", | 48 | "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est", |
49 | "tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL, | 49 | "tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL, |
50 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 50 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
51 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 51 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c index d49dbe8dc96b..e3c5fca0aa8a 100644 --- a/arch/i386/kernel/crash.c +++ b/arch/i386/kernel/crash.c | |||
@@ -105,7 +105,7 @@ static int crash_nmi_callback(struct pt_regs *regs, int cpu) | |||
105 | return 1; | 105 | return 1; |
106 | local_irq_disable(); | 106 | local_irq_disable(); |
107 | 107 | ||
108 | if (!user_mode(regs)) { | 108 | if (!user_mode_vm(regs)) { |
109 | crash_fixup_ss_esp(&fixed_regs, regs); | 109 | crash_fixup_ss_esp(&fixed_regs, regs); |
110 | regs = &fixed_regs; | 110 | regs = &fixed_regs; |
111 | } | 111 | } |
diff --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c index 6a93d75db431..5efceebc48dc 100644 --- a/arch/i386/kernel/dmi_scan.c +++ b/arch/i386/kernel/dmi_scan.c | |||
@@ -3,8 +3,10 @@ | |||
3 | #include <linux/init.h> | 3 | #include <linux/init.h> |
4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
5 | #include <linux/dmi.h> | 5 | #include <linux/dmi.h> |
6 | #include <linux/efi.h> | ||
6 | #include <linux/bootmem.h> | 7 | #include <linux/bootmem.h> |
7 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
9 | #include <asm/dmi.h> | ||
8 | 10 | ||
9 | static char * __init dmi_string(struct dmi_header *dm, u8 s) | 11 | static char * __init dmi_string(struct dmi_header *dm, u8 s) |
10 | { | 12 | { |
@@ -106,7 +108,7 @@ static void __init dmi_save_devices(struct dmi_header *dm) | |||
106 | struct dmi_device *dev; | 108 | struct dmi_device *dev; |
107 | 109 | ||
108 | for (i = 0; i < count; i++) { | 110 | for (i = 0; i < count; i++) { |
109 | char *d = ((char *) dm) + (i * 2); | 111 | char *d = (char *)(dm + 1) + (i * 2); |
110 | 112 | ||
111 | /* Skip disabled device */ | 113 | /* Skip disabled device */ |
112 | if ((*d & 0x80) == 0) | 114 | if ((*d & 0x80) == 0) |
@@ -184,47 +186,72 @@ static void __init dmi_decode(struct dmi_header *dm) | |||
184 | } | 186 | } |
185 | } | 187 | } |
186 | 188 | ||
187 | void __init dmi_scan_machine(void) | 189 | static int __init dmi_present(char __iomem *p) |
188 | { | 190 | { |
189 | u8 buf[15]; | 191 | u8 buf[15]; |
190 | char __iomem *p, *q; | 192 | memcpy_fromio(buf, p, 15); |
193 | if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) { | ||
194 | u16 num = (buf[13] << 8) | buf[12]; | ||
195 | u16 len = (buf[7] << 8) | buf[6]; | ||
196 | u32 base = (buf[11] << 24) | (buf[10] << 16) | | ||
197 | (buf[9] << 8) | buf[8]; | ||
191 | 198 | ||
192 | /* | 199 | /* |
193 | * no iounmap() for that ioremap(); it would be a no-op, but it's | 200 | * DMI version 0.0 means that the real version is taken from |
194 | * so early in setup that sucker gets confused into doing what | 201 | * the SMBIOS version, which we don't know at this point. |
195 | * it shouldn't if we actually call it. | 202 | */ |
196 | */ | 203 | if (buf[14] != 0) |
197 | p = ioremap(0xF0000, 0x10000); | 204 | printk(KERN_INFO "DMI %d.%d present.\n", |
198 | if (p == NULL) | 205 | buf[14] >> 4, buf[14] & 0xF); |
199 | goto out; | 206 | else |
200 | 207 | printk(KERN_INFO "DMI present.\n"); | |
201 | for (q = p; q < p + 0x10000; q += 16) { | 208 | if (dmi_table(base,len, num, dmi_decode) == 0) |
202 | memcpy_fromio(buf, q, 15); | 209 | return 0; |
203 | if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) { | 210 | } |
204 | u16 num = (buf[13] << 8) | buf[12]; | 211 | return 1; |
205 | u16 len = (buf[7] << 8) | buf[6]; | 212 | } |
206 | u32 base = (buf[11] << 24) | (buf[10] << 16) | | 213 | |
207 | (buf[9] << 8) | buf[8]; | 214 | void __init dmi_scan_machine(void) |
208 | 215 | { | |
209 | /* | 216 | char __iomem *p, *q; |
210 | * DMI version 0.0 means that the real version is taken from | 217 | int rc; |
211 | * the SMBIOS version, which we don't know at this point. | 218 | |
212 | */ | 219 | if (efi_enabled) { |
213 | if (buf[14] != 0) | 220 | if (efi.smbios == EFI_INVALID_TABLE_ADDR) |
214 | printk(KERN_INFO "DMI %d.%d present.\n", | 221 | goto out; |
215 | buf[14] >> 4, buf[14] & 0xF); | 222 | |
216 | else | 223 | /* This is called as a core_initcall() because it isn't |
217 | printk(KERN_INFO "DMI present.\n"); | 224 | * needed during early boot. This also means we can |
225 | * iounmap the space when we're done with it. | ||
226 | */ | ||
227 | p = dmi_ioremap(efi.smbios, 32); | ||
228 | if (p == NULL) | ||
229 | goto out; | ||
230 | |||
231 | rc = dmi_present(p + 0x10); /* offset of _DMI_ string */ | ||
232 | dmi_iounmap(p, 32); | ||
233 | if (!rc) | ||
234 | return; | ||
235 | } | ||
236 | else { | ||
237 | /* | ||
238 | * no iounmap() for that ioremap(); it would be a no-op, but | ||
239 | * it's so early in setup that sucker gets confused into doing | ||
240 | * what it shouldn't if we actually call it. | ||
241 | */ | ||
242 | p = dmi_ioremap(0xF0000, 0x10000); | ||
243 | if (p == NULL) | ||
244 | goto out; | ||
218 | 245 | ||
219 | if (dmi_table(base,len, num, dmi_decode) == 0) | 246 | for (q = p; q < p + 0x10000; q += 16) { |
247 | rc = dmi_present(q); | ||
248 | if (!rc) | ||
220 | return; | 249 | return; |
221 | } | 250 | } |
222 | } | 251 | } |
223 | 252 | out: printk(KERN_INFO "DMI not present or invalid.\n"); | |
224 | out: printk(KERN_INFO "DMI not present or invalid.\n"); | ||
225 | } | 253 | } |
226 | 254 | ||
227 | |||
228 | /** | 255 | /** |
229 | * dmi_check_system - check system DMI data | 256 | * dmi_check_system - check system DMI data |
230 | * @list: array of dmi_system_id structures to match against | 257 | * @list: array of dmi_system_id structures to match against |
@@ -299,3 +326,33 @@ struct dmi_device * dmi_find_device(int type, const char *name, | |||
299 | return NULL; | 326 | return NULL; |
300 | } | 327 | } |
301 | EXPORT_SYMBOL(dmi_find_device); | 328 | EXPORT_SYMBOL(dmi_find_device); |
329 | |||
330 | /** | ||
331 | * dmi_get_year - Return year of a DMI date | ||
332 | * @field: data index (like dmi_get_system_info) | ||
333 | * | ||
334 | * Returns -1 when the field doesn't exist. 0 when it is broken. | ||
335 | */ | ||
336 | int dmi_get_year(int field) | ||
337 | { | ||
338 | int year; | ||
339 | char *s = dmi_get_system_info(field); | ||
340 | |||
341 | if (!s) | ||
342 | return -1; | ||
343 | if (*s == '\0') | ||
344 | return 0; | ||
345 | s = strrchr(s, '/'); | ||
346 | if (!s) | ||
347 | return 0; | ||
348 | |||
349 | s += 1; | ||
350 | year = simple_strtoul(s, NULL, 0); | ||
351 | if (year && year < 100) { /* 2-digit year */ | ||
352 | year += 1900; | ||
353 | if (year < 1996) /* no dates < spec 1.0 */ | ||
354 | year += 100; | ||
355 | } | ||
356 | |||
357 | return year; | ||
358 | } | ||
diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c index c9cad7ba0d2d..9202b67c4b2e 100644 --- a/arch/i386/kernel/efi.c +++ b/arch/i386/kernel/efi.c | |||
@@ -115,7 +115,7 @@ static void efi_call_phys_epilog(void) | |||
115 | unsigned long cr4; | 115 | unsigned long cr4; |
116 | struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0); | 116 | struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0); |
117 | 117 | ||
118 | cpu_gdt_descr->address = __va(cpu_gdt_descr->address); | 118 | cpu_gdt_descr->address = (unsigned long)__va(cpu_gdt_descr->address); |
119 | load_gdt(cpu_gdt_descr); | 119 | load_gdt(cpu_gdt_descr); |
120 | 120 | ||
121 | cr4 = read_cr4(); | 121 | cr4 = read_cr4(); |
@@ -361,7 +361,7 @@ void __init efi_init(void) | |||
361 | */ | 361 | */ |
362 | c16 = (efi_char16_t *) boot_ioremap(efi.systab->fw_vendor, 2); | 362 | c16 = (efi_char16_t *) boot_ioremap(efi.systab->fw_vendor, 2); |
363 | if (c16) { | 363 | if (c16) { |
364 | for (i = 0; i < sizeof(vendor) && *c16; ++i) | 364 | for (i = 0; i < (sizeof(vendor) - 1) && *c16; ++i) |
365 | vendor[i] = *c16++; | 365 | vendor[i] = *c16++; |
366 | vendor[i] = '\0'; | 366 | vendor[i] = '\0'; |
367 | } else | 367 | } else |
@@ -381,29 +381,38 @@ void __init efi_init(void) | |||
381 | if (config_tables == NULL) | 381 | if (config_tables == NULL) |
382 | printk(KERN_ERR PFX "Could not map EFI Configuration Table!\n"); | 382 | printk(KERN_ERR PFX "Could not map EFI Configuration Table!\n"); |
383 | 383 | ||
384 | efi.mps = EFI_INVALID_TABLE_ADDR; | ||
385 | efi.acpi = EFI_INVALID_TABLE_ADDR; | ||
386 | efi.acpi20 = EFI_INVALID_TABLE_ADDR; | ||
387 | efi.smbios = EFI_INVALID_TABLE_ADDR; | ||
388 | efi.sal_systab = EFI_INVALID_TABLE_ADDR; | ||
389 | efi.boot_info = EFI_INVALID_TABLE_ADDR; | ||
390 | efi.hcdp = EFI_INVALID_TABLE_ADDR; | ||
391 | efi.uga = EFI_INVALID_TABLE_ADDR; | ||
392 | |||
384 | for (i = 0; i < num_config_tables; i++) { | 393 | for (i = 0; i < num_config_tables; i++) { |
385 | if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) { | 394 | if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) { |
386 | efi.mps = (void *)config_tables[i].table; | 395 | efi.mps = config_tables[i].table; |
387 | printk(KERN_INFO " MPS=0x%lx ", config_tables[i].table); | 396 | printk(KERN_INFO " MPS=0x%lx ", config_tables[i].table); |
388 | } else | 397 | } else |
389 | if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) { | 398 | if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) { |
390 | efi.acpi20 = __va(config_tables[i].table); | 399 | efi.acpi20 = config_tables[i].table; |
391 | printk(KERN_INFO " ACPI 2.0=0x%lx ", config_tables[i].table); | 400 | printk(KERN_INFO " ACPI 2.0=0x%lx ", config_tables[i].table); |
392 | } else | 401 | } else |
393 | if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) { | 402 | if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) { |
394 | efi.acpi = __va(config_tables[i].table); | 403 | efi.acpi = config_tables[i].table; |
395 | printk(KERN_INFO " ACPI=0x%lx ", config_tables[i].table); | 404 | printk(KERN_INFO " ACPI=0x%lx ", config_tables[i].table); |
396 | } else | 405 | } else |
397 | if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) { | 406 | if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) { |
398 | efi.smbios = (void *) config_tables[i].table; | 407 | efi.smbios = config_tables[i].table; |
399 | printk(KERN_INFO " SMBIOS=0x%lx ", config_tables[i].table); | 408 | printk(KERN_INFO " SMBIOS=0x%lx ", config_tables[i].table); |
400 | } else | 409 | } else |
401 | if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) { | 410 | if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) { |
402 | efi.hcdp = (void *)config_tables[i].table; | 411 | efi.hcdp = config_tables[i].table; |
403 | printk(KERN_INFO " HCDP=0x%lx ", config_tables[i].table); | 412 | printk(KERN_INFO " HCDP=0x%lx ", config_tables[i].table); |
404 | } else | 413 | } else |
405 | if (efi_guidcmp(config_tables[i].guid, UGA_IO_PROTOCOL_GUID) == 0) { | 414 | if (efi_guidcmp(config_tables[i].guid, UGA_IO_PROTOCOL_GUID) == 0) { |
406 | efi.uga = (void *)config_tables[i].table; | 415 | efi.uga = config_tables[i].table; |
407 | printk(KERN_INFO " UGA=0x%lx ", config_tables[i].table); | 416 | printk(KERN_INFO " UGA=0x%lx ", config_tables[i].table); |
408 | } | 417 | } |
409 | } | 418 | } |
@@ -543,7 +552,7 @@ efi_initialize_iomem_resources(struct resource *code_resource, | |||
543 | if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) > | 552 | if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) > |
544 | 0x100000000ULL) | 553 | 0x100000000ULL) |
545 | continue; | 554 | continue; |
546 | res = alloc_bootmem_low(sizeof(struct resource)); | 555 | res = kzalloc(sizeof(struct resource), GFP_ATOMIC); |
547 | switch (md->type) { | 556 | switch (md->type) { |
548 | case EFI_RESERVED_TYPE: | 557 | case EFI_RESERVED_TYPE: |
549 | res->name = "Reserved Memory"; | 558 | res->name = "Reserved Memory"; |
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 4d704724b2f5..cfc683f153b9 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S | |||
@@ -226,6 +226,10 @@ ENTRY(system_call) | |||
226 | pushl %eax # save orig_eax | 226 | pushl %eax # save orig_eax |
227 | SAVE_ALL | 227 | SAVE_ALL |
228 | GET_THREAD_INFO(%ebp) | 228 | GET_THREAD_INFO(%ebp) |
229 | testl $TF_MASK,EFLAGS(%esp) | ||
230 | jz no_singlestep | ||
231 | orl $_TIF_SINGLESTEP,TI_flags(%ebp) | ||
232 | no_singlestep: | ||
229 | # system call tracing in operation / emulation | 233 | # system call tracing in operation / emulation |
230 | /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ | 234 | /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ |
231 | testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp) | 235 | testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp) |
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index e0b7c632efbc..3debc2e26542 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S | |||
@@ -450,7 +450,6 @@ int_msg: | |||
450 | 450 | ||
451 | .globl boot_gdt_descr | 451 | .globl boot_gdt_descr |
452 | .globl idt_descr | 452 | .globl idt_descr |
453 | .globl cpu_gdt_descr | ||
454 | 453 | ||
455 | ALIGN | 454 | ALIGN |
456 | # early boot GDT descriptor (must use 1:1 address mapping) | 455 | # early boot GDT descriptor (must use 1:1 address mapping) |
@@ -470,8 +469,6 @@ cpu_gdt_descr: | |||
470 | .word GDT_ENTRIES*8-1 | 469 | .word GDT_ENTRIES*8-1 |
471 | .long cpu_gdt_table | 470 | .long cpu_gdt_table |
472 | 471 | ||
473 | .fill NR_CPUS-1,8,0 # space for the other GDT descriptors | ||
474 | |||
475 | /* | 472 | /* |
476 | * The boot_gdt_table must mirror the equivalent in setup.S and is | 473 | * The boot_gdt_table must mirror the equivalent in setup.S and is |
477 | * used only for booting. | 474 | * used only for booting. |
@@ -485,7 +482,7 @@ ENTRY(boot_gdt_table) | |||
485 | /* | 482 | /* |
486 | * The Global Descriptor Table contains 28 quadwords, per-CPU. | 483 | * The Global Descriptor Table contains 28 quadwords, per-CPU. |
487 | */ | 484 | */ |
488 | .align PAGE_SIZE_asm | 485 | .align L1_CACHE_BYTES |
489 | ENTRY(cpu_gdt_table) | 486 | ENTRY(cpu_gdt_table) |
490 | .quad 0x0000000000000000 /* NULL descriptor */ | 487 | .quad 0x0000000000000000 /* NULL descriptor */ |
491 | .quad 0x0000000000000000 /* 0x0b reserved */ | 488 | .quad 0x0000000000000000 /* 0x0b reserved */ |
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 39d9a5fa907e..f8f132aa5472 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -351,8 +351,8 @@ static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold) | |||
351 | { | 351 | { |
352 | int i, j; | 352 | int i, j; |
353 | Dprintk("Rotating IRQs among CPUs.\n"); | 353 | Dprintk("Rotating IRQs among CPUs.\n"); |
354 | for (i = 0; i < NR_CPUS; i++) { | 354 | for_each_online_cpu(i) { |
355 | for (j = 0; cpu_online(i) && (j < NR_IRQS); j++) { | 355 | for (j = 0; j < NR_IRQS; j++) { |
356 | if (!irq_desc[j].action) | 356 | if (!irq_desc[j].action) |
357 | continue; | 357 | continue; |
358 | /* Is it a significant load ? */ | 358 | /* Is it a significant load ? */ |
@@ -381,7 +381,7 @@ static void do_irq_balance(void) | |||
381 | unsigned long imbalance = 0; | 381 | unsigned long imbalance = 0; |
382 | cpumask_t allowed_mask, target_cpu_mask, tmp; | 382 | cpumask_t allowed_mask, target_cpu_mask, tmp; |
383 | 383 | ||
384 | for (i = 0; i < NR_CPUS; i++) { | 384 | for_each_possible_cpu(i) { |
385 | int package_index; | 385 | int package_index; |
386 | CPU_IRQ(i) = 0; | 386 | CPU_IRQ(i) = 0; |
387 | if (!cpu_online(i)) | 387 | if (!cpu_online(i)) |
@@ -422,9 +422,7 @@ static void do_irq_balance(void) | |||
422 | } | 422 | } |
423 | } | 423 | } |
424 | /* Find the least loaded processor package */ | 424 | /* Find the least loaded processor package */ |
425 | for (i = 0; i < NR_CPUS; i++) { | 425 | for_each_online_cpu(i) { |
426 | if (!cpu_online(i)) | ||
427 | continue; | ||
428 | if (i != CPU_TO_PACKAGEINDEX(i)) | 426 | if (i != CPU_TO_PACKAGEINDEX(i)) |
429 | continue; | 427 | continue; |
430 | if (min_cpu_irq > CPU_IRQ(i)) { | 428 | if (min_cpu_irq > CPU_IRQ(i)) { |
@@ -441,9 +439,7 @@ tryanothercpu: | |||
441 | */ | 439 | */ |
442 | tmp_cpu_irq = 0; | 440 | tmp_cpu_irq = 0; |
443 | tmp_loaded = -1; | 441 | tmp_loaded = -1; |
444 | for (i = 0; i < NR_CPUS; i++) { | 442 | for_each_online_cpu(i) { |
445 | if (!cpu_online(i)) | ||
446 | continue; | ||
447 | if (i != CPU_TO_PACKAGEINDEX(i)) | 443 | if (i != CPU_TO_PACKAGEINDEX(i)) |
448 | continue; | 444 | continue; |
449 | if (max_cpu_irq <= CPU_IRQ(i)) | 445 | if (max_cpu_irq <= CPU_IRQ(i)) |
@@ -619,9 +615,7 @@ static int __init balanced_irq_init(void) | |||
619 | if (smp_num_siblings > 1 && !cpus_empty(tmp)) | 615 | if (smp_num_siblings > 1 && !cpus_empty(tmp)) |
620 | physical_balance = 1; | 616 | physical_balance = 1; |
621 | 617 | ||
622 | for (i = 0; i < NR_CPUS; i++) { | 618 | for_each_online_cpu(i) { |
623 | if (!cpu_online(i)) | ||
624 | continue; | ||
625 | irq_cpu_data[i].irq_delta = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); | 619 | irq_cpu_data[i].irq_delta = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); |
626 | irq_cpu_data[i].last_irq = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); | 620 | irq_cpu_data[i].last_irq = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); |
627 | if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) { | 621 | if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) { |
@@ -638,9 +632,11 @@ static int __init balanced_irq_init(void) | |||
638 | else | 632 | else |
639 | printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); | 633 | printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); |
640 | failed: | 634 | failed: |
641 | for (i = 0; i < NR_CPUS; i++) { | 635 | for_each_possible_cpu(i) { |
642 | kfree(irq_cpu_data[i].irq_delta); | 636 | kfree(irq_cpu_data[i].irq_delta); |
637 | irq_cpu_data[i].irq_delta = NULL; | ||
643 | kfree(irq_cpu_data[i].last_irq); | 638 | kfree(irq_cpu_data[i].last_irq); |
639 | irq_cpu_data[i].last_irq = NULL; | ||
644 | } | 640 | } |
645 | return 0; | 641 | return 0; |
646 | } | 642 | } |
@@ -648,7 +644,7 @@ failed: | |||
648 | int __init irqbalance_disable(char *str) | 644 | int __init irqbalance_disable(char *str) |
649 | { | 645 | { |
650 | irqbalance_disabled = 1; | 646 | irqbalance_disabled = 1; |
651 | return 0; | 647 | return 1; |
652 | } | 648 | } |
653 | 649 | ||
654 | __setup("noirqbalance", irqbalance_disable); | 650 | __setup("noirqbalance", irqbalance_disable); |
@@ -1761,7 +1757,8 @@ static void __init setup_ioapic_ids_from_mpc(void) | |||
1761 | * Don't check I/O APIC IDs for xAPIC systems. They have | 1757 | * Don't check I/O APIC IDs for xAPIC systems. They have |
1762 | * no meaning without the serial APIC bus. | 1758 | * no meaning without the serial APIC bus. |
1763 | */ | 1759 | */ |
1764 | if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && boot_cpu_data.x86 < 15)) | 1760 | if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) |
1761 | || APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) | ||
1765 | return; | 1762 | return; |
1766 | /* | 1763 | /* |
1767 | * This is broken; anything with a real cpu count has to | 1764 | * This is broken; anything with a real cpu count has to |
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index 694a13997637..f19768789e8a 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c | |||
@@ -35,12 +35,56 @@ | |||
35 | #include <asm/cacheflush.h> | 35 | #include <asm/cacheflush.h> |
36 | #include <asm/kdebug.h> | 36 | #include <asm/kdebug.h> |
37 | #include <asm/desc.h> | 37 | #include <asm/desc.h> |
38 | #include <asm/uaccess.h> | ||
38 | 39 | ||
39 | void jprobe_return_end(void); | 40 | void jprobe_return_end(void); |
40 | 41 | ||
41 | DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; | 42 | DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; |
42 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); | 43 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); |
43 | 44 | ||
45 | /* insert a jmp code */ | ||
46 | static inline void set_jmp_op(void *from, void *to) | ||
47 | { | ||
48 | struct __arch_jmp_op { | ||
49 | char op; | ||
50 | long raddr; | ||
51 | } __attribute__((packed)) *jop; | ||
52 | jop = (struct __arch_jmp_op *)from; | ||
53 | jop->raddr = (long)(to) - ((long)(from) + 5); | ||
54 | jop->op = RELATIVEJUMP_INSTRUCTION; | ||
55 | } | ||
56 | |||
57 | /* | ||
58 | * returns non-zero if opcodes can be boosted. | ||
59 | */ | ||
60 | static inline int can_boost(kprobe_opcode_t opcode) | ||
61 | { | ||
62 | switch (opcode & 0xf0 ) { | ||
63 | case 0x70: | ||
64 | return 0; /* can't boost conditional jump */ | ||
65 | case 0x90: | ||
66 | /* can't boost call and pushf */ | ||
67 | return opcode != 0x9a && opcode != 0x9c; | ||
68 | case 0xc0: | ||
69 | /* can't boost undefined opcodes and soft-interruptions */ | ||
70 | return (0xc1 < opcode && opcode < 0xc6) || | ||
71 | (0xc7 < opcode && opcode < 0xcc) || opcode == 0xcf; | ||
72 | case 0xd0: | ||
73 | /* can boost AA* and XLAT */ | ||
74 | return (opcode == 0xd4 || opcode == 0xd5 || opcode == 0xd7); | ||
75 | case 0xe0: | ||
76 | /* can boost in/out and (may be) jmps */ | ||
77 | return (0xe3 < opcode && opcode != 0xe8); | ||
78 | case 0xf0: | ||
79 | /* clear and set flags can be boost */ | ||
80 | return (opcode == 0xf5 || (0xf7 < opcode && opcode < 0xfe)); | ||
81 | default: | ||
82 | /* currently, can't boost 2 bytes opcodes */ | ||
83 | return opcode != 0x0f; | ||
84 | } | ||
85 | } | ||
86 | |||
87 | |||
44 | /* | 88 | /* |
45 | * returns non-zero if opcode modifies the interrupt flag. | 89 | * returns non-zero if opcode modifies the interrupt flag. |
46 | */ | 90 | */ |
@@ -65,6 +109,11 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) | |||
65 | 109 | ||
66 | memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); | 110 | memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); |
67 | p->opcode = *p->addr; | 111 | p->opcode = *p->addr; |
112 | if (can_boost(p->opcode)) { | ||
113 | p->ainsn.boostable = 0; | ||
114 | } else { | ||
115 | p->ainsn.boostable = -1; | ||
116 | } | ||
68 | return 0; | 117 | return 0; |
69 | } | 118 | } |
70 | 119 | ||
@@ -84,9 +133,9 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) | |||
84 | 133 | ||
85 | void __kprobes arch_remove_kprobe(struct kprobe *p) | 134 | void __kprobes arch_remove_kprobe(struct kprobe *p) |
86 | { | 135 | { |
87 | down(&kprobe_mutex); | 136 | mutex_lock(&kprobe_mutex); |
88 | free_insn_slot(p->ainsn.insn); | 137 | free_insn_slot(p->ainsn.insn); |
89 | up(&kprobe_mutex); | 138 | mutex_unlock(&kprobe_mutex); |
90 | } | 139 | } |
91 | 140 | ||
92 | static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | 141 | static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) |
@@ -155,9 +204,13 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
155 | { | 204 | { |
156 | struct kprobe *p; | 205 | struct kprobe *p; |
157 | int ret = 0; | 206 | int ret = 0; |
158 | kprobe_opcode_t *addr = NULL; | 207 | kprobe_opcode_t *addr; |
159 | unsigned long *lp; | ||
160 | struct kprobe_ctlblk *kcb; | 208 | struct kprobe_ctlblk *kcb; |
209 | #ifdef CONFIG_PREEMPT | ||
210 | unsigned pre_preempt_count = preempt_count(); | ||
211 | #endif /* CONFIG_PREEMPT */ | ||
212 | |||
213 | addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t)); | ||
161 | 214 | ||
162 | /* | 215 | /* |
163 | * We don't want to be preempted for the entire | 216 | * We don't want to be preempted for the entire |
@@ -166,17 +219,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
166 | preempt_disable(); | 219 | preempt_disable(); |
167 | kcb = get_kprobe_ctlblk(); | 220 | kcb = get_kprobe_ctlblk(); |
168 | 221 | ||
169 | /* Check if the application is using LDT entry for its code segment and | ||
170 | * calculate the address by reading the base address from the LDT entry. | ||
171 | */ | ||
172 | if ((regs->xcs & 4) && (current->mm)) { | ||
173 | lp = (unsigned long *) ((unsigned long)((regs->xcs >> 3) * 8) | ||
174 | + (char *) current->mm->context.ldt); | ||
175 | addr = (kprobe_opcode_t *) (get_desc_base(lp) + regs->eip - | ||
176 | sizeof(kprobe_opcode_t)); | ||
177 | } else { | ||
178 | addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t)); | ||
179 | } | ||
180 | /* Check we're not actually recursing */ | 222 | /* Check we're not actually recursing */ |
181 | if (kprobe_running()) { | 223 | if (kprobe_running()) { |
182 | p = get_kprobe(addr); | 224 | p = get_kprobe(addr); |
@@ -252,6 +294,21 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
252 | /* handler has already set things up, so skip ss setup */ | 294 | /* handler has already set things up, so skip ss setup */ |
253 | return 1; | 295 | return 1; |
254 | 296 | ||
297 | if (p->ainsn.boostable == 1 && | ||
298 | #ifdef CONFIG_PREEMPT | ||
299 | !(pre_preempt_count) && /* | ||
300 | * This enables booster when the direct | ||
301 | * execution path aren't preempted. | ||
302 | */ | ||
303 | #endif /* CONFIG_PREEMPT */ | ||
304 | !p->post_handler && !p->break_handler ) { | ||
305 | /* Boost up -- we can execute copied instructions directly */ | ||
306 | reset_current_kprobe(); | ||
307 | regs->eip = (unsigned long)p->ainsn.insn; | ||
308 | preempt_enable_no_resched(); | ||
309 | return 1; | ||
310 | } | ||
311 | |||
255 | ss_probe: | 312 | ss_probe: |
256 | prepare_singlestep(p, regs); | 313 | prepare_singlestep(p, regs); |
257 | kcb->kprobe_status = KPROBE_HIT_SS; | 314 | kcb->kprobe_status = KPROBE_HIT_SS; |
@@ -267,17 +324,44 @@ no_kprobe: | |||
267 | * here. When a retprobed function returns, this probe is hit and | 324 | * here. When a retprobed function returns, this probe is hit and |
268 | * trampoline_probe_handler() runs, calling the kretprobe's handler. | 325 | * trampoline_probe_handler() runs, calling the kretprobe's handler. |
269 | */ | 326 | */ |
270 | void kretprobe_trampoline_holder(void) | 327 | void __kprobes kretprobe_trampoline_holder(void) |
271 | { | 328 | { |
272 | asm volatile ( ".global kretprobe_trampoline\n" | 329 | asm volatile ( ".global kretprobe_trampoline\n" |
273 | "kretprobe_trampoline: \n" | 330 | "kretprobe_trampoline: \n" |
274 | "nop\n"); | 331 | " pushf\n" |
275 | } | 332 | /* skip cs, eip, orig_eax, es, ds */ |
333 | " subl $20, %esp\n" | ||
334 | " pushl %eax\n" | ||
335 | " pushl %ebp\n" | ||
336 | " pushl %edi\n" | ||
337 | " pushl %esi\n" | ||
338 | " pushl %edx\n" | ||
339 | " pushl %ecx\n" | ||
340 | " pushl %ebx\n" | ||
341 | " movl %esp, %eax\n" | ||
342 | " call trampoline_handler\n" | ||
343 | /* move eflags to cs */ | ||
344 | " movl 48(%esp), %edx\n" | ||
345 | " movl %edx, 44(%esp)\n" | ||
346 | /* save true return address on eflags */ | ||
347 | " movl %eax, 48(%esp)\n" | ||
348 | " popl %ebx\n" | ||
349 | " popl %ecx\n" | ||
350 | " popl %edx\n" | ||
351 | " popl %esi\n" | ||
352 | " popl %edi\n" | ||
353 | " popl %ebp\n" | ||
354 | " popl %eax\n" | ||
355 | /* skip eip, orig_eax, es, ds */ | ||
356 | " addl $16, %esp\n" | ||
357 | " popf\n" | ||
358 | " ret\n"); | ||
359 | } | ||
276 | 360 | ||
277 | /* | 361 | /* |
278 | * Called when we hit the probe point at kretprobe_trampoline | 362 | * Called from kretprobe_trampoline |
279 | */ | 363 | */ |
280 | int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | 364 | fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) |
281 | { | 365 | { |
282 | struct kretprobe_instance *ri = NULL; | 366 | struct kretprobe_instance *ri = NULL; |
283 | struct hlist_head *head; | 367 | struct hlist_head *head; |
@@ -306,8 +390,11 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
306 | /* another task is sharing our hash bucket */ | 390 | /* another task is sharing our hash bucket */ |
307 | continue; | 391 | continue; |
308 | 392 | ||
309 | if (ri->rp && ri->rp->handler) | 393 | if (ri->rp && ri->rp->handler){ |
394 | __get_cpu_var(current_kprobe) = &ri->rp->kp; | ||
310 | ri->rp->handler(ri, regs); | 395 | ri->rp->handler(ri, regs); |
396 | __get_cpu_var(current_kprobe) = NULL; | ||
397 | } | ||
311 | 398 | ||
312 | orig_ret_address = (unsigned long)ri->ret_addr; | 399 | orig_ret_address = (unsigned long)ri->ret_addr; |
313 | recycle_rp_inst(ri); | 400 | recycle_rp_inst(ri); |
@@ -322,18 +409,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
322 | } | 409 | } |
323 | 410 | ||
324 | BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); | 411 | BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); |
325 | regs->eip = orig_ret_address; | ||
326 | 412 | ||
327 | reset_current_kprobe(); | ||
328 | spin_unlock_irqrestore(&kretprobe_lock, flags); | 413 | spin_unlock_irqrestore(&kretprobe_lock, flags); |
329 | preempt_enable_no_resched(); | ||
330 | 414 | ||
331 | /* | 415 | return (void*)orig_ret_address; |
332 | * By returning a non-zero value, we are telling | ||
333 | * kprobe_handler() that we don't want the post_handler | ||
334 | * to run (and have re-enabled preemption) | ||
335 | */ | ||
336 | return 1; | ||
337 | } | 416 | } |
338 | 417 | ||
339 | /* | 418 | /* |
@@ -357,15 +436,17 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
357 | * 2) If the single-stepped instruction was a call, the return address | 436 | * 2) If the single-stepped instruction was a call, the return address |
358 | * that is atop the stack is the address following the copied instruction. | 437 | * that is atop the stack is the address following the copied instruction. |
359 | * We need to make it the address following the original instruction. | 438 | * We need to make it the address following the original instruction. |
439 | * | ||
440 | * This function also checks instruction size for preparing direct execution. | ||
360 | */ | 441 | */ |
361 | static void __kprobes resume_execution(struct kprobe *p, | 442 | static void __kprobes resume_execution(struct kprobe *p, |
362 | struct pt_regs *regs, struct kprobe_ctlblk *kcb) | 443 | struct pt_regs *regs, struct kprobe_ctlblk *kcb) |
363 | { | 444 | { |
364 | unsigned long *tos = (unsigned long *)®s->esp; | 445 | unsigned long *tos = (unsigned long *)®s->esp; |
365 | unsigned long next_eip = 0; | ||
366 | unsigned long copy_eip = (unsigned long)p->ainsn.insn; | 446 | unsigned long copy_eip = (unsigned long)p->ainsn.insn; |
367 | unsigned long orig_eip = (unsigned long)p->addr; | 447 | unsigned long orig_eip = (unsigned long)p->addr; |
368 | 448 | ||
449 | regs->eflags &= ~TF_MASK; | ||
369 | switch (p->ainsn.insn[0]) { | 450 | switch (p->ainsn.insn[0]) { |
370 | case 0x9c: /* pushfl */ | 451 | case 0x9c: /* pushfl */ |
371 | *tos &= ~(TF_MASK | IF_MASK); | 452 | *tos &= ~(TF_MASK | IF_MASK); |
@@ -375,37 +456,51 @@ static void __kprobes resume_execution(struct kprobe *p, | |||
375 | case 0xcb: | 456 | case 0xcb: |
376 | case 0xc2: | 457 | case 0xc2: |
377 | case 0xca: | 458 | case 0xca: |
378 | regs->eflags &= ~TF_MASK; | 459 | case 0xea: /* jmp absolute -- eip is correct */ |
379 | /* eip is already adjusted, no more changes required*/ | 460 | /* eip is already adjusted, no more changes required */ |
380 | return; | 461 | p->ainsn.boostable = 1; |
462 | goto no_change; | ||
381 | case 0xe8: /* call relative - Fix return addr */ | 463 | case 0xe8: /* call relative - Fix return addr */ |
382 | *tos = orig_eip + (*tos - copy_eip); | 464 | *tos = orig_eip + (*tos - copy_eip); |
383 | break; | 465 | break; |
384 | case 0xff: | 466 | case 0xff: |
385 | if ((p->ainsn.insn[1] & 0x30) == 0x10) { | 467 | if ((p->ainsn.insn[1] & 0x30) == 0x10) { |
386 | /* call absolute, indirect */ | 468 | /* call absolute, indirect */ |
387 | /* Fix return addr; eip is correct. */ | 469 | /* |
388 | next_eip = regs->eip; | 470 | * Fix return addr; eip is correct. |
471 | * But this is not boostable | ||
472 | */ | ||
389 | *tos = orig_eip + (*tos - copy_eip); | 473 | *tos = orig_eip + (*tos - copy_eip); |
474 | goto no_change; | ||
390 | } else if (((p->ainsn.insn[1] & 0x31) == 0x20) || /* jmp near, absolute indirect */ | 475 | } else if (((p->ainsn.insn[1] & 0x31) == 0x20) || /* jmp near, absolute indirect */ |
391 | ((p->ainsn.insn[1] & 0x31) == 0x21)) { /* jmp far, absolute indirect */ | 476 | ((p->ainsn.insn[1] & 0x31) == 0x21)) { /* jmp far, absolute indirect */ |
392 | /* eip is correct. */ | 477 | /* eip is correct. And this is boostable */ |
393 | next_eip = regs->eip; | 478 | p->ainsn.boostable = 1; |
479 | goto no_change; | ||
394 | } | 480 | } |
395 | break; | ||
396 | case 0xea: /* jmp absolute -- eip is correct */ | ||
397 | next_eip = regs->eip; | ||
398 | break; | ||
399 | default: | 481 | default: |
400 | break; | 482 | break; |
401 | } | 483 | } |
402 | 484 | ||
403 | regs->eflags &= ~TF_MASK; | 485 | if (p->ainsn.boostable == 0) { |
404 | if (next_eip) { | 486 | if ((regs->eip > copy_eip) && |
405 | regs->eip = next_eip; | 487 | (regs->eip - copy_eip) + 5 < MAX_INSN_SIZE) { |
406 | } else { | 488 | /* |
407 | regs->eip = orig_eip + (regs->eip - copy_eip); | 489 | * These instructions can be executed directly if it |
490 | * jumps back to correct address. | ||
491 | */ | ||
492 | set_jmp_op((void *)regs->eip, | ||
493 | (void *)orig_eip + (regs->eip - copy_eip)); | ||
494 | p->ainsn.boostable = 1; | ||
495 | } else { | ||
496 | p->ainsn.boostable = -1; | ||
497 | } | ||
408 | } | 498 | } |
499 | |||
500 | regs->eip = orig_eip + (regs->eip - copy_eip); | ||
501 | |||
502 | no_change: | ||
503 | return; | ||
409 | } | 504 | } |
410 | 505 | ||
411 | /* | 506 | /* |
@@ -453,15 +548,57 @@ static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) | |||
453 | struct kprobe *cur = kprobe_running(); | 548 | struct kprobe *cur = kprobe_running(); |
454 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 549 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
455 | 550 | ||
456 | if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) | 551 | switch(kcb->kprobe_status) { |
457 | return 1; | 552 | case KPROBE_HIT_SS: |
458 | 553 | case KPROBE_REENTER: | |
459 | if (kcb->kprobe_status & KPROBE_HIT_SS) { | 554 | /* |
460 | resume_execution(cur, regs, kcb); | 555 | * We are here because the instruction being single |
556 | * stepped caused a page fault. We reset the current | ||
557 | * kprobe and the eip points back to the probe address | ||
558 | * and allow the page fault handler to continue as a | ||
559 | * normal page fault. | ||
560 | */ | ||
561 | regs->eip = (unsigned long)cur->addr; | ||
461 | regs->eflags |= kcb->kprobe_old_eflags; | 562 | regs->eflags |= kcb->kprobe_old_eflags; |
462 | 563 | if (kcb->kprobe_status == KPROBE_REENTER) | |
463 | reset_current_kprobe(); | 564 | restore_previous_kprobe(kcb); |
565 | else | ||
566 | reset_current_kprobe(); | ||
464 | preempt_enable_no_resched(); | 567 | preempt_enable_no_resched(); |
568 | break; | ||
569 | case KPROBE_HIT_ACTIVE: | ||
570 | case KPROBE_HIT_SSDONE: | ||
571 | /* | ||
572 | * We increment the nmissed count for accounting, | ||
573 | * we can also use npre/npostfault count for accouting | ||
574 | * these specific fault cases. | ||
575 | */ | ||
576 | kprobes_inc_nmissed_count(cur); | ||
577 | |||
578 | /* | ||
579 | * We come here because instructions in the pre/post | ||
580 | * handler caused the page_fault, this could happen | ||
581 | * if handler tries to access user space by | ||
582 | * copy_from_user(), get_user() etc. Let the | ||
583 | * user-specified handler try to fix it first. | ||
584 | */ | ||
585 | if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) | ||
586 | return 1; | ||
587 | |||
588 | /* | ||
589 | * In case the user-specified fault handler returned | ||
590 | * zero, try to fix up. | ||
591 | */ | ||
592 | if (fixup_exception(regs)) | ||
593 | return 1; | ||
594 | |||
595 | /* | ||
596 | * fixup_exception() could not handle it, | ||
597 | * Let do_page_fault() fix it. | ||
598 | */ | ||
599 | break; | ||
600 | default: | ||
601 | break; | ||
465 | } | 602 | } |
466 | return 0; | 603 | return 0; |
467 | } | 604 | } |
@@ -475,6 +612,9 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
475 | struct die_args *args = (struct die_args *)data; | 612 | struct die_args *args = (struct die_args *)data; |
476 | int ret = NOTIFY_DONE; | 613 | int ret = NOTIFY_DONE; |
477 | 614 | ||
615 | if (args->regs && user_mode(args->regs)) | ||
616 | return ret; | ||
617 | |||
478 | switch (val) { | 618 | switch (val) { |
479 | case DIE_INT3: | 619 | case DIE_INT3: |
480 | if (kprobe_handler(args->regs)) | 620 | if (kprobe_handler(args->regs)) |
@@ -564,12 +704,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | |||
564 | return 0; | 704 | return 0; |
565 | } | 705 | } |
566 | 706 | ||
567 | static struct kprobe trampoline_p = { | ||
568 | .addr = (kprobe_opcode_t *) &kretprobe_trampoline, | ||
569 | .pre_handler = trampoline_probe_handler | ||
570 | }; | ||
571 | |||
572 | int __init arch_init_kprobes(void) | 707 | int __init arch_init_kprobes(void) |
573 | { | 708 | { |
574 | return register_kprobe(&trampoline_p); | 709 | return 0; |
575 | } | 710 | } |
diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c index 5390b521aca0..e7c138f66c5a 100644 --- a/arch/i386/kernel/microcode.c +++ b/arch/i386/kernel/microcode.c | |||
@@ -81,6 +81,7 @@ | |||
81 | #include <linux/miscdevice.h> | 81 | #include <linux/miscdevice.h> |
82 | #include <linux/spinlock.h> | 82 | #include <linux/spinlock.h> |
83 | #include <linux/mm.h> | 83 | #include <linux/mm.h> |
84 | #include <linux/mutex.h> | ||
84 | 85 | ||
85 | #include <asm/msr.h> | 86 | #include <asm/msr.h> |
86 | #include <asm/uaccess.h> | 87 | #include <asm/uaccess.h> |
@@ -114,7 +115,7 @@ MODULE_LICENSE("GPL"); | |||
114 | static DEFINE_SPINLOCK(microcode_update_lock); | 115 | static DEFINE_SPINLOCK(microcode_update_lock); |
115 | 116 | ||
116 | /* no concurrent ->write()s are allowed on /dev/cpu/microcode */ | 117 | /* no concurrent ->write()s are allowed on /dev/cpu/microcode */ |
117 | static DECLARE_MUTEX(microcode_sem); | 118 | static DEFINE_MUTEX(microcode_mutex); |
118 | 119 | ||
119 | static void __user *user_buffer; /* user area microcode data buffer */ | 120 | static void __user *user_buffer; /* user area microcode data buffer */ |
120 | static unsigned int user_buffer_size; /* it's size */ | 121 | static unsigned int user_buffer_size; /* it's size */ |
@@ -202,8 +203,6 @@ static inline void mark_microcode_update (int cpu_num, microcode_header_t *mc_he | |||
202 | } else if (mc_header->rev == uci->rev) { | 203 | } else if (mc_header->rev == uci->rev) { |
203 | /* notify the caller of success on this cpu */ | 204 | /* notify the caller of success on this cpu */ |
204 | uci->err = MC_SUCCESS; | 205 | uci->err = MC_SUCCESS; |
205 | printk(KERN_ERR "microcode: CPU%d already at revision" | ||
206 | " 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); | ||
207 | goto out; | 206 | goto out; |
208 | } | 207 | } |
209 | 208 | ||
@@ -369,7 +368,6 @@ static void do_update_one (void * unused) | |||
369 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; | 368 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; |
370 | 369 | ||
371 | if (uci->mc == NULL) { | 370 | if (uci->mc == NULL) { |
372 | printk(KERN_INFO "microcode: No new microcode data for CPU%d\n", cpu_num); | ||
373 | return; | 371 | return; |
374 | } | 372 | } |
375 | 373 | ||
@@ -447,7 +445,7 @@ static ssize_t microcode_write (struct file *file, const char __user *buf, size_ | |||
447 | return -EINVAL; | 445 | return -EINVAL; |
448 | } | 446 | } |
449 | 447 | ||
450 | down(µcode_sem); | 448 | mutex_lock(µcode_mutex); |
451 | 449 | ||
452 | user_buffer = (void __user *) buf; | 450 | user_buffer = (void __user *) buf; |
453 | user_buffer_size = (int) len; | 451 | user_buffer_size = (int) len; |
@@ -456,31 +454,14 @@ static ssize_t microcode_write (struct file *file, const char __user *buf, size_ | |||
456 | if (!ret) | 454 | if (!ret) |
457 | ret = (ssize_t)len; | 455 | ret = (ssize_t)len; |
458 | 456 | ||
459 | up(µcode_sem); | 457 | mutex_unlock(µcode_mutex); |
460 | 458 | ||
461 | return ret; | 459 | return ret; |
462 | } | 460 | } |
463 | 461 | ||
464 | static int microcode_ioctl (struct inode *inode, struct file *file, | ||
465 | unsigned int cmd, unsigned long arg) | ||
466 | { | ||
467 | switch (cmd) { | ||
468 | /* | ||
469 | * XXX: will be removed after microcode_ctl | ||
470 | * is updated to ignore failure of this ioctl() | ||
471 | */ | ||
472 | case MICROCODE_IOCFREE: | ||
473 | return 0; | ||
474 | default: | ||
475 | return -EINVAL; | ||
476 | } | ||
477 | return -EINVAL; | ||
478 | } | ||
479 | |||
480 | static struct file_operations microcode_fops = { | 462 | static struct file_operations microcode_fops = { |
481 | .owner = THIS_MODULE, | 463 | .owner = THIS_MODULE, |
482 | .write = microcode_write, | 464 | .write = microcode_write, |
483 | .ioctl = microcode_ioctl, | ||
484 | .open = microcode_open, | 465 | .open = microcode_open, |
485 | }; | 466 | }; |
486 | 467 | ||
@@ -511,7 +492,6 @@ static int __init microcode_init (void) | |||
511 | static void __exit microcode_exit (void) | 492 | static void __exit microcode_exit (void) |
512 | { | 493 | { |
513 | misc_deregister(µcode_dev); | 494 | misc_deregister(µcode_dev); |
514 | printk(KERN_INFO "IA-32 Microcode Update Driver v" MICROCODE_VERSION " unregistered\n"); | ||
515 | } | 495 | } |
516 | 496 | ||
517 | module_init(microcode_init) | 497 | module_init(microcode_init) |
diff --git a/arch/i386/kernel/module.c b/arch/i386/kernel/module.c index 5149c8a621f0..470cf97e7cd3 100644 --- a/arch/i386/kernel/module.c +++ b/arch/i386/kernel/module.c | |||
@@ -104,26 +104,38 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
104 | return -ENOEXEC; | 104 | return -ENOEXEC; |
105 | } | 105 | } |
106 | 106 | ||
107 | extern void apply_alternatives(void *start, void *end); | ||
108 | |||
109 | int module_finalize(const Elf_Ehdr *hdr, | 107 | int module_finalize(const Elf_Ehdr *hdr, |
110 | const Elf_Shdr *sechdrs, | 108 | const Elf_Shdr *sechdrs, |
111 | struct module *me) | 109 | struct module *me) |
112 | { | 110 | { |
113 | const Elf_Shdr *s; | 111 | const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL; |
114 | char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | 112 | char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; |
115 | 113 | ||
116 | /* look for .altinstructions to patch */ | ||
117 | for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { | 114 | for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { |
118 | void *seg; | 115 | if (!strcmp(".text", secstrings + s->sh_name)) |
119 | if (strcmp(".altinstructions", secstrings + s->sh_name)) | 116 | text = s; |
120 | continue; | 117 | if (!strcmp(".altinstructions", secstrings + s->sh_name)) |
121 | seg = (void *)s->sh_addr; | 118 | alt = s; |
122 | apply_alternatives(seg, seg + s->sh_size); | 119 | if (!strcmp(".smp_locks", secstrings + s->sh_name)) |
123 | } | 120 | locks= s; |
121 | } | ||
122 | |||
123 | if (alt) { | ||
124 | /* patch .altinstructions */ | ||
125 | void *aseg = (void *)alt->sh_addr; | ||
126 | apply_alternatives(aseg, aseg + alt->sh_size); | ||
127 | } | ||
128 | if (locks && text) { | ||
129 | void *lseg = (void *)locks->sh_addr; | ||
130 | void *tseg = (void *)text->sh_addr; | ||
131 | alternatives_smp_module_add(me, me->name, | ||
132 | lseg, lseg + locks->sh_size, | ||
133 | tseg, tseg + text->sh_size); | ||
134 | } | ||
124 | return 0; | 135 | return 0; |
125 | } | 136 | } |
126 | 137 | ||
127 | void module_arch_cleanup(struct module *mod) | 138 | void module_arch_cleanup(struct module *mod) |
128 | { | 139 | { |
140 | alternatives_smp_module_del(mod); | ||
129 | } | 141 | } |
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index e6e2f43db85e..8d8aa9d1796d 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c | |||
@@ -828,6 +828,8 @@ void __init find_smp_config (void) | |||
828 | smp_scan_config(address, 0x400); | 828 | smp_scan_config(address, 0x400); |
829 | } | 829 | } |
830 | 830 | ||
831 | int es7000_plat; | ||
832 | |||
831 | /* -------------------------------------------------------------------------- | 833 | /* -------------------------------------------------------------------------- |
832 | ACPI-based MP Configuration | 834 | ACPI-based MP Configuration |
833 | -------------------------------------------------------------------------- */ | 835 | -------------------------------------------------------------------------- */ |
@@ -935,7 +937,8 @@ void __init mp_register_ioapic ( | |||
935 | mp_ioapics[idx].mpc_apicaddr = address; | 937 | mp_ioapics[idx].mpc_apicaddr = address; |
936 | 938 | ||
937 | set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); | 939 | set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); |
938 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 < 15)) | 940 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) |
941 | && !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) | ||
939 | tmpid = io_apic_get_unique_id(idx, id); | 942 | tmpid = io_apic_get_unique_id(idx, id); |
940 | else | 943 | else |
941 | tmpid = id; | 944 | tmpid = id; |
@@ -1011,8 +1014,6 @@ void __init mp_override_legacy_irq ( | |||
1011 | return; | 1014 | return; |
1012 | } | 1015 | } |
1013 | 1016 | ||
1014 | int es7000_plat; | ||
1015 | |||
1016 | void __init mp_config_acpi_legacy_irqs (void) | 1017 | void __init mp_config_acpi_legacy_irqs (void) |
1017 | { | 1018 | { |
1018 | struct mpc_config_intsrc intsrc; | 1019 | struct mpc_config_intsrc intsrc; |
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index be87c5e2ee95..d43b498ec745 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c | |||
@@ -138,12 +138,12 @@ static int __init check_nmi_watchdog(void) | |||
138 | if (nmi_watchdog == NMI_LOCAL_APIC) | 138 | if (nmi_watchdog == NMI_LOCAL_APIC) |
139 | smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0); | 139 | smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0); |
140 | 140 | ||
141 | for_each_cpu(cpu) | 141 | for_each_possible_cpu(cpu) |
142 | prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count; | 142 | prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count; |
143 | local_irq_enable(); | 143 | local_irq_enable(); |
144 | mdelay((10*1000)/nmi_hz); // wait 10 ticks | 144 | mdelay((10*1000)/nmi_hz); // wait 10 ticks |
145 | 145 | ||
146 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | 146 | for_each_possible_cpu(cpu) { |
147 | #ifdef CONFIG_SMP | 147 | #ifdef CONFIG_SMP |
148 | /* Check cpu_callin_map here because that is set | 148 | /* Check cpu_callin_map here because that is set |
149 | after the timer is started. */ | 149 | after the timer is started. */ |
@@ -510,7 +510,7 @@ void touch_nmi_watchdog (void) | |||
510 | * Just reset the alert counters, (other CPUs might be | 510 | * Just reset the alert counters, (other CPUs might be |
511 | * spinning on locks we hold): | 511 | * spinning on locks we hold): |
512 | */ | 512 | */ |
513 | for (i = 0; i < NR_CPUS; i++) | 513 | for_each_possible_cpu(i) |
514 | alert_counter[i] = 0; | 514 | alert_counter[i] = 0; |
515 | 515 | ||
516 | /* | 516 | /* |
@@ -529,7 +529,8 @@ void nmi_watchdog_tick (struct pt_regs * regs) | |||
529 | * always switch the stack NMI-atomically, it's safe to use | 529 | * always switch the stack NMI-atomically, it's safe to use |
530 | * smp_processor_id(). | 530 | * smp_processor_id(). |
531 | */ | 531 | */ |
532 | int sum, cpu = smp_processor_id(); | 532 | unsigned int sum; |
533 | int cpu = smp_processor_id(); | ||
533 | 534 | ||
534 | sum = per_cpu(irq_stat, cpu).apic_timer_irqs; | 535 | sum = per_cpu(irq_stat, cpu).apic_timer_irqs; |
535 | 536 | ||
@@ -543,7 +544,7 @@ void nmi_watchdog_tick (struct pt_regs * regs) | |||
543 | /* | 544 | /* |
544 | * die_nmi will return ONLY if NOTIFY_STOP happens.. | 545 | * die_nmi will return ONLY if NOTIFY_STOP happens.. |
545 | */ | 546 | */ |
546 | die_nmi(regs, "NMI Watchdog detected LOCKUP"); | 547 | die_nmi(regs, "BUG: NMI Watchdog detected LOCKUP"); |
547 | } else { | 548 | } else { |
548 | last_irq_sums[cpu] = sum; | 549 | last_irq_sums[cpu] = sum; |
549 | alert_counter[cpu] = 0; | 550 | alert_counter[cpu] = 0; |
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 0480454ebffa..6259afea46d1 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #include <linux/kallsyms.h> | 38 | #include <linux/kallsyms.h> |
39 | #include <linux/ptrace.h> | 39 | #include <linux/ptrace.h> |
40 | #include <linux/random.h> | 40 | #include <linux/random.h> |
41 | #include <linux/kprobes.h> | ||
42 | 41 | ||
43 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
44 | #include <asm/pgtable.h> | 43 | #include <asm/pgtable.h> |
@@ -295,7 +294,7 @@ void show_regs(struct pt_regs * regs) | |||
295 | printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id()); | 294 | printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id()); |
296 | print_symbol("EIP is at %s\n", regs->eip); | 295 | print_symbol("EIP is at %s\n", regs->eip); |
297 | 296 | ||
298 | if (user_mode(regs)) | 297 | if (user_mode_vm(regs)) |
299 | printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); | 298 | printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); |
300 | printk(" EFLAGS: %08lx %s (%s %.*s)\n", | 299 | printk(" EFLAGS: %08lx %s (%s %.*s)\n", |
301 | regs->eflags, print_tainted(), system_utsname.release, | 300 | regs->eflags, print_tainted(), system_utsname.release, |
@@ -364,13 +363,6 @@ void exit_thread(void) | |||
364 | struct task_struct *tsk = current; | 363 | struct task_struct *tsk = current; |
365 | struct thread_struct *t = &tsk->thread; | 364 | struct thread_struct *t = &tsk->thread; |
366 | 365 | ||
367 | /* | ||
368 | * Remove function-return probe instances associated with this task | ||
369 | * and put them back on the free list. Do not insert an exit probe for | ||
370 | * this function, it will be disabled by kprobe_flush_task if you do. | ||
371 | */ | ||
372 | kprobe_flush_task(tsk); | ||
373 | |||
374 | /* The process may have allocated an io port bitmap... nuke it. */ | 366 | /* The process may have allocated an io port bitmap... nuke it. */ |
375 | if (unlikely(NULL != t->io_bitmap_ptr)) { | 367 | if (unlikely(NULL != t->io_bitmap_ptr)) { |
376 | int cpu = get_cpu(); | 368 | int cpu = get_cpu(); |
@@ -789,7 +781,6 @@ unsigned long get_wchan(struct task_struct *p) | |||
789 | } while (count++ < 16); | 781 | } while (count++ < 16); |
790 | return 0; | 782 | return 0; |
791 | } | 783 | } |
792 | EXPORT_SYMBOL(get_wchan); | ||
793 | 784 | ||
794 | /* | 785 | /* |
795 | * sys_alloc_thread_area: get a yet unused TLS descriptor index. | 786 | * sys_alloc_thread_area: get a yet unused TLS descriptor index. |
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index 5c1fb6aada5b..506462ef36a0 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c | |||
@@ -34,10 +34,10 @@ | |||
34 | 34 | ||
35 | /* | 35 | /* |
36 | * Determines which flags the user has access to [1 = access, 0 = no access]. | 36 | * Determines which flags the user has access to [1 = access, 0 = no access]. |
37 | * Prohibits changing ID(21), VIP(20), VIF(19), VM(17), IOPL(12-13), IF(9). | 37 | * Prohibits changing ID(21), VIP(20), VIF(19), VM(17), NT(14), IOPL(12-13), IF(9). |
38 | * Also masks reserved bits (31-22, 15, 5, 3, 1). | 38 | * Also masks reserved bits (31-22, 15, 5, 3, 1). |
39 | */ | 39 | */ |
40 | #define FLAG_MASK 0x00054dd5 | 40 | #define FLAG_MASK 0x00050dd5 |
41 | 41 | ||
42 | /* set's the trap flag. */ | 42 | /* set's the trap flag. */ |
43 | #define TRAP_FLAG 0x100 | 43 | #define TRAP_FLAG 0x100 |
diff --git a/arch/i386/kernel/semaphore.c b/arch/i386/kernel/semaphore.c index 7455ab643943..967dc74df9ee 100644 --- a/arch/i386/kernel/semaphore.c +++ b/arch/i386/kernel/semaphore.c | |||
@@ -110,11 +110,11 @@ asm( | |||
110 | ".align 4\n" | 110 | ".align 4\n" |
111 | ".globl __write_lock_failed\n" | 111 | ".globl __write_lock_failed\n" |
112 | "__write_lock_failed:\n\t" | 112 | "__write_lock_failed:\n\t" |
113 | LOCK "addl $" RW_LOCK_BIAS_STR ",(%eax)\n" | 113 | LOCK_PREFIX "addl $" RW_LOCK_BIAS_STR ",(%eax)\n" |
114 | "1: rep; nop\n\t" | 114 | "1: rep; nop\n\t" |
115 | "cmpl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" | 115 | "cmpl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" |
116 | "jne 1b\n\t" | 116 | "jne 1b\n\t" |
117 | LOCK "subl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" | 117 | LOCK_PREFIX "subl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" |
118 | "jnz __write_lock_failed\n\t" | 118 | "jnz __write_lock_failed\n\t" |
119 | "ret" | 119 | "ret" |
120 | ); | 120 | ); |
@@ -124,11 +124,11 @@ asm( | |||
124 | ".align 4\n" | 124 | ".align 4\n" |
125 | ".globl __read_lock_failed\n" | 125 | ".globl __read_lock_failed\n" |
126 | "__read_lock_failed:\n\t" | 126 | "__read_lock_failed:\n\t" |
127 | LOCK "incl (%eax)\n" | 127 | LOCK_PREFIX "incl (%eax)\n" |
128 | "1: rep; nop\n\t" | 128 | "1: rep; nop\n\t" |
129 | "cmpl $1,(%eax)\n\t" | 129 | "cmpl $1,(%eax)\n\t" |
130 | "js 1b\n\t" | 130 | "js 1b\n\t" |
131 | LOCK "decl (%eax)\n\t" | 131 | LOCK_PREFIX "decl (%eax)\n\t" |
132 | "js __read_lock_failed\n\t" | 132 | "js __read_lock_failed\n\t" |
133 | "ret" | 133 | "ret" |
134 | ); | 134 | ); |
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index a0b407585679..eacc3f0a2ea4 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/kexec.h> | 47 | #include <linux/kexec.h> |
48 | #include <linux/crash_dump.h> | 48 | #include <linux/crash_dump.h> |
49 | #include <linux/dmi.h> | 49 | #include <linux/dmi.h> |
50 | #include <linux/pfn.h> | ||
50 | 51 | ||
51 | #include <video/edid.h> | 52 | #include <video/edid.h> |
52 | 53 | ||
@@ -1059,10 +1060,10 @@ static int __init | |||
1059 | free_available_memory(unsigned long start, unsigned long end, void *arg) | 1060 | free_available_memory(unsigned long start, unsigned long end, void *arg) |
1060 | { | 1061 | { |
1061 | /* check max_low_pfn */ | 1062 | /* check max_low_pfn */ |
1062 | if (start >= ((max_low_pfn + 1) << PAGE_SHIFT)) | 1063 | if (start >= (max_low_pfn << PAGE_SHIFT)) |
1063 | return 0; | 1064 | return 0; |
1064 | if (end >= ((max_low_pfn + 1) << PAGE_SHIFT)) | 1065 | if (end >= (max_low_pfn << PAGE_SHIFT)) |
1065 | end = (max_low_pfn + 1) << PAGE_SHIFT; | 1066 | end = max_low_pfn << PAGE_SHIFT; |
1066 | if (start < end) | 1067 | if (start < end) |
1067 | free_bootmem(start, end - start); | 1068 | free_bootmem(start, end - start); |
1068 | 1069 | ||
@@ -1287,9 +1288,7 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat | |||
1287 | probe_roms(); | 1288 | probe_roms(); |
1288 | for (i = 0; i < e820.nr_map; i++) { | 1289 | for (i = 0; i < e820.nr_map; i++) { |
1289 | struct resource *res; | 1290 | struct resource *res; |
1290 | if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL) | 1291 | res = kzalloc(sizeof(struct resource), GFP_ATOMIC); |
1291 | continue; | ||
1292 | res = alloc_bootmem_low(sizeof(struct resource)); | ||
1293 | switch (e820.map[i].type) { | 1292 | switch (e820.map[i].type) { |
1294 | case E820_RAM: res->name = "System RAM"; break; | 1293 | case E820_RAM: res->name = "System RAM"; break; |
1295 | case E820_ACPI: res->name = "ACPI Tables"; break; | 1294 | case E820_ACPI: res->name = "ACPI Tables"; break; |
@@ -1317,13 +1316,15 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat | |||
1317 | 1316 | ||
1318 | /* | 1317 | /* |
1319 | * Request address space for all standard resources | 1318 | * Request address space for all standard resources |
1319 | * | ||
1320 | * This is called just before pcibios_assign_resources(), which is also | ||
1321 | * an fs_initcall, but is linked in later (in arch/i386/pci/i386.c). | ||
1320 | */ | 1322 | */ |
1321 | static void __init register_memory(void) | 1323 | static int __init request_standard_resources(void) |
1322 | { | 1324 | { |
1323 | unsigned long gapstart, gapsize, round; | 1325 | int i; |
1324 | unsigned long long last; | ||
1325 | int i; | ||
1326 | 1326 | ||
1327 | printk("Setting up standard PCI resources\n"); | ||
1327 | if (efi_enabled) | 1328 | if (efi_enabled) |
1328 | efi_initialize_iomem_resources(&code_resource, &data_resource); | 1329 | efi_initialize_iomem_resources(&code_resource, &data_resource); |
1329 | else | 1330 | else |
@@ -1335,6 +1336,16 @@ static void __init register_memory(void) | |||
1335 | /* request I/O space for devices used on all i[345]86 PCs */ | 1336 | /* request I/O space for devices used on all i[345]86 PCs */ |
1336 | for (i = 0; i < STANDARD_IO_RESOURCES; i++) | 1337 | for (i = 0; i < STANDARD_IO_RESOURCES; i++) |
1337 | request_resource(&ioport_resource, &standard_io_resources[i]); | 1338 | request_resource(&ioport_resource, &standard_io_resources[i]); |
1339 | return 0; | ||
1340 | } | ||
1341 | |||
1342 | fs_initcall(request_standard_resources); | ||
1343 | |||
1344 | static void __init register_memory(void) | ||
1345 | { | ||
1346 | unsigned long gapstart, gapsize, round; | ||
1347 | unsigned long long last; | ||
1348 | int i; | ||
1338 | 1349 | ||
1339 | /* | 1350 | /* |
1340 | * Search for the bigest gap in the low 32 bits of the e820 | 1351 | * Search for the bigest gap in the low 32 bits of the e820 |
@@ -1378,101 +1389,6 @@ static void __init register_memory(void) | |||
1378 | pci_mem_start, gapstart, gapsize); | 1389 | pci_mem_start, gapstart, gapsize); |
1379 | } | 1390 | } |
1380 | 1391 | ||
1381 | /* Use inline assembly to define this because the nops are defined | ||
1382 | as inline assembly strings in the include files and we cannot | ||
1383 | get them easily into strings. */ | ||
1384 | asm("\t.data\nintelnops: " | ||
1385 | GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6 | ||
1386 | GENERIC_NOP7 GENERIC_NOP8); | ||
1387 | asm("\t.data\nk8nops: " | ||
1388 | K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 | ||
1389 | K8_NOP7 K8_NOP8); | ||
1390 | asm("\t.data\nk7nops: " | ||
1391 | K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6 | ||
1392 | K7_NOP7 K7_NOP8); | ||
1393 | |||
1394 | extern unsigned char intelnops[], k8nops[], k7nops[]; | ||
1395 | static unsigned char *intel_nops[ASM_NOP_MAX+1] = { | ||
1396 | NULL, | ||
1397 | intelnops, | ||
1398 | intelnops + 1, | ||
1399 | intelnops + 1 + 2, | ||
1400 | intelnops + 1 + 2 + 3, | ||
1401 | intelnops + 1 + 2 + 3 + 4, | ||
1402 | intelnops + 1 + 2 + 3 + 4 + 5, | ||
1403 | intelnops + 1 + 2 + 3 + 4 + 5 + 6, | ||
1404 | intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7, | ||
1405 | }; | ||
1406 | static unsigned char *k8_nops[ASM_NOP_MAX+1] = { | ||
1407 | NULL, | ||
1408 | k8nops, | ||
1409 | k8nops + 1, | ||
1410 | k8nops + 1 + 2, | ||
1411 | k8nops + 1 + 2 + 3, | ||
1412 | k8nops + 1 + 2 + 3 + 4, | ||
1413 | k8nops + 1 + 2 + 3 + 4 + 5, | ||
1414 | k8nops + 1 + 2 + 3 + 4 + 5 + 6, | ||
1415 | k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, | ||
1416 | }; | ||
1417 | static unsigned char *k7_nops[ASM_NOP_MAX+1] = { | ||
1418 | NULL, | ||
1419 | k7nops, | ||
1420 | k7nops + 1, | ||
1421 | k7nops + 1 + 2, | ||
1422 | k7nops + 1 + 2 + 3, | ||
1423 | k7nops + 1 + 2 + 3 + 4, | ||
1424 | k7nops + 1 + 2 + 3 + 4 + 5, | ||
1425 | k7nops + 1 + 2 + 3 + 4 + 5 + 6, | ||
1426 | k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, | ||
1427 | }; | ||
1428 | static struct nop { | ||
1429 | int cpuid; | ||
1430 | unsigned char **noptable; | ||
1431 | } noptypes[] = { | ||
1432 | { X86_FEATURE_K8, k8_nops }, | ||
1433 | { X86_FEATURE_K7, k7_nops }, | ||
1434 | { -1, NULL } | ||
1435 | }; | ||
1436 | |||
1437 | /* Replace instructions with better alternatives for this CPU type. | ||
1438 | |||
1439 | This runs before SMP is initialized to avoid SMP problems with | ||
1440 | self modifying code. This implies that assymetric systems where | ||
1441 | APs have less capabilities than the boot processor are not handled. | ||
1442 | Tough. Make sure you disable such features by hand. */ | ||
1443 | void apply_alternatives(void *start, void *end) | ||
1444 | { | ||
1445 | struct alt_instr *a; | ||
1446 | int diff, i, k; | ||
1447 | unsigned char **noptable = intel_nops; | ||
1448 | for (i = 0; noptypes[i].cpuid >= 0; i++) { | ||
1449 | if (boot_cpu_has(noptypes[i].cpuid)) { | ||
1450 | noptable = noptypes[i].noptable; | ||
1451 | break; | ||
1452 | } | ||
1453 | } | ||
1454 | for (a = start; (void *)a < end; a++) { | ||
1455 | if (!boot_cpu_has(a->cpuid)) | ||
1456 | continue; | ||
1457 | BUG_ON(a->replacementlen > a->instrlen); | ||
1458 | memcpy(a->instr, a->replacement, a->replacementlen); | ||
1459 | diff = a->instrlen - a->replacementlen; | ||
1460 | /* Pad the rest with nops */ | ||
1461 | for (i = a->replacementlen; diff > 0; diff -= k, i += k) { | ||
1462 | k = diff; | ||
1463 | if (k > ASM_NOP_MAX) | ||
1464 | k = ASM_NOP_MAX; | ||
1465 | memcpy(a->instr + i, noptable[k], k); | ||
1466 | } | ||
1467 | } | ||
1468 | } | ||
1469 | |||
1470 | void __init alternative_instructions(void) | ||
1471 | { | ||
1472 | extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; | ||
1473 | apply_alternatives(__alt_instructions, __alt_instructions_end); | ||
1474 | } | ||
1475 | |||
1476 | static char * __init machine_specific_memory_setup(void); | 1392 | static char * __init machine_specific_memory_setup(void); |
1477 | 1393 | ||
1478 | #ifdef CONFIG_MCA | 1394 | #ifdef CONFIG_MCA |
@@ -1555,6 +1471,16 @@ void __init setup_arch(char **cmdline_p) | |||
1555 | 1471 | ||
1556 | parse_cmdline_early(cmdline_p); | 1472 | parse_cmdline_early(cmdline_p); |
1557 | 1473 | ||
1474 | #ifdef CONFIG_EARLY_PRINTK | ||
1475 | { | ||
1476 | char *s = strstr(*cmdline_p, "earlyprintk="); | ||
1477 | if (s) { | ||
1478 | setup_early_printk(strchr(s, '=') + 1); | ||
1479 | printk("early console enabled\n"); | ||
1480 | } | ||
1481 | } | ||
1482 | #endif | ||
1483 | |||
1558 | max_low_pfn = setup_memory(); | 1484 | max_low_pfn = setup_memory(); |
1559 | 1485 | ||
1560 | /* | 1486 | /* |
@@ -1579,19 +1505,6 @@ void __init setup_arch(char **cmdline_p) | |||
1579 | * NOTE: at this point the bootmem allocator is fully available. | 1505 | * NOTE: at this point the bootmem allocator is fully available. |
1580 | */ | 1506 | */ |
1581 | 1507 | ||
1582 | #ifdef CONFIG_EARLY_PRINTK | ||
1583 | { | ||
1584 | char *s = strstr(*cmdline_p, "earlyprintk="); | ||
1585 | if (s) { | ||
1586 | extern void setup_early_printk(char *); | ||
1587 | |||
1588 | setup_early_printk(strchr(s, '=') + 1); | ||
1589 | printk("early console enabled\n"); | ||
1590 | } | ||
1591 | } | ||
1592 | #endif | ||
1593 | |||
1594 | |||
1595 | dmi_scan_machine(); | 1508 | dmi_scan_machine(); |
1596 | 1509 | ||
1597 | #ifdef CONFIG_X86_GENERICARCH | 1510 | #ifdef CONFIG_X86_GENERICARCH |
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c index 963616d364ec..5c352c3a9e7f 100644 --- a/arch/i386/kernel/signal.c +++ b/arch/i386/kernel/signal.c | |||
@@ -123,7 +123,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *peax | |||
123 | err |= __get_user(tmp, &sc->seg); \ | 123 | err |= __get_user(tmp, &sc->seg); \ |
124 | loadsegment(seg,tmp); } | 124 | loadsegment(seg,tmp); } |
125 | 125 | ||
126 | #define FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_OF | X86_EFLAGS_DF | \ | 126 | #define FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_RF | \ |
127 | X86_EFLAGS_OF | X86_EFLAGS_DF | \ | ||
127 | X86_EFLAGS_TF | X86_EFLAGS_SF | X86_EFLAGS_ZF | \ | 128 | X86_EFLAGS_TF | X86_EFLAGS_SF | X86_EFLAGS_ZF | \ |
128 | X86_EFLAGS_AF | X86_EFLAGS_PF | X86_EFLAGS_CF) | 129 | X86_EFLAGS_AF | X86_EFLAGS_PF | X86_EFLAGS_CF) |
129 | 130 | ||
@@ -582,9 +583,6 @@ static void fastcall do_signal(struct pt_regs *regs) | |||
582 | if (!user_mode(regs)) | 583 | if (!user_mode(regs)) |
583 | return; | 584 | return; |
584 | 585 | ||
585 | if (try_to_freeze()) | ||
586 | goto no_signal; | ||
587 | |||
588 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 586 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
589 | oldset = ¤t->saved_sigmask; | 587 | oldset = ¤t->saved_sigmask; |
590 | else | 588 | else |
@@ -613,7 +611,6 @@ static void fastcall do_signal(struct pt_regs *regs) | |||
613 | return; | 611 | return; |
614 | } | 612 | } |
615 | 613 | ||
616 | no_signal: | ||
617 | /* Did we come from a system call? */ | 614 | /* Did we come from a system call? */ |
618 | if (regs->orig_eax >= 0) { | 615 | if (regs->orig_eax >= 0) { |
619 | /* Restart the system call - no handlers present */ | 616 | /* Restart the system call - no handlers present */ |
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 218d725a5a1e..d134e9643a58 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c | |||
@@ -504,27 +504,23 @@ void unlock_ipi_call_lock(void) | |||
504 | spin_unlock_irq(&call_lock); | 504 | spin_unlock_irq(&call_lock); |
505 | } | 505 | } |
506 | 506 | ||
507 | static struct call_data_struct * call_data; | 507 | static struct call_data_struct *call_data; |
508 | 508 | ||
509 | /* | 509 | /** |
510 | * this function sends a 'generic call function' IPI to all other CPUs | 510 | * smp_call_function(): Run a function on all other CPUs. |
511 | * in the system. | 511 | * @func: The function to run. This must be fast and non-blocking. |
512 | */ | 512 | * @info: An arbitrary pointer to pass to the function. |
513 | 513 | * @nonatomic: currently unused. | |
514 | int smp_call_function (void (*func) (void *info), void *info, int nonatomic, | 514 | * @wait: If true, wait (atomically) until function has completed on other CPUs. |
515 | int wait) | 515 | * |
516 | /* | 516 | * Returns 0 on success, else a negative status code. Does not return until |
517 | * [SUMMARY] Run a function on all other CPUs. | ||
518 | * <func> The function to run. This must be fast and non-blocking. | ||
519 | * <info> An arbitrary pointer to pass to the function. | ||
520 | * <nonatomic> currently unused. | ||
521 | * <wait> If true, wait (atomically) until function has completed on other CPUs. | ||
522 | * [RETURNS] 0 on success, else a negative status code. Does not return until | ||
523 | * remote CPUs are nearly ready to execute <<func>> or are or have executed. | 517 | * remote CPUs are nearly ready to execute <<func>> or are or have executed. |
524 | * | 518 | * |
525 | * You must not call this function with disabled interrupts or from a | 519 | * You must not call this function with disabled interrupts or from a |
526 | * hardware interrupt handler or from a bottom half handler. | 520 | * hardware interrupt handler or from a bottom half handler. |
527 | */ | 521 | */ |
522 | int smp_call_function (void (*func) (void *info), void *info, int nonatomic, | ||
523 | int wait) | ||
528 | { | 524 | { |
529 | struct call_data_struct data; | 525 | struct call_data_struct data; |
530 | int cpus; | 526 | int cpus; |
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index eba7f53f8b4a..a6969903f2d6 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
@@ -72,6 +72,9 @@ int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; | |||
72 | /* Core ID of each logical CPU */ | 72 | /* Core ID of each logical CPU */ |
73 | int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; | 73 | int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; |
74 | 74 | ||
75 | /* Last level cache ID of each logical CPU */ | ||
76 | int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID}; | ||
77 | |||
75 | /* representing HT siblings of each logical CPU */ | 78 | /* representing HT siblings of each logical CPU */ |
76 | cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; | 79 | cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; |
77 | EXPORT_SYMBOL(cpu_sibling_map); | 80 | EXPORT_SYMBOL(cpu_sibling_map); |
@@ -440,6 +443,18 @@ static void __devinit smp_callin(void) | |||
440 | 443 | ||
441 | static int cpucount; | 444 | static int cpucount; |
442 | 445 | ||
446 | /* maps the cpu to the sched domain representing multi-core */ | ||
447 | cpumask_t cpu_coregroup_map(int cpu) | ||
448 | { | ||
449 | struct cpuinfo_x86 *c = cpu_data + cpu; | ||
450 | /* | ||
451 | * For perf, we return last level cache shared map. | ||
452 | * TBD: when power saving sched policy is added, we will return | ||
453 | * cpu_core_map when power saving policy is enabled | ||
454 | */ | ||
455 | return c->llc_shared_map; | ||
456 | } | ||
457 | |||
443 | /* representing cpus for which sibling maps can be computed */ | 458 | /* representing cpus for which sibling maps can be computed */ |
444 | static cpumask_t cpu_sibling_setup_map; | 459 | static cpumask_t cpu_sibling_setup_map; |
445 | 460 | ||
@@ -459,12 +474,16 @@ set_cpu_sibling_map(int cpu) | |||
459 | cpu_set(cpu, cpu_sibling_map[i]); | 474 | cpu_set(cpu, cpu_sibling_map[i]); |
460 | cpu_set(i, cpu_core_map[cpu]); | 475 | cpu_set(i, cpu_core_map[cpu]); |
461 | cpu_set(cpu, cpu_core_map[i]); | 476 | cpu_set(cpu, cpu_core_map[i]); |
477 | cpu_set(i, c[cpu].llc_shared_map); | ||
478 | cpu_set(cpu, c[i].llc_shared_map); | ||
462 | } | 479 | } |
463 | } | 480 | } |
464 | } else { | 481 | } else { |
465 | cpu_set(cpu, cpu_sibling_map[cpu]); | 482 | cpu_set(cpu, cpu_sibling_map[cpu]); |
466 | } | 483 | } |
467 | 484 | ||
485 | cpu_set(cpu, c[cpu].llc_shared_map); | ||
486 | |||
468 | if (current_cpu_data.x86_max_cores == 1) { | 487 | if (current_cpu_data.x86_max_cores == 1) { |
469 | cpu_core_map[cpu] = cpu_sibling_map[cpu]; | 488 | cpu_core_map[cpu] = cpu_sibling_map[cpu]; |
470 | c[cpu].booted_cores = 1; | 489 | c[cpu].booted_cores = 1; |
@@ -472,6 +491,11 @@ set_cpu_sibling_map(int cpu) | |||
472 | } | 491 | } |
473 | 492 | ||
474 | for_each_cpu_mask(i, cpu_sibling_setup_map) { | 493 | for_each_cpu_mask(i, cpu_sibling_setup_map) { |
494 | if (cpu_llc_id[cpu] != BAD_APICID && | ||
495 | cpu_llc_id[cpu] == cpu_llc_id[i]) { | ||
496 | cpu_set(i, c[cpu].llc_shared_map); | ||
497 | cpu_set(cpu, c[i].llc_shared_map); | ||
498 | } | ||
475 | if (phys_proc_id[cpu] == phys_proc_id[i]) { | 499 | if (phys_proc_id[cpu] == phys_proc_id[i]) { |
476 | cpu_set(i, cpu_core_map[cpu]); | 500 | cpu_set(i, cpu_core_map[cpu]); |
477 | cpu_set(cpu, cpu_core_map[i]); | 501 | cpu_set(cpu, cpu_core_map[i]); |
@@ -899,6 +923,7 @@ static int __devinit do_boot_cpu(int apicid, int cpu) | |||
899 | unsigned short nmi_high = 0, nmi_low = 0; | 923 | unsigned short nmi_high = 0, nmi_low = 0; |
900 | 924 | ||
901 | ++cpucount; | 925 | ++cpucount; |
926 | alternatives_smp_switch(1); | ||
902 | 927 | ||
903 | /* | 928 | /* |
904 | * We can't use kernel_thread since we must avoid to | 929 | * We can't use kernel_thread since we must avoid to |
@@ -1002,7 +1027,6 @@ void cpu_exit_clear(void) | |||
1002 | 1027 | ||
1003 | cpu_clear(cpu, cpu_callout_map); | 1028 | cpu_clear(cpu, cpu_callout_map); |
1004 | cpu_clear(cpu, cpu_callin_map); | 1029 | cpu_clear(cpu, cpu_callin_map); |
1005 | cpu_clear(cpu, cpu_present_map); | ||
1006 | 1030 | ||
1007 | cpu_clear(cpu, smp_commenced_mask); | 1031 | cpu_clear(cpu, smp_commenced_mask); |
1008 | unmap_cpu_to_logical_apicid(cpu); | 1032 | unmap_cpu_to_logical_apicid(cpu); |
@@ -1014,21 +1038,20 @@ struct warm_boot_cpu_info { | |||
1014 | int cpu; | 1038 | int cpu; |
1015 | }; | 1039 | }; |
1016 | 1040 | ||
1017 | static void __devinit do_warm_boot_cpu(void *p) | 1041 | static void __cpuinit do_warm_boot_cpu(void *p) |
1018 | { | 1042 | { |
1019 | struct warm_boot_cpu_info *info = p; | 1043 | struct warm_boot_cpu_info *info = p; |
1020 | do_boot_cpu(info->apicid, info->cpu); | 1044 | do_boot_cpu(info->apicid, info->cpu); |
1021 | complete(info->complete); | 1045 | complete(info->complete); |
1022 | } | 1046 | } |
1023 | 1047 | ||
1024 | int __devinit smp_prepare_cpu(int cpu) | 1048 | static int __cpuinit __smp_prepare_cpu(int cpu) |
1025 | { | 1049 | { |
1026 | DECLARE_COMPLETION(done); | 1050 | DECLARE_COMPLETION(done); |
1027 | struct warm_boot_cpu_info info; | 1051 | struct warm_boot_cpu_info info; |
1028 | struct work_struct task; | 1052 | struct work_struct task; |
1029 | int apicid, ret; | 1053 | int apicid, ret; |
1030 | 1054 | ||
1031 | lock_cpu_hotplug(); | ||
1032 | apicid = x86_cpu_to_apicid[cpu]; | 1055 | apicid = x86_cpu_to_apicid[cpu]; |
1033 | if (apicid == BAD_APICID) { | 1056 | if (apicid == BAD_APICID) { |
1034 | ret = -ENODEV; | 1057 | ret = -ENODEV; |
@@ -1053,7 +1076,6 @@ int __devinit smp_prepare_cpu(int cpu) | |||
1053 | zap_low_mappings(); | 1076 | zap_low_mappings(); |
1054 | ret = 0; | 1077 | ret = 0; |
1055 | exit: | 1078 | exit: |
1056 | unlock_cpu_hotplug(); | ||
1057 | return ret; | 1079 | return ret; |
1058 | } | 1080 | } |
1059 | #endif | 1081 | #endif |
@@ -1358,6 +1380,8 @@ void __cpu_die(unsigned int cpu) | |||
1358 | /* They ack this in play_dead by setting CPU_DEAD */ | 1380 | /* They ack this in play_dead by setting CPU_DEAD */ |
1359 | if (per_cpu(cpu_state, cpu) == CPU_DEAD) { | 1381 | if (per_cpu(cpu_state, cpu) == CPU_DEAD) { |
1360 | printk ("CPU %d is now offline\n", cpu); | 1382 | printk ("CPU %d is now offline\n", cpu); |
1383 | if (1 == num_online_cpus()) | ||
1384 | alternatives_smp_switch(0); | ||
1361 | return; | 1385 | return; |
1362 | } | 1386 | } |
1363 | msleep(100); | 1387 | msleep(100); |
@@ -1379,6 +1403,22 @@ void __cpu_die(unsigned int cpu) | |||
1379 | 1403 | ||
1380 | int __devinit __cpu_up(unsigned int cpu) | 1404 | int __devinit __cpu_up(unsigned int cpu) |
1381 | { | 1405 | { |
1406 | #ifdef CONFIG_HOTPLUG_CPU | ||
1407 | int ret=0; | ||
1408 | |||
1409 | /* | ||
1410 | * We do warm boot only on cpus that had booted earlier | ||
1411 | * Otherwise cold boot is all handled from smp_boot_cpus(). | ||
1412 | * cpu_callin_map is set during AP kickstart process. Its reset | ||
1413 | * when a cpu is taken offline from cpu_exit_clear(). | ||
1414 | */ | ||
1415 | if (!cpu_isset(cpu, cpu_callin_map)) | ||
1416 | ret = __smp_prepare_cpu(cpu); | ||
1417 | |||
1418 | if (ret) | ||
1419 | return -EIO; | ||
1420 | #endif | ||
1421 | |||
1382 | /* In case one didn't come up */ | 1422 | /* In case one didn't come up */ |
1383 | if (!cpu_isset(cpu, cpu_callin_map)) { | 1423 | if (!cpu_isset(cpu, cpu_callin_map)) { |
1384 | printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu); | 1424 | printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu); |
diff --git a/arch/i386/kernel/sys_i386.c b/arch/i386/kernel/sys_i386.c index a4a61976ecb9..8fdb1fb17a5f 100644 --- a/arch/i386/kernel/sys_i386.c +++ b/arch/i386/kernel/sys_i386.c | |||
@@ -40,14 +40,13 @@ asmlinkage int sys_pipe(unsigned long __user * fildes) | |||
40 | return error; | 40 | return error; |
41 | } | 41 | } |
42 | 42 | ||
43 | /* common code for old and new mmaps */ | 43 | asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, |
44 | static inline long do_mmap2( | 44 | unsigned long prot, unsigned long flags, |
45 | unsigned long addr, unsigned long len, | 45 | unsigned long fd, unsigned long pgoff) |
46 | unsigned long prot, unsigned long flags, | ||
47 | unsigned long fd, unsigned long pgoff) | ||
48 | { | 46 | { |
49 | int error = -EBADF; | 47 | int error = -EBADF; |
50 | struct file * file = NULL; | 48 | struct file *file = NULL; |
49 | struct mm_struct *mm = current->mm; | ||
51 | 50 | ||
52 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | 51 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); |
53 | if (!(flags & MAP_ANONYMOUS)) { | 52 | if (!(flags & MAP_ANONYMOUS)) { |
@@ -56,9 +55,9 @@ static inline long do_mmap2( | |||
56 | goto out; | 55 | goto out; |
57 | } | 56 | } |
58 | 57 | ||
59 | down_write(¤t->mm->mmap_sem); | 58 | down_write(&mm->mmap_sem); |
60 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | 59 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); |
61 | up_write(¤t->mm->mmap_sem); | 60 | up_write(&mm->mmap_sem); |
62 | 61 | ||
63 | if (file) | 62 | if (file) |
64 | fput(file); | 63 | fput(file); |
@@ -66,13 +65,6 @@ out: | |||
66 | return error; | 65 | return error; |
67 | } | 66 | } |
68 | 67 | ||
69 | asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, | ||
70 | unsigned long prot, unsigned long flags, | ||
71 | unsigned long fd, unsigned long pgoff) | ||
72 | { | ||
73 | return do_mmap2(addr, len, prot, flags, fd, pgoff); | ||
74 | } | ||
75 | |||
76 | /* | 68 | /* |
77 | * Perform the select(nd, in, out, ex, tv) and mmap() system | 69 | * Perform the select(nd, in, out, ex, tv) and mmap() system |
78 | * calls. Linux/i386 didn't use to be able to handle more than | 70 | * calls. Linux/i386 didn't use to be able to handle more than |
@@ -101,7 +93,8 @@ asmlinkage int old_mmap(struct mmap_arg_struct __user *arg) | |||
101 | if (a.offset & ~PAGE_MASK) | 93 | if (a.offset & ~PAGE_MASK) |
102 | goto out; | 94 | goto out; |
103 | 95 | ||
104 | err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); | 96 | err = sys_mmap2(a.addr, a.len, a.prot, a.flags, |
97 | a.fd, a.offset >> PAGE_SHIFT); | ||
105 | out: | 98 | out: |
106 | return err; | 99 | return err; |
107 | } | 100 | } |
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S index ac687d00a1ce..4f58b9c0efe3 100644 --- a/arch/i386/kernel/syscall_table.S +++ b/arch/i386/kernel/syscall_table.S | |||
@@ -310,3 +310,7 @@ ENTRY(sys_call_table) | |||
310 | .long sys_pselect6 | 310 | .long sys_pselect6 |
311 | .long sys_ppoll | 311 | .long sys_ppoll |
312 | .long sys_unshare /* 310 */ | 312 | .long sys_unshare /* 310 */ |
313 | .long sys_set_robust_list | ||
314 | .long sys_get_robust_list | ||
315 | .long sys_splice | ||
316 | .long sys_sync_file_range | ||
diff --git a/arch/i386/kernel/timers/timer_hpet.c b/arch/i386/kernel/timers/timer_hpet.c index be242723c339..17a6fe7166e7 100644 --- a/arch/i386/kernel/timers/timer_hpet.c +++ b/arch/i386/kernel/timers/timer_hpet.c | |||
@@ -46,7 +46,7 @@ static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; | |||
46 | * | 46 | * |
47 | * -johnstul@us.ibm.com "math is hard, lets go shopping!" | 47 | * -johnstul@us.ibm.com "math is hard, lets go shopping!" |
48 | */ | 48 | */ |
49 | static unsigned long cyc2ns_scale; | 49 | static unsigned long cyc2ns_scale __read_mostly; |
50 | #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ | 50 | #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ |
51 | 51 | ||
52 | static inline void set_cyc2ns_scale(unsigned long cpu_khz) | 52 | static inline void set_cyc2ns_scale(unsigned long cpu_khz) |
diff --git a/arch/i386/kernel/timers/timer_pm.c b/arch/i386/kernel/timers/timer_pm.c index 264edaaac315..144e94a04933 100644 --- a/arch/i386/kernel/timers/timer_pm.c +++ b/arch/i386/kernel/timers/timer_pm.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/pci.h> | ||
18 | #include <asm/types.h> | 19 | #include <asm/types.h> |
19 | #include <asm/timer.h> | 20 | #include <asm/timer.h> |
20 | #include <asm/smp.h> | 21 | #include <asm/smp.h> |
@@ -45,24 +46,31 @@ static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; | |||
45 | 46 | ||
46 | #define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */ | 47 | #define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */ |
47 | 48 | ||
49 | static int pmtmr_need_workaround __read_mostly = 1; | ||
50 | |||
48 | /*helper function to safely read acpi pm timesource*/ | 51 | /*helper function to safely read acpi pm timesource*/ |
49 | static inline u32 read_pmtmr(void) | 52 | static inline u32 read_pmtmr(void) |
50 | { | 53 | { |
51 | u32 v1=0,v2=0,v3=0; | 54 | if (pmtmr_need_workaround) { |
52 | /* It has been reported that because of various broken | 55 | u32 v1, v2, v3; |
53 | * chipsets (ICH4, PIIX4 and PIIX4E) where the ACPI PM time | 56 | |
54 | * source is not latched, so you must read it multiple | 57 | /* It has been reported that because of various broken |
55 | * times to insure a safe value is read. | 58 | * chipsets (ICH4, PIIX4 and PIIX4E) where the ACPI PM time |
56 | */ | 59 | * source is not latched, so you must read it multiple |
57 | do { | 60 | * times to insure a safe value is read. |
58 | v1 = inl(pmtmr_ioport); | 61 | */ |
59 | v2 = inl(pmtmr_ioport); | 62 | do { |
60 | v3 = inl(pmtmr_ioport); | 63 | v1 = inl(pmtmr_ioport); |
61 | } while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) | 64 | v2 = inl(pmtmr_ioport); |
62 | || (v3 > v1 && v3 < v2)); | 65 | v3 = inl(pmtmr_ioport); |
63 | 66 | } while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) | |
64 | /* mask the output to 24 bits */ | 67 | || (v3 > v1 && v3 < v2)); |
65 | return v2 & ACPI_PM_MASK; | 68 | |
69 | /* mask the output to 24 bits */ | ||
70 | return v2 & ACPI_PM_MASK; | ||
71 | } | ||
72 | |||
73 | return inl(pmtmr_ioport) & ACPI_PM_MASK; | ||
66 | } | 74 | } |
67 | 75 | ||
68 | 76 | ||
@@ -263,6 +271,72 @@ struct init_timer_opts __initdata timer_pmtmr_init = { | |||
263 | .opts = &timer_pmtmr, | 271 | .opts = &timer_pmtmr, |
264 | }; | 272 | }; |
265 | 273 | ||
274 | #ifdef CONFIG_PCI | ||
275 | /* | ||
276 | * PIIX4 Errata: | ||
277 | * | ||
278 | * The power management timer may return improper results when read. | ||
279 | * Although the timer value settles properly after incrementing, | ||
280 | * while incrementing there is a 3 ns window every 69.8 ns where the | ||
281 | * timer value is indeterminate (a 4.2% chance that the data will be | ||
282 | * incorrect when read). As a result, the ACPI free running count up | ||
283 | * timer specification is violated due to erroneous reads. | ||
284 | */ | ||
285 | static int __init pmtmr_bug_check(void) | ||
286 | { | ||
287 | static struct pci_device_id gray_list[] __initdata = { | ||
288 | /* these chipsets may have bug. */ | ||
289 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, | ||
290 | PCI_DEVICE_ID_INTEL_82801DB_0) }, | ||
291 | { }, | ||
292 | }; | ||
293 | struct pci_dev *dev; | ||
294 | int pmtmr_has_bug = 0; | ||
295 | u8 rev; | ||
296 | |||
297 | if (cur_timer != &timer_pmtmr || !pmtmr_need_workaround) | ||
298 | return 0; | ||
299 | |||
300 | dev = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
301 | PCI_DEVICE_ID_INTEL_82371AB_3, NULL); | ||
302 | if (dev) { | ||
303 | pci_read_config_byte(dev, PCI_REVISION_ID, &rev); | ||
304 | /* the bug has been fixed in PIIX4M */ | ||
305 | if (rev < 3) { | ||
306 | printk(KERN_WARNING "* Found PM-Timer Bug on this " | ||
307 | "chipset. Due to workarounds for a bug,\n" | ||
308 | "* this time source is slow. Consider trying " | ||
309 | "other time sources (clock=)\n"); | ||
310 | pmtmr_has_bug = 1; | ||
311 | } | ||
312 | pci_dev_put(dev); | ||
313 | } | ||
314 | |||
315 | if (pci_dev_present(gray_list)) { | ||
316 | printk(KERN_WARNING "* This chipset may have PM-Timer Bug. Due" | ||
317 | " to workarounds for a bug,\n" | ||
318 | "* this time source is slow. If you are sure your timer" | ||
319 | " does not have\n" | ||
320 | "* this bug, please use \"pmtmr_good\" to disable the " | ||
321 | "workaround\n"); | ||
322 | pmtmr_has_bug = 1; | ||
323 | } | ||
324 | |||
325 | if (!pmtmr_has_bug) | ||
326 | pmtmr_need_workaround = 0; | ||
327 | |||
328 | return 0; | ||
329 | } | ||
330 | device_initcall(pmtmr_bug_check); | ||
331 | #endif | ||
332 | |||
333 | static int __init pmtr_good_setup(char *__str) | ||
334 | { | ||
335 | pmtmr_need_workaround = 0; | ||
336 | return 1; | ||
337 | } | ||
338 | __setup("pmtmr_good", pmtr_good_setup); | ||
339 | |||
266 | MODULE_LICENSE("GPL"); | 340 | MODULE_LICENSE("GPL"); |
267 | MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>"); | 341 | MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>"); |
268 | MODULE_DESCRIPTION("Power Management Timer (PMTMR) as primary timing source for x86"); | 342 | MODULE_DESCRIPTION("Power Management Timer (PMTMR) as primary timing source for x86"); |
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c index a7f5a2aceba2..5e41ee29c8cf 100644 --- a/arch/i386/kernel/timers/timer_tsc.c +++ b/arch/i386/kernel/timers/timer_tsc.c | |||
@@ -74,7 +74,7 @@ late_initcall(start_lost_tick_compensation); | |||
74 | * | 74 | * |
75 | * -johnstul@us.ibm.com "math is hard, lets go shopping!" | 75 | * -johnstul@us.ibm.com "math is hard, lets go shopping!" |
76 | */ | 76 | */ |
77 | static unsigned long cyc2ns_scale; | 77 | static unsigned long cyc2ns_scale __read_mostly; |
78 | #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ | 78 | #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ |
79 | 79 | ||
80 | static inline void set_cyc2ns_scale(unsigned long cpu_khz) | 80 | static inline void set_cyc2ns_scale(unsigned long cpu_khz) |
diff --git a/arch/i386/kernel/topology.c b/arch/i386/kernel/topology.c index 67a0e1baa28b..296355292c7c 100644 --- a/arch/i386/kernel/topology.c +++ b/arch/i386/kernel/topology.c | |||
@@ -41,6 +41,15 @@ int arch_register_cpu(int num){ | |||
41 | parent = &node_devices[node].node; | 41 | parent = &node_devices[node].node; |
42 | #endif /* CONFIG_NUMA */ | 42 | #endif /* CONFIG_NUMA */ |
43 | 43 | ||
44 | /* | ||
45 | * CPU0 cannot be offlined due to several | ||
46 | * restrictions and assumptions in kernel. This basically | ||
47 | * doesnt add a control file, one cannot attempt to offline | ||
48 | * BSP. | ||
49 | */ | ||
50 | if (!num) | ||
51 | cpu_devices[num].cpu.no_control = 1; | ||
52 | |||
44 | return register_cpu(&cpu_devices[num].cpu, num, parent); | 53 | return register_cpu(&cpu_devices[num].cpu, num, parent); |
45 | } | 54 | } |
46 | 55 | ||
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index b814dbdcc91e..e38527994590 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -92,32 +92,51 @@ asmlinkage void spurious_interrupt_bug(void); | |||
92 | asmlinkage void machine_check(void); | 92 | asmlinkage void machine_check(void); |
93 | 93 | ||
94 | static int kstack_depth_to_print = 24; | 94 | static int kstack_depth_to_print = 24; |
95 | struct notifier_block *i386die_chain; | 95 | ATOMIC_NOTIFIER_HEAD(i386die_chain); |
96 | static DEFINE_SPINLOCK(die_notifier_lock); | ||
97 | 96 | ||
98 | int register_die_notifier(struct notifier_block *nb) | 97 | int register_die_notifier(struct notifier_block *nb) |
99 | { | 98 | { |
100 | int err = 0; | 99 | vmalloc_sync_all(); |
101 | unsigned long flags; | 100 | return atomic_notifier_chain_register(&i386die_chain, nb); |
102 | spin_lock_irqsave(&die_notifier_lock, flags); | ||
103 | err = notifier_chain_register(&i386die_chain, nb); | ||
104 | spin_unlock_irqrestore(&die_notifier_lock, flags); | ||
105 | return err; | ||
106 | } | 101 | } |
107 | EXPORT_SYMBOL(register_die_notifier); | 102 | EXPORT_SYMBOL(register_die_notifier); |
108 | 103 | ||
104 | int unregister_die_notifier(struct notifier_block *nb) | ||
105 | { | ||
106 | return atomic_notifier_chain_unregister(&i386die_chain, nb); | ||
107 | } | ||
108 | EXPORT_SYMBOL(unregister_die_notifier); | ||
109 | |||
109 | static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) | 110 | static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) |
110 | { | 111 | { |
111 | return p > (void *)tinfo && | 112 | return p > (void *)tinfo && |
112 | p < (void *)tinfo + THREAD_SIZE - 3; | 113 | p < (void *)tinfo + THREAD_SIZE - 3; |
113 | } | 114 | } |
114 | 115 | ||
115 | static void print_addr_and_symbol(unsigned long addr, char *log_lvl) | 116 | /* |
117 | * Print CONFIG_STACK_BACKTRACE_COLS address/symbol entries per line. | ||
118 | */ | ||
119 | static inline int print_addr_and_symbol(unsigned long addr, char *log_lvl, | ||
120 | int printed) | ||
116 | { | 121 | { |
117 | printk(log_lvl); | 122 | if (!printed) |
123 | printk(log_lvl); | ||
124 | |||
125 | #if CONFIG_STACK_BACKTRACE_COLS == 1 | ||
118 | printk(" [<%08lx>] ", addr); | 126 | printk(" [<%08lx>] ", addr); |
127 | #else | ||
128 | printk(" <%08lx> ", addr); | ||
129 | #endif | ||
119 | print_symbol("%s", addr); | 130 | print_symbol("%s", addr); |
120 | printk("\n"); | 131 | |
132 | printed = (printed + 1) % CONFIG_STACK_BACKTRACE_COLS; | ||
133 | |||
134 | if (printed) | ||
135 | printk(" "); | ||
136 | else | ||
137 | printk("\n"); | ||
138 | |||
139 | return printed; | ||
121 | } | 140 | } |
122 | 141 | ||
123 | static inline unsigned long print_context_stack(struct thread_info *tinfo, | 142 | static inline unsigned long print_context_stack(struct thread_info *tinfo, |
@@ -125,20 +144,24 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, | |||
125 | char *log_lvl) | 144 | char *log_lvl) |
126 | { | 145 | { |
127 | unsigned long addr; | 146 | unsigned long addr; |
147 | int printed = 0; /* nr of entries already printed on current line */ | ||
128 | 148 | ||
129 | #ifdef CONFIG_FRAME_POINTER | 149 | #ifdef CONFIG_FRAME_POINTER |
130 | while (valid_stack_ptr(tinfo, (void *)ebp)) { | 150 | while (valid_stack_ptr(tinfo, (void *)ebp)) { |
131 | addr = *(unsigned long *)(ebp + 4); | 151 | addr = *(unsigned long *)(ebp + 4); |
132 | print_addr_and_symbol(addr, log_lvl); | 152 | printed = print_addr_and_symbol(addr, log_lvl, printed); |
133 | ebp = *(unsigned long *)ebp; | 153 | ebp = *(unsigned long *)ebp; |
134 | } | 154 | } |
135 | #else | 155 | #else |
136 | while (valid_stack_ptr(tinfo, stack)) { | 156 | while (valid_stack_ptr(tinfo, stack)) { |
137 | addr = *stack++; | 157 | addr = *stack++; |
138 | if (__kernel_text_address(addr)) | 158 | if (__kernel_text_address(addr)) |
139 | print_addr_and_symbol(addr, log_lvl); | 159 | printed = print_addr_and_symbol(addr, log_lvl, printed); |
140 | } | 160 | } |
141 | #endif | 161 | #endif |
162 | if (printed) | ||
163 | printk("\n"); | ||
164 | |||
142 | return ebp; | 165 | return ebp; |
143 | } | 166 | } |
144 | 167 | ||
@@ -166,8 +189,7 @@ static void show_trace_log_lvl(struct task_struct *task, | |||
166 | stack = (unsigned long*)context->previous_esp; | 189 | stack = (unsigned long*)context->previous_esp; |
167 | if (!stack) | 190 | if (!stack) |
168 | break; | 191 | break; |
169 | printk(log_lvl); | 192 | printk("%s =======================\n", log_lvl); |
170 | printk(" =======================\n"); | ||
171 | } | 193 | } |
172 | } | 194 | } |
173 | 195 | ||
@@ -194,21 +216,17 @@ static void show_stack_log_lvl(struct task_struct *task, unsigned long *esp, | |||
194 | for(i = 0; i < kstack_depth_to_print; i++) { | 216 | for(i = 0; i < kstack_depth_to_print; i++) { |
195 | if (kstack_end(stack)) | 217 | if (kstack_end(stack)) |
196 | break; | 218 | break; |
197 | if (i && ((i % 8) == 0)) { | 219 | if (i && ((i % 8) == 0)) |
198 | printk("\n"); | 220 | printk("\n%s ", log_lvl); |
199 | printk(log_lvl); | ||
200 | printk(" "); | ||
201 | } | ||
202 | printk("%08lx ", *stack++); | 221 | printk("%08lx ", *stack++); |
203 | } | 222 | } |
204 | printk("\n"); | 223 | printk("\n%sCall Trace:\n", log_lvl); |
205 | printk(log_lvl); | ||
206 | printk("Call Trace:\n"); | ||
207 | show_trace_log_lvl(task, esp, log_lvl); | 224 | show_trace_log_lvl(task, esp, log_lvl); |
208 | } | 225 | } |
209 | 226 | ||
210 | void show_stack(struct task_struct *task, unsigned long *esp) | 227 | void show_stack(struct task_struct *task, unsigned long *esp) |
211 | { | 228 | { |
229 | printk(" "); | ||
212 | show_stack_log_lvl(task, esp, ""); | 230 | show_stack_log_lvl(task, esp, ""); |
213 | } | 231 | } |
214 | 232 | ||
@@ -233,7 +251,7 @@ void show_registers(struct pt_regs *regs) | |||
233 | 251 | ||
234 | esp = (unsigned long) (®s->esp); | 252 | esp = (unsigned long) (®s->esp); |
235 | savesegment(ss, ss); | 253 | savesegment(ss, ss); |
236 | if (user_mode(regs)) { | 254 | if (user_mode_vm(regs)) { |
237 | in_kernel = 0; | 255 | in_kernel = 0; |
238 | esp = regs->esp; | 256 | esp = regs->esp; |
239 | ss = regs->xss & 0xffff; | 257 | ss = regs->xss & 0xffff; |
@@ -333,6 +351,8 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
333 | static int die_counter; | 351 | static int die_counter; |
334 | unsigned long flags; | 352 | unsigned long flags; |
335 | 353 | ||
354 | oops_enter(); | ||
355 | |||
336 | if (die.lock_owner != raw_smp_processor_id()) { | 356 | if (die.lock_owner != raw_smp_processor_id()) { |
337 | console_verbose(); | 357 | console_verbose(); |
338 | spin_lock_irqsave(&die.lock, flags); | 358 | spin_lock_irqsave(&die.lock, flags); |
@@ -365,8 +385,12 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
365 | #endif | 385 | #endif |
366 | if (nl) | 386 | if (nl) |
367 | printk("\n"); | 387 | printk("\n"); |
368 | notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); | 388 | if (notify_die(DIE_OOPS, str, regs, err, |
369 | show_registers(regs); | 389 | current->thread.trap_no, SIGSEGV) != |
390 | NOTIFY_STOP) | ||
391 | show_registers(regs); | ||
392 | else | ||
393 | regs = NULL; | ||
370 | } else | 394 | } else |
371 | printk(KERN_EMERG "Recursive die() failure, output suppressed\n"); | 395 | printk(KERN_EMERG "Recursive die() failure, output suppressed\n"); |
372 | 396 | ||
@@ -374,6 +398,9 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
374 | die.lock_owner = -1; | 398 | die.lock_owner = -1; |
375 | spin_unlock_irqrestore(&die.lock, flags); | 399 | spin_unlock_irqrestore(&die.lock, flags); |
376 | 400 | ||
401 | if (!regs) | ||
402 | return; | ||
403 | |||
377 | if (kexec_should_crash(current)) | 404 | if (kexec_should_crash(current)) |
378 | crash_kexec(regs); | 405 | crash_kexec(regs); |
379 | 406 | ||
@@ -385,6 +412,7 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
385 | ssleep(5); | 412 | ssleep(5); |
386 | panic("Fatal exception"); | 413 | panic("Fatal exception"); |
387 | } | 414 | } |
415 | oops_exit(); | ||
388 | do_exit(SIGSEGV); | 416 | do_exit(SIGSEGV); |
389 | } | 417 | } |
390 | 418 | ||
@@ -601,7 +629,7 @@ static DEFINE_SPINLOCK(nmi_print_lock); | |||
601 | 629 | ||
602 | void die_nmi (struct pt_regs *regs, const char *msg) | 630 | void die_nmi (struct pt_regs *regs, const char *msg) |
603 | { | 631 | { |
604 | if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 0, SIGINT) == | 632 | if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 2, SIGINT) == |
605 | NOTIFY_STOP) | 633 | NOTIFY_STOP) |
606 | return; | 634 | return; |
607 | 635 | ||
@@ -623,7 +651,7 @@ void die_nmi (struct pt_regs *regs, const char *msg) | |||
623 | /* If we are in kernel we are probably nested up pretty bad | 651 | /* If we are in kernel we are probably nested up pretty bad |
624 | * and might aswell get out now while we still can. | 652 | * and might aswell get out now while we still can. |
625 | */ | 653 | */ |
626 | if (!user_mode(regs)) { | 654 | if (!user_mode_vm(regs)) { |
627 | current->thread.trap_no = 2; | 655 | current->thread.trap_no = 2; |
628 | crash_kexec(regs); | 656 | crash_kexec(regs); |
629 | } | 657 | } |
@@ -640,7 +668,7 @@ static void default_do_nmi(struct pt_regs * regs) | |||
640 | reason = get_nmi_reason(); | 668 | reason = get_nmi_reason(); |
641 | 669 | ||
642 | if (!(reason & 0xc0)) { | 670 | if (!(reason & 0xc0)) { |
643 | if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) | 671 | if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT) |
644 | == NOTIFY_STOP) | 672 | == NOTIFY_STOP) |
645 | return; | 673 | return; |
646 | #ifdef CONFIG_X86_LOCAL_APIC | 674 | #ifdef CONFIG_X86_LOCAL_APIC |
@@ -656,7 +684,7 @@ static void default_do_nmi(struct pt_regs * regs) | |||
656 | unknown_nmi_error(reason, regs); | 684 | unknown_nmi_error(reason, regs); |
657 | return; | 685 | return; |
658 | } | 686 | } |
659 | if (notify_die(DIE_NMI, "nmi", regs, reason, 0, SIGINT) == NOTIFY_STOP) | 687 | if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) |
660 | return; | 688 | return; |
661 | if (reason & 0x80) | 689 | if (reason & 0x80) |
662 | mem_parity_error(reason, regs); | 690 | mem_parity_error(reason, regs); |
@@ -694,6 +722,7 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code) | |||
694 | 722 | ||
695 | void set_nmi_callback(nmi_callback_t callback) | 723 | void set_nmi_callback(nmi_callback_t callback) |
696 | { | 724 | { |
725 | vmalloc_sync_all(); | ||
697 | rcu_assign_pointer(nmi_callback, callback); | 726 | rcu_assign_pointer(nmi_callback, callback); |
698 | } | 727 | } |
699 | EXPORT_SYMBOL_GPL(set_nmi_callback); | 728 | EXPORT_SYMBOL_GPL(set_nmi_callback); |
@@ -1164,6 +1193,6 @@ void __init trap_init(void) | |||
1164 | static int __init kstack_setup(char *s) | 1193 | static int __init kstack_setup(char *s) |
1165 | { | 1194 | { |
1166 | kstack_depth_to_print = simple_strtoul(s, NULL, 0); | 1195 | kstack_depth_to_print = simple_strtoul(s, NULL, 0); |
1167 | return 0; | 1196 | return 1; |
1168 | } | 1197 | } |
1169 | __setup("kstack=", kstack_setup); | 1198 | __setup("kstack=", kstack_setup); |
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c index f51c894a7da5..aee14fafd13d 100644 --- a/arch/i386/kernel/vm86.c +++ b/arch/i386/kernel/vm86.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/smp_lock.h> | 43 | #include <linux/smp_lock.h> |
44 | #include <linux/highmem.h> | 44 | #include <linux/highmem.h> |
45 | #include <linux/ptrace.h> | 45 | #include <linux/ptrace.h> |
46 | #include <linux/audit.h> | ||
46 | 47 | ||
47 | #include <asm/uaccess.h> | 48 | #include <asm/uaccess.h> |
48 | #include <asm/io.h> | 49 | #include <asm/io.h> |
@@ -252,6 +253,7 @@ out: | |||
252 | static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk) | 253 | static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk) |
253 | { | 254 | { |
254 | struct tss_struct *tss; | 255 | struct tss_struct *tss; |
256 | long eax; | ||
255 | /* | 257 | /* |
256 | * make sure the vm86() system call doesn't try to do anything silly | 258 | * make sure the vm86() system call doesn't try to do anything silly |
257 | */ | 259 | */ |
@@ -305,13 +307,19 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk | |||
305 | tsk->thread.screen_bitmap = info->screen_bitmap; | 307 | tsk->thread.screen_bitmap = info->screen_bitmap; |
306 | if (info->flags & VM86_SCREEN_BITMAP) | 308 | if (info->flags & VM86_SCREEN_BITMAP) |
307 | mark_screen_rdonly(tsk->mm); | 309 | mark_screen_rdonly(tsk->mm); |
310 | __asm__ __volatile__("xorl %eax,%eax; movl %eax,%fs; movl %eax,%gs\n\t"); | ||
311 | __asm__ __volatile__("movl %%eax, %0\n" :"=r"(eax)); | ||
312 | |||
313 | /*call audit_syscall_exit since we do not exit via the normal paths */ | ||
314 | if (unlikely(current->audit_context)) | ||
315 | audit_syscall_exit(current, AUDITSC_RESULT(eax), eax); | ||
316 | |||
308 | __asm__ __volatile__( | 317 | __asm__ __volatile__( |
309 | "xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs\n\t" | ||
310 | "movl %0,%%esp\n\t" | 318 | "movl %0,%%esp\n\t" |
311 | "movl %1,%%ebp\n\t" | 319 | "movl %1,%%ebp\n\t" |
312 | "jmp resume_userspace" | 320 | "jmp resume_userspace" |
313 | : /* no outputs */ | 321 | : /* no outputs */ |
314 | :"r" (&info->regs), "r" (task_thread_info(tsk)) : "ax"); | 322 | :"r" (&info->regs), "r" (task_thread_info(tsk))); |
315 | /* we never return here */ | 323 | /* we never return here */ |
316 | } | 324 | } |
317 | 325 | ||
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index 4710195b6b74..8831303a473f 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <asm-generic/vmlinux.lds.h> | 7 | #include <asm-generic/vmlinux.lds.h> |
8 | #include <asm/thread_info.h> | 8 | #include <asm/thread_info.h> |
9 | #include <asm/page.h> | 9 | #include <asm/page.h> |
10 | #include <asm/cache.h> | ||
10 | 11 | ||
11 | OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") | 12 | OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") |
12 | OUTPUT_ARCH(i386) | 13 | OUTPUT_ARCH(i386) |
@@ -68,6 +69,26 @@ SECTIONS | |||
68 | *(.data.init_task) | 69 | *(.data.init_task) |
69 | } | 70 | } |
70 | 71 | ||
72 | /* might get freed after init */ | ||
73 | . = ALIGN(4096); | ||
74 | __smp_alt_begin = .; | ||
75 | __smp_alt_instructions = .; | ||
76 | .smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) { | ||
77 | *(.smp_altinstructions) | ||
78 | } | ||
79 | __smp_alt_instructions_end = .; | ||
80 | . = ALIGN(4); | ||
81 | __smp_locks = .; | ||
82 | .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { | ||
83 | *(.smp_locks) | ||
84 | } | ||
85 | __smp_locks_end = .; | ||
86 | .smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) { | ||
87 | *(.smp_altinstr_replacement) | ||
88 | } | ||
89 | . = ALIGN(4096); | ||
90 | __smp_alt_end = .; | ||
91 | |||
71 | /* will be freed after init */ | 92 | /* will be freed after init */ |
72 | . = ALIGN(4096); /* Init code and data */ | 93 | . = ALIGN(4096); /* Init code and data */ |
73 | __init_begin = .; | 94 | __init_begin = .; |
@@ -115,7 +136,7 @@ SECTIONS | |||
115 | __initramfs_start = .; | 136 | __initramfs_start = .; |
116 | .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) } | 137 | .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) } |
117 | __initramfs_end = .; | 138 | __initramfs_end = .; |
118 | . = ALIGN(32); | 139 | . = ALIGN(L1_CACHE_BYTES); |
119 | __per_cpu_start = .; | 140 | __per_cpu_start = .; |
120 | .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } | 141 | .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } |
121 | __per_cpu_end = .; | 142 | __per_cpu_end = .; |
diff --git a/arch/i386/kernel/vsyscall-sigreturn.S b/arch/i386/kernel/vsyscall-sigreturn.S index fadb5bc3c374..a92262f41659 100644 --- a/arch/i386/kernel/vsyscall-sigreturn.S +++ b/arch/i386/kernel/vsyscall-sigreturn.S | |||
@@ -44,7 +44,7 @@ __kernel_rt_sigreturn: | |||
44 | .LSTARTCIEDLSI1: | 44 | .LSTARTCIEDLSI1: |
45 | .long 0 /* CIE ID */ | 45 | .long 0 /* CIE ID */ |
46 | .byte 1 /* Version number */ | 46 | .byte 1 /* Version number */ |
47 | .string "zR" /* NUL-terminated augmentation string */ | 47 | .string "zRS" /* NUL-terminated augmentation string */ |
48 | .uleb128 1 /* Code alignment factor */ | 48 | .uleb128 1 /* Code alignment factor */ |
49 | .sleb128 -4 /* Data alignment factor */ | 49 | .sleb128 -4 /* Data alignment factor */ |
50 | .byte 8 /* Return address register column */ | 50 | .byte 8 /* Return address register column */ |
diff --git a/arch/i386/kernel/vsyscall-sysenter.S b/arch/i386/kernel/vsyscall-sysenter.S index 76b728159403..3b62baa6a371 100644 --- a/arch/i386/kernel/vsyscall-sysenter.S +++ b/arch/i386/kernel/vsyscall-sysenter.S | |||
@@ -21,6 +21,9 @@ | |||
21 | * instruction clobbers %esp, the user's %esp won't even survive entry | 21 | * instruction clobbers %esp, the user's %esp won't even survive entry |
22 | * into the kernel. We store %esp in %ebp. Code in entry.S must fetch | 22 | * into the kernel. We store %esp in %ebp. Code in entry.S must fetch |
23 | * arg6 from the stack. | 23 | * arg6 from the stack. |
24 | * | ||
25 | * You can not use this vsyscall for the clone() syscall because the | ||
26 | * three dwords on the parent stack do not get copied to the child. | ||
24 | */ | 27 | */ |
25 | .text | 28 | .text |
26 | .globl __kernel_vsyscall | 29 | .globl __kernel_vsyscall |