]> git.ipfire.org Git - thirdparty/kernel/stable.git/blame - arch/x86/kernel/process_64.c
x86-64: make compat_start_thread() match start_thread()
[thirdparty/kernel/stable.git] / arch / x86 / kernel / process_64.c
CommitLineData
1da177e4 1/*
1da177e4
LT
2 * Copyright (C) 1995 Linus Torvalds
3 *
4 * Pentium III FXSR, SSE support
5 * Gareth Hughes <gareth@valinux.com>, May 2000
6612538c 6 *
1da177e4
LT
7 * X86-64 port
8 * Andi Kleen.
76e4f660
AR
9 *
10 * CPU hotplug support - ashok.raj@intel.com
1da177e4
LT
11 */
12
13/*
14 * This file handles the architecture-dependent parts of process handling..
15 */
16
42059429 17#include <linux/stackprotector.h>
76e4f660 18#include <linux/cpu.h>
1da177e4
LT
19#include <linux/errno.h>
20#include <linux/sched.h>
6612538c 21#include <linux/fs.h>
1da177e4
LT
22#include <linux/kernel.h>
23#include <linux/mm.h>
24#include <linux/elfcore.h>
25#include <linux/smp.h>
26#include <linux/slab.h>
27#include <linux/user.h>
1da177e4 28#include <linux/interrupt.h>
6612538c 29#include <linux/utsname.h>
1da177e4 30#include <linux/delay.h>
6612538c 31#include <linux/module.h>
1da177e4 32#include <linux/ptrace.h>
95833c83 33#include <linux/notifier.h>
c6fd91f0 34#include <linux/kprobes.h>
1eeb66a1 35#include <linux/kdebug.h>
02290683 36#include <linux/tick.h>
529e25f6 37#include <linux/prctl.h>
7de08b4e
GP
38#include <linux/uaccess.h>
39#include <linux/io.h>
8b96f011 40#include <linux/ftrace.h>
48ec4d95 41#include <linux/dmi.h>
1da177e4 42
1da177e4
LT
43#include <asm/pgtable.h>
44#include <asm/system.h>
1da177e4
LT
45#include <asm/processor.h>
46#include <asm/i387.h>
47#include <asm/mmu_context.h>
1da177e4 48#include <asm/prctl.h>
1da177e4
LT
49#include <asm/desc.h>
50#include <asm/proto.h>
51#include <asm/ia32.h>
95833c83 52#include <asm/idle.h>
bbc1f698 53#include <asm/syscalls.h>
bf53de90 54#include <asm/ds.h>
1da177e4
LT
55
56asmlinkage extern void ret_from_fork(void);
57
3d1e42a7 58DEFINE_PER_CPU(unsigned long, old_rsp);
c2558e0e 59static DEFINE_PER_CPU(unsigned char, is_idle);
3d1e42a7 60
1da177e4
LT
61unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
62
e041c683 63static ATOMIC_NOTIFIER_HEAD(idle_notifier);
95833c83
AK
64
65void idle_notifier_register(struct notifier_block *n)
66{
e041c683 67 atomic_notifier_chain_register(&idle_notifier, n);
95833c83 68}
c7d87d79
VP
69EXPORT_SYMBOL_GPL(idle_notifier_register);
70
71void idle_notifier_unregister(struct notifier_block *n)
72{
73 atomic_notifier_chain_unregister(&idle_notifier, n);
74}
75EXPORT_SYMBOL_GPL(idle_notifier_unregister);
95833c83 76
95833c83
AK
77void enter_idle(void)
78{
c2558e0e 79 percpu_write(is_idle, 1);
e041c683 80 atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL);
95833c83
AK
81}
82
83static void __exit_idle(void)
84{
c2558e0e 85 if (x86_test_and_clear_bit_percpu(0, is_idle) == 0)
a15da49d 86 return;
e041c683 87 atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL);
95833c83
AK
88}
89
90/* Called from interrupts to signify idle end */
91void exit_idle(void)
92{
a15da49d
AK
93 /* idle loop has pid 0 */
94 if (current->pid)
95833c83
AK
95 return;
96 __exit_idle();
97}
98
913da64b 99#ifndef CONFIG_SMP
76e4f660
AR
100static inline void play_dead(void)
101{
102 BUG();
103}
913da64b 104#endif
76e4f660 105
1da177e4
LT
106/*
107 * The idle thread. There's no useful work to be
108 * done, so just try to conserve power and have a
109 * low exit latency (ie sit in a loop waiting for
110 * somebody to say that they'd like to reschedule)
111 */
b10db7f0 112void cpu_idle(void)
1da177e4 113{
495ab9c0 114 current_thread_info()->status |= TS_POLLING;
ce22bd92 115
ce22bd92 116 /*
5c79d2a5
TH
117 * If we're the non-boot CPU, nothing set the stack canary up
118 * for us. CPU0 already has it initialized but no harm in
119 * doing it again. This is a good place for updating it, as
120 * we wont ever return from this function (so the invalid
121 * canaries already on the stack wont ever trigger).
ce22bd92 122 */
18aa8bb1
IM
123 boot_init_stack_canary();
124
1da177e4
LT
125 /* endless idle loop with no priority at all */
126 while (1) {
b8f8c3cf 127 tick_nohz_stop_sched_tick(1);
1da177e4 128 while (!need_resched()) {
1da177e4 129
1da177e4 130 rmb();
6ddd2a27 131
76e4f660
AR
132 if (cpu_is_offline(smp_processor_id()))
133 play_dead();
d331e739
VP
134 /*
135 * Idle routines should keep interrupts disabled
136 * from here on, until they go to idle.
137 * Otherwise, idle callbacks can misfire.
138 */
139 local_irq_disable();
95833c83 140 enter_idle();
81d68a96
SR
141 /* Don't trace irqs off for idle */
142 stop_critical_timings();
6ddd2a27 143 pm_idle();
81d68a96 144 start_critical_timings();
a15da49d
AK
145 /* In many cases the interrupt that ended idle
146 has already called exit_idle. But some idle
147 loops can be woken up without interrupt. */
95833c83 148 __exit_idle();
1da177e4
LT
149 }
150
02290683 151 tick_nohz_restart_sched_tick();
5bfb5d69 152 preempt_enable_no_resched();
1da177e4 153 schedule();
5bfb5d69 154 preempt_disable();
1da177e4
LT
155 }
156}
157
6612538c 158/* Prints also some state that isn't saved in the pt_regs */
e2ce07c8 159void __show_regs(struct pt_regs *regs, int all)
1da177e4
LT
160{
161 unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs;
bb1995d5 162 unsigned long d0, d1, d2, d3, d6, d7;
6612538c
HS
163 unsigned int fsindex, gsindex;
164 unsigned int ds, cs, es;
48ec4d95 165 const char *board;
1da177e4
LT
166
167 printk("\n");
168 print_modules();
48ec4d95
KM
169 board = dmi_get_system_info(DMI_PRODUCT_NAME);
170 if (!board)
171 board = "";
172 printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s %s\n",
9acf23c4 173 current->pid, current->comm, print_tainted(),
96b644bd
SH
174 init_utsname()->release,
175 (int)strcspn(init_utsname()->version, " "),
48ec4d95 176 init_utsname()->version, board);
8092c654 177 printk(KERN_INFO "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip);
aafbd7eb 178 printk_address(regs->ip, 1);
8092c654
GP
179 printk(KERN_INFO "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss,
180 regs->sp, regs->flags);
181 printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n",
65ea5b03 182 regs->ax, regs->bx, regs->cx);
8092c654 183 printk(KERN_INFO "RDX: %016lx RSI: %016lx RDI: %016lx\n",
65ea5b03 184 regs->dx, regs->si, regs->di);
8092c654 185 printk(KERN_INFO "RBP: %016lx R08: %016lx R09: %016lx\n",
65ea5b03 186 regs->bp, regs->r8, regs->r9);
8092c654 187 printk(KERN_INFO "R10: %016lx R11: %016lx R12: %016lx\n",
7de08b4e 188 regs->r10, regs->r11, regs->r12);
8092c654 189 printk(KERN_INFO "R13: %016lx R14: %016lx R15: %016lx\n",
7de08b4e 190 regs->r13, regs->r14, regs->r15);
1da177e4 191
7de08b4e
GP
192 asm("movl %%ds,%0" : "=r" (ds));
193 asm("movl %%cs,%0" : "=r" (cs));
194 asm("movl %%es,%0" : "=r" (es));
1da177e4
LT
195 asm("movl %%fs,%0" : "=r" (fsindex));
196 asm("movl %%gs,%0" : "=r" (gsindex));
197
198 rdmsrl(MSR_FS_BASE, fs);
7de08b4e
GP
199 rdmsrl(MSR_GS_BASE, gs);
200 rdmsrl(MSR_KERNEL_GS_BASE, shadowgs);
1da177e4 201
e2ce07c8
PE
202 if (!all)
203 return;
1da177e4 204
f51c9452
GOC
205 cr0 = read_cr0();
206 cr2 = read_cr2();
207 cr3 = read_cr3();
208 cr4 = read_cr4();
1da177e4 209
8092c654 210 printk(KERN_INFO "FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n",
7de08b4e 211 fs, fsindex, gs, gsindex, shadowgs);
8092c654
GP
212 printk(KERN_INFO "CS: %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds,
213 es, cr0);
214 printk(KERN_INFO "CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3,
215 cr4);
bb1995d5
AS
216
217 get_debugreg(d0, 0);
218 get_debugreg(d1, 1);
219 get_debugreg(d2, 2);
8092c654 220 printk(KERN_INFO "DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2);
bb1995d5
AS
221 get_debugreg(d3, 3);
222 get_debugreg(d6, 6);
223 get_debugreg(d7, 7);
8092c654 224 printk(KERN_INFO "DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7);
1da177e4
LT
225}
226
227void show_regs(struct pt_regs *regs)
228{
8092c654 229 printk(KERN_INFO "CPU %d:", smp_processor_id());
e2ce07c8 230 __show_regs(regs, 1);
bc850d6b 231 show_trace(NULL, regs, (void *)(regs + 1), regs->bp);
1da177e4
LT
232}
233
1da177e4
LT
234void release_thread(struct task_struct *dead_task)
235{
236 if (dead_task->mm) {
237 if (dead_task->mm->context.size) {
238 printk("WARNING: dead process %8s still has LDT? <%p/%d>\n",
239 dead_task->comm,
240 dead_task->mm->context.ldt,
241 dead_task->mm->context.size);
242 BUG();
243 }
244 }
245}
246
247static inline void set_32bit_tls(struct task_struct *t, int tls, u32 addr)
248{
6612538c 249 struct user_desc ud = {
1da177e4
LT
250 .base_addr = addr,
251 .limit = 0xfffff,
252 .seg_32bit = 1,
253 .limit_in_pages = 1,
254 .useable = 1,
255 };
ade1af77 256 struct desc_struct *desc = t->thread.tls_array;
1da177e4 257 desc += tls;
80fbb69a 258 fill_ldt(desc, &ud);
1da177e4
LT
259}
260
261static inline u32 read_32bit_tls(struct task_struct *t, int tls)
262{
91394eb0 263 return get_desc_base(&t->thread.tls_array[tls]);
1da177e4
LT
264}
265
266/*
267 * This gets called before we allocate a new thread and copy
268 * the current task into it.
269 */
270void prepare_to_copy(struct task_struct *tsk)
271{
272 unlazy_fpu(tsk);
273}
274
6f2c55b8 275int copy_thread(unsigned long clone_flags, unsigned long sp,
1da177e4 276 unsigned long unused,
7de08b4e 277 struct task_struct *p, struct pt_regs *regs)
1da177e4
LT
278{
279 int err;
7de08b4e 280 struct pt_regs *childregs;
1da177e4
LT
281 struct task_struct *me = current;
282
a88cde13 283 childregs = ((struct pt_regs *)
57eafdc2 284 (THREAD_SIZE + task_stack_page(p))) - 1;
1da177e4
LT
285 *childregs = *regs;
286
65ea5b03
PA
287 childregs->ax = 0;
288 childregs->sp = sp;
289 if (sp == ~0UL)
290 childregs->sp = (unsigned long)childregs;
1da177e4 291
faca6227
PA
292 p->thread.sp = (unsigned long) childregs;
293 p->thread.sp0 = (unsigned long) (childregs+1);
294 p->thread.usersp = me->thread.usersp;
1da177e4 295
e4f17c43 296 set_tsk_thread_flag(p, TIF_FORK);
1da177e4
LT
297
298 p->thread.fs = me->thread.fs;
299 p->thread.gs = me->thread.gs;
300
ada85708
JF
301 savesegment(gs, p->thread.gsindex);
302 savesegment(fs, p->thread.fsindex);
303 savesegment(es, p->thread.es);
304 savesegment(ds, p->thread.ds);
1da177e4 305
d3a4f48d 306 if (unlikely(test_tsk_thread_flag(me, TIF_IO_BITMAP))) {
1da177e4
LT
307 p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
308 if (!p->thread.io_bitmap_ptr) {
309 p->thread.io_bitmap_max = 0;
310 return -ENOMEM;
311 }
a88cde13
AK
312 memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr,
313 IO_BITMAP_BYTES);
d3a4f48d 314 set_tsk_thread_flag(p, TIF_IO_BITMAP);
6612538c 315 }
1da177e4
LT
316
317 /*
318 * Set a new TLS for the child thread?
319 */
320 if (clone_flags & CLONE_SETTLS) {
321#ifdef CONFIG_IA32_EMULATION
322 if (test_thread_flag(TIF_IA32))
efd1ca52 323 err = do_set_thread_area(p, -1,
65ea5b03 324 (struct user_desc __user *)childregs->si, 0);
7de08b4e
GP
325 else
326#endif
327 err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8);
328 if (err)
1da177e4
LT
329 goto out;
330 }
bf53de90 331
2311f0de
MM
332 clear_tsk_thread_flag(p, TIF_DS_AREA_MSR);
333 p->thread.ds_ctx = NULL;
bf53de90
MM
334
335 clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR);
336 p->thread.debugctlmsr = 0;
337
1da177e4
LT
338 err = 0;
339out:
340 if (err && p->thread.io_bitmap_ptr) {
341 kfree(p->thread.io_bitmap_ptr);
342 p->thread.io_bitmap_max = 0;
343 }
344 return err;
345}
346
513ad84b
IM
347void
348start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
349{
ada85708
JF
350 loadsegment(fs, 0);
351 loadsegment(es, 0);
352 loadsegment(ds, 0);
513ad84b
IM
353 load_gs_index(0);
354 regs->ip = new_ip;
355 regs->sp = new_sp;
3d1e42a7 356 percpu_write(old_rsp, new_sp);
513ad84b
IM
357 regs->cs = __USER_CS;
358 regs->ss = __USER_DS;
a6f05a6a 359 regs->flags = X86_EFLAGS_IF;
513ad84b 360 set_fs(USER_DS);
aa283f49
SS
361 /*
362 * Free the old FP and other extended state
363 */
364 free_thread_xstate(current);
513ad84b
IM
365}
366EXPORT_SYMBOL_GPL(start_thread);
367
a6f05a6a
PA
368#ifdef CONFIG_IA32_EMULATION
369void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp)
370{
371 loadsegment(fs, 0);
372 loadsegment(ds, __USER32_DS);
373 loadsegment(es, __USER32_DS);
374 load_gs_index(0);
375 regs->ip = new_ip;
376 regs->sp = new_sp;
377 percpu_write(old_rsp, new_sp);
378 regs->cs = __USER32_CS;
379 regs->ss = __USER32_DS;
380 regs->flags = X86_EFLAGS_IF;
381 set_fs(USER_DS);
382 /*
383 * Free the old FP and other extended state
384 */
385 free_thread_xstate(current);
386}
387#endif
388
1da177e4
LT
389/*
390 * switch_to(x,y) should switch tasks from x to y.
391 *
6612538c 392 * This could still be optimized:
1da177e4
LT
393 * - fold all the options into a flag word and test it with a single test.
394 * - could test fs/gs bitsliced
099f318b
AK
395 *
396 * Kprobes not supported here. Set the probe on schedule instead.
8b96f011 397 * Function graph tracer not supported too.
1da177e4 398 */
8b96f011 399__notrace_funcgraph struct task_struct *
a88cde13 400__switch_to(struct task_struct *prev_p, struct task_struct *next_p)
1da177e4 401{
87b935a0
JF
402 struct thread_struct *prev = &prev_p->thread;
403 struct thread_struct *next = &next_p->thread;
6612538c 404 int cpu = smp_processor_id();
1da177e4 405 struct tss_struct *tss = &per_cpu(init_tss, cpu);
478de5a9 406 unsigned fsindex, gsindex;
17950c5b
JF
407 bool preload_fpu;
408
409 /*
410 * If the task has used fpu the last 5 timeslices, just do a full
411 * restore of the math state immediately to avoid the trap; the
412 * chances of needing FPU soon are obviously high now
413 */
414 preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5;
1da177e4 415
e07e23e1 416 /* we're going to use this soon, after a few expensive things */
17950c5b 417 if (preload_fpu)
61c4628b 418 prefetch(next->xstate);
e07e23e1 419
1da177e4
LT
420 /*
421 * Reload esp0, LDT and the page table pointer:
422 */
7818a1e0 423 load_sp0(tss, next);
1da177e4 424
7de08b4e 425 /*
1da177e4
LT
426 * Switch DS and ES.
427 * This won't pick up thread selector changes, but I guess that is ok.
428 */
ada85708 429 savesegment(es, prev->es);
1da177e4 430 if (unlikely(next->es | prev->es))
7de08b4e 431 loadsegment(es, next->es);
ada85708
JF
432
433 savesegment(ds, prev->ds);
1da177e4
LT
434 if (unlikely(next->ds | prev->ds))
435 loadsegment(ds, next->ds);
436
478de5a9
JF
437
438 /* We must save %fs and %gs before load_TLS() because
439 * %fs and %gs may be cleared by load_TLS().
440 *
441 * (e.g. xen_load_tls())
442 */
443 savesegment(fs, fsindex);
444 savesegment(gs, gsindex);
445
1da177e4
LT
446 load_TLS(next, cpu);
447
16d9dbf0
JF
448 /* Must be after DS reload */
449 unlazy_fpu(prev_p);
450
17950c5b
JF
451 /* Make sure cpu is ready for new context */
452 if (preload_fpu)
453 clts();
454
3fe0a63e
JF
455 /*
456 * Leave lazy mode, flushing any hypercalls made here.
457 * This must be done before restoring TLS segments so
458 * the GDT and LDT are properly updated, and must be
459 * done before math_state_restore, so the TS bit is up
460 * to date.
461 */
224101ed 462 arch_end_context_switch(next_p);
3fe0a63e 463
7de08b4e 464 /*
1da177e4 465 * Switch FS and GS.
87b935a0
JF
466 *
467 * Segment register != 0 always requires a reload. Also
468 * reload when it has changed. When prev process used 64bit
469 * base always reload to avoid an information leak.
1da177e4 470 */
87b935a0
JF
471 if (unlikely(fsindex | next->fsindex | prev->fs)) {
472 loadsegment(fs, next->fsindex);
7de08b4e 473 /*
87b935a0
JF
474 * Check if the user used a selector != 0; if yes
475 * clear 64bit base, since overloaded base is always
476 * mapped to the Null selector
477 */
478 if (fsindex)
7de08b4e 479 prev->fs = 0;
1da177e4 480 }
87b935a0
JF
481 /* when next process has a 64bit base use it */
482 if (next->fs)
483 wrmsrl(MSR_FS_BASE, next->fs);
484 prev->fsindex = fsindex;
485
486 if (unlikely(gsindex | next->gsindex | prev->gs)) {
487 load_gs_index(next->gsindex);
488 if (gsindex)
7de08b4e 489 prev->gs = 0;
1da177e4 490 }
87b935a0
JF
491 if (next->gs)
492 wrmsrl(MSR_KERNEL_GS_BASE, next->gs);
493 prev->gsindex = gsindex;
1da177e4 494
7de08b4e 495 /*
45948d77 496 * Switch the PDA and FPU contexts.
1da177e4 497 */
3d1e42a7
BG
498 prev->usersp = percpu_read(old_rsp);
499 percpu_write(old_rsp, next->usersp);
c6f5e0ac 500 percpu_write(current_task, next_p);
18bd057b 501
9af45651 502 percpu_write(kernel_stack,
87b935a0 503 (unsigned long)task_stack_page(next_p) +
9af45651 504 THREAD_SIZE - KERNEL_STACK_OFFSET);
1da177e4
LT
505
506 /*
d3a4f48d 507 * Now maybe reload the debug registers and handle I/O bitmaps
1da177e4 508 */
eee3af4a
MM
509 if (unlikely(task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT ||
510 task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
d3a4f48d 511 __switch_to_xtra(prev_p, next_p, tss);
1da177e4 512
17950c5b
JF
513 /*
514 * Preload the FPU context, now that we've determined that the
515 * task is likely to be using it.
e07e23e1 516 */
17950c5b
JF
517 if (preload_fpu)
518 __math_state_restore();
1da177e4
LT
519 return prev_p;
520}
521
522/*
523 * sys_execve() executes a new program.
524 */
6612538c 525asmlinkage
1da177e4 526long sys_execve(char __user *name, char __user * __user *argv,
5d119b2c 527 char __user * __user *envp, struct pt_regs *regs)
1da177e4
LT
528{
529 long error;
7de08b4e 530 char *filename;
1da177e4
LT
531
532 filename = getname(name);
533 error = PTR_ERR(filename);
5d119b2c 534 if (IS_ERR(filename))
1da177e4 535 return error;
5d119b2c 536 error = do_execve(filename, argv, envp, regs);
1da177e4
LT
537 putname(filename);
538 return error;
539}
540
541void set_personality_64bit(void)
542{
543 /* inherit personality from parent */
544
545 /* Make sure to be in 64bit mode */
6612538c 546 clear_thread_flag(TIF_IA32);
1da177e4
LT
547
548 /* TBD: overwrites user setup. Should have two bits.
549 But 64bit processes have always behaved this way,
550 so it's not too bad. The main problem is just that
6612538c 551 32bit childs are affected again. */
1da177e4
LT
552 current->personality &= ~READ_IMPLIES_EXEC;
553}
554
a88cde13
AK
555asmlinkage long
556sys_clone(unsigned long clone_flags, unsigned long newsp,
557 void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
1da177e4
LT
558{
559 if (!newsp)
65ea5b03 560 newsp = regs->sp;
1da177e4
LT
561 return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
562}
563
1da177e4
LT
564unsigned long get_wchan(struct task_struct *p)
565{
566 unsigned long stack;
7de08b4e 567 u64 fp, ip;
1da177e4
LT
568 int count = 0;
569
7de08b4e
GP
570 if (!p || p == current || p->state == TASK_RUNNING)
571 return 0;
57eafdc2 572 stack = (unsigned long)task_stack_page(p);
e1e23bb0 573 if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE)
1da177e4 574 return 0;
faca6227 575 fp = *(u64 *)(p->thread.sp);
7de08b4e 576 do {
a88cde13 577 if (fp < (unsigned long)stack ||
e1e23bb0 578 fp >= (unsigned long)stack+THREAD_SIZE)
7de08b4e 579 return 0;
65ea5b03
PA
580 ip = *(u64 *)(fp+8);
581 if (!in_sched_functions(ip))
582 return ip;
7de08b4e
GP
583 fp = *(u64 *)fp;
584 } while (count++ < 16);
1da177e4
LT
585 return 0;
586}
587
588long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
7de08b4e
GP
589{
590 int ret = 0;
1da177e4
LT
591 int doit = task == current;
592 int cpu;
593
7de08b4e 594 switch (code) {
1da177e4 595 case ARCH_SET_GS:
84929801 596 if (addr >= TASK_SIZE_OF(task))
7de08b4e 597 return -EPERM;
1da177e4 598 cpu = get_cpu();
7de08b4e 599 /* handle small bases via the GDT because that's faster to
1da177e4 600 switch. */
7de08b4e
GP
601 if (addr <= 0xffffffff) {
602 set_32bit_tls(task, GS_TLS, addr);
603 if (doit) {
1da177e4 604 load_TLS(&task->thread, cpu);
7de08b4e 605 load_gs_index(GS_TLS_SEL);
1da177e4 606 }
7de08b4e 607 task->thread.gsindex = GS_TLS_SEL;
1da177e4 608 task->thread.gs = 0;
7de08b4e 609 } else {
1da177e4
LT
610 task->thread.gsindex = 0;
611 task->thread.gs = addr;
612 if (doit) {
a88cde13
AK
613 load_gs_index(0);
614 ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr);
7de08b4e 615 }
1da177e4
LT
616 }
617 put_cpu();
618 break;
619 case ARCH_SET_FS:
620 /* Not strictly needed for fs, but do it for symmetry
621 with gs */
84929801 622 if (addr >= TASK_SIZE_OF(task))
6612538c 623 return -EPERM;
1da177e4 624 cpu = get_cpu();
6612538c 625 /* handle small bases via the GDT because that's faster to
1da177e4 626 switch. */
6612538c 627 if (addr <= 0xffffffff) {
1da177e4 628 set_32bit_tls(task, FS_TLS, addr);
6612538c
HS
629 if (doit) {
630 load_TLS(&task->thread, cpu);
ada85708 631 loadsegment(fs, FS_TLS_SEL);
1da177e4
LT
632 }
633 task->thread.fsindex = FS_TLS_SEL;
634 task->thread.fs = 0;
6612538c 635 } else {
1da177e4
LT
636 task->thread.fsindex = 0;
637 task->thread.fs = addr;
638 if (doit) {
639 /* set the selector to 0 to not confuse
640 __switch_to */
ada85708 641 loadsegment(fs, 0);
a88cde13 642 ret = checking_wrmsrl(MSR_FS_BASE, addr);
1da177e4
LT
643 }
644 }
645 put_cpu();
646 break;
6612538c
HS
647 case ARCH_GET_FS: {
648 unsigned long base;
1da177e4
LT
649 if (task->thread.fsindex == FS_TLS_SEL)
650 base = read_32bit_tls(task, FS_TLS);
a88cde13 651 else if (doit)
1da177e4 652 rdmsrl(MSR_FS_BASE, base);
a88cde13 653 else
1da177e4 654 base = task->thread.fs;
6612538c
HS
655 ret = put_user(base, (unsigned long __user *)addr);
656 break;
1da177e4 657 }
6612538c 658 case ARCH_GET_GS: {
1da177e4 659 unsigned long base;
97c2803c 660 unsigned gsindex;
1da177e4
LT
661 if (task->thread.gsindex == GS_TLS_SEL)
662 base = read_32bit_tls(task, GS_TLS);
97c2803c 663 else if (doit) {
ada85708 664 savesegment(gs, gsindex);
97c2803c
JB
665 if (gsindex)
666 rdmsrl(MSR_KERNEL_GS_BASE, base);
667 else
668 base = task->thread.gs;
7de08b4e 669 } else
1da177e4 670 base = task->thread.gs;
6612538c 671 ret = put_user(base, (unsigned long __user *)addr);
1da177e4
LT
672 break;
673 }
674
675 default:
676 ret = -EINVAL;
677 break;
6612538c 678 }
1da177e4 679
6612538c
HS
680 return ret;
681}
1da177e4
LT
682
683long sys_arch_prctl(int code, unsigned long addr)
684{
685 return do_arch_prctl(current, code, addr);
1da177e4
LT
686}
687