aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/process_32.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-10-12 06:35:23 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-12 06:37:32 -0400
commit365d46dc9be9b3c833990a06f3994b1987eda578 (patch)
tree9397d1304144a288411f2118707f44ff5e862fa6 /arch/x86/kernel/process_32.c
parent5dc64a3442b98eaa0e3730c35fcf00cf962a93e7 (diff)
parentfd048088306656824958e7783ffcee27e241b361 (diff)
Merge branch 'linus' into x86/xen
Conflicts: arch/x86/kernel/cpu/common.c arch/x86/kernel/process_64.c arch/x86/xen/enlighten.c
Diffstat (limited to 'arch/x86/kernel/process_32.c')
-rw-r--r--arch/x86/kernel/process_32.c63
1 files changed, 51 insertions, 12 deletions
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index b76b38ff962b..922c14058f97 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>
@@ -55,6 +56,9 @@
55#include <asm/tlbflush.h> 56#include <asm/tlbflush.h>
56#include <asm/cpu.h> 57#include <asm/cpu.h>
57#include <asm/kdebug.h> 58#include <asm/kdebug.h>
59#include <asm/idle.h>
60#include <asm/syscalls.h>
61#include <asm/smp.h>
58 62
59asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); 63asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
60 64
@@ -125,6 +129,7 @@ void __show_registers(struct pt_regs *regs, int all)
125 unsigned long d0, d1, d2, d3, d6, d7; 129 unsigned long d0, d1, d2, d3, d6, d7;
126 unsigned long sp; 130 unsigned long sp;
127 unsigned short ss, gs; 131 unsigned short ss, gs;
132 const char *board;
128 133
129 if (user_mode_vm(regs)) { 134 if (user_mode_vm(regs)) {
130 sp = regs->sp; 135 sp = regs->sp;
@@ -137,11 +142,15 @@ void __show_registers(struct pt_regs *regs, int all)
137 } 142 }
138 143
139 printk("\n"); 144 printk("\n");
140 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",
141 task_pid_nr(current), current->comm, 150 task_pid_nr(current), current->comm,
142 print_tainted(), init_utsname()->release, 151 print_tainted(), init_utsname()->release,
143 (int)strcspn(init_utsname()->version, " "), 152 (int)strcspn(init_utsname()->version, " "),
144 init_utsname()->version); 153 init_utsname()->version, board);
145 154
146 printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n", 155 printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
147 (u16)regs->cs, regs->ip, regs->flags, 156 (u16)regs->cs, regs->ip, regs->flags,
@@ -241,6 +250,14 @@ void exit_thread(void)
241 tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; 250 tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
242 put_cpu(); 251 put_cpu();
243 } 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 */
244} 261}
245 262
246void flush_thread(void) 263void flush_thread(void)
@@ -402,6 +419,35 @@ int set_tsc_mode(unsigned int val)
402 return 0; 419 return 0;
403} 420}
404 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
405static noinline void 451static noinline void
406__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,
407 struct tss_struct *tss) 453 struct tss_struct *tss)
@@ -412,14 +458,7 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
412 prev = &prev_p->thread; 458 prev = &prev_p->thread;
413 next = &next_p->thread; 459 next = &next_p->thread;
414 460
415 debugctl = prev->debugctlmsr; 461 debugctl = update_debugctl(prev, next, prev->debugctlmsr);
416 if (next->ds_area_msr != prev->ds_area_msr) {
417 /* we clear debugctl to make sure DS
418 * is not in use when we change it */
419 debugctl = 0;
420 update_debugctlmsr(0);
421 wrmsr(MSR_IA32_DS_AREA, next->ds_area_msr, 0);
422 }
423 462
424 if (next->debugctlmsr != debugctl) 463 if (next->debugctlmsr != debugctl)
425 update_debugctlmsr(next->debugctlmsr); 464 update_debugctlmsr(next->debugctlmsr);
@@ -443,13 +482,13 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
443 hard_enable_TSC(); 482 hard_enable_TSC();
444 } 483 }
445 484
446#ifdef X86_BTS 485#ifdef CONFIG_X86_PTRACE_BTS
447 if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) 486 if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
448 ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); 487 ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
449 488
450 if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) 489 if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
451 ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); 490 ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
452#endif 491#endif /* CONFIG_X86_PTRACE_BTS */
453 492
454 493
455 if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { 494 if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {