diff options
Diffstat (limited to 'arch/x86/kernel/process_32.c')
| -rw-r--r-- | arch/x86/kernel/process_32.c | 105 | 
1 files changed, 54 insertions, 51 deletions
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 31f40b24bf5..0a1302fe6d4 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -37,6 +37,7 @@  #include <linux/tick.h>  #include <linux/percpu.h>  #include <linux/prctl.h> +#include <linux/dmi.h>  #include <asm/uaccess.h>  #include <asm/pgtable.h> @@ -56,6 +57,8 @@  #include <asm/cpu.h>  #include <asm/kdebug.h>  #include <asm/idle.h> +#include <asm/syscalls.h> +#include <asm/smp.h>  asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); @@ -73,47 +76,12 @@ unsigned long thread_saved_pc(struct task_struct *tsk)  	return ((unsigned long *)tsk->thread.sp)[3];  } -#ifdef CONFIG_HOTPLUG_CPU -#include <asm/nmi.h> - -static void cpu_exit_clear(void) -{ -	int cpu = raw_smp_processor_id(); - -	idle_task_exit(); - -	cpu_uninit(); -	irq_ctx_exit(cpu); - -	cpu_clear(cpu, cpu_callout_map); -	cpu_clear(cpu, cpu_callin_map); - -	numa_remove_cpu(cpu); -	c1e_remove_cpu(cpu); -} - -/* We don't actually take CPU down, just spin without interrupts. */ -static inline void play_dead(void) -{ -	/* This must be done before dead CPU ack */ -	cpu_exit_clear(); -	mb(); -	/* Ack it */ -	__get_cpu_var(cpu_state) = CPU_DEAD; - -	/* -	 * With physical CPU hotplug, we should halt the cpu -	 */ -	local_irq_disable(); -	/* mask all interrupts, flush any and all caches, and halt */ -	wbinvd_halt(); -} -#else +#ifndef CONFIG_SMP  static inline void play_dead(void)  {  	BUG();  } -#endif /* CONFIG_HOTPLUG_CPU */ +#endif  /*   * The idle thread. There's no useful work to be @@ -155,12 +123,13 @@ void cpu_idle(void)  	}  } -void __show_registers(struct pt_regs *regs, int all) +void __show_regs(struct pt_regs *regs, int all)  {  	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;  	unsigned long d0, d1, d2, d3, d6, d7;  	unsigned long sp;  	unsigned short ss, gs; +	const char *board;  	if (user_mode_vm(regs)) {  		sp = regs->sp; @@ -173,11 +142,15 @@ void __show_registers(struct pt_regs *regs, int all)  	}  	printk("\n"); -	printk("Pid: %d, comm: %s %s (%s %.*s)\n", + +	board = dmi_get_system_info(DMI_PRODUCT_NAME); +	if (!board) +		board = ""; +	printk("Pid: %d, comm: %s %s (%s %.*s) %s\n",  			task_pid_nr(current), current->comm,  			print_tainted(), init_utsname()->release,  			(int)strcspn(init_utsname()->version, " "), -			init_utsname()->version); +			init_utsname()->version, board);  	printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",  			(u16)regs->cs, regs->ip, regs->flags, @@ -216,7 +189,7 @@ void __show_registers(struct pt_regs *regs, int all)  void show_regs(struct pt_regs *regs)  { -	__show_registers(regs, 1); +	__show_regs(regs, 1);  	show_trace(NULL, regs, ®s->sp, regs->bp);  } @@ -277,6 +250,14 @@ void exit_thread(void)  		tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET;  		put_cpu();  	} +#ifdef CONFIG_X86_DS +	/* Free any DS contexts that have not been properly released. */ +	if (unlikely(current->thread.ds_ctx)) { +		/* we clear debugctl to make sure DS is not used. */ +		update_debugctlmsr(0); +		ds_free(current->thread.ds_ctx); +	} +#endif /* CONFIG_X86_DS */  }  void flush_thread(void) @@ -438,6 +419,35 @@ int set_tsc_mode(unsigned int val)  	return 0;  } +#ifdef CONFIG_X86_DS +static int update_debugctl(struct thread_struct *prev, +			struct thread_struct *next, unsigned long debugctl) +{ +	unsigned long ds_prev = 0; +	unsigned long ds_next = 0; + +	if (prev->ds_ctx) +		ds_prev = (unsigned long)prev->ds_ctx->ds; +	if (next->ds_ctx) +		ds_next = (unsigned long)next->ds_ctx->ds; + +	if (ds_next != ds_prev) { +		/* we clear debugctl to make sure DS +		 * is not in use when we change it */ +		debugctl = 0; +		update_debugctlmsr(0); +		wrmsr(MSR_IA32_DS_AREA, ds_next, 0); +	} +	return debugctl; +} +#else +static int update_debugctl(struct thread_struct *prev, +			struct thread_struct *next, unsigned long debugctl) +{ +	return debugctl; +} +#endif /* CONFIG_X86_DS */ +  static noinline void  __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,  		 struct tss_struct *tss) @@ -448,14 +458,7 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,  	prev = &prev_p->thread;  	next = &next_p->thread; -	debugctl = prev->debugctlmsr; -	if (next->ds_area_msr != prev->ds_area_msr) { -		/* we clear debugctl to make sure DS -		 * is not in use when we change it */ -		debugctl = 0; -		update_debugctlmsr(0); -		wrmsr(MSR_IA32_DS_AREA, next->ds_area_msr, 0); -	} +	debugctl = update_debugctl(prev, next, prev->debugctlmsr);  	if (next->debugctlmsr != debugctl)  		update_debugctlmsr(next->debugctlmsr); @@ -479,13 +482,13 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,  			hard_enable_TSC();  	} -#ifdef X86_BTS +#ifdef CONFIG_X86_PTRACE_BTS  	if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))  		ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);  	if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))  		ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); -#endif +#endif /* CONFIG_X86_PTRACE_BTS */  	if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {  | 
