regulator: core: silence warning: "VDD1: ramp_delay not set"
[cascardo/linux.git] / arch / x86 / um / ptrace_32.c
1 /*
2  * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3  * Licensed under the GPL
4  */
5
6 #include <linux/mm.h>
7 #include <linux/sched.h>
8 #include <asm/uaccess.h>
9 #include <asm/ptrace-abi.h>
10 #include <skas.h>
11
12 extern int arch_switch_tls(struct task_struct *to);
13
14 void arch_switch_to(struct task_struct *to)
15 {
16         int err = arch_switch_tls(to);
17         if (!err)
18                 return;
19
20         if (err != -EINVAL)
21                 printk(KERN_WARNING "arch_switch_tls failed, errno %d, "
22                        "not EINVAL\n", -err);
23         else
24                 printk(KERN_WARNING "arch_switch_tls failed, errno = EINVAL\n");
25 }
26
27 int is_syscall(unsigned long addr)
28 {
29         unsigned short instr;
30         int n;
31
32         n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
33         if (n) {
34                 /* access_process_vm() grants access to vsyscall and stub,
35                  * while copy_from_user doesn't. Maybe access_process_vm is
36                  * slow, but that doesn't matter, since it will be called only
37                  * in case of singlestepping, if copy_from_user failed.
38                  */
39                 n = access_process_vm(current, addr, &instr, sizeof(instr), 0);
40                 if (n != sizeof(instr)) {
41                         printk(KERN_ERR "is_syscall : failed to read "
42                                "instruction from 0x%lx\n", addr);
43                         return 1;
44                 }
45         }
46         /* int 0x80 or sysenter */
47         return (instr == 0x80cd) || (instr == 0x340f);
48 }
49
50 /* determines which flags the user has access to. */
51 /* 1 = access 0 = no access */
52 #define FLAG_MASK 0x00044dd5
53
54 static const int reg_offsets[] = {
55         [EBX] = HOST_BX,
56         [ECX] = HOST_CX,
57         [EDX] = HOST_DX,
58         [ESI] = HOST_SI,
59         [EDI] = HOST_DI,
60         [EBP] = HOST_BP,
61         [EAX] = HOST_AX,
62         [DS] = HOST_DS,
63         [ES] = HOST_ES,
64         [FS] = HOST_FS,
65         [GS] = HOST_GS,
66         [EIP] = HOST_IP,
67         [CS] = HOST_CS,
68         [EFL] = HOST_EFLAGS,
69         [UESP] = HOST_SP,
70         [SS] = HOST_SS,
71         [ORIG_EAX] = HOST_ORIG_AX,
72 };
73
74 int putreg(struct task_struct *child, int regno, unsigned long value)
75 {
76         regno >>= 2;
77         switch (regno) {
78         case EBX:
79         case ECX:
80         case EDX:
81         case ESI:
82         case EDI:
83         case EBP:
84         case EAX:
85         case EIP:
86         case UESP:
87                 break;
88         case ORIG_EAX:
89                 /* Update the syscall number. */
90                 UPT_SYSCALL_NR(&child->thread.regs.regs) = value;
91                 break;
92         case FS:
93                 if (value && (value & 3) != 3)
94                         return -EIO;
95                 break;
96         case GS:
97                 if (value && (value & 3) != 3)
98                         return -EIO;
99                 break;
100         case DS:
101         case ES:
102                 if (value && (value & 3) != 3)
103                         return -EIO;
104                 value &= 0xffff;
105                 break;
106         case SS:
107         case CS:
108                 if ((value & 3) != 3)
109                         return -EIO;
110                 value &= 0xffff;
111                 break;
112         case EFL:
113                 value &= FLAG_MASK;
114                 child->thread.regs.regs.gp[HOST_EFLAGS] |= value;
115                 return 0;
116         default :
117                 panic("Bad register in putreg() : %d\n", regno);
118         }
119         child->thread.regs.regs.gp[reg_offsets[regno]] = value;
120         return 0;
121 }
122
123 int poke_user(struct task_struct *child, long addr, long data)
124 {
125         if ((addr & 3) || addr < 0)
126                 return -EIO;
127
128         if (addr < MAX_REG_OFFSET)
129                 return putreg(child, addr, data);
130         else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
131                  (addr <= offsetof(struct user, u_debugreg[7]))) {
132                 addr -= offsetof(struct user, u_debugreg[0]);
133                 addr = addr >> 2;
134                 if ((addr == 4) || (addr == 5))
135                         return -EIO;
136                 child->thread.arch.debugregs[addr] = data;
137                 return 0;
138         }
139         return -EIO;
140 }
141
142 unsigned long getreg(struct task_struct *child, int regno)
143 {
144         unsigned long mask = ~0UL;
145
146         regno >>= 2;
147         switch (regno) {
148         case FS:
149         case GS:
150         case DS:
151         case ES:
152         case SS:
153         case CS:
154                 mask = 0xffff;
155                 break;
156         case EIP:
157         case UESP:
158         case EAX:
159         case EBX:
160         case ECX:
161         case EDX:
162         case ESI:
163         case EDI:
164         case EBP:
165         case EFL:
166         case ORIG_EAX:
167                 break;
168         default:
169                 panic("Bad register in getreg() : %d\n", regno);
170         }
171         return mask & child->thread.regs.regs.gp[reg_offsets[regno]];
172 }
173
174 /* read the word at location addr in the USER area. */
175 int peek_user(struct task_struct *child, long addr, long data)
176 {
177         unsigned long tmp;
178
179         if ((addr & 3) || addr < 0)
180                 return -EIO;
181
182         tmp = 0;  /* Default return condition */
183         if (addr < MAX_REG_OFFSET) {
184                 tmp = getreg(child, addr);
185         }
186         else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
187                  (addr <= offsetof(struct user, u_debugreg[7]))) {
188                 addr -= offsetof(struct user, u_debugreg[0]);
189                 addr = addr >> 2;
190                 tmp = child->thread.arch.debugregs[addr];
191         }
192         return put_user(tmp, (unsigned long __user *) data);
193 }
194
195 static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
196 {
197         int err, n, cpu = task_cpu(child);
198         struct user_i387_struct fpregs;
199
200         err = save_i387_registers(userspace_pid[cpu],
201                                   (unsigned long *) &fpregs);
202         if (err)
203                 return err;
204
205         n = copy_to_user(buf, &fpregs, sizeof(fpregs));
206         if(n > 0)
207                 return -EFAULT;
208
209         return n;
210 }
211
212 static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
213 {
214         int n, cpu = task_cpu(child);
215         struct user_i387_struct fpregs;
216
217         n = copy_from_user(&fpregs, buf, sizeof(fpregs));
218         if (n > 0)
219                 return -EFAULT;
220
221         return restore_i387_registers(userspace_pid[cpu],
222                                     (unsigned long *) &fpregs);
223 }
224
225 static int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
226 {
227         int err, n, cpu = task_cpu(child);
228         struct user_fxsr_struct fpregs;
229
230         err = save_fpx_registers(userspace_pid[cpu], (unsigned long *) &fpregs);
231         if (err)
232                 return err;
233
234         n = copy_to_user(buf, &fpregs, sizeof(fpregs));
235         if(n > 0)
236                 return -EFAULT;
237
238         return n;
239 }
240
241 static int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
242 {
243         int n, cpu = task_cpu(child);
244         struct user_fxsr_struct fpregs;
245
246         n = copy_from_user(&fpregs, buf, sizeof(fpregs));
247         if (n > 0)
248                 return -EFAULT;
249
250         return restore_fpx_registers(userspace_pid[cpu],
251                                      (unsigned long *) &fpregs);
252 }
253
254 long subarch_ptrace(struct task_struct *child, long request,
255                     unsigned long addr, unsigned long data)
256 {
257         int ret = -EIO;
258         void __user *datap = (void __user *) data;
259         switch (request) {
260         case PTRACE_GETFPREGS: /* Get the child FPU state. */
261                 ret = get_fpregs(datap, child);
262                 break;
263         case PTRACE_SETFPREGS: /* Set the child FPU state. */
264                 ret = set_fpregs(datap, child);
265                 break;
266         case PTRACE_GETFPXREGS: /* Get the child FPU state. */
267                 ret = get_fpxregs(datap, child);
268                 break;
269         case PTRACE_SETFPXREGS: /* Set the child FPU state. */
270                 ret = set_fpxregs(datap, child);
271                 break;
272         default:
273                 ret = -EIO;
274         }
275         return ret;
276 }