ia64/xen-unstable

view linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c @ 7226:072fb38810a6

Revert changes checked in by mistake in previous changeset.
author kaf24@firebug.cl.cam.ac.uk
date Wed Oct 05 15:15:50 2005 +0100 (2005-10-05)
parents 8f8e42887f09
children 4e0c94871be2
line source
1 /*
2 * linux/arch/i386/kernel/process.c
3 *
4 * Copyright (C) 1995 Linus Torvalds
5 *
6 * Pentium III FXSR, SSE support
7 * Gareth Hughes <gareth@valinux.com>, May 2000
8 */
10 /*
11 * This file handles the architecture-dependent parts of process handling..
12 */
14 #include <stdarg.h>
16 #include <linux/cpu.h>
17 #include <linux/errno.h>
18 #include <linux/sched.h>
19 #include <linux/fs.h>
20 #include <linux/kernel.h>
21 #include <linux/mm.h>
22 #include <linux/elfcore.h>
23 #include <linux/smp.h>
24 #include <linux/smp_lock.h>
25 #include <linux/stddef.h>
26 #include <linux/slab.h>
27 #include <linux/vmalloc.h>
28 #include <linux/user.h>
29 #include <linux/a.out.h>
30 #include <linux/interrupt.h>
31 #include <linux/config.h>
32 #include <linux/utsname.h>
33 #include <linux/delay.h>
34 #include <linux/reboot.h>
35 #include <linux/init.h>
36 #include <linux/mc146818rtc.h>
37 #include <linux/module.h>
38 #include <linux/kallsyms.h>
39 #include <linux/ptrace.h>
40 #include <linux/random.h>
42 #include <asm/uaccess.h>
43 #include <asm/pgtable.h>
44 #include <asm/system.h>
45 #include <asm/io.h>
46 #include <asm/ldt.h>
47 #include <asm/processor.h>
48 #include <asm/i387.h>
49 #include <asm/irq.h>
50 #include <asm/desc.h>
51 #include <asm-xen/xen-public/physdev.h>
52 #include <asm-xen/xen-public/vcpu.h>
53 #ifdef CONFIG_MATH_EMULATION
54 #include <asm/math_emu.h>
55 #endif
57 #include <linux/irq.h>
58 #include <linux/err.h>
60 #include <asm/tlbflush.h>
61 #include <asm/cpu.h>
63 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
65 static int hlt_counter;
67 unsigned long boot_option_idle_override = 0;
68 EXPORT_SYMBOL(boot_option_idle_override);
70 /*
71 * Return saved PC of a blocked thread.
72 */
73 unsigned long thread_saved_pc(struct task_struct *tsk)
74 {
75 return ((unsigned long *)tsk->thread.esp)[3];
76 }
78 /*
79 * Powermanagement idle function, if any..
80 */
81 void (*pm_idle)(void);
82 static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
84 void disable_hlt(void)
85 {
86 hlt_counter++;
87 }
89 EXPORT_SYMBOL(disable_hlt);
91 void enable_hlt(void)
92 {
93 hlt_counter--;
94 }
96 EXPORT_SYMBOL(enable_hlt);
98 /* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */
99 extern void stop_hz_timer(void);
100 extern void start_hz_timer(void);
101 void xen_idle(void)
102 {
103 local_irq_disable();
105 if (need_resched()) {
106 local_irq_enable();
107 } else {
108 stop_hz_timer();
109 /* Blocking includes an implicit local_irq_enable(). */
110 HYPERVISOR_sched_op(SCHEDOP_block, 0);
111 start_hz_timer();
112 }
113 }
115 #ifdef CONFIG_HOTPLUG_CPU
116 #include <asm/nmi.h>
117 #ifdef CONFIG_SMP
118 extern void smp_suspend(void);
119 extern void smp_resume(void);
120 #endif
121 /* We don't actually take CPU down, just spin without interrupts. */
122 static inline void play_dead(void)
123 {
124 /* Death loop */
125 while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
126 HYPERVISOR_sched_op(SCHEDOP_yield, 0);
128 __flush_tlb_all();
129 /*
130 * Restore IPI/IRQ mappings before marking online to prevent
131 * race between pending interrupts and restoration of handler.
132 */
133 #ifdef CONFIG_SMP
134 local_irq_enable(); /* XXX Needed for smp_resume(). Clean me up. */
135 smp_resume();
136 #endif
137 cpu_set(smp_processor_id(), cpu_online_map);
138 }
139 #else
140 static inline void play_dead(void)
141 {
142 BUG();
143 }
144 #endif /* CONFIG_HOTPLUG_CPU */
146 void cpu_restore(void)
147 {
148 play_dead();
149 local_irq_enable();
150 cpu_idle();
151 }
153 /*
154 * The idle thread. There's no useful work to be
155 * done, so just try to conserve power and have a
156 * low exit latency (ie sit in a loop waiting for
157 * somebody to say that they'd like to reschedule)
158 */
159 void cpu_idle (void)
160 {
161 int cpu = _smp_processor_id();
163 /* endless idle loop with no priority at all */
164 while (1) {
165 while (!need_resched()) {
167 if (__get_cpu_var(cpu_idle_state))
168 __get_cpu_var(cpu_idle_state) = 0;
169 rmb();
171 if (cpu_is_offline(cpu)) {
172 local_irq_disable();
173 #ifdef CONFIG_SMP
174 smp_suspend();
175 #endif
176 #if defined(CONFIG_XEN) && defined(CONFIG_HOTPLUG_CPU)
177 /* Ack it. From this point on until
178 we get woken up, we're not allowed
179 to take any locks. In particular,
180 don't printk. */
181 __get_cpu_var(cpu_state) = CPU_DEAD;
182 /* Tell hypervisor to take vcpu down. */
183 HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL);
184 #endif
185 play_dead();
186 local_irq_enable();
187 }
189 __get_cpu_var(irq_stat).idle_timestamp = jiffies;
190 xen_idle();
191 }
192 schedule();
193 }
194 }
196 void cpu_idle_wait(void)
197 {
198 unsigned int cpu, this_cpu = get_cpu();
199 cpumask_t map;
201 set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
202 put_cpu();
204 cpus_clear(map);
205 for_each_online_cpu(cpu) {
206 per_cpu(cpu_idle_state, cpu) = 1;
207 cpu_set(cpu, map);
208 }
210 __get_cpu_var(cpu_idle_state) = 0;
212 wmb();
213 do {
214 ssleep(1);
215 for_each_online_cpu(cpu) {
216 if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
217 cpu_clear(cpu, map);
218 }
219 cpus_and(map, map, cpu_online_map);
220 } while (!cpus_empty(map));
221 }
222 EXPORT_SYMBOL_GPL(cpu_idle_wait);
224 /* XXX XEN doesn't use mwait_idle(), select_idle_routine(), idle_setup(). */
225 /* Always use xen_idle() instead. */
226 void __init select_idle_routine(const struct cpuinfo_x86 *c) {}
228 void show_regs(struct pt_regs * regs)
229 {
230 printk("\n");
231 printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
232 printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
233 print_symbol("EIP is at %s\n", regs->eip);
235 if (regs->xcs & 2)
236 printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
237 printk(" EFLAGS: %08lx %s (%s)\n",
238 regs->eflags, print_tainted(), system_utsname.release);
239 printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
240 regs->eax,regs->ebx,regs->ecx,regs->edx);
241 printk("ESI: %08lx EDI: %08lx EBP: %08lx",
242 regs->esi, regs->edi, regs->ebp);
243 printk(" DS: %04x ES: %04x\n",
244 0xffff & regs->xds,0xffff & regs->xes);
246 show_trace(NULL, &regs->esp);
247 }
249 /*
250 * This gets run with %ebx containing the
251 * function to call, and %edx containing
252 * the "args".
253 */
254 extern void kernel_thread_helper(void);
255 __asm__(".section .text\n"
256 ".align 4\n"
257 "kernel_thread_helper:\n\t"
258 "movl %edx,%eax\n\t"
259 "pushl %edx\n\t"
260 "call *%ebx\n\t"
261 "pushl %eax\n\t"
262 "call do_exit\n"
263 ".previous");
265 /*
266 * Create a kernel thread
267 */
268 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
269 {
270 struct pt_regs regs;
272 memset(&regs, 0, sizeof(regs));
274 regs.ebx = (unsigned long) fn;
275 regs.edx = (unsigned long) arg;
277 regs.xds = __USER_DS;
278 regs.xes = __USER_DS;
279 regs.orig_eax = -1;
280 regs.eip = (unsigned long) kernel_thread_helper;
281 regs.xcs = __KERNEL_CS;
282 regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
284 /* Ok, create the new process.. */
285 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
286 }
288 /*
289 * Free current thread data structures etc..
290 */
291 void exit_thread(void)
292 {
293 struct task_struct *tsk = current;
294 struct thread_struct *t = &tsk->thread;
296 /* The process may have allocated an io port bitmap... nuke it. */
297 if (unlikely(NULL != t->io_bitmap_ptr)) {
298 physdev_op_t op = { 0 };
299 op.cmd = PHYSDEVOP_SET_IOBITMAP;
300 HYPERVISOR_physdev_op(&op);
301 kfree(t->io_bitmap_ptr);
302 t->io_bitmap_ptr = NULL;
303 }
304 }
306 void flush_thread(void)
307 {
308 struct task_struct *tsk = current;
310 memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
311 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
312 /*
313 * Forget coprocessor state..
314 */
315 clear_fpu(tsk);
316 clear_used_math();
317 }
319 void release_thread(struct task_struct *dead_task)
320 {
321 if (dead_task->mm) {
322 // temporary debugging check
323 if (dead_task->mm->context.size) {
324 printk("WARNING: dead process %8s still has LDT? <%p/%d>\n",
325 dead_task->comm,
326 dead_task->mm->context.ldt,
327 dead_task->mm->context.size);
328 BUG();
329 }
330 }
332 release_vm86_irqs(dead_task);
333 }
335 /*
336 * This gets called before we allocate a new thread and copy
337 * the current task into it.
338 */
339 void prepare_to_copy(struct task_struct *tsk)
340 {
341 unlazy_fpu(tsk);
342 }
344 int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
345 unsigned long unused,
346 struct task_struct * p, struct pt_regs * regs)
347 {
348 struct pt_regs * childregs;
349 struct task_struct *tsk;
350 int err;
352 childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
353 /*
354 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
355 * This is necessary to guarantee that the entire "struct pt_regs"
356 * is accessable even if the CPU haven't stored the SS/ESP registers
357 * on the stack (interrupt gate does not save these registers
358 * when switching to the same priv ring).
359 * Therefore beware: accessing the xss/esp fields of the
360 * "struct pt_regs" is possible, but they may contain the
361 * completely wrong values.
362 */
363 childregs = (struct pt_regs *) ((unsigned long) childregs - 8);
364 *childregs = *regs;
365 childregs->eax = 0;
366 childregs->esp = esp;
368 p->thread.esp = (unsigned long) childregs;
369 p->thread.esp0 = (unsigned long) (childregs+1);
371 p->thread.eip = (unsigned long) ret_from_fork;
373 savesegment(fs,p->thread.fs);
374 savesegment(gs,p->thread.gs);
376 tsk = current;
377 if (unlikely(NULL != tsk->thread.io_bitmap_ptr)) {
378 p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
379 if (!p->thread.io_bitmap_ptr) {
380 p->thread.io_bitmap_max = 0;
381 return -ENOMEM;
382 }
383 memcpy(p->thread.io_bitmap_ptr, tsk->thread.io_bitmap_ptr,
384 IO_BITMAP_BYTES);
385 }
387 /*
388 * Set a new TLS for the child thread?
389 */
390 if (clone_flags & CLONE_SETTLS) {
391 struct desc_struct *desc;
392 struct user_desc info;
393 int idx;
395 err = -EFAULT;
396 if (copy_from_user(&info, (void __user *)childregs->esi, sizeof(info)))
397 goto out;
398 err = -EINVAL;
399 if (LDT_empty(&info))
400 goto out;
402 idx = info.entry_number;
403 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
404 goto out;
406 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
407 desc->a = LDT_entry_a(&info);
408 desc->b = LDT_entry_b(&info);
409 }
411 p->thread.io_pl = current->thread.io_pl;
413 err = 0;
414 out:
415 if (err && p->thread.io_bitmap_ptr) {
416 kfree(p->thread.io_bitmap_ptr);
417 p->thread.io_bitmap_max = 0;
418 }
419 return err;
420 }
422 /*
423 * fill in the user structure for a core dump..
424 */
425 void dump_thread(struct pt_regs * regs, struct user * dump)
426 {
427 int i;
429 /* changed the size calculations - should hopefully work better. lbt */
430 dump->magic = CMAGIC;
431 dump->start_code = 0;
432 dump->start_stack = regs->esp & ~(PAGE_SIZE - 1);
433 dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
434 dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
435 dump->u_dsize -= dump->u_tsize;
436 dump->u_ssize = 0;
437 for (i = 0; i < 8; i++)
438 dump->u_debugreg[i] = current->thread.debugreg[i];
440 if (dump->start_stack < TASK_SIZE)
441 dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
443 dump->regs.ebx = regs->ebx;
444 dump->regs.ecx = regs->ecx;
445 dump->regs.edx = regs->edx;
446 dump->regs.esi = regs->esi;
447 dump->regs.edi = regs->edi;
448 dump->regs.ebp = regs->ebp;
449 dump->regs.eax = regs->eax;
450 dump->regs.ds = regs->xds;
451 dump->regs.es = regs->xes;
452 savesegment(fs,dump->regs.fs);
453 savesegment(gs,dump->regs.gs);
454 dump->regs.orig_eax = regs->orig_eax;
455 dump->regs.eip = regs->eip;
456 dump->regs.cs = regs->xcs;
457 dump->regs.eflags = regs->eflags;
458 dump->regs.esp = regs->esp;
459 dump->regs.ss = regs->xss;
461 dump->u_fpvalid = dump_fpu (regs, &dump->i387);
462 }
464 /*
465 * Capture the user space registers if the task is not running (in user space)
466 */
467 int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
468 {
469 struct pt_regs ptregs;
471 ptregs = *(struct pt_regs *)
472 ((unsigned long)tsk->thread_info+THREAD_SIZE - sizeof(ptregs));
473 ptregs.xcs &= 0xffff;
474 ptregs.xds &= 0xffff;
475 ptregs.xes &= 0xffff;
476 ptregs.xss &= 0xffff;
478 elf_core_copy_regs(regs, &ptregs);
480 boot_option_idle_override = 1;
481 return 1;
482 }
484 /*
485 * switch_to(x,yn) should switch tasks from x to y.
486 *
487 * We fsave/fwait so that an exception goes off at the right time
488 * (as a call from the fsave or fwait in effect) rather than to
489 * the wrong process. Lazy FP saving no longer makes any sense
490 * with modern CPU's, and this simplifies a lot of things (SMP
491 * and UP become the same).
492 *
493 * NOTE! We used to use the x86 hardware context switching. The
494 * reason for not using it any more becomes apparent when you
495 * try to recover gracefully from saved state that is no longer
496 * valid (stale segment register values in particular). With the
497 * hardware task-switch, there is no way to fix up bad state in
498 * a reasonable manner.
499 *
500 * The fact that Intel documents the hardware task-switching to
501 * be slow is a fairly red herring - this code is not noticeably
502 * faster. However, there _is_ some room for improvement here,
503 * so the performance issues may eventually be a valid point.
504 * More important, however, is the fact that this allows us much
505 * more flexibility.
506 *
507 * The return value (in %eax) will be the "prev" task after
508 * the task-switch, and shows up in ret_from_fork in entry.S,
509 * for example.
510 */
511 struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
512 {
513 struct thread_struct *prev = &prev_p->thread,
514 *next = &next_p->thread;
515 int cpu = smp_processor_id();
516 struct tss_struct *tss = &per_cpu(init_tss, cpu);
517 physdev_op_t iopl_op, iobmp_op;
518 multicall_entry_t _mcl[8], *mcl = _mcl;
520 /* XEN NOTE: FS/GS saved in switch_mm(), not here. */
522 /*
523 * This is basically '__unlazy_fpu', except that we queue a
524 * multicall to indicate FPU task switch, rather than
525 * synchronously trapping to Xen.
526 */
527 if (prev_p->thread_info->status & TS_USEDFPU) {
528 __save_init_fpu(prev_p); /* _not_ save_init_fpu() */
529 mcl->op = __HYPERVISOR_fpu_taskswitch;
530 mcl->args[0] = 1;
531 mcl++;
532 }
534 /*
535 * Reload esp0, LDT and the page table pointer:
536 * This is load_esp0(tss, next) with a multicall.
537 */
538 tss->esp0 = next->esp0;
539 mcl->op = __HYPERVISOR_stack_switch;
540 mcl->args[0] = tss->ss0;
541 mcl->args[1] = tss->esp0;
542 mcl++;
544 /*
545 * Load the per-thread Thread-Local Storage descriptor.
546 * This is load_TLS(next, cpu) with multicalls.
547 */
548 #define C(i) do { \
549 if (unlikely(next->tls_array[i].a != prev->tls_array[i].a || \
550 next->tls_array[i].b != prev->tls_array[i].b)) { \
551 mcl->op = __HYPERVISOR_update_descriptor; \
552 *(u64 *)&mcl->args[0] = virt_to_machine( \
553 &get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i]);\
554 *(u64 *)&mcl->args[2] = *(u64 *)&next->tls_array[i]; \
555 mcl++; \
556 } \
557 } while (0)
558 C(0); C(1); C(2);
559 #undef C
561 if (unlikely(prev->io_pl != next->io_pl)) {
562 iopl_op.cmd = PHYSDEVOP_SET_IOPL;
563 iopl_op.u.set_iopl.iopl = (next->io_pl == 0) ? 1 : next->io_pl;
564 mcl->op = __HYPERVISOR_physdev_op;
565 mcl->args[0] = (unsigned long)&iopl_op;
566 mcl++;
567 }
569 if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
570 iobmp_op.cmd =
571 PHYSDEVOP_SET_IOBITMAP;
572 iobmp_op.u.set_iobitmap.bitmap =
573 (char *)next->io_bitmap_ptr;
574 iobmp_op.u.set_iobitmap.nr_ports =
575 next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
576 mcl->op = __HYPERVISOR_physdev_op;
577 mcl->args[0] = (unsigned long)&iobmp_op;
578 mcl++;
579 }
581 (void)HYPERVISOR_multicall(_mcl, mcl - _mcl);
583 /*
584 * Restore %fs and %gs if needed.
585 */
586 if (unlikely(next->fs | next->gs)) {
587 loadsegment(fs, next->fs);
588 loadsegment(gs, next->gs);
589 }
591 /*
592 * Now maybe reload the debug registers
593 */
594 if (unlikely(next->debugreg[7])) {
595 loaddebug(next, 0);
596 loaddebug(next, 1);
597 loaddebug(next, 2);
598 loaddebug(next, 3);
599 /* no 4 and 5 */
600 loaddebug(next, 6);
601 loaddebug(next, 7);
602 }
604 return prev_p;
605 }
607 asmlinkage int sys_fork(struct pt_regs regs)
608 {
609 return do_fork(SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
610 }
612 asmlinkage int sys_clone(struct pt_regs regs)
613 {
614 unsigned long clone_flags;
615 unsigned long newsp;
616 int __user *parent_tidptr, *child_tidptr;
618 clone_flags = regs.ebx;
619 newsp = regs.ecx;
620 parent_tidptr = (int __user *)regs.edx;
621 child_tidptr = (int __user *)regs.edi;
622 if (!newsp)
623 newsp = regs.esp;
624 return do_fork(clone_flags, newsp, &regs, 0, parent_tidptr, child_tidptr);
625 }
627 /*
628 * This is trivial, and on the face of it looks like it
629 * could equally well be done in user mode.
630 *
631 * Not so, for quite unobvious reasons - register pressure.
632 * In user mode vfork() cannot have a stack frame, and if
633 * done by calling the "clone()" system call directly, you
634 * do not have enough call-clobbered registers to hold all
635 * the information you need.
636 */
637 asmlinkage int sys_vfork(struct pt_regs regs)
638 {
639 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
640 }
642 /*
643 * sys_execve() executes a new program.
644 */
645 asmlinkage int sys_execve(struct pt_regs regs)
646 {
647 int error;
648 char * filename;
650 filename = getname((char __user *) regs.ebx);
651 error = PTR_ERR(filename);
652 if (IS_ERR(filename))
653 goto out;
654 error = do_execve(filename,
655 (char __user * __user *) regs.ecx,
656 (char __user * __user *) regs.edx,
657 &regs);
658 if (error == 0) {
659 task_lock(current);
660 current->ptrace &= ~PT_DTRACE;
661 task_unlock(current);
662 /* Make sure we don't return using sysenter.. */
663 set_thread_flag(TIF_IRET);
664 }
665 putname(filename);
666 out:
667 return error;
668 }
670 #define top_esp (THREAD_SIZE - sizeof(unsigned long))
671 #define top_ebp (THREAD_SIZE - 2*sizeof(unsigned long))
673 unsigned long get_wchan(struct task_struct *p)
674 {
675 unsigned long ebp, esp, eip;
676 unsigned long stack_page;
677 int count = 0;
678 if (!p || p == current || p->state == TASK_RUNNING)
679 return 0;
680 stack_page = (unsigned long)p->thread_info;
681 esp = p->thread.esp;
682 if (!stack_page || esp < stack_page || esp > top_esp+stack_page)
683 return 0;
684 /* include/asm-i386/system.h:switch_to() pushes ebp last. */
685 ebp = *(unsigned long *) esp;
686 do {
687 if (ebp < stack_page || ebp > top_ebp+stack_page)
688 return 0;
689 eip = *(unsigned long *) (ebp+4);
690 if (!in_sched_functions(eip))
691 return eip;
692 ebp = *(unsigned long *) ebp;
693 } while (count++ < 16);
694 return 0;
695 }
697 /*
698 * sys_alloc_thread_area: get a yet unused TLS descriptor index.
699 */
700 static int get_free_idx(void)
701 {
702 struct thread_struct *t = &current->thread;
703 int idx;
705 for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
706 if (desc_empty(t->tls_array + idx))
707 return idx + GDT_ENTRY_TLS_MIN;
708 return -ESRCH;
709 }
711 /*
712 * Set a given TLS descriptor:
713 */
714 asmlinkage int sys_set_thread_area(struct user_desc __user *u_info)
715 {
716 struct thread_struct *t = &current->thread;
717 struct user_desc info;
718 struct desc_struct *desc;
719 int cpu, idx;
721 if (copy_from_user(&info, u_info, sizeof(info)))
722 return -EFAULT;
723 idx = info.entry_number;
725 /*
726 * index -1 means the kernel should try to find and
727 * allocate an empty descriptor:
728 */
729 if (idx == -1) {
730 idx = get_free_idx();
731 if (idx < 0)
732 return idx;
733 if (put_user(idx, &u_info->entry_number))
734 return -EFAULT;
735 }
737 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
738 return -EINVAL;
740 desc = t->tls_array + idx - GDT_ENTRY_TLS_MIN;
742 /*
743 * We must not get preempted while modifying the TLS.
744 */
745 cpu = get_cpu();
747 if (LDT_empty(&info)) {
748 desc->a = 0;
749 desc->b = 0;
750 } else {
751 desc->a = LDT_entry_a(&info);
752 desc->b = LDT_entry_b(&info);
753 }
754 load_TLS(t, cpu);
756 put_cpu();
758 return 0;
759 }
761 /*
762 * Get the current Thread-Local Storage area:
763 */
765 #define GET_BASE(desc) ( \
766 (((desc)->a >> 16) & 0x0000ffff) | \
767 (((desc)->b << 16) & 0x00ff0000) | \
768 ( (desc)->b & 0xff000000) )
770 #define GET_LIMIT(desc) ( \
771 ((desc)->a & 0x0ffff) | \
772 ((desc)->b & 0xf0000) )
774 #define GET_32BIT(desc) (((desc)->b >> 22) & 1)
775 #define GET_CONTENTS(desc) (((desc)->b >> 10) & 3)
776 #define GET_WRITABLE(desc) (((desc)->b >> 9) & 1)
777 #define GET_LIMIT_PAGES(desc) (((desc)->b >> 23) & 1)
778 #define GET_PRESENT(desc) (((desc)->b >> 15) & 1)
779 #define GET_USEABLE(desc) (((desc)->b >> 20) & 1)
781 asmlinkage int sys_get_thread_area(struct user_desc __user *u_info)
782 {
783 struct user_desc info;
784 struct desc_struct *desc;
785 int idx;
787 if (get_user(idx, &u_info->entry_number))
788 return -EFAULT;
789 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
790 return -EINVAL;
792 desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
794 info.entry_number = idx;
795 info.base_addr = GET_BASE(desc);
796 info.limit = GET_LIMIT(desc);
797 info.seg_32bit = GET_32BIT(desc);
798 info.contents = GET_CONTENTS(desc);
799 info.read_exec_only = !GET_WRITABLE(desc);
800 info.limit_in_pages = GET_LIMIT_PAGES(desc);
801 info.seg_not_present = !GET_PRESENT(desc);
802 info.useable = GET_USEABLE(desc);
804 if (copy_to_user(u_info, &info, sizeof(info)))
805 return -EFAULT;
806 return 0;
807 }
809 unsigned long arch_align_stack(unsigned long sp)
810 {
811 if (randomize_va_space)
812 sp -= get_random_int() % 8192;
813 return sp & ~0xf;
814 }