Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / arch / x86_64 / kernel / sys_arch_prctl.c
1 #include <lwk/kernel.h>
2 #include <lwk/task.h>
3 #include <arch/prctl.h>
4 #include <arch/uaccess.h>
5
6
7 long
8 do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
9 {
10         int ret = 0; 
11         int doit = task == current;
12
13         switch (code) { 
14         case ARCH_SET_GS:
15                 if (addr >= task->arch.addr_limit)
16                         return -EPERM; 
17
18                 task->arch.thread.gsindex = 0;
19                 task->arch.thread.gs = addr;
20                 if (doit) {
21                         /* The kernel's %gs is currently loaded, so this
22                            call is needed to set the user version. */
23                         load_gs_index(0);
24                         ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr);
25                 } 
26
27                 break;
28         case ARCH_SET_FS:
29                 /* Not strictly needed for fs, but do it for symmetry
30                    with gs */
31                 if (addr >= task->arch.addr_limit)
32                         return -EPERM; 
33
34                 task->arch.thread.fsindex = 0;
35                 task->arch.thread.fs = addr;
36                 if (doit) {
37                         /* The kernel doesn't use %fs so we can set it
38                            directly.  set the selector to 0 to not confuse
39                            __switch_to */
40                         asm volatile("movl %0,%%fs" :: "r" (0));
41                         ret = checking_wrmsrl(MSR_FS_BASE, addr);
42                 }
43
44                 break;
45         case ARCH_GET_FS: { 
46                 unsigned long base; 
47                 if (doit)
48                         rdmsrl(MSR_FS_BASE, base);
49                 else
50                         base = task->arch.thread.fs;
51                 ret = put_user(base, (unsigned long __user *)addr); 
52                 break; 
53         }
54         case ARCH_GET_GS: { 
55                 unsigned long base;
56                 unsigned gsindex;
57                 if (doit) {
58                         asm("movl %%gs,%0" : "=r" (gsindex));
59                         if (gsindex)
60                                 rdmsrl(MSR_KERNEL_GS_BASE, base);
61                         else
62                                 base = task->arch.thread.gs;
63                 }
64                 else
65                         base = task->arch.thread.gs;
66                 ret = put_user(base, (unsigned long __user *)addr); 
67                 break;
68         }
69
70         default:
71                 ret = -EINVAL;
72                 break;
73         } 
74
75         return ret;     
76 }
77
78
79 long
80 sys_arch_prctl(int code, unsigned long addr)
81 {
82         return do_arch_prctl(current, code, addr);
83 }
84