aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/Makefile2
-rw-r--r--arch/x86/kernel/apic.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k8.c18
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k8.h17
-rw-r--r--arch/x86/kernel/ds.c88
-rw-r--r--arch/x86/kernel/i387.c2
-rw-r--r--arch/x86/kernel/io_apic.c48
-rw-r--r--arch/x86/kernel/kvmclock.c2
-rw-r--r--arch/x86/kernel/pci-calgary_64.c2
-rw-r--r--arch/x86/kernel/xsave.c2
10 files changed, 107 insertions, 76 deletions
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index e489ff9cb3e2..b62a7667828e 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -41,7 +41,7 @@ obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
41obj-y += process.o 41obj-y += process.o
42obj-y += i387.o xsave.o 42obj-y += i387.o xsave.o
43obj-y += ptrace.o 43obj-y += ptrace.o
44obj-y += ds.o 44obj-$(CONFIG_X86_DS) += ds.o
45obj-$(CONFIG_X86_32) += tls.o 45obj-$(CONFIG_X86_32) += tls.o
46obj-$(CONFIG_IA32_EMULATION) += tls.o 46obj-$(CONFIG_IA32_EMULATION) += tls.o
47obj-y += step.o 47obj-y += step.o
diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c
index 04a7f960bbc0..16f94879b525 100644
--- a/arch/x86/kernel/apic.c
+++ b/arch/x86/kernel/apic.c
@@ -1315,7 +1315,7 @@ void enable_x2apic(void)
1315 } 1315 }
1316} 1316}
1317 1317
1318void enable_IR_x2apic(void) 1318void __init enable_IR_x2apic(void)
1319{ 1319{
1320#ifdef CONFIG_INTR_REMAP 1320#ifdef CONFIG_INTR_REMAP
1321 int ret; 1321 int ret;
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index d3dcd58b87cd..7f05f44b97e9 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -115,9 +115,20 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data)
115 u32 i = 0; 115 u32 i = 0;
116 116
117 if (cpu_family == CPU_HW_PSTATE) { 117 if (cpu_family == CPU_HW_PSTATE) {
118 rdmsr(MSR_PSTATE_STATUS, lo, hi); 118 if (data->currpstate == HW_PSTATE_INVALID) {
119 i = lo & HW_PSTATE_MASK; 119 /* read (initial) hw pstate if not yet set */
120 data->currpstate = i; 120 rdmsr(MSR_PSTATE_STATUS, lo, hi);
121 i = lo & HW_PSTATE_MASK;
122
123 /*
124 * a workaround for family 11h erratum 311 might cause
125 * an "out-of-range Pstate if the core is in Pstate-0
126 */
127 if (i >= data->numps)
128 data->currpstate = HW_PSTATE_0;
129 else
130 data->currpstate = i;
131 }
121 return 0; 132 return 0;
122 } 133 }
123 do { 134 do {
@@ -1121,6 +1132,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
1121 } 1132 }
1122 1133
1123 data->cpu = pol->cpu; 1134 data->cpu = pol->cpu;
1135 data->currpstate = HW_PSTATE_INVALID;
1124 1136
1125 if (powernow_k8_cpu_init_acpi(data)) { 1137 if (powernow_k8_cpu_init_acpi(data)) {
1126 /* 1138 /*
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
index ab48cfed4d96..65cfb5d7f77f 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
@@ -5,6 +5,19 @@
5 * http://www.gnu.org/licenses/gpl.html 5 * http://www.gnu.org/licenses/gpl.html
6 */ 6 */
7 7
8
9enum pstate {
10 HW_PSTATE_INVALID = 0xff,
11 HW_PSTATE_0 = 0,
12 HW_PSTATE_1 = 1,
13 HW_PSTATE_2 = 2,
14 HW_PSTATE_3 = 3,
15 HW_PSTATE_4 = 4,
16 HW_PSTATE_5 = 5,
17 HW_PSTATE_6 = 6,
18 HW_PSTATE_7 = 7,
19};
20
8struct powernow_k8_data { 21struct powernow_k8_data {
9 unsigned int cpu; 22 unsigned int cpu;
10 23
@@ -23,7 +36,9 @@ struct powernow_k8_data {
23 u32 exttype; /* extended interface = 1 */ 36 u32 exttype; /* extended interface = 1 */
24 37
25 /* keep track of the current fid / vid or pstate */ 38 /* keep track of the current fid / vid or pstate */
26 u32 currvid, currfid, currpstate; 39 u32 currvid;
40 u32 currfid;
41 enum pstate currpstate;
27 42
28 /* the powernow_table includes all frequency and vid/fid pairings: 43 /* the powernow_table includes all frequency and vid/fid pairings:
29 * fid are the lower 8 bits of the index, vid are the upper 8 bits. 44 * fid are the lower 8 bits of the index, vid are the upper 8 bits.
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c
index d1a121443bde..a2d1176c38ee 100644
--- a/arch/x86/kernel/ds.c
+++ b/arch/x86/kernel/ds.c
@@ -21,8 +21,6 @@
21 */ 21 */
22 22
23 23
24#ifdef CONFIG_X86_DS
25
26#include <asm/ds.h> 24#include <asm/ds.h>
27 25
28#include <linux/errno.h> 26#include <linux/errno.h>
@@ -211,14 +209,15 @@ static DEFINE_PER_CPU(struct ds_context *, system_context);
211static inline struct ds_context *ds_get_context(struct task_struct *task) 209static inline struct ds_context *ds_get_context(struct task_struct *task)
212{ 210{
213 struct ds_context *context; 211 struct ds_context *context;
212 unsigned long irq;
214 213
215 spin_lock(&ds_lock); 214 spin_lock_irqsave(&ds_lock, irq);
216 215
217 context = (task ? task->thread.ds_ctx : this_system_context); 216 context = (task ? task->thread.ds_ctx : this_system_context);
218 if (context) 217 if (context)
219 context->count++; 218 context->count++;
220 219
221 spin_unlock(&ds_lock); 220 spin_unlock_irqrestore(&ds_lock, irq);
222 221
223 return context; 222 return context;
224} 223}
@@ -226,55 +225,46 @@ static inline struct ds_context *ds_get_context(struct task_struct *task)
226/* 225/*
227 * Same as ds_get_context, but allocates the context and it's DS 226 * Same as ds_get_context, but allocates the context and it's DS
228 * structure, if necessary; returns NULL; if out of memory. 227 * structure, if necessary; returns NULL; if out of memory.
229 *
230 * pre: requires ds_lock to be held
231 */ 228 */
232static inline struct ds_context *ds_alloc_context(struct task_struct *task) 229static inline struct ds_context *ds_alloc_context(struct task_struct *task)
233{ 230{
234 struct ds_context **p_context = 231 struct ds_context **p_context =
235 (task ? &task->thread.ds_ctx : &this_system_context); 232 (task ? &task->thread.ds_ctx : &this_system_context);
236 struct ds_context *context = *p_context; 233 struct ds_context *context = *p_context;
234 unsigned long irq;
237 235
238 if (!context) { 236 if (!context) {
239 spin_unlock(&ds_lock);
240
241 context = kzalloc(sizeof(*context), GFP_KERNEL); 237 context = kzalloc(sizeof(*context), GFP_KERNEL);
242 238 if (!context)
243 if (!context) {
244 spin_lock(&ds_lock);
245 return NULL; 239 return NULL;
246 }
247 240
248 context->ds = kzalloc(ds_cfg.sizeof_ds, GFP_KERNEL); 241 context->ds = kzalloc(ds_cfg.sizeof_ds, GFP_KERNEL);
249 if (!context->ds) { 242 if (!context->ds) {
250 kfree(context); 243 kfree(context);
251 spin_lock(&ds_lock);
252 return NULL; 244 return NULL;
253 } 245 }
254 246
255 spin_lock(&ds_lock); 247 spin_lock_irqsave(&ds_lock, irq);
256 /* 248
257 * Check for race - another CPU could have allocated
258 * it meanwhile:
259 */
260 if (*p_context) { 249 if (*p_context) {
261 kfree(context->ds); 250 kfree(context->ds);
262 kfree(context); 251 kfree(context);
263 return *p_context;
264 }
265 252
266 *p_context = context; 253 context = *p_context;
254 } else {
255 *p_context = context;
267 256
268 context->this = p_context; 257 context->this = p_context;
269 context->task = task; 258 context->task = task;
270 259
271 if (task) 260 if (task)
272 set_tsk_thread_flag(task, TIF_DS_AREA_MSR); 261 set_tsk_thread_flag(task, TIF_DS_AREA_MSR);
273 262
274 if (!task || (task == current)) 263 if (!task || (task == current))
275 wrmsr(MSR_IA32_DS_AREA, (unsigned long)context->ds, 0); 264 wrmsrl(MSR_IA32_DS_AREA,
276 265 (unsigned long)context->ds);
277 get_tracer(task); 266 }
267 spin_unlock_irqrestore(&ds_lock, irq);
278 } 268 }
279 269
280 context->count++; 270 context->count++;
@@ -288,10 +278,12 @@ static inline struct ds_context *ds_alloc_context(struct task_struct *task)
288 */ 278 */
289static inline void ds_put_context(struct ds_context *context) 279static inline void ds_put_context(struct ds_context *context)
290{ 280{
281 unsigned long irq;
282
291 if (!context) 283 if (!context)
292 return; 284 return;
293 285
294 spin_lock(&ds_lock); 286 spin_lock_irqsave(&ds_lock, irq);
295 287
296 if (--context->count) 288 if (--context->count)
297 goto out; 289 goto out;
@@ -313,7 +305,7 @@ static inline void ds_put_context(struct ds_context *context)
313 kfree(context->ds); 305 kfree(context->ds);
314 kfree(context); 306 kfree(context);
315 out: 307 out:
316 spin_unlock(&ds_lock); 308 spin_unlock_irqrestore(&ds_lock, irq);
317} 309}
318 310
319 311
@@ -384,6 +376,7 @@ static int ds_request(struct task_struct *task, void *base, size_t size,
384 struct ds_context *context; 376 struct ds_context *context;
385 unsigned long buffer, adj; 377 unsigned long buffer, adj;
386 const unsigned long alignment = (1 << 3); 378 const unsigned long alignment = (1 << 3);
379 unsigned long irq;
387 int error = 0; 380 int error = 0;
388 381
389 if (!ds_cfg.sizeof_ds) 382 if (!ds_cfg.sizeof_ds)
@@ -398,26 +391,27 @@ static int ds_request(struct task_struct *task, void *base, size_t size,
398 return -EOPNOTSUPP; 391 return -EOPNOTSUPP;
399 392
400 393
401 spin_lock(&ds_lock);
402
403 error = -ENOMEM;
404 context = ds_alloc_context(task); 394 context = ds_alloc_context(task);
405 if (!context) 395 if (!context)
406 goto out_unlock; 396 return -ENOMEM;
397
398 spin_lock_irqsave(&ds_lock, irq);
407 399
408 error = -EPERM; 400 error = -EPERM;
409 if (!check_tracer(task)) 401 if (!check_tracer(task))
410 goto out_unlock; 402 goto out_unlock;
411 403
404 get_tracer(task);
405
412 error = -EALREADY; 406 error = -EALREADY;
413 if (context->owner[qual] == current) 407 if (context->owner[qual] == current)
414 goto out_unlock; 408 goto out_put_tracer;
415 error = -EPERM; 409 error = -EPERM;
416 if (context->owner[qual] != NULL) 410 if (context->owner[qual] != NULL)
417 goto out_unlock; 411 goto out_put_tracer;
418 context->owner[qual] = current; 412 context->owner[qual] = current;
419 413
420 spin_unlock(&ds_lock); 414 spin_unlock_irqrestore(&ds_lock, irq);
421 415
422 416
423 error = -ENOMEM; 417 error = -ENOMEM;
@@ -465,10 +459,17 @@ static int ds_request(struct task_struct *task, void *base, size_t size,
465 out_release: 459 out_release:
466 context->owner[qual] = NULL; 460 context->owner[qual] = NULL;
467 ds_put_context(context); 461 ds_put_context(context);
462 put_tracer(task);
463 return error;
464
465 out_put_tracer:
466 spin_unlock_irqrestore(&ds_lock, irq);
467 ds_put_context(context);
468 put_tracer(task);
468 return error; 469 return error;
469 470
470 out_unlock: 471 out_unlock:
471 spin_unlock(&ds_lock); 472 spin_unlock_irqrestore(&ds_lock, irq);
472 ds_put_context(context); 473 ds_put_context(context);
473 return error; 474 return error;
474} 475}
@@ -818,13 +819,21 @@ static const struct ds_configuration ds_cfg_var = {
818 .sizeof_ds = sizeof(long) * 12, 819 .sizeof_ds = sizeof(long) * 12,
819 .sizeof_field = sizeof(long), 820 .sizeof_field = sizeof(long),
820 .sizeof_rec[ds_bts] = sizeof(long) * 3, 821 .sizeof_rec[ds_bts] = sizeof(long) * 3,
822#ifdef __i386__
821 .sizeof_rec[ds_pebs] = sizeof(long) * 10 823 .sizeof_rec[ds_pebs] = sizeof(long) * 10
824#else
825 .sizeof_rec[ds_pebs] = sizeof(long) * 18
826#endif
822}; 827};
823static const struct ds_configuration ds_cfg_64 = { 828static const struct ds_configuration ds_cfg_64 = {
824 .sizeof_ds = 8 * 12, 829 .sizeof_ds = 8 * 12,
825 .sizeof_field = 8, 830 .sizeof_field = 8,
826 .sizeof_rec[ds_bts] = 8 * 3, 831 .sizeof_rec[ds_bts] = 8 * 3,
832#ifdef __i386__
827 .sizeof_rec[ds_pebs] = 8 * 10 833 .sizeof_rec[ds_pebs] = 8 * 10
834#else
835 .sizeof_rec[ds_pebs] = 8 * 18
836#endif
828}; 837};
829 838
830static inline void 839static inline void
@@ -878,4 +887,3 @@ void ds_free(struct ds_context *context)
878 while (leftovers--) 887 while (leftovers--)
879 ds_put_context(context); 888 ds_put_context(context);
880} 889}
881#endif /* CONFIG_X86_DS */
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
index 1f20608d4ca8..b0f61f0dcd0a 100644
--- a/arch/x86/kernel/i387.c
+++ b/arch/x86/kernel/i387.c
@@ -58,7 +58,7 @@ void __cpuinit mxcsr_feature_mask_init(void)
58 stts(); 58 stts();
59} 59}
60 60
61void __init init_thread_xstate(void) 61void __cpuinit init_thread_xstate(void)
62{ 62{
63 if (!HAVE_HWFP) { 63 if (!HAVE_HWFP) {
64 xstate_size = sizeof(struct i387_soft_struct); 64 xstate_size = sizeof(struct i387_soft_struct);
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c
index c9513e1ff28d..9043251210fb 100644
--- a/arch/x86/kernel/io_apic.c
+++ b/arch/x86/kernel/io_apic.c
@@ -3608,27 +3608,7 @@ int __init io_apic_get_redir_entries (int ioapic)
3608 3608
3609int __init probe_nr_irqs(void) 3609int __init probe_nr_irqs(void)
3610{ 3610{
3611 int idx; 3611 return NR_IRQS;
3612 int nr = 0;
3613#ifndef CONFIG_XEN
3614 int nr_min = 32;
3615#else
3616 int nr_min = NR_IRQS;
3617#endif
3618
3619 for (idx = 0; idx < nr_ioapics; idx++)
3620 nr += io_apic_get_redir_entries(idx) + 1;
3621
3622 /* double it for hotplug and msi and nmi */
3623 nr <<= 1;
3624
3625 /* something wrong ? */
3626 if (nr < nr_min)
3627 nr = nr_min;
3628 if (WARN_ON(nr > NR_IRQS))
3629 nr = NR_IRQS;
3630
3631 return nr;
3632} 3612}
3633 3613
3634/* -------------------------------------------------------------------------- 3614/* --------------------------------------------------------------------------
@@ -3775,7 +3755,9 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
3775void __init setup_ioapic_dest(void) 3755void __init setup_ioapic_dest(void)
3776{ 3756{
3777 int pin, ioapic, irq, irq_entry; 3757 int pin, ioapic, irq, irq_entry;
3758 struct irq_desc *desc;
3778 struct irq_cfg *cfg; 3759 struct irq_cfg *cfg;
3760 cpumask_t mask;
3779 3761
3780 if (skip_ioapic_setup == 1) 3762 if (skip_ioapic_setup == 1)
3781 return; 3763 return;
@@ -3792,16 +3774,30 @@ void __init setup_ioapic_dest(void)
3792 * cpu is online. 3774 * cpu is online.
3793 */ 3775 */
3794 cfg = irq_cfg(irq); 3776 cfg = irq_cfg(irq);
3795 if (!cfg->vector) 3777 if (!cfg->vector) {
3796 setup_IO_APIC_irq(ioapic, pin, irq, 3778 setup_IO_APIC_irq(ioapic, pin, irq,
3797 irq_trigger(irq_entry), 3779 irq_trigger(irq_entry),
3798 irq_polarity(irq_entry)); 3780 irq_polarity(irq_entry));
3781 continue;
3782
3783 }
3784
3785 /*
3786 * Honour affinities which have been set in early boot
3787 */
3788 desc = irq_to_desc(irq);
3789 if (desc->status &
3790 (IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
3791 mask = desc->affinity;
3792 else
3793 mask = TARGET_CPUS;
3794
3799#ifdef CONFIG_INTR_REMAP 3795#ifdef CONFIG_INTR_REMAP
3800 else if (intr_remapping_enabled) 3796 if (intr_remapping_enabled)
3801 set_ir_ioapic_affinity_irq(irq, TARGET_CPUS); 3797 set_ir_ioapic_affinity_irq(irq, mask);
3802#endif
3803 else 3798 else
3804 set_ioapic_affinity_irq(irq, TARGET_CPUS); 3799#endif
3800 set_ioapic_affinity_irq(irq, mask);
3805 } 3801 }
3806 3802
3807 } 3803 }
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index 1c9cc431ea4f..e169ae9b6a62 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -128,7 +128,7 @@ static int kvm_register_clock(char *txt)
128} 128}
129 129
130#ifdef CONFIG_X86_LOCAL_APIC 130#ifdef CONFIG_X86_LOCAL_APIC
131static void __devinit kvm_setup_secondary_clock(void) 131static void __cpuinit kvm_setup_secondary_clock(void)
132{ 132{
133 /* 133 /*
134 * Now that the first cpu already had this clocksource initialized, 134 * Now that the first cpu already had this clocksource initialized,
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index e1e731d78f38..d28bbdc35e4e 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -1567,7 +1567,7 @@ static int __init calgary_parse_options(char *p)
1567 ++p; 1567 ++p;
1568 if (*p == '\0') 1568 if (*p == '\0')
1569 break; 1569 break;
1570 bridge = simple_strtol(p, &endp, 0); 1570 bridge = simple_strtoul(p, &endp, 0);
1571 if (p == endp) 1571 if (p == endp)
1572 break; 1572 break;
1573 1573
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c
index b13acb75e822..15c3e6999182 100644
--- a/arch/x86/kernel/xsave.c
+++ b/arch/x86/kernel/xsave.c
@@ -310,7 +310,7 @@ static void __init setup_xstate_init(void)
310/* 310/*
311 * Enable and initialize the xsave feature. 311 * Enable and initialize the xsave feature.
312 */ 312 */
313void __init xsave_cntxt_init(void) 313void __ref xsave_cntxt_init(void)
314{ 314{
315 unsigned int eax, ebx, ecx, edx; 315 unsigned int eax, ebx, ecx, edx;
316 316