aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/process_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/process_64.c')
-rw-r--r--arch/x86/kernel/process_64.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 416fb9282f4f..836ef6575f01 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -16,6 +16,7 @@
16 16
17#include <stdarg.h> 17#include <stdarg.h>
18 18
19#include <linux/stackprotector.h>
19#include <linux/cpu.h> 20#include <linux/cpu.h>
20#include <linux/errno.h> 21#include <linux/errno.h>
21#include <linux/sched.h> 22#include <linux/sched.h>
@@ -40,13 +41,13 @@
40#include <linux/uaccess.h> 41#include <linux/uaccess.h>
41#include <linux/io.h> 42#include <linux/io.h>
42#include <linux/ftrace.h> 43#include <linux/ftrace.h>
44#include <linux/dmi.h>
43 45
44#include <asm/pgtable.h> 46#include <asm/pgtable.h>
45#include <asm/system.h> 47#include <asm/system.h>
46#include <asm/processor.h> 48#include <asm/processor.h>
47#include <asm/i387.h> 49#include <asm/i387.h>
48#include <asm/mmu_context.h> 50#include <asm/mmu_context.h>
49#include <asm/pda.h>
50#include <asm/prctl.h> 51#include <asm/prctl.h>
51#include <asm/desc.h> 52#include <asm/desc.h>
52#include <asm/proto.h> 53#include <asm/proto.h>
@@ -57,6 +58,12 @@
57 58
58asmlinkage extern void ret_from_fork(void); 59asmlinkage extern void ret_from_fork(void);
59 60
61DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
62EXPORT_PER_CPU_SYMBOL(current_task);
63
64DEFINE_PER_CPU(unsigned long, old_rsp);
65static DEFINE_PER_CPU(unsigned char, is_idle);
66
60unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED; 67unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
61 68
62static ATOMIC_NOTIFIER_HEAD(idle_notifier); 69static ATOMIC_NOTIFIER_HEAD(idle_notifier);
@@ -75,13 +82,13 @@ EXPORT_SYMBOL_GPL(idle_notifier_unregister);
75 82
76void enter_idle(void) 83void enter_idle(void)
77{ 84{
78 write_pda(isidle, 1); 85 percpu_write(is_idle, 1);
79 atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL); 86 atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL);
80} 87}
81 88
82static void __exit_idle(void) 89static void __exit_idle(void)
83{ 90{
84 if (test_and_clear_bit_pda(0, isidle) == 0) 91 if (x86_test_and_clear_bit_percpu(0, is_idle) == 0)
85 return; 92 return;
86 atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL); 93 atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL);
87} 94}
@@ -111,6 +118,16 @@ static inline void play_dead(void)
111void cpu_idle(void) 118void cpu_idle(void)
112{ 119{
113 current_thread_info()->status |= TS_POLLING; 120 current_thread_info()->status |= TS_POLLING;
121
122 /*
123 * If we're the non-boot CPU, nothing set the stack canary up
124 * for us. CPU0 already has it initialized but no harm in
125 * doing it again. This is a good place for updating it, as
126 * we wont ever return from this function (so the invalid
127 * canaries already on the stack wont ever trigger).
128 */
129 boot_init_stack_canary();
130
114 /* endless idle loop with no priority at all */ 131 /* endless idle loop with no priority at all */
115 while (1) { 132 while (1) {
116 tick_nohz_stop_sched_tick(1); 133 tick_nohz_stop_sched_tick(1);
@@ -151,14 +168,18 @@ void __show_regs(struct pt_regs *regs, int all)
151 unsigned long d0, d1, d2, d3, d6, d7; 168 unsigned long d0, d1, d2, d3, d6, d7;
152 unsigned int fsindex, gsindex; 169 unsigned int fsindex, gsindex;
153 unsigned int ds, cs, es; 170 unsigned int ds, cs, es;
171 const char *board;
154 172
155 printk("\n"); 173 printk("\n");
156 print_modules(); 174 print_modules();
157 printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s\n", 175 board = dmi_get_system_info(DMI_PRODUCT_NAME);
176 if (!board)
177 board = "";
178 printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s %s\n",
158 current->pid, current->comm, print_tainted(), 179 current->pid, current->comm, print_tainted(),
159 init_utsname()->release, 180 init_utsname()->release,
160 (int)strcspn(init_utsname()->version, " "), 181 (int)strcspn(init_utsname()->version, " "),
161 init_utsname()->version); 182 init_utsname()->version, board);
162 printk(KERN_INFO "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip); 183 printk(KERN_INFO "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip);
163 printk_address(regs->ip, 1); 184 printk_address(regs->ip, 1);
164 printk(KERN_INFO "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, 185 printk(KERN_INFO "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss,
@@ -392,7 +413,7 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
392 load_gs_index(0); 413 load_gs_index(0);
393 regs->ip = new_ip; 414 regs->ip = new_ip;
394 regs->sp = new_sp; 415 regs->sp = new_sp;
395 write_pda(oldrsp, new_sp); 416 percpu_write(old_rsp, new_sp);
396 regs->cs = __USER_CS; 417 regs->cs = __USER_CS;
397 regs->ss = __USER_DS; 418 regs->ss = __USER_DS;
398 regs->flags = 0x200; 419 regs->flags = 0x200;
@@ -613,21 +634,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
613 /* 634 /*
614 * Switch the PDA and FPU contexts. 635 * Switch the PDA and FPU contexts.
615 */ 636 */
616 prev->usersp = read_pda(oldrsp); 637 prev->usersp = percpu_read(old_rsp);
617 write_pda(oldrsp, next->usersp); 638 percpu_write(old_rsp, next->usersp);
618 write_pda(pcurrent, next_p); 639 percpu_write(current_task, next_p);
619 640
620 write_pda(kernelstack, 641 percpu_write(kernel_stack,
621 (unsigned long)task_stack_page(next_p) + 642 (unsigned long)task_stack_page(next_p) +
622 THREAD_SIZE - PDA_STACKOFFSET); 643 THREAD_SIZE - KERNEL_STACK_OFFSET);
623#ifdef CONFIG_CC_STACKPROTECTOR
624 write_pda(stack_canary, next_p->stack_canary);
625 /*
626 * Build time only check to make sure the stack_canary is at
627 * offset 40 in the pda; this is a gcc ABI requirement
628 */
629 BUILD_BUG_ON(offsetof(struct x8664_pda, stack_canary) != 40);
630#endif
631 644
632 /* 645 /*
633 * Now maybe reload the debug registers and handle I/O bitmaps 646 * Now maybe reload the debug registers and handle I/O bitmaps