diff options
Diffstat (limited to 'arch/i386/kernel/cpu')
-rw-r--r-- | arch/i386/kernel/cpu/amd.c | 5 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/common.c | 249 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/intel.c | 12 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/intel_cacheinfo.c | 11 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/mcheck/non-fatal.c | 6 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/mcheck/therm_throt.c | 3 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/mtrr/Makefile | 4 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/mtrr/amd.c | 2 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/mtrr/centaur.c | 9 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/mtrr/cyrix.c | 25 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/mtrr/generic.c | 78 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/mtrr/if.c | 31 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/mtrr/main.c | 71 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/mtrr/mtrr.h | 25 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/proc.c | 3 |
15 files changed, 373 insertions, 161 deletions
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index e4758095d87a..41cfea57232b 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c | |||
@@ -104,10 +104,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
104 | f_vide(); | 104 | f_vide(); |
105 | rdtscl(d2); | 105 | rdtscl(d2); |
106 | d = d2-d; | 106 | d = d2-d; |
107 | 107 | ||
108 | /* Knock these two lines out if it debugs out ok */ | ||
109 | printk(KERN_INFO "AMD K6 stepping B detected - "); | ||
110 | /* -- cut here -- */ | ||
111 | if (d > 20*K6_BUG_LOOP) | 108 | if (d > 20*K6_BUG_LOOP) |
112 | printk("system stability may be impaired when more than 32 MB are used.\n"); | 109 | printk("system stability may be impaired when more than 32 MB are used.\n"); |
113 | else | 110 | else |
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index d9f3e3c31f05..1b34c56f8123 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c | |||
@@ -18,14 +18,15 @@ | |||
18 | #include <asm/apic.h> | 18 | #include <asm/apic.h> |
19 | #include <mach_apic.h> | 19 | #include <mach_apic.h> |
20 | #endif | 20 | #endif |
21 | #include <asm/pda.h> | ||
21 | 22 | ||
22 | #include "cpu.h" | 23 | #include "cpu.h" |
23 | 24 | ||
24 | DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); | 25 | DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); |
25 | EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr); | 26 | EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr); |
26 | 27 | ||
27 | DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); | 28 | struct i386_pda *_cpu_pda[NR_CPUS] __read_mostly; |
28 | EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); | 29 | EXPORT_SYMBOL(_cpu_pda); |
29 | 30 | ||
30 | static int cachesize_override __cpuinitdata = -1; | 31 | static int cachesize_override __cpuinitdata = -1; |
31 | static int disable_x86_fxsr __cpuinitdata; | 32 | static int disable_x86_fxsr __cpuinitdata; |
@@ -235,29 +236,14 @@ static int __cpuinit have_cpuid_p(void) | |||
235 | return flag_is_changeable_p(X86_EFLAGS_ID); | 236 | return flag_is_changeable_p(X86_EFLAGS_ID); |
236 | } | 237 | } |
237 | 238 | ||
238 | /* Do minimum CPU detection early. | 239 | void __init cpu_detect(struct cpuinfo_x86 *c) |
239 | Fields really needed: vendor, cpuid_level, family, model, mask, cache alignment. | ||
240 | The others are not touched to avoid unwanted side effects. | ||
241 | |||
242 | WARNING: this function is only called on the BP. Don't add code here | ||
243 | that is supposed to run on all CPUs. */ | ||
244 | static void __init early_cpu_detect(void) | ||
245 | { | 240 | { |
246 | struct cpuinfo_x86 *c = &boot_cpu_data; | ||
247 | |||
248 | c->x86_cache_alignment = 32; | ||
249 | |||
250 | if (!have_cpuid_p()) | ||
251 | return; | ||
252 | |||
253 | /* Get vendor name */ | 241 | /* Get vendor name */ |
254 | cpuid(0x00000000, &c->cpuid_level, | 242 | cpuid(0x00000000, &c->cpuid_level, |
255 | (int *)&c->x86_vendor_id[0], | 243 | (int *)&c->x86_vendor_id[0], |
256 | (int *)&c->x86_vendor_id[8], | 244 | (int *)&c->x86_vendor_id[8], |
257 | (int *)&c->x86_vendor_id[4]); | 245 | (int *)&c->x86_vendor_id[4]); |
258 | 246 | ||
259 | get_cpu_vendor(c, 1); | ||
260 | |||
261 | c->x86 = 4; | 247 | c->x86 = 4; |
262 | if (c->cpuid_level >= 0x00000001) { | 248 | if (c->cpuid_level >= 0x00000001) { |
263 | u32 junk, tfms, cap0, misc; | 249 | u32 junk, tfms, cap0, misc; |
@@ -274,6 +260,26 @@ static void __init early_cpu_detect(void) | |||
274 | } | 260 | } |
275 | } | 261 | } |
276 | 262 | ||
263 | /* Do minimum CPU detection early. | ||
264 | Fields really needed: vendor, cpuid_level, family, model, mask, cache alignment. | ||
265 | The others are not touched to avoid unwanted side effects. | ||
266 | |||
267 | WARNING: this function is only called on the BP. Don't add code here | ||
268 | that is supposed to run on all CPUs. */ | ||
269 | static void __init early_cpu_detect(void) | ||
270 | { | ||
271 | struct cpuinfo_x86 *c = &boot_cpu_data; | ||
272 | |||
273 | c->x86_cache_alignment = 32; | ||
274 | |||
275 | if (!have_cpuid_p()) | ||
276 | return; | ||
277 | |||
278 | cpu_detect(c); | ||
279 | |||
280 | get_cpu_vendor(c, 1); | ||
281 | } | ||
282 | |||
277 | static void __cpuinit generic_identify(struct cpuinfo_x86 * c) | 283 | static void __cpuinit generic_identify(struct cpuinfo_x86 * c) |
278 | { | 284 | { |
279 | u32 tfms, xlvl; | 285 | u32 tfms, xlvl; |
@@ -308,6 +314,8 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 * c) | |||
308 | #else | 314 | #else |
309 | c->apicid = (ebx >> 24) & 0xFF; | 315 | c->apicid = (ebx >> 24) & 0xFF; |
310 | #endif | 316 | #endif |
317 | if (c->x86_capability[0] & (1<<19)) | ||
318 | c->x86_clflush_size = ((ebx >> 8) & 0xff) * 8; | ||
311 | } else { | 319 | } else { |
312 | /* Have CPUID level 0 only - unheard of */ | 320 | /* Have CPUID level 0 only - unheard of */ |
313 | c->x86 = 4; | 321 | c->x86 = 4; |
@@ -372,6 +380,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
372 | c->x86_vendor_id[0] = '\0'; /* Unset */ | 380 | c->x86_vendor_id[0] = '\0'; /* Unset */ |
373 | c->x86_model_id[0] = '\0'; /* Unset */ | 381 | c->x86_model_id[0] = '\0'; /* Unset */ |
374 | c->x86_max_cores = 1; | 382 | c->x86_max_cores = 1; |
383 | c->x86_clflush_size = 32; | ||
375 | memset(&c->x86_capability, 0, sizeof c->x86_capability); | 384 | memset(&c->x86_capability, 0, sizeof c->x86_capability); |
376 | 385 | ||
377 | if (!have_cpuid_p()) { | 386 | if (!have_cpuid_p()) { |
@@ -591,42 +600,24 @@ void __init early_cpu_init(void) | |||
591 | disable_pse = 1; | 600 | disable_pse = 1; |
592 | #endif | 601 | #endif |
593 | } | 602 | } |
594 | /* | 603 | |
595 | * cpu_init() initializes state that is per-CPU. Some data is already | 604 | /* Make sure %gs is initialized properly in idle threads */ |
596 | * initialized (naturally) in the bootstrap process, such as the GDT | 605 | struct pt_regs * __devinit idle_regs(struct pt_regs *regs) |
597 | * and IDT. We reload them nevertheless, this function acts as a | ||
598 | * 'CPU state barrier', nothing should get across. | ||
599 | */ | ||
600 | void __cpuinit cpu_init(void) | ||
601 | { | 606 | { |
602 | int cpu = smp_processor_id(); | 607 | memset(regs, 0, sizeof(struct pt_regs)); |
603 | struct tss_struct * t = &per_cpu(init_tss, cpu); | 608 | regs->xgs = __KERNEL_PDA; |
604 | struct thread_struct *thread = ¤t->thread; | 609 | return regs; |
605 | struct desc_struct *gdt; | 610 | } |
606 | __u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu); | ||
607 | struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); | ||
608 | 611 | ||
609 | if (cpu_test_and_set(cpu, cpu_initialized)) { | 612 | static __cpuinit int alloc_gdt(int cpu) |
610 | printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); | 613 | { |
611 | for (;;) local_irq_enable(); | 614 | struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); |
612 | } | 615 | struct desc_struct *gdt; |
613 | printk(KERN_INFO "Initializing CPU#%d\n", cpu); | 616 | struct i386_pda *pda; |
614 | 617 | ||
615 | if (cpu_has_vme || cpu_has_tsc || cpu_has_de) | 618 | gdt = (struct desc_struct *)cpu_gdt_descr->address; |
616 | clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); | 619 | pda = cpu_pda(cpu); |
617 | if (tsc_disable && cpu_has_tsc) { | ||
618 | printk(KERN_NOTICE "Disabling TSC...\n"); | ||
619 | /**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/ | ||
620 | clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability); | ||
621 | set_in_cr4(X86_CR4_TSD); | ||
622 | } | ||
623 | 620 | ||
624 | /* The CPU hotplug case */ | ||
625 | if (cpu_gdt_descr->address) { | ||
626 | gdt = (struct desc_struct *)cpu_gdt_descr->address; | ||
627 | memset(gdt, 0, PAGE_SIZE); | ||
628 | goto old_gdt; | ||
629 | } | ||
630 | /* | 621 | /* |
631 | * This is a horrible hack to allocate the GDT. The problem | 622 | * This is a horrible hack to allocate the GDT. The problem |
632 | * is that cpu_init() is called really early for the boot CPU | 623 | * is that cpu_init() is called really early for the boot CPU |
@@ -634,43 +625,130 @@ void __cpuinit cpu_init(void) | |||
634 | * CPUs, when bootmem will have gone away | 625 | * CPUs, when bootmem will have gone away |
635 | */ | 626 | */ |
636 | if (NODE_DATA(0)->bdata->node_bootmem_map) { | 627 | if (NODE_DATA(0)->bdata->node_bootmem_map) { |
637 | gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE); | 628 | BUG_ON(gdt != NULL || pda != NULL); |
638 | /* alloc_bootmem_pages panics on failure, so no check */ | 629 | |
630 | gdt = alloc_bootmem_pages(PAGE_SIZE); | ||
631 | pda = alloc_bootmem(sizeof(*pda)); | ||
632 | /* alloc_bootmem(_pages) panics on failure, so no check */ | ||
633 | |||
639 | memset(gdt, 0, PAGE_SIZE); | 634 | memset(gdt, 0, PAGE_SIZE); |
635 | memset(pda, 0, sizeof(*pda)); | ||
640 | } else { | 636 | } else { |
641 | gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL); | 637 | /* GDT and PDA might already have been allocated if |
642 | if (unlikely(!gdt)) { | 638 | this is a CPU hotplug re-insertion. */ |
643 | printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu); | 639 | if (gdt == NULL) |
644 | for (;;) | 640 | gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL); |
645 | local_irq_enable(); | 641 | |
642 | if (pda == NULL) | ||
643 | pda = kmalloc_node(sizeof(*pda), GFP_KERNEL, cpu_to_node(cpu)); | ||
644 | |||
645 | if (unlikely(!gdt || !pda)) { | ||
646 | free_pages((unsigned long)gdt, 0); | ||
647 | kfree(pda); | ||
648 | return 0; | ||
646 | } | 649 | } |
647 | } | 650 | } |
648 | old_gdt: | 651 | |
652 | cpu_gdt_descr->address = (unsigned long)gdt; | ||
653 | cpu_pda(cpu) = pda; | ||
654 | |||
655 | return 1; | ||
656 | } | ||
657 | |||
658 | /* Initial PDA used by boot CPU */ | ||
659 | struct i386_pda boot_pda = { | ||
660 | ._pda = &boot_pda, | ||
661 | .cpu_number = 0, | ||
662 | .pcurrent = &init_task, | ||
663 | }; | ||
664 | |||
665 | static inline void set_kernel_gs(void) | ||
666 | { | ||
667 | /* Set %gs for this CPU's PDA. Memory clobber is to create a | ||
668 | barrier with respect to any PDA operations, so the compiler | ||
669 | doesn't move any before here. */ | ||
670 | asm volatile ("mov %0, %%gs" : : "r" (__KERNEL_PDA) : "memory"); | ||
671 | } | ||
672 | |||
673 | /* Initialize the CPU's GDT and PDA. The boot CPU does this for | ||
674 | itself, but secondaries find this done for them. */ | ||
675 | __cpuinit int init_gdt(int cpu, struct task_struct *idle) | ||
676 | { | ||
677 | struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); | ||
678 | struct desc_struct *gdt; | ||
679 | struct i386_pda *pda; | ||
680 | |||
681 | /* For non-boot CPUs, the GDT and PDA should already have been | ||
682 | allocated. */ | ||
683 | if (!alloc_gdt(cpu)) { | ||
684 | printk(KERN_CRIT "CPU%d failed to allocate GDT or PDA\n", cpu); | ||
685 | return 0; | ||
686 | } | ||
687 | |||
688 | gdt = (struct desc_struct *)cpu_gdt_descr->address; | ||
689 | pda = cpu_pda(cpu); | ||
690 | |||
691 | BUG_ON(gdt == NULL || pda == NULL); | ||
692 | |||
649 | /* | 693 | /* |
650 | * Initialize the per-CPU GDT with the boot GDT, | 694 | * Initialize the per-CPU GDT with the boot GDT, |
651 | * and set up the GDT descriptor: | 695 | * and set up the GDT descriptor: |
652 | */ | 696 | */ |
653 | memcpy(gdt, cpu_gdt_table, GDT_SIZE); | 697 | memcpy(gdt, cpu_gdt_table, GDT_SIZE); |
698 | cpu_gdt_descr->size = GDT_SIZE - 1; | ||
654 | 699 | ||
655 | /* Set up GDT entry for 16bit stack */ | 700 | pack_descriptor((u32 *)&gdt[GDT_ENTRY_PDA].a, |
656 | *(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |= | 701 | (u32 *)&gdt[GDT_ENTRY_PDA].b, |
657 | ((((__u64)stk16_off) << 16) & 0x000000ffffff0000ULL) | | 702 | (unsigned long)pda, sizeof(*pda) - 1, |
658 | ((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) | | 703 | 0x80 | DESCTYPE_S | 0x2, 0); /* present read-write data segment */ |
659 | (CPU_16BIT_STACK_SIZE - 1); | ||
660 | 704 | ||
661 | cpu_gdt_descr->size = GDT_SIZE - 1; | 705 | memset(pda, 0, sizeof(*pda)); |
662 | cpu_gdt_descr->address = (unsigned long)gdt; | 706 | pda->_pda = pda; |
707 | pda->cpu_number = cpu; | ||
708 | pda->pcurrent = idle; | ||
709 | |||
710 | return 1; | ||
711 | } | ||
712 | |||
713 | /* Common CPU init for both boot and secondary CPUs */ | ||
714 | static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) | ||
715 | { | ||
716 | struct tss_struct * t = &per_cpu(init_tss, cpu); | ||
717 | struct thread_struct *thread = &curr->thread; | ||
718 | struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); | ||
663 | 719 | ||
720 | /* Reinit these anyway, even if they've already been done (on | ||
721 | the boot CPU, this will transition from the boot gdt+pda to | ||
722 | the real ones). */ | ||
664 | load_gdt(cpu_gdt_descr); | 723 | load_gdt(cpu_gdt_descr); |
724 | set_kernel_gs(); | ||
725 | |||
726 | if (cpu_test_and_set(cpu, cpu_initialized)) { | ||
727 | printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); | ||
728 | for (;;) local_irq_enable(); | ||
729 | } | ||
730 | |||
731 | printk(KERN_INFO "Initializing CPU#%d\n", cpu); | ||
732 | |||
733 | if (cpu_has_vme || cpu_has_tsc || cpu_has_de) | ||
734 | clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); | ||
735 | if (tsc_disable && cpu_has_tsc) { | ||
736 | printk(KERN_NOTICE "Disabling TSC...\n"); | ||
737 | /**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/ | ||
738 | clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability); | ||
739 | set_in_cr4(X86_CR4_TSD); | ||
740 | } | ||
741 | |||
665 | load_idt(&idt_descr); | 742 | load_idt(&idt_descr); |
666 | 743 | ||
667 | /* | 744 | /* |
668 | * Set up and load the per-CPU TSS and LDT | 745 | * Set up and load the per-CPU TSS and LDT |
669 | */ | 746 | */ |
670 | atomic_inc(&init_mm.mm_count); | 747 | atomic_inc(&init_mm.mm_count); |
671 | current->active_mm = &init_mm; | 748 | curr->active_mm = &init_mm; |
672 | BUG_ON(current->mm); | 749 | if (curr->mm) |
673 | enter_lazy_tlb(&init_mm, current); | 750 | BUG(); |
751 | enter_lazy_tlb(&init_mm, curr); | ||
674 | 752 | ||
675 | load_esp0(t, thread); | 753 | load_esp0(t, thread); |
676 | set_tss_desc(cpu,t); | 754 | set_tss_desc(cpu,t); |
@@ -682,8 +760,8 @@ old_gdt: | |||
682 | __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss); | 760 | __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss); |
683 | #endif | 761 | #endif |
684 | 762 | ||
685 | /* Clear %fs and %gs. */ | 763 | /* Clear %fs. */ |
686 | asm volatile ("movl %0, %%fs; movl %0, %%gs" : : "r" (0)); | 764 | asm volatile ("mov %0, %%fs" : : "r" (0)); |
687 | 765 | ||
688 | /* Clear all 6 debug registers: */ | 766 | /* Clear all 6 debug registers: */ |
689 | set_debugreg(0, 0); | 767 | set_debugreg(0, 0); |
@@ -701,6 +779,37 @@ old_gdt: | |||
701 | mxcsr_feature_mask_init(); | 779 | mxcsr_feature_mask_init(); |
702 | } | 780 | } |
703 | 781 | ||
782 | /* Entrypoint to initialize secondary CPU */ | ||
783 | void __cpuinit secondary_cpu_init(void) | ||
784 | { | ||
785 | int cpu = smp_processor_id(); | ||
786 | struct task_struct *curr = current; | ||
787 | |||
788 | _cpu_init(cpu, curr); | ||
789 | } | ||
790 | |||
791 | /* | ||
792 | * cpu_init() initializes state that is per-CPU. Some data is already | ||
793 | * initialized (naturally) in the bootstrap process, such as the GDT | ||
794 | * and IDT. We reload them nevertheless, this function acts as a | ||
795 | * 'CPU state barrier', nothing should get across. | ||
796 | */ | ||
797 | void __cpuinit cpu_init(void) | ||
798 | { | ||
799 | int cpu = smp_processor_id(); | ||
800 | struct task_struct *curr = current; | ||
801 | |||
802 | /* Set up the real GDT and PDA, so we can transition from the | ||
803 | boot versions. */ | ||
804 | if (!init_gdt(cpu, curr)) { | ||
805 | /* failed to allocate something; not much we can do... */ | ||
806 | for (;;) | ||
807 | local_irq_enable(); | ||
808 | } | ||
809 | |||
810 | _cpu_init(cpu, curr); | ||
811 | } | ||
812 | |||
704 | #ifdef CONFIG_HOTPLUG_CPU | 813 | #ifdef CONFIG_HOTPLUG_CPU |
705 | void __cpuinit cpu_uninit(void) | 814 | void __cpuinit cpu_uninit(void) |
706 | { | 815 | { |
diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c index 94a95aa5227e..56fe26584957 100644 --- a/arch/i386/kernel/cpu/intel.c +++ b/arch/i386/kernel/cpu/intel.c | |||
@@ -107,7 +107,7 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) | |||
107 | * Note that the workaround only should be initialized once... | 107 | * Note that the workaround only should be initialized once... |
108 | */ | 108 | */ |
109 | c->f00f_bug = 0; | 109 | c->f00f_bug = 0; |
110 | if ( c->x86 == 5 ) { | 110 | if (!paravirt_enabled() && c->x86 == 5) { |
111 | static int f00f_workaround_enabled = 0; | 111 | static int f00f_workaround_enabled = 0; |
112 | 112 | ||
113 | c->f00f_bug = 1; | 113 | c->f00f_bug = 1; |
@@ -195,8 +195,16 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) | |||
195 | if ((c->x86 == 0xf && c->x86_model >= 0x03) || | 195 | if ((c->x86 == 0xf && c->x86_model >= 0x03) || |
196 | (c->x86 == 0x6 && c->x86_model >= 0x0e)) | 196 | (c->x86 == 0x6 && c->x86_model >= 0x0e)) |
197 | set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability); | 197 | set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability); |
198 | } | ||
199 | 198 | ||
199 | if (cpu_has_ds) { | ||
200 | unsigned int l1; | ||
201 | rdmsr(MSR_IA32_MISC_ENABLE, l1, l2); | ||
202 | if (!(l1 & (1<<11))) | ||
203 | set_bit(X86_FEATURE_BTS, c->x86_capability); | ||
204 | if (!(l1 & (1<<12))) | ||
205 | set_bit(X86_FEATURE_PEBS, c->x86_capability); | ||
206 | } | ||
207 | } | ||
200 | 208 | ||
201 | static unsigned int __cpuinit intel_size_cache(struct cpuinfo_x86 * c, unsigned int size) | 209 | static unsigned int __cpuinit intel_size_cache(struct cpuinfo_x86 * c, unsigned int size) |
202 | { | 210 | { |
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index 5c43be47587f..80b4c5d421b1 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c | |||
@@ -480,12 +480,10 @@ static int __cpuinit detect_cache_attributes(unsigned int cpu) | |||
480 | if (num_cache_leaves == 0) | 480 | if (num_cache_leaves == 0) |
481 | return -ENOENT; | 481 | return -ENOENT; |
482 | 482 | ||
483 | cpuid4_info[cpu] = kmalloc( | 483 | cpuid4_info[cpu] = kzalloc( |
484 | sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL); | 484 | sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL); |
485 | if (unlikely(cpuid4_info[cpu] == NULL)) | 485 | if (unlikely(cpuid4_info[cpu] == NULL)) |
486 | return -ENOMEM; | 486 | return -ENOMEM; |
487 | memset(cpuid4_info[cpu], 0, | ||
488 | sizeof(struct _cpuid4_info) * num_cache_leaves); | ||
489 | 487 | ||
490 | oldmask = current->cpus_allowed; | 488 | oldmask = current->cpus_allowed; |
491 | retval = set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 489 | retval = set_cpus_allowed(current, cpumask_of_cpu(cpu)); |
@@ -658,17 +656,14 @@ static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu) | |||
658 | return -ENOENT; | 656 | return -ENOENT; |
659 | 657 | ||
660 | /* Allocate all required memory */ | 658 | /* Allocate all required memory */ |
661 | cache_kobject[cpu] = kmalloc(sizeof(struct kobject), GFP_KERNEL); | 659 | cache_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL); |
662 | if (unlikely(cache_kobject[cpu] == NULL)) | 660 | if (unlikely(cache_kobject[cpu] == NULL)) |
663 | goto err_out; | 661 | goto err_out; |
664 | memset(cache_kobject[cpu], 0, sizeof(struct kobject)); | ||
665 | 662 | ||
666 | index_kobject[cpu] = kmalloc( | 663 | index_kobject[cpu] = kzalloc( |
667 | sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL); | 664 | sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL); |
668 | if (unlikely(index_kobject[cpu] == NULL)) | 665 | if (unlikely(index_kobject[cpu] == NULL)) |
669 | goto err_out; | 666 | goto err_out; |
670 | memset(index_kobject[cpu], 0, | ||
671 | sizeof(struct _index_kobject) * num_cache_leaves); | ||
672 | 667 | ||
673 | return 0; | 668 | return 0; |
674 | 669 | ||
diff --git a/arch/i386/kernel/cpu/mcheck/non-fatal.c b/arch/i386/kernel/cpu/mcheck/non-fatal.c index 1f9153ae5b03..6b5d3518a1c0 100644 --- a/arch/i386/kernel/cpu/mcheck/non-fatal.c +++ b/arch/i386/kernel/cpu/mcheck/non-fatal.c | |||
@@ -51,10 +51,10 @@ static void mce_checkregs (void *info) | |||
51 | } | 51 | } |
52 | } | 52 | } |
53 | 53 | ||
54 | static void mce_work_fn(void *data); | 54 | static void mce_work_fn(struct work_struct *work); |
55 | static DECLARE_WORK(mce_work, mce_work_fn, NULL); | 55 | static DECLARE_DELAYED_WORK(mce_work, mce_work_fn); |
56 | 56 | ||
57 | static void mce_work_fn(void *data) | 57 | static void mce_work_fn(struct work_struct *work) |
58 | { | 58 | { |
59 | on_each_cpu(mce_checkregs, NULL, 1, 1); | 59 | on_each_cpu(mce_checkregs, NULL, 1, 1); |
60 | schedule_delayed_work(&mce_work, MCE_RATE); | 60 | schedule_delayed_work(&mce_work, MCE_RATE); |
diff --git a/arch/i386/kernel/cpu/mcheck/therm_throt.c b/arch/i386/kernel/cpu/mcheck/therm_throt.c index 2d8703b7ce65..065005c3f168 100644 --- a/arch/i386/kernel/cpu/mcheck/therm_throt.c +++ b/arch/i386/kernel/cpu/mcheck/therm_throt.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/cpu.h> | 20 | #include <linux/cpu.h> |
21 | #include <asm/cpu.h> | 21 | #include <asm/cpu.h> |
22 | #include <linux/notifier.h> | 22 | #include <linux/notifier.h> |
23 | #include <linux/jiffies.h> | ||
23 | #include <asm/therm_throt.h> | 24 | #include <asm/therm_throt.h> |
24 | 25 | ||
25 | /* How long to wait between reporting thermal events */ | 26 | /* How long to wait between reporting thermal events */ |
@@ -115,7 +116,6 @@ static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev) | |||
115 | return sysfs_create_group(&sys_dev->kobj, &thermal_throttle_attr_group); | 116 | return sysfs_create_group(&sys_dev->kobj, &thermal_throttle_attr_group); |
116 | } | 117 | } |
117 | 118 | ||
118 | #ifdef CONFIG_HOTPLUG_CPU | ||
119 | static __cpuinit void thermal_throttle_remove_dev(struct sys_device *sys_dev) | 119 | static __cpuinit void thermal_throttle_remove_dev(struct sys_device *sys_dev) |
120 | { | 120 | { |
121 | return sysfs_remove_group(&sys_dev->kobj, &thermal_throttle_attr_group); | 121 | return sysfs_remove_group(&sys_dev->kobj, &thermal_throttle_attr_group); |
@@ -152,7 +152,6 @@ static struct notifier_block thermal_throttle_cpu_notifier = | |||
152 | { | 152 | { |
153 | .notifier_call = thermal_throttle_cpu_callback, | 153 | .notifier_call = thermal_throttle_cpu_callback, |
154 | }; | 154 | }; |
155 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
156 | 155 | ||
157 | static __init int thermal_throttle_init_device(void) | 156 | static __init int thermal_throttle_init_device(void) |
158 | { | 157 | { |
diff --git a/arch/i386/kernel/cpu/mtrr/Makefile b/arch/i386/kernel/cpu/mtrr/Makefile index a25b701ab84e..191fc0533649 100644 --- a/arch/i386/kernel/cpu/mtrr/Makefile +++ b/arch/i386/kernel/cpu/mtrr/Makefile | |||
@@ -1,5 +1,3 @@ | |||
1 | obj-y := main.o if.o generic.o state.o | 1 | obj-y := main.o if.o generic.o state.o |
2 | obj-y += amd.o | 2 | obj-$(CONFIG_X86_32) += amd.o cyrix.o centaur.o |
3 | obj-y += cyrix.o | ||
4 | obj-y += centaur.o | ||
5 | 3 | ||
diff --git a/arch/i386/kernel/cpu/mtrr/amd.c b/arch/i386/kernel/cpu/mtrr/amd.c index 1a1e04b6fd00..0949cdbf848a 100644 --- a/arch/i386/kernel/cpu/mtrr/amd.c +++ b/arch/i386/kernel/cpu/mtrr/amd.c | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | static void | 8 | static void |
9 | amd_get_mtrr(unsigned int reg, unsigned long *base, | 9 | amd_get_mtrr(unsigned int reg, unsigned long *base, |
10 | unsigned int *size, mtrr_type * type) | 10 | unsigned long *size, mtrr_type * type) |
11 | { | 11 | { |
12 | unsigned long low, high; | 12 | unsigned long low, high; |
13 | 13 | ||
diff --git a/arch/i386/kernel/cpu/mtrr/centaur.c b/arch/i386/kernel/cpu/mtrr/centaur.c index 33f00ac314ef..cb9aa3a7a7ab 100644 --- a/arch/i386/kernel/cpu/mtrr/centaur.c +++ b/arch/i386/kernel/cpu/mtrr/centaur.c | |||
@@ -17,7 +17,7 @@ static u8 centaur_mcr_type; /* 0 for winchip, 1 for winchip2 */ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | static int | 19 | static int |
20 | centaur_get_free_region(unsigned long base, unsigned long size) | 20 | centaur_get_free_region(unsigned long base, unsigned long size, int replace_reg) |
21 | /* [SUMMARY] Get a free MTRR. | 21 | /* [SUMMARY] Get a free MTRR. |
22 | <base> The starting (base) address of the region. | 22 | <base> The starting (base) address of the region. |
23 | <size> The size (in bytes) of the region. | 23 | <size> The size (in bytes) of the region. |
@@ -26,10 +26,11 @@ centaur_get_free_region(unsigned long base, unsigned long size) | |||
26 | { | 26 | { |
27 | int i, max; | 27 | int i, max; |
28 | mtrr_type ltype; | 28 | mtrr_type ltype; |
29 | unsigned long lbase; | 29 | unsigned long lbase, lsize; |
30 | unsigned int lsize; | ||
31 | 30 | ||
32 | max = num_var_ranges; | 31 | max = num_var_ranges; |
32 | if (replace_reg >= 0 && replace_reg < max) | ||
33 | return replace_reg; | ||
33 | for (i = 0; i < max; ++i) { | 34 | for (i = 0; i < max; ++i) { |
34 | if (centaur_mcr_reserved & (1 << i)) | 35 | if (centaur_mcr_reserved & (1 << i)) |
35 | continue; | 36 | continue; |
@@ -49,7 +50,7 @@ mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) | |||
49 | 50 | ||
50 | static void | 51 | static void |
51 | centaur_get_mcr(unsigned int reg, unsigned long *base, | 52 | centaur_get_mcr(unsigned int reg, unsigned long *base, |
52 | unsigned int *size, mtrr_type * type) | 53 | unsigned long *size, mtrr_type * type) |
53 | { | 54 | { |
54 | *base = centaur_mcr[reg].high >> PAGE_SHIFT; | 55 | *base = centaur_mcr[reg].high >> PAGE_SHIFT; |
55 | *size = -(centaur_mcr[reg].low & 0xfffff000) >> PAGE_SHIFT; | 56 | *size = -(centaur_mcr[reg].low & 0xfffff000) >> PAGE_SHIFT; |
diff --git a/arch/i386/kernel/cpu/mtrr/cyrix.c b/arch/i386/kernel/cpu/mtrr/cyrix.c index 9027a987006b..0737a596db43 100644 --- a/arch/i386/kernel/cpu/mtrr/cyrix.c +++ b/arch/i386/kernel/cpu/mtrr/cyrix.c | |||
@@ -9,7 +9,7 @@ int arr3_protected; | |||
9 | 9 | ||
10 | static void | 10 | static void |
11 | cyrix_get_arr(unsigned int reg, unsigned long *base, | 11 | cyrix_get_arr(unsigned int reg, unsigned long *base, |
12 | unsigned int *size, mtrr_type * type) | 12 | unsigned long *size, mtrr_type * type) |
13 | { | 13 | { |
14 | unsigned long flags; | 14 | unsigned long flags; |
15 | unsigned char arr, ccr3, rcr, shift; | 15 | unsigned char arr, ccr3, rcr, shift; |
@@ -77,7 +77,7 @@ cyrix_get_arr(unsigned int reg, unsigned long *base, | |||
77 | } | 77 | } |
78 | 78 | ||
79 | static int | 79 | static int |
80 | cyrix_get_free_region(unsigned long base, unsigned long size) | 80 | cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg) |
81 | /* [SUMMARY] Get a free ARR. | 81 | /* [SUMMARY] Get a free ARR. |
82 | <base> The starting (base) address of the region. | 82 | <base> The starting (base) address of the region. |
83 | <size> The size (in bytes) of the region. | 83 | <size> The size (in bytes) of the region. |
@@ -86,9 +86,24 @@ cyrix_get_free_region(unsigned long base, unsigned long size) | |||
86 | { | 86 | { |
87 | int i; | 87 | int i; |
88 | mtrr_type ltype; | 88 | mtrr_type ltype; |
89 | unsigned long lbase; | 89 | unsigned long lbase, lsize; |
90 | unsigned int lsize; | ||
91 | 90 | ||
91 | switch (replace_reg) { | ||
92 | case 7: | ||
93 | if (size < 0x40) | ||
94 | break; | ||
95 | case 6: | ||
96 | case 5: | ||
97 | case 4: | ||
98 | return replace_reg; | ||
99 | case 3: | ||
100 | if (arr3_protected) | ||
101 | break; | ||
102 | case 2: | ||
103 | case 1: | ||
104 | case 0: | ||
105 | return replace_reg; | ||
106 | } | ||
92 | /* If we are to set up a region >32M then look at ARR7 immediately */ | 107 | /* If we are to set up a region >32M then look at ARR7 immediately */ |
93 | if (size > 0x2000) { | 108 | if (size > 0x2000) { |
94 | cyrix_get_arr(7, &lbase, &lsize, <ype); | 109 | cyrix_get_arr(7, &lbase, &lsize, <ype); |
@@ -214,7 +229,7 @@ static void cyrix_set_arr(unsigned int reg, unsigned long base, | |||
214 | 229 | ||
215 | typedef struct { | 230 | typedef struct { |
216 | unsigned long base; | 231 | unsigned long base; |
217 | unsigned int size; | 232 | unsigned long size; |
218 | mtrr_type type; | 233 | mtrr_type type; |
219 | } arr_state_t; | 234 | } arr_state_t; |
220 | 235 | ||
diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c index 0b61eed8bbd8..f77fc53db654 100644 --- a/arch/i386/kernel/cpu/mtrr/generic.c +++ b/arch/i386/kernel/cpu/mtrr/generic.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/init.h> | 3 | #include <linux/init.h> |
4 | #include <linux/slab.h> | 4 | #include <linux/slab.h> |
5 | #include <linux/mm.h> | 5 | #include <linux/mm.h> |
6 | #include <linux/module.h> | ||
6 | #include <asm/io.h> | 7 | #include <asm/io.h> |
7 | #include <asm/mtrr.h> | 8 | #include <asm/mtrr.h> |
8 | #include <asm/msr.h> | 9 | #include <asm/msr.h> |
@@ -15,12 +16,19 @@ struct mtrr_state { | |||
15 | struct mtrr_var_range *var_ranges; | 16 | struct mtrr_var_range *var_ranges; |
16 | mtrr_type fixed_ranges[NUM_FIXED_RANGES]; | 17 | mtrr_type fixed_ranges[NUM_FIXED_RANGES]; |
17 | unsigned char enabled; | 18 | unsigned char enabled; |
19 | unsigned char have_fixed; | ||
18 | mtrr_type def_type; | 20 | mtrr_type def_type; |
19 | }; | 21 | }; |
20 | 22 | ||
21 | static unsigned long smp_changes_mask; | 23 | static unsigned long smp_changes_mask; |
22 | static struct mtrr_state mtrr_state = {}; | 24 | static struct mtrr_state mtrr_state = {}; |
23 | 25 | ||
26 | #undef MODULE_PARAM_PREFIX | ||
27 | #define MODULE_PARAM_PREFIX "mtrr." | ||
28 | |||
29 | static __initdata int mtrr_show; | ||
30 | module_param_named(show, mtrr_show, bool, 0); | ||
31 | |||
24 | /* Get the MSR pair relating to a var range */ | 32 | /* Get the MSR pair relating to a var range */ |
25 | static void __init | 33 | static void __init |
26 | get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr) | 34 | get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr) |
@@ -43,6 +51,14 @@ get_fixed_ranges(mtrr_type * frs) | |||
43 | rdmsr(MTRRfix4K_C0000_MSR + i, p[6 + i * 2], p[7 + i * 2]); | 51 | rdmsr(MTRRfix4K_C0000_MSR + i, p[6 + i * 2], p[7 + i * 2]); |
44 | } | 52 | } |
45 | 53 | ||
54 | static void __init print_fixed(unsigned base, unsigned step, const mtrr_type*types) | ||
55 | { | ||
56 | unsigned i; | ||
57 | |||
58 | for (i = 0; i < 8; ++i, ++types, base += step) | ||
59 | printk(KERN_INFO "MTRR %05X-%05X %s\n", base, base + step - 1, mtrr_attrib_to_str(*types)); | ||
60 | } | ||
61 | |||
46 | /* Grab all of the MTRR state for this CPU into *state */ | 62 | /* Grab all of the MTRR state for this CPU into *state */ |
47 | void __init get_mtrr_state(void) | 63 | void __init get_mtrr_state(void) |
48 | { | 64 | { |
@@ -58,13 +74,49 @@ void __init get_mtrr_state(void) | |||
58 | } | 74 | } |
59 | vrs = mtrr_state.var_ranges; | 75 | vrs = mtrr_state.var_ranges; |
60 | 76 | ||
77 | rdmsr(MTRRcap_MSR, lo, dummy); | ||
78 | mtrr_state.have_fixed = (lo >> 8) & 1; | ||
79 | |||
61 | for (i = 0; i < num_var_ranges; i++) | 80 | for (i = 0; i < num_var_ranges; i++) |
62 | get_mtrr_var_range(i, &vrs[i]); | 81 | get_mtrr_var_range(i, &vrs[i]); |
63 | get_fixed_ranges(mtrr_state.fixed_ranges); | 82 | if (mtrr_state.have_fixed) |
83 | get_fixed_ranges(mtrr_state.fixed_ranges); | ||
64 | 84 | ||
65 | rdmsr(MTRRdefType_MSR, lo, dummy); | 85 | rdmsr(MTRRdefType_MSR, lo, dummy); |
66 | mtrr_state.def_type = (lo & 0xff); | 86 | mtrr_state.def_type = (lo & 0xff); |
67 | mtrr_state.enabled = (lo & 0xc00) >> 10; | 87 | mtrr_state.enabled = (lo & 0xc00) >> 10; |
88 | |||
89 | if (mtrr_show) { | ||
90 | int high_width; | ||
91 | |||
92 | printk(KERN_INFO "MTRR default type: %s\n", mtrr_attrib_to_str(mtrr_state.def_type)); | ||
93 | if (mtrr_state.have_fixed) { | ||
94 | printk(KERN_INFO "MTRR fixed ranges %sabled:\n", | ||
95 | mtrr_state.enabled & 1 ? "en" : "dis"); | ||
96 | print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0); | ||
97 | for (i = 0; i < 2; ++i) | ||
98 | print_fixed(0x80000 + i * 0x20000, 0x04000, mtrr_state.fixed_ranges + (i + 1) * 8); | ||
99 | for (i = 0; i < 8; ++i) | ||
100 | print_fixed(0xC0000 + i * 0x08000, 0x01000, mtrr_state.fixed_ranges + (i + 3) * 8); | ||
101 | } | ||
102 | printk(KERN_INFO "MTRR variable ranges %sabled:\n", | ||
103 | mtrr_state.enabled & 2 ? "en" : "dis"); | ||
104 | high_width = ((size_or_mask ? ffs(size_or_mask) - 1 : 32) - (32 - PAGE_SHIFT) + 3) / 4; | ||
105 | for (i = 0; i < num_var_ranges; ++i) { | ||
106 | if (mtrr_state.var_ranges[i].mask_lo & (1 << 11)) | ||
107 | printk(KERN_INFO "MTRR %u base %0*X%05X000 mask %0*X%05X000 %s\n", | ||
108 | i, | ||
109 | high_width, | ||
110 | mtrr_state.var_ranges[i].base_hi, | ||
111 | mtrr_state.var_ranges[i].base_lo >> 12, | ||
112 | high_width, | ||
113 | mtrr_state.var_ranges[i].mask_hi, | ||
114 | mtrr_state.var_ranges[i].mask_lo >> 12, | ||
115 | mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff)); | ||
116 | else | ||
117 | printk(KERN_INFO "MTRR %u disabled\n", i); | ||
118 | } | ||
119 | } | ||
68 | } | 120 | } |
69 | 121 | ||
70 | /* Some BIOS's are fucked and don't set all MTRRs the same! */ | 122 | /* Some BIOS's are fucked and don't set all MTRRs the same! */ |
@@ -95,7 +147,7 @@ void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b) | |||
95 | smp_processor_id(), msr, a, b); | 147 | smp_processor_id(), msr, a, b); |
96 | } | 148 | } |
97 | 149 | ||
98 | int generic_get_free_region(unsigned long base, unsigned long size) | 150 | int generic_get_free_region(unsigned long base, unsigned long size, int replace_reg) |
99 | /* [SUMMARY] Get a free MTRR. | 151 | /* [SUMMARY] Get a free MTRR. |
100 | <base> The starting (base) address of the region. | 152 | <base> The starting (base) address of the region. |
101 | <size> The size (in bytes) of the region. | 153 | <size> The size (in bytes) of the region. |
@@ -104,10 +156,11 @@ int generic_get_free_region(unsigned long base, unsigned long size) | |||
104 | { | 156 | { |
105 | int i, max; | 157 | int i, max; |
106 | mtrr_type ltype; | 158 | mtrr_type ltype; |
107 | unsigned long lbase; | 159 | unsigned long lbase, lsize; |
108 | unsigned lsize; | ||
109 | 160 | ||
110 | max = num_var_ranges; | 161 | max = num_var_ranges; |
162 | if (replace_reg >= 0 && replace_reg < max) | ||
163 | return replace_reg; | ||
111 | for (i = 0; i < max; ++i) { | 164 | for (i = 0; i < max; ++i) { |
112 | mtrr_if->get(i, &lbase, &lsize, <ype); | 165 | mtrr_if->get(i, &lbase, &lsize, <ype); |
113 | if (lsize == 0) | 166 | if (lsize == 0) |
@@ -117,7 +170,7 @@ int generic_get_free_region(unsigned long base, unsigned long size) | |||
117 | } | 170 | } |
118 | 171 | ||
119 | static void generic_get_mtrr(unsigned int reg, unsigned long *base, | 172 | static void generic_get_mtrr(unsigned int reg, unsigned long *base, |
120 | unsigned int *size, mtrr_type * type) | 173 | unsigned long *size, mtrr_type *type) |
121 | { | 174 | { |
122 | unsigned int mask_lo, mask_hi, base_lo, base_hi; | 175 | unsigned int mask_lo, mask_hi, base_lo, base_hi; |
123 | 176 | ||
@@ -202,7 +255,9 @@ static int set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr) | |||
202 | return changed; | 255 | return changed; |
203 | } | 256 | } |
204 | 257 | ||
205 | static unsigned long set_mtrr_state(u32 deftype_lo, u32 deftype_hi) | 258 | static u32 deftype_lo, deftype_hi; |
259 | |||
260 | static unsigned long set_mtrr_state(void) | ||
206 | /* [SUMMARY] Set the MTRR state for this CPU. | 261 | /* [SUMMARY] Set the MTRR state for this CPU. |
207 | <state> The MTRR state information to read. | 262 | <state> The MTRR state information to read. |
208 | <ctxt> Some relevant CPU context. | 263 | <ctxt> Some relevant CPU context. |
@@ -217,14 +272,14 @@ static unsigned long set_mtrr_state(u32 deftype_lo, u32 deftype_hi) | |||
217 | if (set_mtrr_var_ranges(i, &mtrr_state.var_ranges[i])) | 272 | if (set_mtrr_var_ranges(i, &mtrr_state.var_ranges[i])) |
218 | change_mask |= MTRR_CHANGE_MASK_VARIABLE; | 273 | change_mask |= MTRR_CHANGE_MASK_VARIABLE; |
219 | 274 | ||
220 | if (set_fixed_ranges(mtrr_state.fixed_ranges)) | 275 | if (mtrr_state.have_fixed && set_fixed_ranges(mtrr_state.fixed_ranges)) |
221 | change_mask |= MTRR_CHANGE_MASK_FIXED; | 276 | change_mask |= MTRR_CHANGE_MASK_FIXED; |
222 | 277 | ||
223 | /* Set_mtrr_restore restores the old value of MTRRdefType, | 278 | /* Set_mtrr_restore restores the old value of MTRRdefType, |
224 | so to set it we fiddle with the saved value */ | 279 | so to set it we fiddle with the saved value */ |
225 | if ((deftype_lo & 0xff) != mtrr_state.def_type | 280 | if ((deftype_lo & 0xff) != mtrr_state.def_type |
226 | || ((deftype_lo & 0xc00) >> 10) != mtrr_state.enabled) { | 281 | || ((deftype_lo & 0xc00) >> 10) != mtrr_state.enabled) { |
227 | deftype_lo |= (mtrr_state.def_type | mtrr_state.enabled << 10); | 282 | deftype_lo = (deftype_lo & ~0xcff) | mtrr_state.def_type | (mtrr_state.enabled << 10); |
228 | change_mask |= MTRR_CHANGE_MASK_DEFTYPE; | 283 | change_mask |= MTRR_CHANGE_MASK_DEFTYPE; |
229 | } | 284 | } |
230 | 285 | ||
@@ -233,7 +288,6 @@ static unsigned long set_mtrr_state(u32 deftype_lo, u32 deftype_hi) | |||
233 | 288 | ||
234 | 289 | ||
235 | static unsigned long cr4 = 0; | 290 | static unsigned long cr4 = 0; |
236 | static u32 deftype_lo, deftype_hi; | ||
237 | static DEFINE_SPINLOCK(set_atomicity_lock); | 291 | static DEFINE_SPINLOCK(set_atomicity_lock); |
238 | 292 | ||
239 | /* | 293 | /* |
@@ -271,7 +325,7 @@ static void prepare_set(void) __acquires(set_atomicity_lock) | |||
271 | rdmsr(MTRRdefType_MSR, deftype_lo, deftype_hi); | 325 | rdmsr(MTRRdefType_MSR, deftype_lo, deftype_hi); |
272 | 326 | ||
273 | /* Disable MTRRs, and set the default type to uncached */ | 327 | /* Disable MTRRs, and set the default type to uncached */ |
274 | mtrr_wrmsr(MTRRdefType_MSR, deftype_lo & 0xf300UL, deftype_hi); | 328 | mtrr_wrmsr(MTRRdefType_MSR, deftype_lo & ~0xcff, deftype_hi); |
275 | } | 329 | } |
276 | 330 | ||
277 | static void post_set(void) __releases(set_atomicity_lock) | 331 | static void post_set(void) __releases(set_atomicity_lock) |
@@ -300,7 +354,7 @@ static void generic_set_all(void) | |||
300 | prepare_set(); | 354 | prepare_set(); |
301 | 355 | ||
302 | /* Actually set the state */ | 356 | /* Actually set the state */ |
303 | mask = set_mtrr_state(deftype_lo,deftype_hi); | 357 | mask = set_mtrr_state(); |
304 | 358 | ||
305 | post_set(); | 359 | post_set(); |
306 | local_irq_restore(flags); | 360 | local_irq_restore(flags); |
@@ -366,7 +420,7 @@ int generic_validate_add_page(unsigned long base, unsigned long size, unsigned i | |||
366 | printk(KERN_WARNING "mtrr: base(0x%lx000) is not 4 MiB aligned\n", base); | 420 | printk(KERN_WARNING "mtrr: base(0x%lx000) is not 4 MiB aligned\n", base); |
367 | return -EINVAL; | 421 | return -EINVAL; |
368 | } | 422 | } |
369 | if (!(base + size < 0x70000000 || base > 0x7003FFFF) && | 423 | if (!(base + size < 0x70000 || base > 0x7003F) && |
370 | (type == MTRR_TYPE_WRCOMB | 424 | (type == MTRR_TYPE_WRCOMB |
371 | || type == MTRR_TYPE_WRBACK)) { | 425 | || type == MTRR_TYPE_WRBACK)) { |
372 | printk(KERN_WARNING "mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n"); | 426 | printk(KERN_WARNING "mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n"); |
diff --git a/arch/i386/kernel/cpu/mtrr/if.c b/arch/i386/kernel/cpu/mtrr/if.c index 5ac051bb9d55..5ae1705eafa6 100644 --- a/arch/i386/kernel/cpu/mtrr/if.c +++ b/arch/i386/kernel/cpu/mtrr/if.c | |||
@@ -17,7 +17,7 @@ extern unsigned int *usage_table; | |||
17 | 17 | ||
18 | #define FILE_FCOUNT(f) (((struct seq_file *)((f)->private_data))->private) | 18 | #define FILE_FCOUNT(f) (((struct seq_file *)((f)->private_data))->private) |
19 | 19 | ||
20 | static char *mtrr_strings[MTRR_NUM_TYPES] = | 20 | static const char *const mtrr_strings[MTRR_NUM_TYPES] = |
21 | { | 21 | { |
22 | "uncachable", /* 0 */ | 22 | "uncachable", /* 0 */ |
23 | "write-combining", /* 1 */ | 23 | "write-combining", /* 1 */ |
@@ -28,7 +28,7 @@ static char *mtrr_strings[MTRR_NUM_TYPES] = | |||
28 | "write-back", /* 6 */ | 28 | "write-back", /* 6 */ |
29 | }; | 29 | }; |
30 | 30 | ||
31 | char *mtrr_attrib_to_str(int x) | 31 | const char *mtrr_attrib_to_str(int x) |
32 | { | 32 | { |
33 | return (x <= 6) ? mtrr_strings[x] : "?"; | 33 | return (x <= 6) ? mtrr_strings[x] : "?"; |
34 | } | 34 | } |
@@ -44,10 +44,9 @@ mtrr_file_add(unsigned long base, unsigned long size, | |||
44 | 44 | ||
45 | max = num_var_ranges; | 45 | max = num_var_ranges; |
46 | if (fcount == NULL) { | 46 | if (fcount == NULL) { |
47 | fcount = kmalloc(max * sizeof *fcount, GFP_KERNEL); | 47 | fcount = kzalloc(max * sizeof *fcount, GFP_KERNEL); |
48 | if (!fcount) | 48 | if (!fcount) |
49 | return -ENOMEM; | 49 | return -ENOMEM; |
50 | memset(fcount, 0, max * sizeof *fcount); | ||
51 | FILE_FCOUNT(file) = fcount; | 50 | FILE_FCOUNT(file) = fcount; |
52 | } | 51 | } |
53 | if (!page) { | 52 | if (!page) { |
@@ -155,6 +154,7 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) | |||
155 | { | 154 | { |
156 | int err = 0; | 155 | int err = 0; |
157 | mtrr_type type; | 156 | mtrr_type type; |
157 | unsigned long size; | ||
158 | struct mtrr_sentry sentry; | 158 | struct mtrr_sentry sentry; |
159 | struct mtrr_gentry gentry; | 159 | struct mtrr_gentry gentry; |
160 | void __user *arg = (void __user *) __arg; | 160 | void __user *arg = (void __user *) __arg; |
@@ -235,15 +235,15 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) | |||
235 | case MTRRIOC_GET_ENTRY: | 235 | case MTRRIOC_GET_ENTRY: |
236 | if (gentry.regnum >= num_var_ranges) | 236 | if (gentry.regnum >= num_var_ranges) |
237 | return -EINVAL; | 237 | return -EINVAL; |
238 | mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type); | 238 | mtrr_if->get(gentry.regnum, &gentry.base, &size, &type); |
239 | 239 | ||
240 | /* Hide entries that go above 4GB */ | 240 | /* Hide entries that go above 4GB */ |
241 | if (gentry.base + gentry.size > 0x100000 | 241 | if (gentry.base + size - 1 >= (1UL << (8 * sizeof(gentry.size) - PAGE_SHIFT)) |
242 | || gentry.size == 0x100000) | 242 | || size >= (1UL << (8 * sizeof(gentry.size) - PAGE_SHIFT))) |
243 | gentry.base = gentry.size = gentry.type = 0; | 243 | gentry.base = gentry.size = gentry.type = 0; |
244 | else { | 244 | else { |
245 | gentry.base <<= PAGE_SHIFT; | 245 | gentry.base <<= PAGE_SHIFT; |
246 | gentry.size <<= PAGE_SHIFT; | 246 | gentry.size = size << PAGE_SHIFT; |
247 | gentry.type = type; | 247 | gentry.type = type; |
248 | } | 248 | } |
249 | 249 | ||
@@ -273,8 +273,14 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) | |||
273 | case MTRRIOC_GET_PAGE_ENTRY: | 273 | case MTRRIOC_GET_PAGE_ENTRY: |
274 | if (gentry.regnum >= num_var_ranges) | 274 | if (gentry.regnum >= num_var_ranges) |
275 | return -EINVAL; | 275 | return -EINVAL; |
276 | mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type); | 276 | mtrr_if->get(gentry.regnum, &gentry.base, &size, &type); |
277 | gentry.type = type; | 277 | /* Hide entries that would overflow */ |
278 | if (size != (__typeof__(gentry.size))size) | ||
279 | gentry.base = gentry.size = gentry.type = 0; | ||
280 | else { | ||
281 | gentry.size = size; | ||
282 | gentry.type = type; | ||
283 | } | ||
278 | break; | 284 | break; |
279 | } | 285 | } |
280 | 286 | ||
@@ -353,8 +359,7 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset) | |||
353 | char factor; | 359 | char factor; |
354 | int i, max, len; | 360 | int i, max, len; |
355 | mtrr_type type; | 361 | mtrr_type type; |
356 | unsigned long base; | 362 | unsigned long base, size; |
357 | unsigned int size; | ||
358 | 363 | ||
359 | len = 0; | 364 | len = 0; |
360 | max = num_var_ranges; | 365 | max = num_var_ranges; |
@@ -373,7 +378,7 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset) | |||
373 | } | 378 | } |
374 | /* RED-PEN: base can be > 32bit */ | 379 | /* RED-PEN: base can be > 32bit */ |
375 | len += seq_printf(seq, | 380 | len += seq_printf(seq, |
376 | "reg%02i: base=0x%05lx000 (%4liMB), size=%4i%cB: %s, count=%d\n", | 381 | "reg%02i: base=0x%05lx000 (%4luMB), size=%4lu%cB: %s, count=%d\n", |
377 | i, base, base >> (20 - PAGE_SHIFT), size, factor, | 382 | i, base, base >> (20 - PAGE_SHIFT), size, factor, |
378 | mtrr_attrib_to_str(type), usage_table[i]); | 383 | mtrr_attrib_to_str(type), usage_table[i]); |
379 | } | 384 | } |
diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index fff90bda4733..16bb7ea87145 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c | |||
@@ -59,7 +59,11 @@ struct mtrr_ops * mtrr_if = NULL; | |||
59 | static void set_mtrr(unsigned int reg, unsigned long base, | 59 | static void set_mtrr(unsigned int reg, unsigned long base, |
60 | unsigned long size, mtrr_type type); | 60 | unsigned long size, mtrr_type type); |
61 | 61 | ||
62 | #ifndef CONFIG_X86_64 | ||
62 | extern int arr3_protected; | 63 | extern int arr3_protected; |
64 | #else | ||
65 | #define arr3_protected 0 | ||
66 | #endif | ||
63 | 67 | ||
64 | void set_mtrr_ops(struct mtrr_ops * ops) | 68 | void set_mtrr_ops(struct mtrr_ops * ops) |
65 | { | 69 | { |
@@ -168,6 +172,13 @@ static void ipi_handler(void *info) | |||
168 | 172 | ||
169 | #endif | 173 | #endif |
170 | 174 | ||
175 | static inline int types_compatible(mtrr_type type1, mtrr_type type2) { | ||
176 | return type1 == MTRR_TYPE_UNCACHABLE || | ||
177 | type2 == MTRR_TYPE_UNCACHABLE || | ||
178 | (type1 == MTRR_TYPE_WRTHROUGH && type2 == MTRR_TYPE_WRBACK) || | ||
179 | (type1 == MTRR_TYPE_WRBACK && type2 == MTRR_TYPE_WRTHROUGH); | ||
180 | } | ||
181 | |||
171 | /** | 182 | /** |
172 | * set_mtrr - update mtrrs on all processors | 183 | * set_mtrr - update mtrrs on all processors |
173 | * @reg: mtrr in question | 184 | * @reg: mtrr in question |
@@ -263,8 +274,8 @@ static void set_mtrr(unsigned int reg, unsigned long base, | |||
263 | 274 | ||
264 | /** | 275 | /** |
265 | * mtrr_add_page - Add a memory type region | 276 | * mtrr_add_page - Add a memory type region |
266 | * @base: Physical base address of region in pages (4 KB) | 277 | * @base: Physical base address of region in pages (in units of 4 kB!) |
267 | * @size: Physical size of region in pages (4 KB) | 278 | * @size: Physical size of region in pages (4 kB) |
268 | * @type: Type of MTRR desired | 279 | * @type: Type of MTRR desired |
269 | * @increment: If this is true do usage counting on the region | 280 | * @increment: If this is true do usage counting on the region |
270 | * | 281 | * |
@@ -300,11 +311,9 @@ static void set_mtrr(unsigned int reg, unsigned long base, | |||
300 | int mtrr_add_page(unsigned long base, unsigned long size, | 311 | int mtrr_add_page(unsigned long base, unsigned long size, |
301 | unsigned int type, char increment) | 312 | unsigned int type, char increment) |
302 | { | 313 | { |
303 | int i; | 314 | int i, replace, error; |
304 | mtrr_type ltype; | 315 | mtrr_type ltype; |
305 | unsigned long lbase; | 316 | unsigned long lbase, lsize; |
306 | unsigned int lsize; | ||
307 | int error; | ||
308 | 317 | ||
309 | if (!mtrr_if) | 318 | if (!mtrr_if) |
310 | return -ENXIO; | 319 | return -ENXIO; |
@@ -324,12 +333,18 @@ int mtrr_add_page(unsigned long base, unsigned long size, | |||
324 | return -ENOSYS; | 333 | return -ENOSYS; |
325 | } | 334 | } |
326 | 335 | ||
336 | if (!size) { | ||
337 | printk(KERN_WARNING "mtrr: zero sized request\n"); | ||
338 | return -EINVAL; | ||
339 | } | ||
340 | |||
327 | if (base & size_or_mask || size & size_or_mask) { | 341 | if (base & size_or_mask || size & size_or_mask) { |
328 | printk(KERN_WARNING "mtrr: base or size exceeds the MTRR width\n"); | 342 | printk(KERN_WARNING "mtrr: base or size exceeds the MTRR width\n"); |
329 | return -EINVAL; | 343 | return -EINVAL; |
330 | } | 344 | } |
331 | 345 | ||
332 | error = -EINVAL; | 346 | error = -EINVAL; |
347 | replace = -1; | ||
333 | 348 | ||
334 | /* No CPU hotplug when we change MTRR entries */ | 349 | /* No CPU hotplug when we change MTRR entries */ |
335 | lock_cpu_hotplug(); | 350 | lock_cpu_hotplug(); |
@@ -337,21 +352,28 @@ int mtrr_add_page(unsigned long base, unsigned long size, | |||
337 | mutex_lock(&mtrr_mutex); | 352 | mutex_lock(&mtrr_mutex); |
338 | for (i = 0; i < num_var_ranges; ++i) { | 353 | for (i = 0; i < num_var_ranges; ++i) { |
339 | mtrr_if->get(i, &lbase, &lsize, <ype); | 354 | mtrr_if->get(i, &lbase, &lsize, <ype); |
340 | if (base >= lbase + lsize) | 355 | if (!lsize || base > lbase + lsize - 1 || base + size - 1 < lbase) |
341 | continue; | ||
342 | if ((base < lbase) && (base + size <= lbase)) | ||
343 | continue; | 356 | continue; |
344 | /* At this point we know there is some kind of overlap/enclosure */ | 357 | /* At this point we know there is some kind of overlap/enclosure */ |
345 | if ((base < lbase) || (base + size > lbase + lsize)) { | 358 | if (base < lbase || base + size - 1 > lbase + lsize - 1) { |
359 | if (base <= lbase && base + size - 1 >= lbase + lsize - 1) { | ||
360 | /* New region encloses an existing region */ | ||
361 | if (type == ltype) { | ||
362 | replace = replace == -1 ? i : -2; | ||
363 | continue; | ||
364 | } | ||
365 | else if (types_compatible(type, ltype)) | ||
366 | continue; | ||
367 | } | ||
346 | printk(KERN_WARNING | 368 | printk(KERN_WARNING |
347 | "mtrr: 0x%lx000,0x%lx000 overlaps existing" | 369 | "mtrr: 0x%lx000,0x%lx000 overlaps existing" |
348 | " 0x%lx000,0x%x000\n", base, size, lbase, | 370 | " 0x%lx000,0x%lx000\n", base, size, lbase, |
349 | lsize); | 371 | lsize); |
350 | goto out; | 372 | goto out; |
351 | } | 373 | } |
352 | /* New region is enclosed by an existing region */ | 374 | /* New region is enclosed by an existing region */ |
353 | if (ltype != type) { | 375 | if (ltype != type) { |
354 | if (type == MTRR_TYPE_UNCACHABLE) | 376 | if (types_compatible(type, ltype)) |
355 | continue; | 377 | continue; |
356 | printk (KERN_WARNING "mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n", | 378 | printk (KERN_WARNING "mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n", |
357 | base, size, mtrr_attrib_to_str(ltype), | 379 | base, size, mtrr_attrib_to_str(ltype), |
@@ -364,10 +386,18 @@ int mtrr_add_page(unsigned long base, unsigned long size, | |||
364 | goto out; | 386 | goto out; |
365 | } | 387 | } |
366 | /* Search for an empty MTRR */ | 388 | /* Search for an empty MTRR */ |
367 | i = mtrr_if->get_free_region(base, size); | 389 | i = mtrr_if->get_free_region(base, size, replace); |
368 | if (i >= 0) { | 390 | if (i >= 0) { |
369 | set_mtrr(i, base, size, type); | 391 | set_mtrr(i, base, size, type); |
370 | usage_table[i] = 1; | 392 | if (likely(replace < 0)) |
393 | usage_table[i] = 1; | ||
394 | else { | ||
395 | usage_table[i] = usage_table[replace] + !!increment; | ||
396 | if (unlikely(replace != i)) { | ||
397 | set_mtrr(replace, 0, 0, 0); | ||
398 | usage_table[replace] = 0; | ||
399 | } | ||
400 | } | ||
371 | } else | 401 | } else |
372 | printk(KERN_INFO "mtrr: no more MTRRs available\n"); | 402 | printk(KERN_INFO "mtrr: no more MTRRs available\n"); |
373 | error = i; | 403 | error = i; |
@@ -455,8 +485,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) | |||
455 | { | 485 | { |
456 | int i, max; | 486 | int i, max; |
457 | mtrr_type ltype; | 487 | mtrr_type ltype; |
458 | unsigned long lbase; | 488 | unsigned long lbase, lsize; |
459 | unsigned int lsize; | ||
460 | int error = -EINVAL; | 489 | int error = -EINVAL; |
461 | 490 | ||
462 | if (!mtrr_if) | 491 | if (!mtrr_if) |
@@ -544,9 +573,11 @@ extern void centaur_init_mtrr(void); | |||
544 | 573 | ||
545 | static void __init init_ifs(void) | 574 | static void __init init_ifs(void) |
546 | { | 575 | { |
576 | #ifndef CONFIG_X86_64 | ||
547 | amd_init_mtrr(); | 577 | amd_init_mtrr(); |
548 | cyrix_init_mtrr(); | 578 | cyrix_init_mtrr(); |
549 | centaur_init_mtrr(); | 579 | centaur_init_mtrr(); |
580 | #endif | ||
550 | } | 581 | } |
551 | 582 | ||
552 | /* The suspend/resume methods are only for CPU without MTRR. CPU using generic | 583 | /* The suspend/resume methods are only for CPU without MTRR. CPU using generic |
@@ -555,7 +586,7 @@ static void __init init_ifs(void) | |||
555 | struct mtrr_value { | 586 | struct mtrr_value { |
556 | mtrr_type ltype; | 587 | mtrr_type ltype; |
557 | unsigned long lbase; | 588 | unsigned long lbase; |
558 | unsigned int lsize; | 589 | unsigned long lsize; |
559 | }; | 590 | }; |
560 | 591 | ||
561 | static struct mtrr_value * mtrr_state; | 592 | static struct mtrr_value * mtrr_state; |
@@ -565,10 +596,8 @@ static int mtrr_save(struct sys_device * sysdev, pm_message_t state) | |||
565 | int i; | 596 | int i; |
566 | int size = num_var_ranges * sizeof(struct mtrr_value); | 597 | int size = num_var_ranges * sizeof(struct mtrr_value); |
567 | 598 | ||
568 | mtrr_state = kmalloc(size,GFP_ATOMIC); | 599 | mtrr_state = kzalloc(size,GFP_ATOMIC); |
569 | if (mtrr_state) | 600 | if (!mtrr_state) |
570 | memset(mtrr_state,0,size); | ||
571 | else | ||
572 | return -ENOMEM; | 601 | return -ENOMEM; |
573 | 602 | ||
574 | for (i = 0; i < num_var_ranges; i++) { | 603 | for (i = 0; i < num_var_ranges; i++) { |
diff --git a/arch/i386/kernel/cpu/mtrr/mtrr.h b/arch/i386/kernel/cpu/mtrr/mtrr.h index 99c9f2682041..d61ea9db6cfe 100644 --- a/arch/i386/kernel/cpu/mtrr/mtrr.h +++ b/arch/i386/kernel/cpu/mtrr/mtrr.h | |||
@@ -43,15 +43,16 @@ struct mtrr_ops { | |||
43 | void (*set_all)(void); | 43 | void (*set_all)(void); |
44 | 44 | ||
45 | void (*get)(unsigned int reg, unsigned long *base, | 45 | void (*get)(unsigned int reg, unsigned long *base, |
46 | unsigned int *size, mtrr_type * type); | 46 | unsigned long *size, mtrr_type * type); |
47 | int (*get_free_region) (unsigned long base, unsigned long size); | 47 | int (*get_free_region)(unsigned long base, unsigned long size, |
48 | 48 | int replace_reg); | |
49 | int (*validate_add_page)(unsigned long base, unsigned long size, | 49 | int (*validate_add_page)(unsigned long base, unsigned long size, |
50 | unsigned int type); | 50 | unsigned int type); |
51 | int (*have_wrcomb)(void); | 51 | int (*have_wrcomb)(void); |
52 | }; | 52 | }; |
53 | 53 | ||
54 | extern int generic_get_free_region(unsigned long base, unsigned long size); | 54 | extern int generic_get_free_region(unsigned long base, unsigned long size, |
55 | int replace_reg); | ||
55 | extern int generic_validate_add_page(unsigned long base, unsigned long size, | 56 | extern int generic_validate_add_page(unsigned long base, unsigned long size, |
56 | unsigned int type); | 57 | unsigned int type); |
57 | 58 | ||
@@ -62,17 +63,17 @@ extern int positive_have_wrcomb(void); | |||
62 | /* library functions for processor-specific routines */ | 63 | /* library functions for processor-specific routines */ |
63 | struct set_mtrr_context { | 64 | struct set_mtrr_context { |
64 | unsigned long flags; | 65 | unsigned long flags; |
65 | unsigned long deftype_lo; | ||
66 | unsigned long deftype_hi; | ||
67 | unsigned long cr4val; | 66 | unsigned long cr4val; |
68 | unsigned long ccr3; | 67 | u32 deftype_lo; |
68 | u32 deftype_hi; | ||
69 | u32 ccr3; | ||
69 | }; | 70 | }; |
70 | 71 | ||
71 | struct mtrr_var_range { | 72 | struct mtrr_var_range { |
72 | unsigned long base_lo; | 73 | u32 base_lo; |
73 | unsigned long base_hi; | 74 | u32 base_hi; |
74 | unsigned long mask_lo; | 75 | u32 mask_lo; |
75 | unsigned long mask_hi; | 76 | u32 mask_hi; |
76 | }; | 77 | }; |
77 | 78 | ||
78 | void set_mtrr_done(struct set_mtrr_context *ctxt); | 79 | void set_mtrr_done(struct set_mtrr_context *ctxt); |
@@ -92,6 +93,6 @@ extern struct mtrr_ops * mtrr_if; | |||
92 | extern unsigned int num_var_ranges; | 93 | extern unsigned int num_var_ranges; |
93 | 94 | ||
94 | void mtrr_state_warn(void); | 95 | void mtrr_state_warn(void); |
95 | char *mtrr_attrib_to_str(int x); | 96 | const char *mtrr_attrib_to_str(int x); |
96 | void mtrr_wrmsr(unsigned, unsigned, unsigned); | 97 | void mtrr_wrmsr(unsigned, unsigned, unsigned); |
97 | 98 | ||
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c index 76aac088a323..6624d8583c42 100644 --- a/arch/i386/kernel/cpu/proc.c +++ b/arch/i386/kernel/cpu/proc.c | |||
@@ -152,9 +152,10 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
152 | seq_printf(m, " [%d]", i); | 152 | seq_printf(m, " [%d]", i); |
153 | } | 153 | } |
154 | 154 | ||
155 | seq_printf(m, "\nbogomips\t: %lu.%02lu\n\n", | 155 | seq_printf(m, "\nbogomips\t: %lu.%02lu\n", |
156 | c->loops_per_jiffy/(500000/HZ), | 156 | c->loops_per_jiffy/(500000/HZ), |
157 | (c->loops_per_jiffy/(5000/HZ)) % 100); | 157 | (c->loops_per_jiffy/(5000/HZ)) % 100); |
158 | seq_printf(m, "clflush size\t: %u\n\n", c->x86_clflush_size); | ||
158 | 159 | ||
159 | return 0; | 160 | return 0; |
160 | } | 161 | } |