aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/alternative.c12
-rw-r--r--arch/x86/kernel/cpu/bugs.c8
-rw-r--r--arch/x86/kernel/cpu/perfctr-watchdog.c7
-rw-r--r--arch/x86/kernel/hpet.c9
-rw-r--r--arch/x86/kernel/pci-gart_64.c10
-rw-r--r--arch/x86/kernel/process_32.c47
-rw-r--r--arch/x86/kernel/process_64.c47
-rw-r--r--arch/x86/kernel/step.c11
-rw-r--r--arch/x86/kernel/tls.c4
-rw-r--r--arch/x86/kernel/tsc_32.c4
-rw-r--r--arch/x86/kernel/tsc_64.c4
11 files changed, 55 insertions, 108 deletions
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 45d79ea890ae..5fed98ca0e1f 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -65,7 +65,8 @@ __setup("noreplace-paravirt", setup_noreplace_paravirt);
65 get them easily into strings. */ 65 get them easily into strings. */
66asm("\t.section .rodata, \"a\"\nintelnops: " 66asm("\t.section .rodata, \"a\"\nintelnops: "
67 GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6 67 GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6
68 GENERIC_NOP7 GENERIC_NOP8); 68 GENERIC_NOP7 GENERIC_NOP8
69 "\t.previous");
69extern const unsigned char intelnops[]; 70extern const unsigned char intelnops[];
70static const unsigned char *const intel_nops[ASM_NOP_MAX+1] = { 71static const unsigned char *const intel_nops[ASM_NOP_MAX+1] = {
71 NULL, 72 NULL,
@@ -83,7 +84,8 @@ static const unsigned char *const intel_nops[ASM_NOP_MAX+1] = {
83#ifdef K8_NOP1 84#ifdef K8_NOP1
84asm("\t.section .rodata, \"a\"\nk8nops: " 85asm("\t.section .rodata, \"a\"\nk8nops: "
85 K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 86 K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6
86 K8_NOP7 K8_NOP8); 87 K8_NOP7 K8_NOP8
88 "\t.previous");
87extern const unsigned char k8nops[]; 89extern const unsigned char k8nops[];
88static const unsigned char *const k8_nops[ASM_NOP_MAX+1] = { 90static const unsigned char *const k8_nops[ASM_NOP_MAX+1] = {
89 NULL, 91 NULL,
@@ -101,7 +103,8 @@ static const unsigned char *const k8_nops[ASM_NOP_MAX+1] = {
101#ifdef K7_NOP1 103#ifdef K7_NOP1
102asm("\t.section .rodata, \"a\"\nk7nops: " 104asm("\t.section .rodata, \"a\"\nk7nops: "
103 K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6 105 K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6
104 K7_NOP7 K7_NOP8); 106 K7_NOP7 K7_NOP8
107 "\t.previous");
105extern const unsigned char k7nops[]; 108extern const unsigned char k7nops[];
106static const unsigned char *const k7_nops[ASM_NOP_MAX+1] = { 109static const unsigned char *const k7_nops[ASM_NOP_MAX+1] = {
107 NULL, 110 NULL,
@@ -119,7 +122,8 @@ static const unsigned char *const k7_nops[ASM_NOP_MAX+1] = {
119#ifdef P6_NOP1 122#ifdef P6_NOP1
120asm("\t.section .rodata, \"a\"\np6nops: " 123asm("\t.section .rodata, \"a\"\np6nops: "
121 P6_NOP1 P6_NOP2 P6_NOP3 P6_NOP4 P6_NOP5 P6_NOP6 124 P6_NOP1 P6_NOP2 P6_NOP3 P6_NOP4 P6_NOP5 P6_NOP6
122 P6_NOP7 P6_NOP8); 125 P6_NOP7 P6_NOP8
126 "\t.previous");
123extern const unsigned char p6nops[]; 127extern const unsigned char p6nops[];
124static const unsigned char *const p6_nops[ASM_NOP_MAX+1] = { 128static const unsigned char *const p6_nops[ASM_NOP_MAX+1] = {
125 NULL, 129 NULL,
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 027e5c003b16..170d2f5523b2 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -143,14 +143,6 @@ static void __init check_config(void)
143#endif 143#endif
144 144
145/* 145/*
146 * If we configured ourselves for a TSC, we'd better have one!
147 */
148#ifdef CONFIG_X86_TSC
149 if (!cpu_has_tsc)
150 panic("Kernel compiled for Pentium+, requires TSC feature!");
151#endif
152
153/*
154 * If we were told we had a good local APIC, check for buggy Pentia, 146 * If we were told we had a good local APIC, check for buggy Pentia,
155 * i.e. all B steppings and the C2 stepping of P54C when using their 147 * i.e. all B steppings and the C2 stepping of P54C when using their
156 * integrated APIC (see 11AP erratum in "Pentium Processor 148 * integrated APIC (see 11AP erratum in "Pentium Processor
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c
index 9b838324b818..b943e10ad814 100644
--- a/arch/x86/kernel/cpu/perfctr-watchdog.c
+++ b/arch/x86/kernel/cpu/perfctr-watchdog.c
@@ -652,9 +652,6 @@ static void probe_nmi_watchdog(void)
652 wd_ops = &p6_wd_ops; 652 wd_ops = &p6_wd_ops;
653 break; 653 break;
654 case 15: 654 case 15:
655 if (boot_cpu_data.x86_model > 0x4)
656 return;
657
658 wd_ops = &p4_wd_ops; 655 wd_ops = &p4_wd_ops;
659 break; 656 break;
660 default: 657 default:
@@ -670,8 +667,10 @@ int lapic_watchdog_init(unsigned nmi_hz)
670{ 667{
671 if (!wd_ops) { 668 if (!wd_ops) {
672 probe_nmi_watchdog(); 669 probe_nmi_watchdog();
673 if (!wd_ops) 670 if (!wd_ops) {
671 printk(KERN_INFO "NMI watchdog: CPU not supported\n");
674 return -1; 672 return -1;
673 }
675 674
676 if (!wd_ops->reserve()) { 675 if (!wd_ops->reserve()) {
677 printk(KERN_ERR 676 printk(KERN_ERR
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 235fd6c77504..36652ea1a265 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -133,13 +133,16 @@ static void hpet_reserve_platform_timers(unsigned long id)
133#ifdef CONFIG_HPET_EMULATE_RTC 133#ifdef CONFIG_HPET_EMULATE_RTC
134 hpet_reserve_timer(&hd, 1); 134 hpet_reserve_timer(&hd, 1);
135#endif 135#endif
136
136 hd.hd_irq[0] = HPET_LEGACY_8254; 137 hd.hd_irq[0] = HPET_LEGACY_8254;
137 hd.hd_irq[1] = HPET_LEGACY_RTC; 138 hd.hd_irq[1] = HPET_LEGACY_RTC;
138 139
139 for (i = 2; i < nrtimers; timer++, i++) 140 for (i = 2; i < nrtimers; timer++, i++)
140 hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >> 141 hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >>
141 Tn_INT_ROUTE_CNF_SHIFT; 142 Tn_INT_ROUTE_CNF_SHIFT;
143
142 hpet_alloc(&hd); 144 hpet_alloc(&hd);
145
143} 146}
144#else 147#else
145static void hpet_reserve_platform_timers(unsigned long id) { } 148static void hpet_reserve_platform_timers(unsigned long id) { }
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index faf3229f8fb3..700e4647dd30 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -615,8 +615,8 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
615 615
616 nommu: 616 nommu:
617 /* Should not happen anymore */ 617 /* Should not happen anymore */
618 printk(KERN_ERR "PCI-DMA: More than 4GB of RAM and no IOMMU\n" 618 printk(KERN_WARNING "PCI-DMA: More than 4GB of RAM and no IOMMU\n"
619 KERN_ERR "PCI-DMA: 32bit PCI IO may malfunction.\n"); 619 KERN_WARNING "falling back to iommu=soft.\n");
620 return -1; 620 return -1;
621} 621}
622 622
@@ -692,9 +692,9 @@ void __init gart_iommu_init(void)
692 !gart_iommu_aperture || 692 !gart_iommu_aperture ||
693 (no_agp && init_k8_gatt(&info) < 0)) { 693 (no_agp && init_k8_gatt(&info) < 0)) {
694 if (end_pfn > MAX_DMA32_PFN) { 694 if (end_pfn > MAX_DMA32_PFN) {
695 printk(KERN_ERR "WARNING more than 4GB of memory " 695 printk(KERN_WARNING "More than 4GB of memory "
696 "but GART IOMMU not available.\n" 696 "but GART IOMMU not available.\n"
697 KERN_ERR "WARNING 32bit PCI may malfunction.\n"); 697 KERN_WARNING "falling back to iommu=soft.\n");
698 } 698 }
699 return; 699 return;
700 } 700 }
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index be3c7a299f02..43930e73f657 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -82,7 +82,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
82 */ 82 */
83void (*pm_idle)(void); 83void (*pm_idle)(void);
84EXPORT_SYMBOL(pm_idle); 84EXPORT_SYMBOL(pm_idle);
85static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
86 85
87void disable_hlt(void) 86void disable_hlt(void)
88{ 87{
@@ -190,9 +189,6 @@ void cpu_idle(void)
190 while (!need_resched()) { 189 while (!need_resched()) {
191 void (*idle)(void); 190 void (*idle)(void);
192 191
193 if (__get_cpu_var(cpu_idle_state))
194 __get_cpu_var(cpu_idle_state) = 0;
195
196 check_pgt_cache(); 192 check_pgt_cache();
197 rmb(); 193 rmb();
198 idle = pm_idle; 194 idle = pm_idle;
@@ -220,40 +216,19 @@ static void do_nothing(void *unused)
220{ 216{
221} 217}
222 218
219/*
220 * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
221 * pm_idle and update to new pm_idle value. Required while changing pm_idle
222 * handler on SMP systems.
223 *
224 * Caller must have changed pm_idle to the new value before the call. Old
225 * pm_idle value will not be used by any CPU after the return of this function.
226 */
223void cpu_idle_wait(void) 227void cpu_idle_wait(void)
224{ 228{
225 unsigned int cpu, this_cpu = get_cpu(); 229 smp_mb();
226 cpumask_t map, tmp = current->cpus_allowed; 230 /* kick all the CPUs so that they exit out of pm_idle */
227 231 smp_call_function(do_nothing, NULL, 0, 1);
228 set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
229 put_cpu();
230
231 cpus_clear(map);
232 for_each_online_cpu(cpu) {
233 per_cpu(cpu_idle_state, cpu) = 1;
234 cpu_set(cpu, map);
235 }
236
237 __get_cpu_var(cpu_idle_state) = 0;
238
239 wmb();
240 do {
241 ssleep(1);
242 for_each_online_cpu(cpu) {
243 if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
244 cpu_clear(cpu, map);
245 }
246 cpus_and(map, map, cpu_online_map);
247 /*
248 * We waited 1 sec, if a CPU still did not call idle
249 * it may be because it is in idle and not waking up
250 * because it has nothing to do.
251 * Give all the remaining CPUS a kick.
252 */
253 smp_call_function_mask(map, do_nothing, NULL, 0);
254 } while (!cpus_empty(map));
255
256 set_cpus_allowed(current, tmp);
257} 232}
258EXPORT_SYMBOL_GPL(cpu_idle_wait); 233EXPORT_SYMBOL_GPL(cpu_idle_wait);
259 234
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 3baf9b9f4c87..46c4c546b499 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -63,7 +63,6 @@ EXPORT_SYMBOL(boot_option_idle_override);
63 */ 63 */
64void (*pm_idle)(void); 64void (*pm_idle)(void);
65EXPORT_SYMBOL(pm_idle); 65EXPORT_SYMBOL(pm_idle);
66static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
67 66
68static ATOMIC_NOTIFIER_HEAD(idle_notifier); 67static ATOMIC_NOTIFIER_HEAD(idle_notifier);
69 68
@@ -173,9 +172,6 @@ void cpu_idle(void)
173 while (!need_resched()) { 172 while (!need_resched()) {
174 void (*idle)(void); 173 void (*idle)(void);
175 174
176 if (__get_cpu_var(cpu_idle_state))
177 __get_cpu_var(cpu_idle_state) = 0;
178
179 rmb(); 175 rmb();
180 idle = pm_idle; 176 idle = pm_idle;
181 if (!idle) 177 if (!idle)
@@ -207,40 +203,19 @@ static void do_nothing(void *unused)
207{ 203{
208} 204}
209 205
206/*
207 * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
208 * pm_idle and update to new pm_idle value. Required while changing pm_idle
209 * handler on SMP systems.
210 *
211 * Caller must have changed pm_idle to the new value before the call. Old
212 * pm_idle value will not be used by any CPU after the return of this function.
213 */
210void cpu_idle_wait(void) 214void cpu_idle_wait(void)
211{ 215{
212 unsigned int cpu, this_cpu = get_cpu(); 216 smp_mb();
213 cpumask_t map, tmp = current->cpus_allowed; 217 /* kick all the CPUs so that they exit out of pm_idle */
214 218 smp_call_function(do_nothing, NULL, 0, 1);
215 set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
216 put_cpu();
217
218 cpus_clear(map);
219 for_each_online_cpu(cpu) {
220 per_cpu(cpu_idle_state, cpu) = 1;
221 cpu_set(cpu, map);
222 }
223
224 __get_cpu_var(cpu_idle_state) = 0;
225
226 wmb();
227 do {
228 ssleep(1);
229 for_each_online_cpu(cpu) {
230 if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
231 cpu_clear(cpu, map);
232 }
233 cpus_and(map, map, cpu_online_map);
234 /*
235 * We waited 1 sec, if a CPU still did not call idle
236 * it may be because it is in idle and not waking up
237 * because it has nothing to do.
238 * Give all the remaining CPUS a kick.
239 */
240 smp_call_function_mask(map, do_nothing, 0, 0);
241 } while (!cpus_empty(map));
242
243 set_cpus_allowed(current, tmp);
244} 219}
245EXPORT_SYMBOL_GPL(cpu_idle_wait); 220EXPORT_SYMBOL_GPL(cpu_idle_wait);
246 221
diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c
index 9d406cdc847f..071ff4798236 100644
--- a/arch/x86/kernel/step.c
+++ b/arch/x86/kernel/step.c
@@ -140,6 +140,9 @@ static int enable_single_step(struct task_struct *child)
140 */ 140 */
141static void write_debugctlmsr(struct task_struct *child, unsigned long val) 141static void write_debugctlmsr(struct task_struct *child, unsigned long val)
142{ 142{
143 if (child->thread.debugctlmsr == val)
144 return;
145
143 child->thread.debugctlmsr = val; 146 child->thread.debugctlmsr = val;
144 147
145 if (child != current) 148 if (child != current)
@@ -165,11 +168,11 @@ static void enable_step(struct task_struct *child, bool block)
165 write_debugctlmsr(child, 168 write_debugctlmsr(child,
166 child->thread.debugctlmsr | DEBUGCTLMSR_BTF); 169 child->thread.debugctlmsr | DEBUGCTLMSR_BTF);
167 } else { 170 } else {
168 write_debugctlmsr(child, 171 write_debugctlmsr(child,
169 child->thread.debugctlmsr & ~DEBUGCTLMSR_BTF); 172 child->thread.debugctlmsr & ~DEBUGCTLMSR_BTF);
170 173
171 if (!child->thread.debugctlmsr) 174 if (!child->thread.debugctlmsr)
172 clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR); 175 clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
173 } 176 }
174} 177}
175 178
diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c
index 022bcaa3b42e..ab6bf375a307 100644
--- a/arch/x86/kernel/tls.c
+++ b/arch/x86/kernel/tls.c
@@ -92,7 +92,7 @@ int do_set_thread_area(struct task_struct *p, int idx,
92asmlinkage int sys_set_thread_area(struct user_desc __user *u_info) 92asmlinkage int sys_set_thread_area(struct user_desc __user *u_info)
93{ 93{
94 int ret = do_set_thread_area(current, -1, u_info, 1); 94 int ret = do_set_thread_area(current, -1, u_info, 1);
95 prevent_tail_call(ret); 95 asmlinkage_protect(1, ret, u_info);
96 return ret; 96 return ret;
97} 97}
98 98
@@ -142,7 +142,7 @@ int do_get_thread_area(struct task_struct *p, int idx,
142asmlinkage int sys_get_thread_area(struct user_desc __user *u_info) 142asmlinkage int sys_get_thread_area(struct user_desc __user *u_info)
143{ 143{
144 int ret = do_get_thread_area(current, -1, u_info); 144 int ret = do_get_thread_area(current, -1, u_info);
145 prevent_tail_call(ret); 145 asmlinkage_protect(1, ret, u_info);
146 return ret; 146 return ret;
147} 147}
148 148
diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c
index f14cfd9d1f94..c2241e04ea5f 100644
--- a/arch/x86/kernel/tsc_32.c
+++ b/arch/x86/kernel/tsc_32.c
@@ -256,9 +256,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
256 ref_freq, freq->new); 256 ref_freq, freq->new);
257 if (!(freq->flags & CPUFREQ_CONST_LOOPS)) { 257 if (!(freq->flags & CPUFREQ_CONST_LOOPS)) {
258 tsc_khz = cpu_khz; 258 tsc_khz = cpu_khz;
259 preempt_disable(); 259 set_cyc2ns_scale(cpu_khz, freq->cpu);
260 set_cyc2ns_scale(cpu_khz, smp_processor_id());
261 preempt_enable();
262 /* 260 /*
263 * TSC based sched_clock turns 261 * TSC based sched_clock turns
264 * to junk w/ cpufreq 262 * to junk w/ cpufreq
diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c
index 947554ddabb6..d3bebaaad842 100644
--- a/arch/x86/kernel/tsc_64.c
+++ b/arch/x86/kernel/tsc_64.c
@@ -148,9 +148,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
148 mark_tsc_unstable("cpufreq changes"); 148 mark_tsc_unstable("cpufreq changes");
149 } 149 }
150 150
151 preempt_disable(); 151 set_cyc2ns_scale(tsc_khz_ref, freq->cpu);
152 set_cyc2ns_scale(tsc_khz_ref, smp_processor_id());
153 preempt_enable();
154 152
155 return 0; 153 return 0;
156} 154}