aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/mtrr.h7
-rw-r--r--arch/x86/kernel/cpu/mtrr/main.c46
-rw-r--r--arch/x86/kernel/smpboot.c14
-rw-r--r--arch/x86/power/cpu.c2
-rw-r--r--kernel/cpu.c14
5 files changed, 73 insertions, 10 deletions
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index a51ada8467de..d5366ec5cb8f 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -121,8 +121,12 @@ extern int mtrr_del_page(int reg, unsigned long base, unsigned long size);
121extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi); 121extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi);
122extern void mtrr_ap_init(void); 122extern void mtrr_ap_init(void);
123extern void mtrr_bp_init(void); 123extern void mtrr_bp_init(void);
124extern void set_mtrr_aps_delayed_init(void);
125extern void mtrr_aps_init(void);
126extern void mtrr_bp_restore(void);
124extern int mtrr_trim_uncached_memory(unsigned long end_pfn); 127extern int mtrr_trim_uncached_memory(unsigned long end_pfn);
125extern int amd_special_default_mtrr(void); 128extern int amd_special_default_mtrr(void);
129extern u32 mtrr_aps_delayed_init;
126# else 130# else
127static inline u8 mtrr_type_lookup(u64 addr, u64 end) 131static inline u8 mtrr_type_lookup(u64 addr, u64 end)
128{ 132{
@@ -161,6 +165,9 @@ static inline void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
161 165
162#define mtrr_ap_init() do {} while (0) 166#define mtrr_ap_init() do {} while (0)
163#define mtrr_bp_init() do {} while (0) 167#define mtrr_bp_init() do {} while (0)
168#define set_mtrr_aps_delayed_init() do {} while (0)
169#define mtrr_aps_init() do {} while (0)
170#define mtrr_bp_restore() do {} while (0)
164# endif 171# endif
165 172
166#ifdef CONFIG_COMPAT 173#ifdef CONFIG_COMPAT
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index 7af0f88a4163..7339be0aa580 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -58,6 +58,7 @@ unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES];
58static DEFINE_MUTEX(mtrr_mutex); 58static DEFINE_MUTEX(mtrr_mutex);
59 59
60u64 size_or_mask, size_and_mask; 60u64 size_or_mask, size_and_mask;
61u32 mtrr_aps_delayed_init;
61 62
62static struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM]; 63static struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM];
63 64
@@ -163,7 +164,10 @@ static void ipi_handler(void *info)
163 if (data->smp_reg != ~0U) { 164 if (data->smp_reg != ~0U) {
164 mtrr_if->set(data->smp_reg, data->smp_base, 165 mtrr_if->set(data->smp_reg, data->smp_base,
165 data->smp_size, data->smp_type); 166 data->smp_size, data->smp_type);
166 } else { 167 } else if (mtrr_aps_delayed_init) {
168 /*
169 * Initialize the MTRRs inaddition to the synchronisation.
170 */
167 mtrr_if->set_all(); 171 mtrr_if->set_all();
168 } 172 }
169 173
@@ -265,6 +269,8 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ
265 */ 269 */
266 if (reg != ~0U) 270 if (reg != ~0U)
267 mtrr_if->set(reg, base, size, type); 271 mtrr_if->set(reg, base, size, type);
272 else if (!mtrr_aps_delayed_init)
273 mtrr_if->set_all();
268 274
269 /* Wait for the others */ 275 /* Wait for the others */
270 while (atomic_read(&data.count)) 276 while (atomic_read(&data.count))
@@ -721,9 +727,7 @@ void __init mtrr_bp_init(void)
721 727
722void mtrr_ap_init(void) 728void mtrr_ap_init(void)
723{ 729{
724 unsigned long flags; 730 if (!use_intel() || mtrr_aps_delayed_init)
725
726 if (!mtrr_if || !use_intel())
727 return; 731 return;
728 /* 732 /*
729 * Ideally we should hold mtrr_mutex here to avoid mtrr entries 733 * Ideally we should hold mtrr_mutex here to avoid mtrr entries
@@ -738,11 +742,7 @@ void mtrr_ap_init(void)
738 * 2. cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug 742 * 2. cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug
739 * lock to prevent mtrr entry changes 743 * lock to prevent mtrr entry changes
740 */ 744 */
741 local_irq_save(flags); 745 set_mtrr(~0U, 0, 0, 0);
742
743 mtrr_if->set_all();
744
745 local_irq_restore(flags);
746} 746}
747 747
748/** 748/**
@@ -753,6 +753,34 @@ void mtrr_save_state(void)
753 smp_call_function_single(0, mtrr_save_fixed_ranges, NULL, 1); 753 smp_call_function_single(0, mtrr_save_fixed_ranges, NULL, 1);
754} 754}
755 755
756void set_mtrr_aps_delayed_init(void)
757{
758 if (!use_intel())
759 return;
760
761 mtrr_aps_delayed_init = 1;
762}
763
764/*
765 * MTRR initialization for all AP's
766 */
767void mtrr_aps_init(void)
768{
769 if (!use_intel())
770 return;
771
772 set_mtrr(~0U, 0, 0, 0);
773 mtrr_aps_delayed_init = 0;
774}
775
776void mtrr_bp_restore(void)
777{
778 if (!use_intel())
779 return;
780
781 mtrr_if->set_all();
782}
783
756static int __init mtrr_init_finialize(void) 784static int __init mtrr_init_finialize(void)
757{ 785{
758 if (!mtrr_if) 786 if (!mtrr_if)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 2fecda69ee64..d720b7e0cf3d 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1116,9 +1116,22 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
1116 1116
1117 if (is_uv_system()) 1117 if (is_uv_system())
1118 uv_system_init(); 1118 uv_system_init();
1119
1120 set_mtrr_aps_delayed_init();
1119out: 1121out:
1120 preempt_enable(); 1122 preempt_enable();
1121} 1123}
1124
1125void arch_enable_nonboot_cpus_begin(void)
1126{
1127 set_mtrr_aps_delayed_init();
1128}
1129
1130void arch_enable_nonboot_cpus_end(void)
1131{
1132 mtrr_aps_init();
1133}
1134
1122/* 1135/*
1123 * Early setup to make printk work. 1136 * Early setup to make printk work.
1124 */ 1137 */
@@ -1140,6 +1153,7 @@ void __init native_smp_cpus_done(unsigned int max_cpus)
1140 setup_ioapic_dest(); 1153 setup_ioapic_dest();
1141#endif 1154#endif
1142 check_nmi_watchdog(); 1155 check_nmi_watchdog();
1156 mtrr_aps_init();
1143} 1157}
1144 1158
1145static int __initdata setup_possible_cpus = -1; 1159static int __initdata setup_possible_cpus = -1;
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index b3d20b9cac63..417c9f5b4afa 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -242,7 +242,7 @@ static void __restore_processor_state(struct saved_context *ctxt)
242 fix_processor_context(); 242 fix_processor_context();
243 243
244 do_fpu_end(); 244 do_fpu_end();
245 mtrr_ap_init(); 245 mtrr_bp_restore();
246 246
247#ifdef CONFIG_X86_OLD_MCE 247#ifdef CONFIG_X86_OLD_MCE
248 mcheck_init(&boot_cpu_data); 248 mcheck_init(&boot_cpu_data);
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 8ce10043e4ac..f5f9485b8c0f 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -413,6 +413,14 @@ int disable_nonboot_cpus(void)
413 return error; 413 return error;
414} 414}
415 415
416void __weak arch_enable_nonboot_cpus_begin(void)
417{
418}
419
420void __weak arch_enable_nonboot_cpus_end(void)
421{
422}
423
416void __ref enable_nonboot_cpus(void) 424void __ref enable_nonboot_cpus(void)
417{ 425{
418 int cpu, error; 426 int cpu, error;
@@ -424,6 +432,9 @@ void __ref enable_nonboot_cpus(void)
424 goto out; 432 goto out;
425 433
426 printk("Enabling non-boot CPUs ...\n"); 434 printk("Enabling non-boot CPUs ...\n");
435
436 arch_enable_nonboot_cpus_begin();
437
427 for_each_cpu(cpu, frozen_cpus) { 438 for_each_cpu(cpu, frozen_cpus) {
428 error = _cpu_up(cpu, 1); 439 error = _cpu_up(cpu, 1);
429 if (!error) { 440 if (!error) {
@@ -432,6 +443,9 @@ void __ref enable_nonboot_cpus(void)
432 } 443 }
433 printk(KERN_WARNING "Error taking CPU%d up: %d\n", cpu, error); 444 printk(KERN_WARNING "Error taking CPU%d up: %d\n", cpu, error);
434 } 445 }
446
447 arch_enable_nonboot_cpus_end();
448
435 cpumask_clear(frozen_cpus); 449 cpumask_clear(frozen_cpus);
436out: 450out:
437 cpu_maps_update_done(); 451 cpu_maps_update_done();