ia64/xen-unstable

view linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c @ 11736:2dd375ce153d

[LINUX] Don't bother to write a 5-bit value to a 2-bit field.
From: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Wed Oct 04 18:55:16 2006 +0100 (2006-10-04)
parents e58e04589d11
children bf25488db8eb
line source
1 /*
2 * linux/arch/x86-64/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 *
9 * X86-64 port
10 * Andi Kleen.
11 *
12 * CPU hotplug support - ashok.raj@intel.com
13 * $Id: process.c,v 1.38 2002/01/15 10:08:03 ak Exp $
14 *
15 * Jun Nakajima <jun.nakajima@intel.com>
16 * Modified for Xen
17 */
19 /*
20 * This file handles the architecture-dependent parts of process handling..
21 */
23 #include <stdarg.h>
25 #include <linux/cpu.h>
26 #include <linux/errno.h>
27 #include <linux/sched.h>
28 #include <linux/kernel.h>
29 #include <linux/mm.h>
30 #include <linux/elfcore.h>
31 #include <linux/smp.h>
32 #include <linux/slab.h>
33 #include <linux/user.h>
34 #include <linux/module.h>
35 #include <linux/a.out.h>
36 #include <linux/interrupt.h>
37 #include <linux/delay.h>
38 #include <linux/ptrace.h>
39 #include <linux/utsname.h>
40 #include <linux/random.h>
41 #include <linux/kprobes.h>
42 #include <linux/notifier.h>
44 #include <asm/uaccess.h>
45 #include <asm/pgtable.h>
46 #include <asm/system.h>
47 #include <asm/io.h>
48 #include <asm/processor.h>
49 #include <asm/i387.h>
50 #include <asm/mmu_context.h>
51 #include <asm/pda.h>
52 #include <asm/prctl.h>
53 #include <asm/kdebug.h>
54 #include <xen/interface/dom0_ops.h>
55 #include <xen/interface/physdev.h>
56 #include <xen/interface/vcpu.h>
57 #include <asm/desc.h>
58 #include <asm/proto.h>
59 #include <asm/hardirq.h>
60 #include <asm/ia32.h>
61 #include <asm/idle.h>
63 #include <xen/cpu_hotplug.h>
65 asmlinkage extern void ret_from_fork(void);
67 unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
69 unsigned long boot_option_idle_override = 0;
70 EXPORT_SYMBOL(boot_option_idle_override);
72 /*
73 * Powermanagement idle function, if any..
74 */
75 void (*pm_idle)(void);
76 static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
78 static struct notifier_block *idle_notifier;
79 static DEFINE_SPINLOCK(idle_notifier_lock);
81 void idle_notifier_register(struct notifier_block *n)
82 {
83 unsigned long flags;
84 spin_lock_irqsave(&idle_notifier_lock, flags);
85 notifier_chain_register(&idle_notifier, n);
86 spin_unlock_irqrestore(&idle_notifier_lock, flags);
87 }
88 EXPORT_SYMBOL_GPL(idle_notifier_register);
90 void idle_notifier_unregister(struct notifier_block *n)
91 {
92 unsigned long flags;
93 spin_lock_irqsave(&idle_notifier_lock, flags);
94 notifier_chain_unregister(&idle_notifier, n);
95 spin_unlock_irqrestore(&idle_notifier_lock, flags);
96 }
97 EXPORT_SYMBOL(idle_notifier_unregister);
99 enum idle_state { CPU_IDLE, CPU_NOT_IDLE };
100 static DEFINE_PER_CPU(enum idle_state, idle_state) = CPU_NOT_IDLE;
102 void enter_idle(void)
103 {
104 __get_cpu_var(idle_state) = CPU_IDLE;
105 notifier_call_chain(&idle_notifier, IDLE_START, NULL);
106 }
108 static void __exit_idle(void)
109 {
110 __get_cpu_var(idle_state) = CPU_NOT_IDLE;
111 notifier_call_chain(&idle_notifier, IDLE_END, NULL);
112 }
114 /* Called from interrupts to signify idle end */
115 void exit_idle(void)
116 {
117 if (current->pid | read_pda(irqcount))
118 return;
119 __exit_idle();
120 }
122 /* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */
123 void xen_idle(void)
124 {
125 local_irq_disable();
127 if (need_resched())
128 local_irq_enable();
129 else {
130 clear_thread_flag(TIF_POLLING_NRFLAG);
131 smp_mb__after_clear_bit();
132 safe_halt();
133 set_thread_flag(TIF_POLLING_NRFLAG);
134 }
135 }
137 #ifdef CONFIG_HOTPLUG_CPU
138 static inline void play_dead(void)
139 {
140 idle_task_exit();
141 local_irq_disable();
142 cpu_clear(smp_processor_id(), cpu_initialized);
143 preempt_enable_no_resched();
144 HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
145 cpu_bringup();
146 }
147 #else
148 static inline void play_dead(void)
149 {
150 BUG();
151 }
152 #endif /* CONFIG_HOTPLUG_CPU */
154 /*
155 * The idle thread. There's no useful work to be
156 * done, so just try to conserve power and have a
157 * low exit latency (ie sit in a loop waiting for
158 * somebody to say that they'd like to reschedule)
159 */
160 void cpu_idle (void)
161 {
162 set_thread_flag(TIF_POLLING_NRFLAG);
164 /* endless idle loop with no priority at all */
165 while (1) {
166 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(smp_processor_id()))
172 play_dead();
173 enter_idle();
174 xen_idle();
175 __exit_idle();
176 }
178 preempt_enable_no_resched();
179 schedule();
180 preempt_disable();
181 }
182 }
184 void cpu_idle_wait(void)
185 {
186 unsigned int cpu, this_cpu = get_cpu();
187 cpumask_t map;
189 set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
190 put_cpu();
192 cpus_clear(map);
193 for_each_online_cpu(cpu) {
194 per_cpu(cpu_idle_state, cpu) = 1;
195 cpu_set(cpu, map);
196 }
198 __get_cpu_var(cpu_idle_state) = 0;
200 wmb();
201 do {
202 ssleep(1);
203 for_each_online_cpu(cpu) {
204 if (cpu_isset(cpu, map) &&
205 !per_cpu(cpu_idle_state, cpu))
206 cpu_clear(cpu, map);
207 }
208 cpus_and(map, map, cpu_online_map);
209 } while (!cpus_empty(map));
210 }
211 EXPORT_SYMBOL_GPL(cpu_idle_wait);
213 /* XXX XEN doesn't use mwait_idle(), select_idle_routine(), idle_setup(). */
214 /* Always use xen_idle() instead. */
215 void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) {}
217 /* Prints also some state that isn't saved in the pt_regs */
218 void __show_regs(struct pt_regs * regs)
219 {
220 unsigned long fs, gs, shadowgs;
221 unsigned int fsindex,gsindex;
222 unsigned int ds,cs,es;
224 printk("\n");
225 print_modules();
226 printk("Pid: %d, comm: %.20s %s %s %.*s\n",
227 current->pid, current->comm, print_tainted(),
228 system_utsname.release,
229 (int)strcspn(system_utsname.version, " "),
230 system_utsname.version);
231 printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
232 printk_address(regs->rip);
233 printk("\nRSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->rsp,
234 regs->eflags);
235 printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
236 regs->rax, regs->rbx, regs->rcx);
237 printk("RDX: %016lx RSI: %016lx RDI: %016lx\n",
238 regs->rdx, regs->rsi, regs->rdi);
239 printk("RBP: %016lx R08: %016lx R09: %016lx\n",
240 regs->rbp, regs->r8, regs->r9);
241 printk("R10: %016lx R11: %016lx R12: %016lx\n",
242 regs->r10, regs->r11, regs->r12);
243 printk("R13: %016lx R14: %016lx R15: %016lx\n",
244 regs->r13, regs->r14, regs->r15);
246 asm("mov %%ds,%0" : "=r" (ds));
247 asm("mov %%cs,%0" : "=r" (cs));
248 asm("mov %%es,%0" : "=r" (es));
249 asm("mov %%fs,%0" : "=r" (fsindex));
250 asm("mov %%gs,%0" : "=r" (gsindex));
252 rdmsrl(MSR_FS_BASE, fs);
253 rdmsrl(MSR_GS_BASE, gs);
254 rdmsrl(MSR_KERNEL_GS_BASE, shadowgs);
256 printk("FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n",
257 fs,fsindex,gs,gsindex,shadowgs);
258 printk("CS: %04x DS: %04x ES: %04x\n", cs, ds, es);
260 }
262 void show_regs(struct pt_regs *regs)
263 {
264 printk("CPU %d:", smp_processor_id());
265 __show_regs(regs);
266 show_trace(&regs->rsp);
267 }
269 /*
270 * Free current thread data structures etc..
271 */
272 void exit_thread(void)
273 {
274 struct task_struct *me = current;
275 struct thread_struct *t = &me->thread;
277 /*
278 * Remove function-return probe instances associated with this task
279 * and put them back on the free list. Do not insert an exit probe for
280 * this function, it will be disabled by kprobe_flush_task if you do.
281 */
282 kprobe_flush_task(me);
284 if (me->thread.io_bitmap_ptr) {
285 #ifndef CONFIG_X86_NO_TSS
286 struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
287 #endif
288 #ifdef CONFIG_XEN
289 struct physdev_set_iobitmap iobmp_op = { 0 };
290 #endif
292 kfree(t->io_bitmap_ptr);
293 t->io_bitmap_ptr = NULL;
294 /*
295 * Careful, clear this in the TSS too:
296 */
297 #ifndef CONFIG_X86_NO_TSS
298 memset(tss->io_bitmap, 0xff, t->io_bitmap_max);
299 put_cpu();
300 #endif
301 #ifdef CONFIG_XEN
302 HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &iobmp_op);
303 #endif
304 t->io_bitmap_max = 0;
305 }
306 }
308 void load_gs_index(unsigned gs)
309 {
310 HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, gs);
311 }
313 void flush_thread(void)
314 {
315 struct task_struct *tsk = current;
316 struct thread_info *t = current_thread_info();
318 if (t->flags & _TIF_ABI_PENDING)
319 t->flags ^= (_TIF_ABI_PENDING | _TIF_IA32);
321 tsk->thread.debugreg0 = 0;
322 tsk->thread.debugreg1 = 0;
323 tsk->thread.debugreg2 = 0;
324 tsk->thread.debugreg3 = 0;
325 tsk->thread.debugreg6 = 0;
326 tsk->thread.debugreg7 = 0;
327 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
328 /*
329 * Forget coprocessor state..
330 */
331 clear_fpu(tsk);
332 clear_used_math();
333 }
335 void release_thread(struct task_struct *dead_task)
336 {
337 if (dead_task->mm) {
338 if (dead_task->mm->context.size) {
339 printk("WARNING: dead process %8s still has LDT? <%p/%d>\n",
340 dead_task->comm,
341 dead_task->mm->context.ldt,
342 dead_task->mm->context.size);
343 BUG();
344 }
345 }
346 }
348 static inline void set_32bit_tls(struct task_struct *t, int tls, u32 addr)
349 {
350 struct user_desc ud = {
351 .base_addr = addr,
352 .limit = 0xfffff,
353 .seg_32bit = 1,
354 .limit_in_pages = 1,
355 .useable = 1,
356 };
357 struct n_desc_struct *desc = (void *)t->thread.tls_array;
358 desc += tls;
359 desc->a = LDT_entry_a(&ud);
360 desc->b = LDT_entry_b(&ud);
361 }
363 static inline u32 read_32bit_tls(struct task_struct *t, int tls)
364 {
365 struct desc_struct *desc = (void *)t->thread.tls_array;
366 desc += tls;
367 return desc->base0 |
368 (((u32)desc->base1) << 16) |
369 (((u32)desc->base2) << 24);
370 }
372 /*
373 * This gets called before we allocate a new thread and copy
374 * the current task into it.
375 */
376 void prepare_to_copy(struct task_struct *tsk)
377 {
378 unlazy_fpu(tsk);
379 }
381 int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp,
382 unsigned long unused,
383 struct task_struct * p, struct pt_regs * regs)
384 {
385 int err;
386 struct pt_regs * childregs;
387 struct task_struct *me = current;
389 childregs = ((struct pt_regs *)
390 (THREAD_SIZE + task_stack_page(p))) - 1;
391 *childregs = *regs;
393 childregs->rax = 0;
394 childregs->rsp = rsp;
395 if (rsp == ~0UL)
396 childregs->rsp = (unsigned long)childregs;
398 p->thread.rsp = (unsigned long) childregs;
399 p->thread.rsp0 = (unsigned long) (childregs+1);
400 p->thread.userrsp = me->thread.userrsp;
402 set_tsk_thread_flag(p, TIF_FORK);
404 p->thread.fs = me->thread.fs;
405 p->thread.gs = me->thread.gs;
407 asm("mov %%gs,%0" : "=m" (p->thread.gsindex));
408 asm("mov %%fs,%0" : "=m" (p->thread.fsindex));
409 asm("mov %%es,%0" : "=m" (p->thread.es));
410 asm("mov %%ds,%0" : "=m" (p->thread.ds));
412 if (unlikely(me->thread.io_bitmap_ptr != NULL)) {
413 p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
414 if (!p->thread.io_bitmap_ptr) {
415 p->thread.io_bitmap_max = 0;
416 return -ENOMEM;
417 }
418 memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr,
419 IO_BITMAP_BYTES);
420 }
422 /*
423 * Set a new TLS for the child thread?
424 */
425 if (clone_flags & CLONE_SETTLS) {
426 #ifdef CONFIG_IA32_EMULATION
427 if (test_thread_flag(TIF_IA32))
428 err = ia32_child_tls(p, childregs);
429 else
430 #endif
431 err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8);
432 if (err)
433 goto out;
434 }
435 p->thread.iopl = current->thread.iopl;
437 err = 0;
438 out:
439 if (err && p->thread.io_bitmap_ptr) {
440 kfree(p->thread.io_bitmap_ptr);
441 p->thread.io_bitmap_max = 0;
442 }
443 return err;
444 }
446 static inline void __save_init_fpu( struct task_struct *tsk )
447 {
448 asm volatile( "rex64 ; fxsave %0 ; fnclex"
449 : "=m" (tsk->thread.i387.fxsave));
450 tsk->thread_info->status &= ~TS_USEDFPU;
451 }
453 /*
454 * switch_to(x,y) should switch tasks from x to y.
455 *
456 * This could still be optimized:
457 * - fold all the options into a flag word and test it with a single test.
458 * - could test fs/gs bitsliced
459 *
460 * Kprobes not supported here. Set the probe on schedule instead.
461 */
462 __kprobes struct task_struct *
463 __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
464 {
465 struct thread_struct *prev = &prev_p->thread,
466 *next = &next_p->thread;
467 int cpu = smp_processor_id();
468 #ifndef CONFIG_X86_NO_TSS
469 struct tss_struct *tss = &per_cpu(init_tss, cpu);
470 #endif
471 struct physdev_set_iopl iopl_op;
472 struct physdev_set_iobitmap iobmp_op;
473 multicall_entry_t _mcl[8], *mcl = _mcl;
475 /*
476 * This is basically '__unlazy_fpu', except that we queue a
477 * multicall to indicate FPU task switch, rather than
478 * synchronously trapping to Xen.
479 * This must be here to ensure both math_state_restore() and
480 * kernel_fpu_begin() work consistently.
481 * The AMD workaround requires it to be after DS reload, or
482 * after DS has been cleared, which we do in __prepare_arch_switch.
483 */
484 if (prev_p->thread_info->status & TS_USEDFPU) {
485 __save_init_fpu(prev_p); /* _not_ save_init_fpu() */
486 mcl->op = __HYPERVISOR_fpu_taskswitch;
487 mcl->args[0] = 1;
488 mcl++;
489 }
491 /*
492 * Reload esp0, LDT and the page table pointer:
493 */
494 mcl->op = __HYPERVISOR_stack_switch;
495 mcl->args[0] = __KERNEL_DS;
496 mcl->args[1] = next->rsp0;
497 mcl++;
499 /*
500 * Load the per-thread Thread-Local Storage descriptor.
501 * This is load_TLS(next, cpu) with multicalls.
502 */
503 #define C(i) do { \
504 if (unlikely(next->tls_array[i] != prev->tls_array[i])) { \
505 mcl->op = __HYPERVISOR_update_descriptor; \
506 mcl->args[0] = virt_to_machine( \
507 &cpu_gdt(cpu)[GDT_ENTRY_TLS_MIN + i]); \
508 mcl->args[1] = next->tls_array[i]; \
509 mcl++; \
510 } \
511 } while (0)
512 C(0); C(1); C(2);
513 #undef C
515 if (unlikely(prev->iopl != next->iopl)) {
516 iopl_op.iopl = (next->iopl == 0) ? 1 : next->iopl;
517 mcl->op = __HYPERVISOR_physdev_op;
518 mcl->args[0] = PHYSDEVOP_set_iopl;
519 mcl->args[1] = (unsigned long)&iopl_op;
520 mcl++;
521 }
523 if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
524 iobmp_op.bitmap = (char *)next->io_bitmap_ptr;
525 iobmp_op.nr_ports = next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
526 mcl->op = __HYPERVISOR_physdev_op;
527 mcl->args[0] = PHYSDEVOP_set_iobitmap;
528 mcl->args[1] = (unsigned long)&iobmp_op;
529 mcl++;
530 }
532 (void)HYPERVISOR_multicall(_mcl, mcl - _mcl);
533 /*
534 * Switch DS and ES.
535 * This won't pick up thread selector changes, but I guess that is ok.
536 */
537 if (unlikely(next->es))
538 loadsegment(es, next->es);
540 if (unlikely(next->ds))
541 loadsegment(ds, next->ds);
543 /*
544 * Switch FS and GS.
545 */
546 if (unlikely(next->fsindex))
547 loadsegment(fs, next->fsindex);
549 if (next->fs)
550 HYPERVISOR_set_segment_base(SEGBASE_FS, next->fs);
552 if (unlikely(next->gsindex))
553 load_gs_index(next->gsindex);
555 if (next->gs)
556 HYPERVISOR_set_segment_base(SEGBASE_GS_USER, next->gs);
558 /*
559 * Switch the PDA context.
560 */
561 prev->userrsp = read_pda(oldrsp);
562 write_pda(oldrsp, next->userrsp);
563 write_pda(pcurrent, next_p);
564 write_pda(kernelstack,
565 task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
567 /*
568 * Now maybe reload the debug registers
569 */
570 if (unlikely(next->debugreg7)) {
571 set_debugreg(next->debugreg0, 0);
572 set_debugreg(next->debugreg1, 1);
573 set_debugreg(next->debugreg2, 2);
574 set_debugreg(next->debugreg3, 3);
575 /* no 4 and 5 */
576 set_debugreg(next->debugreg6, 6);
577 set_debugreg(next->debugreg7, 7);
578 }
580 return prev_p;
581 }
583 /*
584 * sys_execve() executes a new program.
585 */
586 asmlinkage
587 long sys_execve(char __user *name, char __user * __user *argv,
588 char __user * __user *envp, struct pt_regs regs)
589 {
590 long error;
591 char * filename;
593 filename = getname(name);
594 error = PTR_ERR(filename);
595 if (IS_ERR(filename))
596 return error;
597 error = do_execve(filename, argv, envp, &regs);
598 if (error == 0) {
599 task_lock(current);
600 current->ptrace &= ~PT_DTRACE;
601 task_unlock(current);
602 }
603 putname(filename);
604 return error;
605 }
607 void set_personality_64bit(void)
608 {
609 /* inherit personality from parent */
611 /* Make sure to be in 64bit mode */
612 clear_thread_flag(TIF_IA32);
614 /* TBD: overwrites user setup. Should have two bits.
615 But 64bit processes have always behaved this way,
616 so it's not too bad. The main problem is just that
617 32bit childs are affected again. */
618 current->personality &= ~READ_IMPLIES_EXEC;
619 }
621 asmlinkage long sys_fork(struct pt_regs *regs)
622 {
623 return do_fork(SIGCHLD, regs->rsp, regs, 0, NULL, NULL);
624 }
626 asmlinkage long
627 sys_clone(unsigned long clone_flags, unsigned long newsp,
628 void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
629 {
630 if (!newsp)
631 newsp = regs->rsp;
632 return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
633 }
635 /*
636 * This is trivial, and on the face of it looks like it
637 * could equally well be done in user mode.
638 *
639 * Not so, for quite unobvious reasons - register pressure.
640 * In user mode vfork() cannot have a stack frame, and if
641 * done by calling the "clone()" system call directly, you
642 * do not have enough call-clobbered registers to hold all
643 * the information you need.
644 */
645 asmlinkage long sys_vfork(struct pt_regs *regs)
646 {
647 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->rsp, regs, 0,
648 NULL, NULL);
649 }
651 unsigned long get_wchan(struct task_struct *p)
652 {
653 unsigned long stack;
654 u64 fp,rip;
655 int count = 0;
657 if (!p || p == current || p->state==TASK_RUNNING)
658 return 0;
659 stack = (unsigned long)task_stack_page(p);
660 if (p->thread.rsp < stack || p->thread.rsp > stack+THREAD_SIZE)
661 return 0;
662 fp = *(u64 *)(p->thread.rsp);
663 do {
664 if (fp < (unsigned long)stack ||
665 fp > (unsigned long)stack+THREAD_SIZE)
666 return 0;
667 rip = *(u64 *)(fp+8);
668 if (!in_sched_functions(rip))
669 return rip;
670 fp = *(u64 *)fp;
671 } while (count++ < 16);
672 return 0;
673 }
675 long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
676 {
677 int ret = 0;
678 int doit = task == current;
679 int cpu;
681 switch (code) {
682 case ARCH_SET_GS:
683 if (addr >= TASK_SIZE_OF(task))
684 return -EPERM;
685 cpu = get_cpu();
686 /* handle small bases via the GDT because that's faster to
687 switch. */
688 if (addr <= 0xffffffff) {
689 set_32bit_tls(task, GS_TLS, addr);
690 if (doit) {
691 load_TLS(&task->thread, cpu);
692 load_gs_index(GS_TLS_SEL);
693 }
694 task->thread.gsindex = GS_TLS_SEL;
695 task->thread.gs = 0;
696 } else {
697 task->thread.gsindex = 0;
698 task->thread.gs = addr;
699 if (doit) {
700 load_gs_index(0);
701 ret = HYPERVISOR_set_segment_base(
702 SEGBASE_GS_USER, addr);
703 }
704 }
705 put_cpu();
706 break;
707 case ARCH_SET_FS:
708 /* Not strictly needed for fs, but do it for symmetry
709 with gs */
710 if (addr >= TASK_SIZE_OF(task))
711 return -EPERM;
712 cpu = get_cpu();
713 /* handle small bases via the GDT because that's faster to
714 switch. */
715 if (addr <= 0xffffffff) {
716 set_32bit_tls(task, FS_TLS, addr);
717 if (doit) {
718 load_TLS(&task->thread, cpu);
719 asm volatile("movl %0,%%fs" :: "r"(FS_TLS_SEL));
720 }
721 task->thread.fsindex = FS_TLS_SEL;
722 task->thread.fs = 0;
723 } else {
724 task->thread.fsindex = 0;
725 task->thread.fs = addr;
726 if (doit) {
727 /* set the selector to 0 to not confuse
728 __switch_to */
729 asm volatile("movl %0,%%fs" :: "r" (0));
730 ret = HYPERVISOR_set_segment_base(SEGBASE_FS,
731 addr);
732 }
733 }
734 put_cpu();
735 break;
736 case ARCH_GET_FS: {
737 unsigned long base;
738 if (task->thread.fsindex == FS_TLS_SEL)
739 base = read_32bit_tls(task, FS_TLS);
740 else if (doit)
741 rdmsrl(MSR_FS_BASE, base);
742 else
743 base = task->thread.fs;
744 ret = put_user(base, (unsigned long __user *)addr);
745 break;
746 }
747 case ARCH_GET_GS: {
748 unsigned long base;
749 if (task->thread.gsindex == GS_TLS_SEL)
750 base = read_32bit_tls(task, GS_TLS);
751 else if (doit)
752 rdmsrl(MSR_KERNEL_GS_BASE, base);
753 else
754 base = task->thread.gs;
755 ret = put_user(base, (unsigned long __user *)addr);
756 break;
757 }
759 default:
760 ret = -EINVAL;
761 break;
762 }
764 return ret;
765 }
767 long sys_arch_prctl(int code, unsigned long addr)
768 {
769 return do_arch_prctl(current, code, addr);
770 }
772 /*
773 * Capture the user space registers if the task is not running (in user space)
774 */
775 int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
776 {
777 struct pt_regs *pp, ptregs;
779 pp = task_pt_regs(tsk);
781 ptregs = *pp;
782 ptregs.cs &= 0xffff;
783 ptregs.ss &= 0xffff;
785 elf_core_copy_regs(regs, &ptregs);
787 boot_option_idle_override = 1;
788 return 1;
789 }
791 unsigned long arch_align_stack(unsigned long sp)
792 {
793 if (randomize_va_space)
794 sp -= get_random_int() % 8192;
795 return sp & ~0xf;
796 }
798 #ifndef CONFIG_SMP
799 void _restore_vcpu(void)
800 {
801 }
802 #endif