aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/process_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/process_32.c')
-rw-r--r--arch/x86/kernel/process_32.c105
1 files changed, 54 insertions, 51 deletions
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 31f40b24bf5d..0a1302fe6d45 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -37,6 +37,7 @@
37#include <linux/tick.h> 37#include <linux/tick.h>
38#include <linux/percpu.h> 38#include <linux/percpu.h>
39#include <linux/prctl.h> 39#include <linux/prctl.h>
40#include <linux/dmi.h>
40 41
41#include <asm/uaccess.h> 42#include <asm/uaccess.h>
42#include <asm/pgtable.h> 43#include <asm/pgtable.h>
@@ -56,6 +57,8 @@
56#include <asm/cpu.h> 57#include <asm/cpu.h>
57#include <asm/kdebug.h> 58#include <asm/kdebug.h>
58#include <asm/idle.h> 59#include <asm/idle.h>
60#include <asm/syscalls.h>
61#include <asm/smp.h>
59 62
60asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); 63asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
61 64
@@ -73,47 +76,12 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
73 return ((unsigned long *)tsk->thread.sp)[3]; 76 return ((unsigned long *)tsk->thread.sp)[3];
74} 77}
75 78
76#ifdef CONFIG_HOTPLUG_CPU 79#ifndef CONFIG_SMP
77#include <asm/nmi.h>
78
79static void cpu_exit_clear(void)
80{
81 int cpu = raw_smp_processor_id();
82
83 idle_task_exit();
84
85 cpu_uninit();
86 irq_ctx_exit(cpu);
87
88 cpu_clear(cpu, cpu_callout_map);
89 cpu_clear(cpu, cpu_callin_map);
90
91 numa_remove_cpu(cpu);
92 c1e_remove_cpu(cpu);
93}
94
95/* We don't actually take CPU down, just spin without interrupts. */
96static inline void play_dead(void)
97{
98 /* This must be done before dead CPU ack */
99 cpu_exit_clear();
100 mb();
101 /* Ack it */
102 __get_cpu_var(cpu_state) = CPU_DEAD;
103
104 /*
105 * With physical CPU hotplug, we should halt the cpu
106 */
107 local_irq_disable();
108 /* mask all interrupts, flush any and all caches, and halt */
109 wbinvd_halt();
110}
111#else
112static inline void play_dead(void) 80static inline void play_dead(void)
113{ 81{
114 BUG(); 82 BUG();
115} 83}
116#endif /* CONFIG_HOTPLUG_CPU */ 84#endif
117 85
118/* 86/*
119 * The idle thread. There's no useful work to be 87 * The idle thread. There's no useful work to be
@@ -155,12 +123,13 @@ void cpu_idle(void)
155 } 123 }
156} 124}
157 125
158void __show_registers(struct pt_regs *regs, int all) 126void __show_regs(struct pt_regs *regs, int all)
159{ 127{
160 unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L; 128 unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
161 unsigned long d0, d1, d2, d3, d6, d7; 129 unsigned long d0, d1, d2, d3, d6, d7;
162 unsigned long sp; 130 unsigned long sp;
163 unsigned short ss, gs; 131 unsigned short ss, gs;
132 const char *board;
164 133
165 if (user_mode_vm(regs)) { 134 if (user_mode_vm(regs)) {
166 sp = regs->sp; 135 sp = regs->sp;
@@ -173,11 +142,15 @@ void __show_registers(struct pt_regs *regs, int all)
173 } 142 }
174 143
175 printk("\n"); 144 printk("\n");
176 printk("Pid: %d, comm: %s %s (%s %.*s)\n", 145
146 board = dmi_get_system_info(DMI_PRODUCT_NAME);
147 if (!board)
148 board = "";
149 printk("Pid: %d, comm: %s %s (%s %.*s) %s\n",
177 task_pid_nr(current), current->comm, 150 task_pid_nr(current), current->comm,
178 print_tainted(), init_utsname()->release, 151 print_tainted(), init_utsname()->release,
179 (int)strcspn(init_utsname()->version, " "), 152 (int)strcspn(init_utsname()->version, " "),
180 init_utsname()->version); 153 init_utsname()->version, board);
181 154
182 printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n", 155 printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
183 (u16)regs->cs, regs->ip, regs->flags, 156 (u16)regs->cs, regs->ip, regs->flags,
@@ -216,7 +189,7 @@ void __show_registers(struct pt_regs *regs, int all)
216 189
217void show_regs(struct pt_regs *regs) 190void show_regs(struct pt_regs *regs)
218{ 191{
219 __show_registers(regs, 1); 192 __show_regs(regs, 1);
220 show_trace(NULL, regs, &regs->sp, regs->bp); 193 show_trace(NULL, regs, &regs->sp, regs->bp);
221} 194}
222 195
@@ -277,6 +250,14 @@ void exit_thread(void)
277 tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; 250 tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
278 put_cpu(); 251 put_cpu();
279 } 252 }
253#ifdef CONFIG_X86_DS
254 /* Free any DS contexts that have not been properly released. */
255 if (unlikely(current->thread.ds_ctx)) {
256 /* we clear debugctl to make sure DS is not used. */
257 update_debugctlmsr(0);
258 ds_free(current->thread.ds_ctx);
259 }
260#endif /* CONFIG_X86_DS */
280} 261}
281 262
282void flush_thread(void) 263void flush_thread(void)
@@ -438,6 +419,35 @@ int set_tsc_mode(unsigned int val)
438 return 0; 419 return 0;
439} 420}
440 421
422#ifdef CONFIG_X86_DS
423static int update_debugctl(struct thread_struct *prev,
424 struct thread_struct *next, unsigned long debugctl)
425{
426 unsigned long ds_prev = 0;
427 unsigned long ds_next = 0;
428
429 if (prev->ds_ctx)
430 ds_prev = (unsigned long)prev->ds_ctx->ds;
431 if (next->ds_ctx)
432 ds_next = (unsigned long)next->ds_ctx->ds;
433
434 if (ds_next != ds_prev) {
435 /* we clear debugctl to make sure DS
436 * is not in use when we change it */
437 debugctl = 0;
438 update_debugctlmsr(0);
439 wrmsr(MSR_IA32_DS_AREA, ds_next, 0);
440 }
441 return debugctl;
442}
443#else
444static int update_debugctl(struct thread_struct *prev,
445 struct thread_struct *next, unsigned long debugctl)
446{
447 return debugctl;
448}
449#endif /* CONFIG_X86_DS */
450
441static noinline void 451static noinline void
442__switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, 452__switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
443 struct tss_struct *tss) 453 struct tss_struct *tss)
@@ -448,14 +458,7 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
448 prev = &prev_p->thread; 458 prev = &prev_p->thread;
449 next = &next_p->thread; 459 next = &next_p->thread;
450 460
451 debugctl = prev->debugctlmsr; 461 debugctl = update_debugctl(prev, next, prev->debugctlmsr);
452 if (next->ds_area_msr != prev->ds_area_msr) {
453 /* we clear debugctl to make sure DS
454 * is not in use when we change it */
455 debugctl = 0;
456 update_debugctlmsr(0);
457 wrmsr(MSR_IA32_DS_AREA, next->ds_area_msr, 0);
458 }
459 462
460 if (next->debugctlmsr != debugctl) 463 if (next->debugctlmsr != debugctl)
461 update_debugctlmsr(next->debugctlmsr); 464 update_debugctlmsr(next->debugctlmsr);
@@ -479,13 +482,13 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
479 hard_enable_TSC(); 482 hard_enable_TSC();
480 } 483 }
481 484
482#ifdef X86_BTS 485#ifdef CONFIG_X86_PTRACE_BTS
483 if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) 486 if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
484 ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); 487 ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
485 488
486 if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) 489 if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
487 ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); 490 ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
488#endif 491#endif /* CONFIG_X86_PTRACE_BTS */
489 492
490 493
491 if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { 494 if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {