vserver 1.9.3
[linux-2.6.git] / arch / um / sys-i386 / ldt.c
1 /*
2  * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
3  * Licensed under the GPL
4  */
5
6 #include "linux/config.h"
7 #include "linux/slab.h"
8 #include "asm/uaccess.h"
9 #include "asm/ptrace.h"
10 #include "choose-mode.h"
11 #include "kern.h"
12
13 #ifdef CONFIG_MODE_TT
14 extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
15
16 /* XXX this needs copy_to_user and copy_from_user */
17
18 int sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
19 {
20         if(verify_area(VERIFY_READ, ptr, bytecount)) return(-EFAULT);
21         return(modify_ldt(func, ptr, bytecount));
22 }
23 #endif
24
25 #ifdef CONFIG_MODE_SKAS
26 extern int userspace_pid;
27
28 int sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
29 {
30         struct ptrace_ldt ldt;
31         void *buf;
32         int res, n;
33
34         buf = kmalloc(bytecount, GFP_KERNEL);
35         if(buf == NULL)
36                 return(-ENOMEM);
37
38         res = 0;
39
40         switch(func){
41         case 1:
42         case 0x11:
43                 res = copy_from_user(buf, ptr, bytecount);
44                 break;
45         }
46
47         if(res != 0){
48                 res = -EFAULT;
49                 goto out;
50         }
51
52         ldt = ((struct ptrace_ldt) { .func      = func,
53                                      .ptr       = buf,
54                                      .bytecount = bytecount });
55         res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt);
56         if(res < 0)
57                 goto out;
58
59         switch(func){
60         case 0:
61         case 2:
62                 n = res;
63                 res = copy_to_user(ptr, buf, n);
64                 if(res != 0)
65                         res = -EFAULT;
66                 else 
67                         res = n;
68                 break;
69         }
70
71  out:
72         kfree(buf);
73         return(res);
74 }
75 #endif
76
77 int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
78 {
79         return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func, 
80                                 ptr, bytecount));
81 }
82
83
84
85 /*
86  * Overrides for Emacs so that we follow Linus's tabbing style.
87  * Emacs will notice this stuff at the end of the file and automatically
88  * adjust the settings for this buffer only.  This must remain at the end
89  * of the file.
90  * ---------------------------------------------------------------------------
91  * Local variables:
92  * c-file-style: "linux"
93  * End:
94  */