aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/ia32/sys_ia32.c
diff options
context:
space:
mode:
authorTony Luck <tony.luck@intel.com>2010-02-08 13:42:17 -0500
committerTony Luck <tony.luck@intel.com>2010-02-08 13:42:17 -0500
commit32974ad4907cdde6c9de612cd1b2ee0568fb9409 (patch)
tree46d883f7f4fb3f4a5cee8ec9eb2c6b4939d7ae10 /arch/ia64/ia32/sys_ia32.c
parent6339204ecc2aa2067a99595522de0403f0854bb8 (diff)
[IA64] Remove COMPAT_IA32 support
This has been broken since May 2008 when Al Viro killed altroot support. Since nobody has complained, it would appear that there are no users of this code (A plausible theory since the main OSVs that support ia64 prefer to use the IA32-EL software emulation). Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/ia32/sys_ia32.c')
-rw-r--r--arch/ia64/ia32/sys_ia32.c2765
1 files changed, 0 insertions, 2765 deletions
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
deleted file mode 100644
index 045b746b9808..000000000000
--- a/arch/ia64/ia32/sys_ia32.c
+++ /dev/null
@@ -1,2765 +0,0 @@
1/*
2 * sys_ia32.c: Conversion between 32bit and 64bit native syscalls. Derived from sys_sparc32.c.
3 *
4 * Copyright (C) 2000 VA Linux Co
5 * Copyright (C) 2000 Don Dugger <n0ano@valinux.com>
6 * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
7 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
8 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
9 * Copyright (C) 2000-2003, 2005 Hewlett-Packard Co
10 * David Mosberger-Tang <davidm@hpl.hp.com>
11 * Copyright (C) 2004 Gordon Jin <gordon.jin@intel.com>
12 *
13 * These routines maintain argument size conversion between 32bit and 64bit
14 * environment.
15 */
16
17#include <linux/kernel.h>
18#include <linux/syscalls.h>
19#include <linux/sysctl.h>
20#include <linux/sched.h>
21#include <linux/fs.h>
22#include <linux/file.h>
23#include <linux/signal.h>
24#include <linux/resource.h>
25#include <linux/times.h>
26#include <linux/utsname.h>
27#include <linux/smp.h>
28#include <linux/smp_lock.h>
29#include <linux/sem.h>
30#include <linux/msg.h>
31#include <linux/mm.h>
32#include <linux/shm.h>
33#include <linux/slab.h>
34#include <linux/uio.h>
35#include <linux/socket.h>
36#include <linux/quota.h>
37#include <linux/poll.h>
38#include <linux/eventpoll.h>
39#include <linux/personality.h>
40#include <linux/ptrace.h>
41#include <linux/regset.h>
42#include <linux/stat.h>
43#include <linux/ipc.h>
44#include <linux/capability.h>
45#include <linux/compat.h>
46#include <linux/vfs.h>
47#include <linux/mman.h>
48#include <linux/mutex.h>
49
50#include <asm/intrinsics.h>
51#include <asm/types.h>
52#include <asm/uaccess.h>
53#include <asm/unistd.h>
54
55#include "ia32priv.h"
56
57#include <net/scm.h>
58#include <net/sock.h>
59
60#define DEBUG 0
61
62#if DEBUG
63# define DBG(fmt...) printk(KERN_DEBUG fmt)
64#else
65# define DBG(fmt...)
66#endif
67
68#define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
69
70#define OFFSET4K(a) ((a) & 0xfff)
71#define PAGE_START(addr) ((addr) & PAGE_MASK)
72#define MINSIGSTKSZ_IA32 2048
73
74#define high2lowuid(uid) ((uid) > 65535 ? 65534 : (uid))
75#define high2lowgid(gid) ((gid) > 65535 ? 65534 : (gid))
76
77/*
78 * Anything that modifies or inspects ia32 user virtual memory must hold this semaphore
79 * while doing so.
80 */
81/* XXX make per-mm: */
82static DEFINE_MUTEX(ia32_mmap_mutex);
83
84asmlinkage long
85sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp,
86 struct pt_regs *regs)
87{
88 long error;
89 char *filename;
90 unsigned long old_map_base, old_task_size, tssd;
91
92 filename = getname(name);
93 error = PTR_ERR(filename);
94 if (IS_ERR(filename))
95 return error;
96
97 old_map_base = current->thread.map_base;
98 old_task_size = current->thread.task_size;
99 tssd = ia64_get_kr(IA64_KR_TSSD);
100
101 /* we may be exec'ing a 64-bit process: reset map base, task-size, and io-base: */
102 current->thread.map_base = DEFAULT_MAP_BASE;
103 current->thread.task_size = DEFAULT_TASK_SIZE;
104 ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob);
105 ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1);
106
107 error = compat_do_execve(filename, argv, envp, regs);
108 putname(filename);
109
110 if (error < 0) {
111 /* oops, execve failed, switch back to old values... */
112 ia64_set_kr(IA64_KR_IO_BASE, IA32_IOBASE);
113 ia64_set_kr(IA64_KR_TSSD, tssd);
114 current->thread.map_base = old_map_base;
115 current->thread.task_size = old_task_size;
116 }
117
118 return error;
119}
120
121
122#if PAGE_SHIFT > IA32_PAGE_SHIFT
123
124
125static int
126get_page_prot (struct vm_area_struct *vma, unsigned long addr)
127{
128 int prot = 0;
129
130 if (!vma || vma->vm_start > addr)
131 return 0;
132
133 if (vma->vm_flags & VM_READ)
134 prot |= PROT_READ;
135 if (vma->vm_flags & VM_WRITE)
136 prot |= PROT_WRITE;
137 if (vma->vm_flags & VM_EXEC)
138 prot |= PROT_EXEC;
139 return prot;
140}
141
142/*
143 * Map a subpage by creating an anonymous page that contains the union of the old page and
144 * the subpage.
145 */
146static unsigned long
147mmap_subpage (struct file *file, unsigned long start, unsigned long end, int prot, int flags,
148 loff_t off)
149{
150 void *page = NULL;
151 struct inode *inode;
152 unsigned long ret = 0;
153 struct vm_area_struct *vma = find_vma(current->mm, start);
154 int old_prot = get_page_prot(vma, start);
155
156 DBG("mmap_subpage(file=%p,start=0x%lx,end=0x%lx,prot=%x,flags=%x,off=0x%llx)\n",
157 file, start, end, prot, flags, off);
158
159
160 /* Optimize the case where the old mmap and the new mmap are both anonymous */
161 if ((old_prot & PROT_WRITE) && (flags & MAP_ANONYMOUS) && !vma->vm_file) {
162 if (clear_user((void __user *) start, end - start)) {
163 ret = -EFAULT;
164 goto out;
165 }
166 goto skip_mmap;
167 }
168
169 page = (void *) get_zeroed_page(GFP_KERNEL);
170 if (!page)
171 return -ENOMEM;
172
173 if (old_prot)
174 copy_from_user(page, (void __user *) PAGE_START(start), PAGE_SIZE);
175
176 down_write(&current->mm->mmap_sem);
177 {
178 ret = do_mmap(NULL, PAGE_START(start), PAGE_SIZE, prot | PROT_WRITE,
179 flags | MAP_FIXED | MAP_ANONYMOUS, 0);
180 }
181 up_write(&current->mm->mmap_sem);
182
183 if (IS_ERR((void *) ret))
184 goto out;
185
186 if (old_prot) {
187 /* copy back the old page contents. */
188 if (offset_in_page(start))
189 copy_to_user((void __user *) PAGE_START(start), page,
190 offset_in_page(start));
191 if (offset_in_page(end))
192 copy_to_user((void __user *) end, page + offset_in_page(end),
193 PAGE_SIZE - offset_in_page(end));
194 }
195
196 if (!(flags & MAP_ANONYMOUS)) {
197 /* read the file contents */
198 inode = file->f_path.dentry->d_inode;
199 if (!inode->i_fop || !file->f_op->read
200 || ((*file->f_op->read)(file, (char __user *) start, end - start, &off) < 0))
201 {
202 ret = -EINVAL;
203 goto out;
204 }
205 }
206
207 skip_mmap:
208 if (!(prot & PROT_WRITE))
209 ret = sys_mprotect(PAGE_START(start), PAGE_SIZE, prot | old_prot);
210 out:
211 if (page)
212 free_page((unsigned long) page);
213 return ret;
214}
215
216/* SLAB cache for ia64_partial_page structures */
217struct kmem_cache *ia64_partial_page_cachep;
218
219/*
220 * init ia64_partial_page_list.
221 * return 0 means kmalloc fail.
222 */
223struct ia64_partial_page_list*
224ia32_init_pp_list(void)
225{
226 struct ia64_partial_page_list *p;
227
228 if ((p = kmalloc(sizeof(*p), GFP_KERNEL)) == NULL)
229 return p;
230 p->pp_head = NULL;
231 p->ppl_rb = RB_ROOT;
232 p->pp_hint = NULL;
233 atomic_set(&p->pp_count, 1);
234 return p;
235}
236
237/*
238 * Search for the partial page with @start in partial page list @ppl.
239 * If finds the partial page, return the found partial page.
240 * Else, return 0 and provide @pprev, @rb_link, @rb_parent to
241 * be used by later __ia32_insert_pp().
242 */
243static struct ia64_partial_page *
244__ia32_find_pp(struct ia64_partial_page_list *ppl, unsigned int start,
245 struct ia64_partial_page **pprev, struct rb_node ***rb_link,
246 struct rb_node **rb_parent)
247{
248 struct ia64_partial_page *pp;
249 struct rb_node **__rb_link, *__rb_parent, *rb_prev;
250
251 pp = ppl->pp_hint;
252 if (pp && pp->base == start)
253 return pp;
254
255 __rb_link = &ppl->ppl_rb.rb_node;
256 rb_prev = __rb_parent = NULL;
257
258 while (*__rb_link) {
259 __rb_parent = *__rb_link;
260 pp = rb_entry(__rb_parent, struct ia64_partial_page, pp_rb);
261
262 if (pp->base == start) {
263 ppl->pp_hint = pp;
264 return pp;
265 } else if (pp->base < start) {
266 rb_prev = __rb_parent;
267 __rb_link = &__rb_parent->rb_right;
268 } else {
269 __rb_link = &__rb_parent->rb_left;
270 }
271 }
272
273 *rb_link = __rb_link;
274 *rb_parent = __rb_parent;
275 *pprev = NULL;
276 if (rb_prev)
277 *pprev = rb_entry(rb_prev, struct ia64_partial_page, pp_rb);
278 return NULL;
279}
280
281/*
282 * insert @pp into @ppl.
283 */
284static void
285__ia32_insert_pp(struct ia64_partial_page_list *ppl,
286 struct ia64_partial_page *pp, struct ia64_partial_page *prev,
287 struct rb_node **rb_link, struct rb_node *rb_parent)
288{
289 /* link list */
290 if (prev) {
291 pp->next = prev->next;
292 prev->next = pp;
293 } else {
294 ppl->pp_head = pp;
295 if (rb_parent)
296 pp->next = rb_entry(rb_parent,
297 struct ia64_partial_page, pp_rb);
298 else
299 pp->next = NULL;
300 }
301
302 /* link rb */
303 rb_link_node(&pp->pp_rb, rb_parent, rb_link);
304 rb_insert_color(&pp->pp_rb, &ppl->ppl_rb);
305
306 ppl->pp_hint = pp;
307}
308
309/*
310 * delete @pp from partial page list @ppl.
311 */
312static void
313__ia32_delete_pp(struct ia64_partial_page_list *ppl,
314 struct ia64_partial_page *pp, struct ia64_partial_page *prev)
315{
316 if (prev) {
317 prev->next = pp->next;
318 if (ppl->pp_hint == pp)
319 ppl->pp_hint = prev;
320 } else {
321 ppl->pp_head = pp->next;
322 if (ppl->pp_hint == pp)
323 ppl->pp_hint = pp->next;
324 }
325 rb_erase(&pp->pp_rb, &ppl->ppl_rb);
326 kmem_cache_free(ia64_partial_page_cachep, pp);
327}
328
329static struct ia64_partial_page *
330__pp_prev(struct ia64_partial_page *pp)
331{
332 struct rb_node *prev = rb_prev(&pp->pp_rb);
333 if (prev)
334 return rb_entry(prev, struct ia64_partial_page, pp_rb);
335 else
336 return NULL;
337}
338
339/*
340 * Delete partial pages with address between @start and @end.
341 * @start and @end are page aligned.
342 */
343static void
344__ia32_delete_pp_range(unsigned int start, unsigned int end)
345{
346 struct ia64_partial_page *pp, *prev;
347 struct rb_node **rb_link, *rb_parent;
348
349 if (start >= end)
350 return;
351
352 pp = __ia32_find_pp(current->thread.ppl, start, &prev,
353 &rb_link, &rb_parent);
354 if (pp)
355 prev = __pp_prev(pp);
356 else {
357 if (prev)
358 pp = prev->next;
359 else
360 pp = current->thread.ppl->pp_head;
361 }
362
363 while (pp && pp->base < end) {
364 struct ia64_partial_page *tmp = pp->next;
365 __ia32_delete_pp(current->thread.ppl, pp, prev);
366 pp = tmp;
367 }
368}
369
370/*
371 * Set the range between @start and @end in bitmap.
372 * @start and @end should be IA32 page aligned and in the same IA64 page.
373 */
374static int
375__ia32_set_pp(unsigned int start, unsigned int end, int flags)
376{
377 struct ia64_partial_page *pp, *prev;
378 struct rb_node ** rb_link, *rb_parent;
379 unsigned int pstart, start_bit, end_bit, i;
380
381 pstart = PAGE_START(start);
382 start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE;
383 end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE;
384 if (end_bit == 0)
385 end_bit = PAGE_SIZE / IA32_PAGE_SIZE;
386 pp = __ia32_find_pp(current->thread.ppl, pstart, &prev,
387 &rb_link, &rb_parent);
388 if (pp) {
389 for (i = start_bit; i < end_bit; i++)
390 set_bit(i, &pp->bitmap);
391 /*
392 * Check: if this partial page has been set to a full page,
393 * then delete it.
394 */
395 if (find_first_zero_bit(&pp->bitmap, sizeof(pp->bitmap)*8) >=
396 PAGE_SIZE/IA32_PAGE_SIZE) {
397 __ia32_delete_pp(current->thread.ppl, pp, __pp_prev(pp));
398 }
399 return 0;
400 }
401
402 /*
403 * MAP_FIXED may lead to overlapping mmap.
404 * In this case, the requested mmap area may already mmaped as a full
405 * page. So check vma before adding a new partial page.
406 */
407 if (flags & MAP_FIXED) {
408 struct vm_area_struct *vma = find_vma(current->mm, pstart);
409 if (vma && vma->vm_start <= pstart)
410 return 0;
411 }
412
413 /* new a ia64_partial_page */
414 pp = kmem_cache_alloc(ia64_partial_page_cachep, GFP_KERNEL);
415 if (!pp)
416 return -ENOMEM;
417 pp->base = pstart;
418 pp->bitmap = 0;
419 for (i=start_bit; i<end_bit; i++)
420 set_bit(i, &(pp->bitmap));
421 pp->next = NULL;
422 __ia32_insert_pp(current->thread.ppl, pp, prev, rb_link, rb_parent);
423 return 0;
424}
425
426/*
427 * @start and @end should be IA32 page aligned, but don't need to be in the
428 * same IA64 page. Split @start and @end to make sure they're in the same IA64
429 * page, then call __ia32_set_pp().
430 */
431static void
432ia32_set_pp(unsigned int start, unsigned int end, int flags)
433{
434 down_write(&current->mm->mmap_sem);
435 if (flags & MAP_FIXED) {
436 /*
437 * MAP_FIXED may lead to overlapping mmap. When this happens,
438 * a series of complete IA64 pages results in deletion of
439 * old partial pages in that range.
440 */
441 __ia32_delete_pp_range(PAGE_ALIGN(start), PAGE_START(end));
442 }
443
444 if (end < PAGE_ALIGN(start)) {
445 __ia32_set_pp(start, end, flags);
446 } else {
447 if (offset_in_page(start))
448 __ia32_set_pp(start, PAGE_ALIGN(start), flags);
449 if (offset_in_page(end))
450 __ia32_set_pp(PAGE_START(end), end, flags);
451 }
452 up_write(&current->mm->mmap_sem);
453}
454
455/*
456 * Unset the range between @start and @end in bitmap.
457 * @start and @end should be IA32 page aligned and in the same IA64 page.
458 * After doing that, if the bitmap is 0, then free the page and return 1,
459 * else return 0;
460 * If not find the partial page in the list, then
461 * If the vma exists, then the full page is set to a partial page;
462 * Else return -ENOMEM.
463 */
464static int
465__ia32_unset_pp(unsigned int start, unsigned int end)
466{
467 struct ia64_partial_page *pp, *prev;
468 struct rb_node ** rb_link, *rb_parent;
469 unsigned int pstart, start_bit, end_bit, i;
470 struct vm_area_struct *vma;
471
472 pstart = PAGE_START(start);
473 start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE;
474 end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE;
475 if (end_bit == 0)
476 end_bit = PAGE_SIZE / IA32_PAGE_SIZE;
477
478 pp = __ia32_find_pp(current->thread.ppl, pstart, &prev,
479 &rb_link, &rb_parent);
480 if (pp) {
481 for (i = start_bit; i < end_bit; i++)
482 clear_bit(i, &pp->bitmap);
483 if (pp->bitmap == 0) {
484 __ia32_delete_pp(current->thread.ppl, pp, __pp_prev(pp));
485 return 1;
486 }
487 return 0;
488 }
489
490 vma = find_vma(current->mm, pstart);
491 if (!vma || vma->vm_start > pstart) {
492 return -ENOMEM;
493 }
494
495 /* new a ia64_partial_page */
496 pp = kmem_cache_alloc(ia64_partial_page_cachep, GFP_KERNEL);
497 if (!pp)
498 return -ENOMEM;
499 pp->base = pstart;
500 pp->bitmap = 0;
501 for (i = 0; i < start_bit; i++)
502 set_bit(i, &(pp->bitmap));
503 for (i = end_bit; i < PAGE_SIZE / IA32_PAGE_SIZE; i++)
504 set_bit(i, &(pp->bitmap));
505 pp->next = NULL;
506 __ia32_insert_pp(current->thread.ppl, pp, prev, rb_link, rb_parent);
507 return 0;
508}
509
510/*
511 * Delete pp between PAGE_ALIGN(start) and PAGE_START(end) by calling
512 * __ia32_delete_pp_range(). Unset possible partial pages by calling
513 * __ia32_unset_pp().
514 * The returned value see __ia32_unset_pp().
515 */
516static int
517ia32_unset_pp(unsigned int *startp, unsigned int *endp)
518{
519 unsigned int start = *startp, end = *endp;
520 int ret = 0;
521
522 down_write(&current->mm->mmap_sem);
523
524 __ia32_delete_pp_range(PAGE_ALIGN(start), PAGE_START(end));
525
526 if (end < PAGE_ALIGN(start)) {
527 ret = __ia32_unset_pp(start, end);
528 if (ret == 1) {
529 *startp = PAGE_START(start);
530 *endp = PAGE_ALIGN(end);
531 }
532 if (ret == 0) {
533 /* to shortcut sys_munmap() in sys32_munmap() */
534 *startp = PAGE_START(start);
535 *endp = PAGE_START(end);
536 }
537 } else {
538 if (offset_in_page(start)) {
539 ret = __ia32_unset_pp(start, PAGE_ALIGN(start));
540 if (ret == 1)
541 *startp = PAGE_START(start);
542 if (ret == 0)
543 *startp = PAGE_ALIGN(start);
544 if (ret < 0)
545 goto out;
546 }
547 if (offset_in_page(end)) {
548 ret = __ia32_unset_pp(PAGE_START(end), end);
549 if (ret == 1)
550 *endp = PAGE_ALIGN(end);
551 if (ret == 0)
552 *endp = PAGE_START(end);
553 }
554 }
555
556 out:
557 up_write(&current->mm->mmap_sem);
558 return ret;
559}
560
561/*
562 * Compare the range between @start and @end with bitmap in partial page.
563 * @start and @end should be IA32 page aligned and in the same IA64 page.
564 */
565static int
566__ia32_compare_pp(unsigned int start, unsigned int end)
567{
568 struct ia64_partial_page *pp, *prev;
569 struct rb_node ** rb_link, *rb_parent;
570 unsigned int pstart, start_bit, end_bit, size;
571 unsigned int first_bit, next_zero_bit; /* the first range in bitmap */
572
573 pstart = PAGE_START(start);
574
575 pp = __ia32_find_pp(current->thread.ppl, pstart, &prev,
576 &rb_link, &rb_parent);
577 if (!pp)
578 return 1;
579
580 start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE;
581 end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE;
582 size = sizeof(pp->bitmap) * 8;
583 first_bit = find_first_bit(&pp->bitmap, size);
584 next_zero_bit = find_next_zero_bit(&pp->bitmap, size, first_bit);
585 if ((start_bit < first_bit) || (end_bit > next_zero_bit)) {
586 /* exceeds the first range in bitmap */
587 return -ENOMEM;
588 } else if ((start_bit == first_bit) && (end_bit == next_zero_bit)) {
589 first_bit = find_next_bit(&pp->bitmap, size, next_zero_bit);
590 if ((next_zero_bit < first_bit) && (first_bit < size))
591 return 1; /* has next range */
592 else
593 return 0; /* no next range */
594 } else
595 return 1;
596}
597
598/*
599 * @start and @end should be IA32 page aligned, but don't need to be in the
600 * same IA64 page. Split @start and @end to make sure they're in the same IA64
601 * page, then call __ia32_compare_pp().
602 *
603 * Take this as example: the range is the 1st and 2nd 4K page.
604 * Return 0 if they fit bitmap exactly, i.e. bitmap = 00000011;
605 * Return 1 if the range doesn't cover whole bitmap, e.g. bitmap = 00001111;
606 * Return -ENOMEM if the range exceeds the bitmap, e.g. bitmap = 00000001 or
607 * bitmap = 00000101.
608 */
609static int
610ia32_compare_pp(unsigned int *startp, unsigned int *endp)
611{
612 unsigned int start = *startp, end = *endp;
613 int retval = 0;
614
615 down_write(&current->mm->mmap_sem);
616
617 if (end < PAGE_ALIGN(start)) {
618 retval = __ia32_compare_pp(start, end);
619 if (retval == 0) {
620 *startp = PAGE_START(start);
621 *endp = PAGE_ALIGN(end);
622 }
623 } else {
624 if (offset_in_page(start)) {
625 retval = __ia32_compare_pp(start,
626 PAGE_ALIGN(start));
627 if (retval == 0)
628 *startp = PAGE_START(start);
629 if (retval < 0)
630 goto out;
631 }
632 if (offset_in_page(end)) {
633 retval = __ia32_compare_pp(PAGE_START(end), end);
634 if (retval == 0)
635 *endp = PAGE_ALIGN(end);
636 }
637 }
638
639 out:
640 up_write(&current->mm->mmap_sem);
641 return retval;
642}
643
644static void
645__ia32_drop_pp_list(struct ia64_partial_page_list *ppl)
646{
647 struct ia64_partial_page *pp = ppl->pp_head;
648
649 while (pp) {
650 struct ia64_partial_page *next = pp->next;
651 kmem_cache_free(ia64_partial_page_cachep, pp);
652 pp = next;
653 }
654
655 kfree(ppl);
656}
657
658void
659ia32_drop_ia64_partial_page_list(struct task_struct *task)
660{
661 struct ia64_partial_page_list* ppl = task->thread.ppl;
662
663 if (ppl && atomic_dec_and_test(&ppl->pp_count))
664 __ia32_drop_pp_list(ppl);
665}
666
667/*
668 * Copy current->thread.ppl to ppl (already initialized).
669 */
670static int
671__ia32_copy_pp_list(struct ia64_partial_page_list *ppl)
672{
673 struct ia64_partial_page *pp, *tmp, *prev;
674 struct rb_node **rb_link, *rb_parent;
675
676 ppl->pp_head = NULL;
677 ppl->pp_hint = NULL;
678 ppl->ppl_rb = RB_ROOT;
679 rb_link = &ppl->ppl_rb.rb_node;
680 rb_parent = NULL;
681 prev = NULL;
682
683 for (pp = current->thread.ppl->pp_head; pp; pp = pp->next) {
684 tmp = kmem_cache_alloc(ia64_partial_page_cachep, GFP_KERNEL);
685 if (!tmp)
686 return -ENOMEM;
687 *tmp = *pp;
688 __ia32_insert_pp(ppl, tmp, prev, rb_link, rb_parent);
689 prev = tmp;
690 rb_link = &tmp->pp_rb.rb_right;
691 rb_parent = &tmp->pp_rb;
692 }
693 return 0;
694}
695
696int
697ia32_copy_ia64_partial_page_list(struct task_struct *p,
698 unsigned long clone_flags)
699{
700 int retval = 0;
701
702 if (clone_flags & CLONE_VM) {
703 atomic_inc(&current->thread.ppl->pp_count);
704 p->thread.ppl = current->thread.ppl;
705 } else {
706 p->thread.ppl = ia32_init_pp_list();
707 if (!p->thread.ppl)
708 return -ENOMEM;
709 down_write(&current->mm->mmap_sem);
710 {
711 retval = __ia32_copy_pp_list(p->thread.ppl);
712 }
713 up_write(&current->mm->mmap_sem);
714 }
715
716 return retval;
717}
718
719static unsigned long
720emulate_mmap (struct file *file, unsigned long start, unsigned long len, int prot, int flags,
721 loff_t off)
722{
723 unsigned long tmp, end, pend, pstart, ret, is_congruent, fudge = 0;
724 struct inode *inode;
725 loff_t poff;
726
727 end = start + len;
728 pstart = PAGE_START(start);
729 pend = PAGE_ALIGN(end);
730
731 if (flags & MAP_FIXED) {
732 ia32_set_pp((unsigned int)start, (unsigned int)end, flags);
733 if (start > pstart) {
734 if (flags & MAP_SHARED)
735 printk(KERN_INFO
736 "%s(%d): emulate_mmap() can't share head (addr=0x%lx)\n",
737 current->comm, task_pid_nr(current), start);
738 ret = mmap_subpage(file, start, min(PAGE_ALIGN(start), end), prot, flags,
739 off);
740 if (IS_ERR((void *) ret))
741 return ret;
742 pstart += PAGE_SIZE;
743 if (pstart >= pend)
744 goto out; /* done */
745 }
746 if (end < pend) {
747 if (flags & MAP_SHARED)
748 printk(KERN_INFO
749 "%s(%d): emulate_mmap() can't share tail (end=0x%lx)\n",
750 current->comm, task_pid_nr(current), end);
751 ret = mmap_subpage(file, max(start, PAGE_START(end)), end, prot, flags,
752 (off + len) - offset_in_page(end));
753 if (IS_ERR((void *) ret))
754 return ret;
755 pend -= PAGE_SIZE;
756 if (pstart >= pend)
757 goto out; /* done */
758 }
759 } else {
760 /*
761 * If a start address was specified, use it if the entire rounded out area
762 * is available.
763 */
764 if (start && !pstart)
765 fudge = 1; /* handle case of mapping to range (0,PAGE_SIZE) */
766 tmp = arch_get_unmapped_area(file, pstart - fudge, pend - pstart, 0, flags);
767 if (tmp != pstart) {
768 pstart = tmp;
769 start = pstart + offset_in_page(off); /* make start congruent with off */
770 end = start + len;
771 pend = PAGE_ALIGN(end);
772 }
773 }
774
775 poff = off + (pstart - start); /* note: (pstart - start) may be negative */
776 is_congruent = (flags & MAP_ANONYMOUS) || (offset_in_page(poff) == 0);
777
778 if ((flags & MAP_SHARED) && !is_congruent)
779 printk(KERN_INFO "%s(%d): emulate_mmap() can't share contents of incongruent mmap "
780 "(addr=0x%lx,off=0x%llx)\n", current->comm, task_pid_nr(current), start, off);
781
782 DBG("mmap_body: mapping [0x%lx-0x%lx) %s with poff 0x%llx\n", pstart, pend,
783 is_congruent ? "congruent" : "not congruent", poff);
784
785 down_write(&current->mm->mmap_sem);
786 {
787 if (!(flags & MAP_ANONYMOUS) && is_congruent)
788 ret = do_mmap(file, pstart, pend - pstart, prot, flags | MAP_FIXED, poff);
789 else
790 ret = do_mmap(NULL, pstart, pend - pstart,
791 prot | ((flags & MAP_ANONYMOUS) ? 0 : PROT_WRITE),
792 flags | MAP_FIXED | MAP_ANONYMOUS, 0);
793 }
794 up_write(&current->mm->mmap_sem);
795
796 if (IS_ERR((void *) ret))
797 return ret;
798
799 if (!is_congruent) {
800 /* read the file contents */
801 inode = file->f_path.dentry->d_inode;
802 if (!inode->i_fop || !file->f_op->read
803 || ((*file->f_op->read)(file, (char __user *) pstart, pend - pstart, &poff)
804 < 0))
805 {
806 sys_munmap(pstart, pend - pstart);
807 return -EINVAL;
808 }
809 if (!(prot & PROT_WRITE) && sys_mprotect(pstart, pend - pstart, prot) < 0)
810 return -EINVAL;
811 }
812
813 if (!(flags & MAP_FIXED))
814 ia32_set_pp((unsigned int)start, (unsigned int)end, flags);
815out:
816 return start;
817}
818
819#endif /* PAGE_SHIFT > IA32_PAGE_SHIFT */
820
821static inline unsigned int
822get_prot32 (unsigned int prot)
823{
824 if (prot & PROT_WRITE)
825 /* on x86, PROT_WRITE implies PROT_READ which implies PROT_EEC */
826 prot |= PROT_READ | PROT_WRITE | PROT_EXEC;
827 else if (prot & (PROT_READ | PROT_EXEC))
828 /* on x86, there is no distinction between PROT_READ and PROT_EXEC */
829 prot |= (PROT_READ | PROT_EXEC);
830
831 return prot;
832}
833
834unsigned long
835ia32_do_mmap (struct file *file, unsigned long addr, unsigned long len, int prot, int flags,
836 loff_t offset)
837{
838 DBG("ia32_do_mmap(file=%p,addr=0x%lx,len=0x%lx,prot=%x,flags=%x,offset=0x%llx)\n",
839 file, addr, len, prot, flags, offset);
840
841 if (file && (!file->f_op || !file->f_op->mmap))
842 return -ENODEV;
843
844 len = IA32_PAGE_ALIGN(len);
845 if (len == 0)
846 return addr;
847
848 if (len > IA32_PAGE_OFFSET || addr > IA32_PAGE_OFFSET - len)
849 {
850 if (flags & MAP_FIXED)
851 return -ENOMEM;
852 else
853 return -EINVAL;
854 }
855
856 if (OFFSET4K(offset))
857 return -EINVAL;
858
859 prot = get_prot32(prot);
860
861 if (flags & MAP_HUGETLB)
862 return -ENOMEM;
863
864#if PAGE_SHIFT > IA32_PAGE_SHIFT
865 mutex_lock(&ia32_mmap_mutex);
866 {
867 addr = emulate_mmap(file, addr, len, prot, flags, offset);
868 }
869 mutex_unlock(&ia32_mmap_mutex);
870#else
871 down_write(&current->mm->mmap_sem);
872 {
873 addr = do_mmap(file, addr, len, prot, flags, offset);
874 }
875 up_write(&current->mm->mmap_sem);
876#endif
877 DBG("ia32_do_mmap: returning 0x%lx\n", addr);
878 return addr;
879}
880
881/*
882 * Linux/i386 didn't use to be able to handle more than 4 system call parameters, so these
883 * system calls used a memory block for parameter passing..
884 */
885
886struct mmap_arg_struct {
887 unsigned int addr;
888 unsigned int len;
889 unsigned int prot;
890 unsigned int flags;
891 unsigned int fd;
892 unsigned int offset;
893};
894
895asmlinkage long
896sys32_mmap (struct mmap_arg_struct __user *arg)
897{
898 struct mmap_arg_struct a;
899 struct file *file = NULL;
900 unsigned long addr;
901 int flags;
902
903 if (copy_from_user(&a, arg, sizeof(a)))
904 return -EFAULT;
905
906 if (OFFSET4K(a.offset))
907 return -EINVAL;
908
909 flags = a.flags;
910
911 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
912 if (!(flags & MAP_ANONYMOUS)) {
913 file = fget(a.fd);
914 if (!file)
915 return -EBADF;
916 }
917
918 addr = ia32_do_mmap(file, a.addr, a.len, a.prot, flags, a.offset);
919
920 if (file)
921 fput(file);
922 return addr;
923}
924
925asmlinkage long
926sys32_mmap2 (unsigned int addr, unsigned int len, unsigned int prot, unsigned int flags,
927 unsigned int fd, unsigned int pgoff)
928{
929 struct file *file = NULL;
930 unsigned long retval;
931
932 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
933 if (!(flags & MAP_ANONYMOUS)) {
934 file = fget(fd);
935 if (!file)
936 return -EBADF;
937 }
938
939 retval = ia32_do_mmap(file, addr, len, prot, flags,
940 (unsigned long) pgoff << IA32_PAGE_SHIFT);
941
942 if (file)
943 fput(file);
944 return retval;
945}
946
947asmlinkage long
948sys32_munmap (unsigned int start, unsigned int len)
949{
950 unsigned int end = start + len;
951 long ret;
952
953#if PAGE_SHIFT <= IA32_PAGE_SHIFT
954 ret = sys_munmap(start, end - start);
955#else
956 if (OFFSET4K(start))
957 return -EINVAL;
958
959 end = IA32_PAGE_ALIGN(end);
960 if (start >= end)
961 return -EINVAL;
962
963 ret = ia32_unset_pp(&start, &end);
964 if (ret < 0)
965 return ret;
966
967 if (start >= end)
968 return 0;
969
970 mutex_lock(&ia32_mmap_mutex);
971 ret = sys_munmap(start, end - start);
972 mutex_unlock(&ia32_mmap_mutex);
973#endif
974 return ret;
975}
976
977#if PAGE_SHIFT > IA32_PAGE_SHIFT
978
979/*
980 * When mprotect()ing a partial page, we set the permission to the union of the old
981 * settings and the new settings. In other words, it's only possible to make access to a
982 * partial page less restrictive.
983 */
984static long
985mprotect_subpage (unsigned long address, int new_prot)
986{
987 int old_prot;
988 struct vm_area_struct *vma;
989
990 if (new_prot == PROT_NONE)
991 return 0; /* optimize case where nothing changes... */
992 vma = find_vma(current->mm, address);
993 old_prot = get_page_prot(vma, address);
994 return sys_mprotect(address, PAGE_SIZE, new_prot | old_prot);
995}
996
997#endif /* PAGE_SHIFT > IA32_PAGE_SHIFT */
998
999asmlinkage long
1000sys32_mprotect (unsigned int start, unsigned int len, int prot)
1001{
1002 unsigned int end = start + len;
1003#if PAGE_SHIFT > IA32_PAGE_SHIFT
1004 long retval = 0;
1005#endif
1006
1007 prot = get_prot32(prot);
1008
1009#if PAGE_SHIFT <= IA32_PAGE_SHIFT
1010 return sys_mprotect(start, end - start, prot);
1011#else
1012 if (OFFSET4K(start))
1013 return -EINVAL;
1014
1015 end = IA32_PAGE_ALIGN(end);
1016 if (end < start)
1017 return -EINVAL;
1018
1019 retval = ia32_compare_pp(&start, &end);
1020
1021 if (retval < 0)
1022 return retval;
1023
1024 mutex_lock(&ia32_mmap_mutex);
1025 {
1026 if (offset_in_page(start)) {
1027 /* start address is 4KB aligned but not page aligned. */
1028 retval = mprotect_subpage(PAGE_START(start), prot);
1029 if (retval < 0)
1030 goto out;
1031
1032 start = PAGE_ALIGN(start);
1033 if (start >= end)
1034 goto out; /* retval is already zero... */
1035 }
1036
1037 if (offset_in_page(end)) {
1038 /* end address is 4KB aligned but not page aligned. */
1039 retval = mprotect_subpage(PAGE_START(end), prot);
1040 if (retval < 0)
1041 goto out;
1042
1043 end = PAGE_START(end);
1044 }
1045 retval = sys_mprotect(start, end - start, prot);
1046 }
1047 out:
1048 mutex_unlock(&ia32_mmap_mutex);
1049 return retval;
1050#endif
1051}
1052
1053asmlinkage long
1054sys32_mremap (unsigned int addr, unsigned int old_len, unsigned int new_len,
1055 unsigned int flags, unsigned int new_addr)
1056{
1057 long ret;
1058
1059#if PAGE_SHIFT <= IA32_PAGE_SHIFT
1060 ret = sys_mremap(addr, old_len, new_len, flags, new_addr);
1061#else
1062 unsigned int old_end, new_end;
1063
1064 if (OFFSET4K(addr))
1065 return -EINVAL;
1066
1067 old_len = IA32_PAGE_ALIGN(old_len);
1068 new_len = IA32_PAGE_ALIGN(new_len);
1069 old_end = addr + old_len;
1070 new_end = addr + new_len;
1071
1072 if (!new_len)
1073 return -EINVAL;
1074
1075 if ((flags & MREMAP_FIXED) && (OFFSET4K(new_addr)))
1076 return -EINVAL;
1077
1078 if (old_len >= new_len) {
1079 ret = sys32_munmap(addr + new_len, old_len - new_len);
1080 if (ret && old_len != new_len)
1081 return ret;
1082 ret = addr;
1083 if (!(flags & MREMAP_FIXED) || (new_addr == addr))
1084 return ret;
1085 old_len = new_len;
1086 }
1087
1088 addr = PAGE_START(addr);
1089 old_len = PAGE_ALIGN(old_end) - addr;
1090 new_len = PAGE_ALIGN(new_end) - addr;
1091
1092 mutex_lock(&ia32_mmap_mutex);
1093 ret = sys_mremap(addr, old_len, new_len, flags, new_addr);
1094 mutex_unlock(&ia32_mmap_mutex);
1095
1096 if ((ret >= 0) && (old_len < new_len)) {
1097 /* mremap expanded successfully */
1098 ia32_set_pp(old_end, new_end, flags);
1099 }
1100#endif
1101 return ret;
1102}
1103
1104asmlinkage unsigned long
1105sys32_alarm (unsigned int seconds)
1106{
1107 return alarm_setitimer(seconds);
1108}
1109
1110struct sel_arg_struct {
1111 unsigned int n;
1112 unsigned int inp;
1113 unsigned int outp;
1114 unsigned int exp;
1115 unsigned int tvp;
1116};
1117
1118asmlinkage long
1119sys32_old_select (struct sel_arg_struct __user *arg)
1120{
1121 struct sel_arg_struct a;
1122
1123 if (copy_from_user(&a, arg, sizeof(a)))
1124 return -EFAULT;
1125 return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
1126 compat_ptr(a.exp), compat_ptr(a.tvp));
1127}
1128
1129#define SEMOP 1
1130#define SEMGET 2
1131#define SEMCTL 3
1132#define SEMTIMEDOP 4
1133#define MSGSND 11
1134#define MSGRCV 12
1135#define MSGGET 13
1136#define MSGCTL 14
1137#define SHMAT 21
1138#define SHMDT 22
1139#define SHMGET 23
1140#define SHMCTL 24
1141
1142asmlinkage long
1143sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth)
1144{
1145 int version;
1146
1147 version = call >> 16; /* hack for backward compatibility */
1148 call &= 0xffff;
1149
1150 switch (call) {
1151 case SEMTIMEDOP:
1152 if (fifth)
1153 return compat_sys_semtimedop(first, compat_ptr(ptr),
1154 second, compat_ptr(fifth));
1155 /* else fall through for normal semop() */
1156 case SEMOP:
1157 /* struct sembuf is the same on 32 and 64bit :)) */
1158 return sys_semtimedop(first, compat_ptr(ptr), second,
1159 NULL);
1160 case SEMGET:
1161 return sys_semget(first, second, third);
1162 case SEMCTL:
1163 return compat_sys_semctl(first, second, third, compat_ptr(ptr));
1164
1165 case MSGSND:
1166 return compat_sys_msgsnd(first, second, third, compat_ptr(ptr));
1167 case MSGRCV:
1168 return compat_sys_msgrcv(first, second, fifth, third, version, compat_ptr(ptr));
1169 case MSGGET:
1170 return sys_msgget((key_t) first, second);
1171 case MSGCTL:
1172 return compat_sys_msgctl(first, second, compat_ptr(ptr));
1173
1174 case SHMAT:
1175 return compat_sys_shmat(first, second, third, version, compat_ptr(ptr));
1176 break;
1177 case SHMDT:
1178 return sys_shmdt(compat_ptr(ptr));
1179 case SHMGET:
1180 return sys_shmget(first, (unsigned)second, third);
1181 case SHMCTL:
1182 return compat_sys_shmctl(first, second, compat_ptr(ptr));
1183
1184 default:
1185 return -ENOSYS;
1186 }
1187 return -EINVAL;
1188}
1189
1190asmlinkage long
1191compat_sys_wait4 (compat_pid_t pid, compat_uint_t * stat_addr, int options,
1192 struct compat_rusage *ru);
1193
1194asmlinkage long
1195sys32_waitpid (int pid, unsigned int *stat_addr, int options)
1196{
1197 return compat_sys_wait4(pid, stat_addr, options, NULL);
1198}
1199
1200/*
1201 * The order in which registers are stored in the ptrace regs structure
1202 */
1203#define PT_EBX 0
1204#define PT_ECX 1
1205#define PT_EDX 2
1206#define PT_ESI 3
1207#define PT_EDI 4
1208#define PT_EBP 5
1209#define PT_EAX 6
1210#define PT_DS 7
1211#define PT_ES 8
1212#define PT_FS 9
1213#define PT_GS 10
1214#define PT_ORIG_EAX 11
1215#define PT_EIP 12
1216#define PT_CS 13
1217#define PT_EFL 14
1218#define PT_UESP 15
1219#define PT_SS 16
1220
1221static unsigned int
1222getreg (struct task_struct *child, int regno)
1223{
1224 struct pt_regs *child_regs;
1225
1226 child_regs = task_pt_regs(child);
1227 switch (regno / sizeof(int)) {
1228 case PT_EBX: return child_regs->r11;
1229 case PT_ECX: return child_regs->r9;
1230 case PT_EDX: return child_regs->r10;
1231 case PT_ESI: return child_regs->r14;
1232 case PT_EDI: return child_regs->r15;
1233 case PT_EBP: return child_regs->r13;
1234 case PT_EAX: return child_regs->r8;
1235 case PT_ORIG_EAX: return child_regs->r1; /* see dispatch_to_ia32_handler() */
1236 case PT_EIP: return child_regs->cr_iip;
1237 case PT_UESP: return child_regs->r12;
1238 case PT_EFL: return child->thread.eflag;
1239 case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS:
1240 return __USER_DS;
1241 case PT_CS: return __USER_CS;
1242 default:
1243 printk(KERN_ERR "ia32.getreg(): unknown register %d\n", regno);
1244 break;
1245 }
1246 return 0;
1247}
1248
1249static void
1250putreg (struct task_struct *child, int regno, unsigned int value)
1251{
1252 struct pt_regs *child_regs;
1253
1254 child_regs = task_pt_regs(child);
1255 switch (regno / sizeof(int)) {
1256 case PT_EBX: child_regs->r11 = value; break;
1257 case PT_ECX: child_regs->r9 = value; break;
1258 case PT_EDX: child_regs->r10 = value; break;
1259 case PT_ESI: child_regs->r14 = value; break;
1260 case PT_EDI: child_regs->r15 = value; break;
1261 case PT_EBP: child_regs->r13 = value; break;
1262 case PT_EAX: child_regs->r8 = value; break;
1263 case PT_ORIG_EAX: child_regs->r1 = value; break;
1264 case PT_EIP: child_regs->cr_iip = value; break;
1265 case PT_UESP: child_regs->r12 = value; break;
1266 case PT_EFL: child->thread.eflag = value; break;
1267 case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS:
1268 if (value != __USER_DS)
1269 printk(KERN_ERR
1270 "ia32.putreg: attempt to set invalid segment register %d = %x\n",
1271 regno, value);
1272 break;
1273 case PT_CS:
1274 if (value != __USER_CS)
1275 printk(KERN_ERR
1276 "ia32.putreg: attempt to set invalid segment register %d = %x\n",
1277 regno, value);
1278 break;
1279 default:
1280 printk(KERN_ERR "ia32.putreg: unknown register %d\n", regno);
1281 break;
1282 }
1283}
1284
1285static void
1286put_fpreg (int regno, struct _fpreg_ia32 __user *reg, struct pt_regs *ptp,
1287 struct switch_stack *swp, int tos)
1288{
1289 struct _fpreg_ia32 *f;
1290 char buf[32];
1291
1292 f = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
1293 if ((regno += tos) >= 8)
1294 regno -= 8;
1295 switch (regno) {
1296 case 0:
1297 ia64f2ia32f(f, &ptp->f8);
1298 break;
1299 case 1:
1300 ia64f2ia32f(f, &ptp->f9);
1301 break;
1302 case 2:
1303 ia64f2ia32f(f, &ptp->f10);
1304 break;
1305 case 3:
1306 ia64f2ia32f(f, &ptp->f11);
1307 break;
1308 case 4:
1309 case 5:
1310 case 6:
1311 case 7:
1312 ia64f2ia32f(f, &swp->f12 + (regno - 4));
1313 break;
1314 }
1315 copy_to_user(reg, f, sizeof(*reg));
1316}
1317
1318static void
1319get_fpreg (int regno, struct _fpreg_ia32 __user *reg, struct pt_regs *ptp,
1320 struct switch_stack *swp, int tos)
1321{
1322
1323 if ((regno += tos) >= 8)
1324 regno -= 8;
1325 switch (regno) {
1326 case 0:
1327 copy_from_user(&ptp->f8, reg, sizeof(*reg));
1328 break;
1329 case 1:
1330 copy_from_user(&ptp->f9, reg, sizeof(*reg));
1331 break;
1332 case 2:
1333 copy_from_user(&ptp->f10, reg, sizeof(*reg));
1334 break;
1335 case 3:
1336 copy_from_user(&ptp->f11, reg, sizeof(*reg));
1337 break;
1338 case 4:
1339 case 5:
1340 case 6:
1341 case 7:
1342 copy_from_user(&swp->f12 + (regno - 4), reg, sizeof(*reg));
1343 break;
1344 }
1345 return;
1346}
1347
1348int
1349save_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct __user *save)
1350{
1351 struct switch_stack *swp;
1352 struct pt_regs *ptp;
1353 int i, tos;
1354
1355 if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
1356 return -EFAULT;
1357
1358 __put_user(tsk->thread.fcr & 0xffff, &save->cwd);
1359 __put_user(tsk->thread.fsr & 0xffff, &save->swd);
1360 __put_user((tsk->thread.fsr>>16) & 0xffff, &save->twd);
1361 __put_user(tsk->thread.fir, &save->fip);
1362 __put_user((tsk->thread.fir>>32) & 0xffff, &save->fcs);
1363 __put_user(tsk->thread.fdr, &save->foo);
1364 __put_user((tsk->thread.fdr>>32) & 0xffff, &save->fos);
1365
1366 /*
1367 * Stack frames start with 16-bytes of temp space
1368 */
1369 swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1370 ptp = task_pt_regs(tsk);
1371 tos = (tsk->thread.fsr >> 11) & 7;
1372 for (i = 0; i < 8; i++)
1373 put_fpreg(i, &save->st_space[i], ptp, swp, tos);
1374 return 0;
1375}
1376
1377static int
1378restore_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct __user *save)
1379{
1380 struct switch_stack *swp;
1381 struct pt_regs *ptp;
1382 int i, tos;
1383 unsigned int fsrlo, fsrhi, num32;
1384
1385 if (!access_ok(VERIFY_READ, save, sizeof(*save)))
1386 return(-EFAULT);
1387
1388 __get_user(num32, (unsigned int __user *)&save->cwd);
1389 tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f);
1390 __get_user(fsrlo, (unsigned int __user *)&save->swd);
1391 __get_user(fsrhi, (unsigned int __user *)&save->twd);
1392 num32 = (fsrhi << 16) | fsrlo;
1393 tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32;
1394 __get_user(num32, (unsigned int __user *)&save->fip);
1395 tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32;
1396 __get_user(num32, (unsigned int __user *)&save->foo);
1397 tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32;
1398
1399 /*
1400 * Stack frames start with 16-bytes of temp space
1401 */
1402 swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1403 ptp = task_pt_regs(tsk);
1404 tos = (tsk->thread.fsr >> 11) & 7;
1405 for (i = 0; i < 8; i++)
1406 get_fpreg(i, &save->st_space[i], ptp, swp, tos);
1407 return 0;
1408}
1409
1410int
1411save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __user *save)
1412{
1413 struct switch_stack *swp;
1414 struct pt_regs *ptp;
1415 int i, tos;
1416 unsigned long mxcsr=0;
1417 unsigned long num128[2];
1418
1419 if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
1420 return -EFAULT;
1421
1422 __put_user(tsk->thread.fcr & 0xffff, &save->cwd);
1423 __put_user(tsk->thread.fsr & 0xffff, &save->swd);
1424 __put_user((tsk->thread.fsr>>16) & 0xffff, &save->twd);
1425 __put_user(tsk->thread.fir, &save->fip);
1426 __put_user((tsk->thread.fir>>32) & 0xffff, &save->fcs);
1427 __put_user(tsk->thread.fdr, &save->foo);
1428 __put_user((tsk->thread.fdr>>32) & 0xffff, &save->fos);
1429
1430 /*
1431 * Stack frames start with 16-bytes of temp space
1432 */
1433 swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1434 ptp = task_pt_regs(tsk);
1435 tos = (tsk->thread.fsr >> 11) & 7;
1436 for (i = 0; i < 8; i++)
1437 put_fpreg(i, (struct _fpreg_ia32 __user *)&save->st_space[4*i], ptp, swp, tos);
1438
1439 mxcsr = ((tsk->thread.fcr>>32) & 0xff80) | ((tsk->thread.fsr>>32) & 0x3f);
1440 __put_user(mxcsr & 0xffff, &save->mxcsr);
1441 for (i = 0; i < 8; i++) {
1442 memcpy(&(num128[0]), &(swp->f16) + i*2, sizeof(unsigned long));
1443 memcpy(&(num128[1]), &(swp->f17) + i*2, sizeof(unsigned long));
1444 copy_to_user(&save->xmm_space[0] + 4*i, num128, sizeof(struct _xmmreg_ia32));
1445 }
1446 return 0;
1447}
1448
1449static int
1450restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __user *save)
1451{
1452 struct switch_stack *swp;
1453 struct pt_regs *ptp;
1454 int i, tos;
1455 unsigned int fsrlo, fsrhi, num32;
1456 int mxcsr;
1457 unsigned long num64;
1458 unsigned long num128[2];
1459
1460 if (!access_ok(VERIFY_READ, save, sizeof(*save)))
1461 return(-EFAULT);
1462
1463 __get_user(num32, (unsigned int __user *)&save->cwd);
1464 tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f);
1465 __get_user(fsrlo, (unsigned int __user *)&save->swd);
1466 __get_user(fsrhi, (unsigned int __user *)&save->twd);
1467 num32 = (fsrhi << 16) | fsrlo;
1468 tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32;
1469 __get_user(num32, (unsigned int __user *)&save->fip);
1470 tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32;
1471 __get_user(num32, (unsigned int __user *)&save->foo);
1472 tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32;
1473
1474 /*
1475 * Stack frames start with 16-bytes of temp space
1476 */
1477 swp = (struct switch_stack *)(tsk->thread.ksp + 16);
1478 ptp = task_pt_regs(tsk);
1479 tos = (tsk->thread.fsr >> 11) & 7;
1480 for (i = 0; i < 8; i++)
1481 get_fpreg(i, (struct _fpreg_ia32 __user *)&save->st_space[4*i], ptp, swp, tos);
1482
1483 __get_user(mxcsr, (unsigned int __user *)&save->mxcsr);
1484 num64 = mxcsr & 0xff10;
1485 tsk->thread.fcr = (tsk->thread.fcr & (~0xff1000000000UL)) | (num64<<32);
1486 num64 = mxcsr & 0x3f;
1487 tsk->thread.fsr = (tsk->thread.fsr & (~0x3f00000000UL)) | (num64<<32);
1488
1489 for (i = 0; i < 8; i++) {
1490 copy_from_user(num128, &save->xmm_space[0] + 4*i, sizeof(struct _xmmreg_ia32));
1491 memcpy(&(swp->f16) + i*2, &(num128[0]), sizeof(unsigned long));
1492 memcpy(&(swp->f17) + i*2, &(num128[1]), sizeof(unsigned long));
1493 }
1494 return 0;
1495}
1496
1497long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
1498 compat_ulong_t caddr, compat_ulong_t cdata)
1499{
1500 unsigned long addr = caddr;
1501 unsigned long data = cdata;
1502 unsigned int tmp;
1503 long i, ret;
1504
1505 switch (request) {
1506 case PTRACE_PEEKUSR: /* read word at addr in USER area */
1507 ret = -EIO;
1508 if ((addr & 3) || addr > 17*sizeof(int))
1509 break;
1510
1511 tmp = getreg(child, addr);
1512 if (!put_user(tmp, (unsigned int __user *) compat_ptr(data)))
1513 ret = 0;
1514 break;
1515
1516 case PTRACE_POKEUSR: /* write word at addr in USER area */
1517 ret = -EIO;
1518 if ((addr & 3) || addr > 17*sizeof(int))
1519 break;
1520
1521 putreg(child, addr, data);
1522 ret = 0;
1523 break;
1524
1525 case IA32_PTRACE_GETREGS:
1526 if (!access_ok(VERIFY_WRITE, compat_ptr(data), 17*sizeof(int))) {
1527 ret = -EIO;
1528 break;
1529 }
1530 for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) {
1531 put_user(getreg(child, i), (unsigned int __user *) compat_ptr(data));
1532 data += sizeof(int);
1533 }
1534 ret = 0;
1535 break;
1536
1537 case IA32_PTRACE_SETREGS:
1538 if (!access_ok(VERIFY_READ, compat_ptr(data), 17*sizeof(int))) {
1539 ret = -EIO;
1540 break;
1541 }
1542 for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) {
1543 get_user(tmp, (unsigned int __user *) compat_ptr(data));
1544 putreg(child, i, tmp);
1545 data += sizeof(int);
1546 }
1547 ret = 0;
1548 break;
1549
1550 case IA32_PTRACE_GETFPREGS:
1551 ret = save_ia32_fpstate(child, (struct ia32_user_i387_struct __user *)
1552 compat_ptr(data));
1553 break;
1554
1555 case IA32_PTRACE_GETFPXREGS:
1556 ret = save_ia32_fpxstate(child, (struct ia32_user_fxsr_struct __user *)
1557 compat_ptr(data));
1558 break;
1559
1560 case IA32_PTRACE_SETFPREGS:
1561 ret = restore_ia32_fpstate(child, (struct ia32_user_i387_struct __user *)
1562 compat_ptr(data));
1563 break;
1564
1565 case IA32_PTRACE_SETFPXREGS:
1566 ret = restore_ia32_fpxstate(child, (struct ia32_user_fxsr_struct __user *)
1567 compat_ptr(data));
1568 break;
1569
1570 default:
1571 return compat_ptrace_request(child, request, caddr, cdata);
1572 }
1573 return ret;
1574}
1575
1576typedef struct {
1577 unsigned int ss_sp;
1578 unsigned int ss_flags;
1579 unsigned int ss_size;
1580} ia32_stack_t;
1581
1582asmlinkage long
1583sys32_sigaltstack (ia32_stack_t __user *uss32, ia32_stack_t __user *uoss32,
1584 long arg2, long arg3, long arg4, long arg5, long arg6,
1585 long arg7, struct pt_regs pt)
1586{
1587 stack_t uss, uoss;
1588 ia32_stack_t buf32;
1589 int ret;
1590 mm_segment_t old_fs = get_fs();
1591
1592 if (uss32) {
1593 if (copy_from_user(&buf32, uss32, sizeof(ia32_stack_t)))
1594 return -EFAULT;
1595 uss.ss_sp = (void __user *) (long) buf32.ss_sp;
1596 uss.ss_flags = buf32.ss_flags;
1597 /* MINSIGSTKSZ is different for ia32 vs ia64. We lie here to pass the
1598 check and set it to the user requested value later */
1599 if ((buf32.ss_flags != SS_DISABLE) && (buf32.ss_size < MINSIGSTKSZ_IA32)) {
1600 ret = -ENOMEM;
1601 goto out;
1602 }
1603 uss.ss_size = MINSIGSTKSZ;
1604 }
1605 set_fs(KERNEL_DS);
1606 ret = do_sigaltstack(uss32 ? (stack_t __user *) &uss : NULL,
1607 (stack_t __user *) &uoss, pt.r12);
1608 current->sas_ss_size = buf32.ss_size;
1609 set_fs(old_fs);
1610out:
1611 if (ret < 0)
1612 return(ret);
1613 if (uoss32) {
1614 buf32.ss_sp = (long __user) uoss.ss_sp;
1615 buf32.ss_flags = uoss.ss_flags;
1616 buf32.ss_size = uoss.ss_size;
1617 if (copy_to_user(uoss32, &buf32, sizeof(ia32_stack_t)))
1618 return -EFAULT;
1619 }
1620 return ret;
1621}
1622
1623asmlinkage int
1624sys32_msync (unsigned int start, unsigned int len, int flags)
1625{
1626 unsigned int addr;
1627
1628 if (OFFSET4K(start))
1629 return -EINVAL;
1630 addr = PAGE_START(start);
1631 return sys_msync(addr, len + (start - addr), flags);
1632}
1633
1634asmlinkage long
1635sys32_newuname (struct new_utsname __user *name)
1636{
1637 int ret = sys_newuname(name);
1638
1639 if (!ret)
1640 if (copy_to_user(name->machine, "i686\0\0\0", 8))
1641 ret = -EFAULT;
1642 return ret;
1643}
1644
1645asmlinkage long
1646sys32_getresuid16 (u16 __user *ruid, u16 __user *euid, u16 __user *suid)
1647{
1648 uid_t a, b, c;
1649 int ret;
1650 mm_segment_t old_fs = get_fs();
1651
1652 set_fs(KERNEL_DS);
1653 ret = sys_getresuid((uid_t __user *) &a, (uid_t __user *) &b, (uid_t __user *) &c);
1654 set_fs(old_fs);
1655
1656 if (put_user(a, ruid) || put_user(b, euid) || put_user(c, suid))
1657 return -EFAULT;
1658 return ret;
1659}
1660
1661asmlinkage long
1662sys32_getresgid16 (u16 __user *rgid, u16 __user *egid, u16 __user *sgid)
1663{
1664 gid_t a, b, c;
1665 int ret;
1666 mm_segment_t old_fs = get_fs();
1667
1668 set_fs(KERNEL_DS);
1669 ret = sys_getresgid((gid_t __user *) &a, (gid_t __user *) &b, (gid_t __user *) &c);
1670 set_fs(old_fs);
1671
1672 if (ret)
1673 return ret;
1674
1675 return put_user(a, rgid) | put_user(b, egid) | put_user(c, sgid);
1676}
1677
1678asmlinkage long
1679sys32_lseek (unsigned int fd, int offset, unsigned int whence)
1680{
1681 /* Sign-extension of "offset" is important here... */
1682 return sys_lseek(fd, offset, whence);
1683}
1684
1685static int
1686groups16_to_user(short __user *grouplist, struct group_info *group_info)
1687{
1688 int i;
1689 short group;
1690
1691 for (i = 0; i < group_info->ngroups; i++) {
1692 group = (short)GROUP_AT(group_info, i);
1693 if (put_user(group, grouplist+i))
1694 return -EFAULT;
1695 }
1696
1697 return 0;
1698}
1699
1700static int
1701groups16_from_user(struct group_info *group_info, short __user *grouplist)
1702{
1703 int i;
1704 short group;
1705
1706 for (i = 0; i < group_info->ngroups; i++) {
1707 if (get_user(group, grouplist+i))
1708 return -EFAULT;
1709 GROUP_AT(group_info, i) = (gid_t)group;
1710 }
1711
1712 return 0;
1713}
1714
1715asmlinkage long
1716sys32_getgroups16 (int gidsetsize, short __user *grouplist)
1717{
1718 const struct cred *cred = current_cred();
1719 int i;
1720
1721 if (gidsetsize < 0)
1722 return -EINVAL;
1723
1724 i = cred->group_info->ngroups;
1725 if (gidsetsize) {
1726 if (i > gidsetsize) {
1727 i = -EINVAL;
1728 goto out;
1729 }
1730 if (groups16_to_user(grouplist, cred->group_info)) {
1731 i = -EFAULT;
1732 goto out;
1733 }
1734 }
1735out:
1736 return i;
1737}
1738
1739asmlinkage long
1740sys32_setgroups16 (int gidsetsize, short __user *grouplist)
1741{
1742 struct group_info *group_info;
1743 int retval;
1744
1745 if (!capable(CAP_SETGID))
1746 return -EPERM;
1747 if ((unsigned)gidsetsize > NGROUPS_MAX)
1748 return -EINVAL;
1749
1750 group_info = groups_alloc(gidsetsize);
1751 if (!group_info)
1752 return -ENOMEM;
1753 retval = groups16_from_user(group_info, grouplist);
1754 if (retval) {
1755 put_group_info(group_info);
1756 return retval;
1757 }
1758
1759 retval = set_current_groups(group_info);
1760 put_group_info(group_info);
1761
1762 return retval;
1763}
1764
1765asmlinkage long
1766sys32_truncate64 (unsigned int path, unsigned int len_lo, unsigned int len_hi)
1767{
1768 return sys_truncate(compat_ptr(path), ((unsigned long) len_hi << 32) | len_lo);
1769}
1770
1771asmlinkage long
1772sys32_ftruncate64 (int fd, unsigned int len_lo, unsigned int len_hi)
1773{
1774 return sys_ftruncate(fd, ((unsigned long) len_hi << 32) | len_lo);
1775}
1776
1777static int
1778putstat64 (struct stat64 __user *ubuf, struct kstat *kbuf)
1779{
1780 int err;
1781 u64 hdev;
1782
1783 if (clear_user(ubuf, sizeof(*ubuf)))
1784 return -EFAULT;
1785
1786 hdev = huge_encode_dev(kbuf->dev);
1787 err = __put_user(hdev, (u32 __user*)&ubuf->st_dev);
1788 err |= __put_user(hdev >> 32, ((u32 __user*)&ubuf->st_dev) + 1);
1789 err |= __put_user(kbuf->ino, &ubuf->__st_ino);
1790 err |= __put_user(kbuf->ino, &ubuf->st_ino_lo);
1791 err |= __put_user(kbuf->ino >> 32, &ubuf->st_ino_hi);
1792 err |= __put_user(kbuf->mode, &ubuf->st_mode);
1793 err |= __put_user(kbuf->nlink, &ubuf->st_nlink);
1794 err |= __put_user(kbuf->uid, &ubuf->st_uid);
1795 err |= __put_user(kbuf->gid, &ubuf->st_gid);
1796 hdev = huge_encode_dev(kbuf->rdev);
1797 err = __put_user(hdev, (u32 __user*)&ubuf->st_rdev);
1798 err |= __put_user(hdev >> 32, ((u32 __user*)&ubuf->st_rdev) + 1);
1799 err |= __put_user(kbuf->size, &ubuf->st_size_lo);
1800 err |= __put_user((kbuf->size >> 32), &ubuf->st_size_hi);
1801 err |= __put_user(kbuf->atime.tv_sec, &ubuf->st_atime);
1802 err |= __put_user(kbuf->atime.tv_nsec, &ubuf->st_atime_nsec);
1803 err |= __put_user(kbuf->mtime.tv_sec, &ubuf->st_mtime);
1804 err |= __put_user(kbuf->mtime.tv_nsec, &ubuf->st_mtime_nsec);
1805 err |= __put_user(kbuf->ctime.tv_sec, &ubuf->st_ctime);
1806 err |= __put_user(kbuf->ctime.tv_nsec, &ubuf->st_ctime_nsec);
1807 err |= __put_user(kbuf->blksize, &ubuf->st_blksize);
1808 err |= __put_user(kbuf->blocks, &ubuf->st_blocks);
1809 return err;
1810}
1811
1812asmlinkage long
1813sys32_stat64 (char __user *filename, struct stat64 __user *statbuf)
1814{
1815 struct kstat s;
1816 long ret = vfs_stat(filename, &s);
1817 if (!ret)
1818 ret = putstat64(statbuf, &s);
1819 return ret;
1820}
1821
1822asmlinkage long
1823sys32_lstat64 (char __user *filename, struct stat64 __user *statbuf)
1824{
1825 struct kstat s;
1826 long ret = vfs_lstat(filename, &s);
1827 if (!ret)
1828 ret = putstat64(statbuf, &s);
1829 return ret;
1830}
1831
1832asmlinkage long
1833sys32_fstat64 (unsigned int fd, struct stat64 __user *statbuf)
1834{
1835 struct kstat s;
1836 long ret = vfs_fstat(fd, &s);
1837 if (!ret)
1838 ret = putstat64(statbuf, &s);
1839 return ret;
1840}
1841
1842asmlinkage long
1843sys32_sched_rr_get_interval (pid_t pid, struct compat_timespec __user *interval)
1844{
1845 mm_segment_t old_fs = get_fs();
1846 struct timespec t;
1847 long ret;
1848
1849 set_fs(KERNEL_DS);
1850 ret = sys_sched_rr_get_interval(pid, (struct timespec __user *) &t);
1851 set_fs(old_fs);
1852 if (put_compat_timespec(&t, interval))
1853 return -EFAULT;
1854 return ret;
1855}
1856
1857asmlinkage long
1858sys32_pread (unsigned int fd, void __user *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
1859{
1860 return sys_pread64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
1861}
1862
1863asmlinkage long
1864sys32_pwrite (unsigned int fd, void __user *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
1865{
1866 return sys_pwrite64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
1867}
1868
1869asmlinkage long
1870sys32_sendfile (int out_fd, int in_fd, int __user *offset, unsigned int count)
1871{
1872 mm_segment_t old_fs = get_fs();
1873 long ret;
1874 off_t of;
1875
1876 if (offset && get_user(of, offset))
1877 return -EFAULT;
1878
1879 set_fs(KERNEL_DS);
1880 ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *) &of : NULL, count);
1881 set_fs(old_fs);
1882
1883 if (offset && put_user(of, offset))
1884 return -EFAULT;
1885
1886 return ret;
1887}
1888
1889asmlinkage long
1890sys32_personality (unsigned int personality)
1891{
1892 long ret;
1893
1894 if (current->personality == PER_LINUX32 && personality == PER_LINUX)
1895 personality = PER_LINUX32;
1896 ret = sys_personality(personality);
1897 if (ret == PER_LINUX32)
1898 ret = PER_LINUX;
1899 return ret;
1900}
1901
1902asmlinkage unsigned long
1903sys32_brk (unsigned int brk)
1904{
1905 unsigned long ret, obrk;
1906 struct mm_struct *mm = current->mm;
1907
1908 obrk = mm->brk;
1909 ret = sys_brk(brk);
1910 if (ret < obrk)
1911 clear_user(compat_ptr(ret), PAGE_ALIGN(ret) - ret);
1912 return ret;
1913}
1914
1915/* Structure for ia32 emulation on ia64 */
1916struct epoll_event32
1917{
1918 u32 events;
1919 u32 data[2];
1920};
1921
1922asmlinkage long
1923sys32_epoll_ctl(int epfd, int op, int fd, struct epoll_event32 __user *event)
1924{
1925 mm_segment_t old_fs = get_fs();
1926 struct epoll_event event64;
1927 int error;
1928 u32 data_halfword;
1929
1930 if (!access_ok(VERIFY_READ, event, sizeof(struct epoll_event32)))
1931 return -EFAULT;
1932
1933 __get_user(event64.events, &event->events);
1934 __get_user(data_halfword, &event->data[0]);
1935 event64.data = data_halfword;
1936 __get_user(data_halfword, &event->data[1]);
1937 event64.data |= (u64)data_halfword << 32;
1938
1939 set_fs(KERNEL_DS);
1940 error = sys_epoll_ctl(epfd, op, fd, (struct epoll_event __user *) &event64);
1941 set_fs(old_fs);
1942
1943 return error;
1944}
1945
1946asmlinkage long
1947sys32_epoll_wait(int epfd, struct epoll_event32 __user * events, int maxevents,
1948 int timeout)
1949{
1950 struct epoll_event *events64 = NULL;
1951 mm_segment_t old_fs = get_fs();
1952 int numevents, size;
1953 int evt_idx;
1954 int do_free_pages = 0;
1955
1956 if (maxevents <= 0) {
1957 return -EINVAL;
1958 }
1959
1960 /* Verify that the area passed by the user is writeable */
1961 if (!access_ok(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event32)))
1962 return -EFAULT;
1963
1964 /*
1965 * Allocate space for the intermediate copy. If the space needed
1966 * is large enough to cause kmalloc to fail, then try again with
1967 * __get_free_pages.
1968 */
1969 size = maxevents * sizeof(struct epoll_event);
1970 events64 = kmalloc(size, GFP_KERNEL);
1971 if (events64 == NULL) {
1972 events64 = (struct epoll_event *)
1973 __get_free_pages(GFP_KERNEL, get_order(size));
1974 if (events64 == NULL)
1975 return -ENOMEM;
1976 do_free_pages = 1;
1977 }
1978
1979 /* Do the system call */
1980 set_fs(KERNEL_DS); /* copy_to/from_user should work on kernel mem*/
1981 numevents = sys_epoll_wait(epfd, (struct epoll_event __user *) events64,
1982 maxevents, timeout);
1983 set_fs(old_fs);
1984
1985 /* Don't modify userspace memory if we're returning an error */
1986 if (numevents > 0) {
1987 /* Translate the 64-bit structures back into the 32-bit
1988 structures */
1989 for (evt_idx = 0; evt_idx < numevents; evt_idx++) {
1990 __put_user(events64[evt_idx].events,
1991 &events[evt_idx].events);
1992 __put_user((u32)events64[evt_idx].data,
1993 &events[evt_idx].data[0]);
1994 __put_user((u32)(events64[evt_idx].data >> 32),
1995 &events[evt_idx].data[1]);
1996 }
1997 }
1998
1999 if (do_free_pages)
2000 free_pages((unsigned long) events64, get_order(size));
2001 else
2002 kfree(events64);
2003 return numevents;
2004}
2005
2006/*
2007 * Get a yet unused TLS descriptor index.
2008 */
2009static int
2010get_free_idx (void)
2011{
2012 struct thread_struct *t = &current->thread;
2013 int idx;
2014
2015 for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
2016 if (desc_empty(t->tls_array + idx))
2017 return idx + GDT_ENTRY_TLS_MIN;
2018 return -ESRCH;
2019}
2020
2021static void set_tls_desc(struct task_struct *p, int idx,
2022 const struct ia32_user_desc *info, int n)
2023{
2024 struct thread_struct *t = &p->thread;
2025 struct desc_struct *desc = &t->tls_array[idx - GDT_ENTRY_TLS_MIN];
2026 int cpu;
2027
2028 /*
2029 * We must not get preempted while modifying the TLS.
2030 */
2031 cpu = get_cpu();
2032
2033 while (n-- > 0) {
2034 if (LDT_empty(info)) {
2035 desc->a = 0;
2036 desc->b = 0;
2037 } else {
2038 desc->a = LDT_entry_a(info);
2039 desc->b = LDT_entry_b(info);
2040 }
2041
2042 ++info;
2043 ++desc;
2044 }
2045
2046 if (t == &current->thread)
2047 load_TLS(t, cpu);
2048
2049 put_cpu();
2050}
2051
2052/*
2053 * Set a given TLS descriptor:
2054 */
2055asmlinkage int
2056sys32_set_thread_area (struct ia32_user_desc __user *u_info)
2057{
2058 struct ia32_user_desc info;
2059 int idx;
2060
2061 if (copy_from_user(&info, u_info, sizeof(info)))
2062 return -EFAULT;
2063 idx = info.entry_number;
2064
2065 /*
2066 * index -1 means the kernel should try to find and allocate an empty descriptor:
2067 */
2068 if (idx == -1) {
2069 idx = get_free_idx();
2070 if (idx < 0)
2071 return idx;
2072 if (put_user(idx, &u_info->entry_number))
2073 return -EFAULT;
2074 }
2075
2076 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2077 return -EINVAL;
2078
2079 set_tls_desc(current, idx, &info, 1);
2080 return 0;
2081}
2082
2083/*
2084 * Get the current Thread-Local Storage area:
2085 */
2086
2087#define GET_BASE(desc) ( \
2088 (((desc)->a >> 16) & 0x0000ffff) | \
2089 (((desc)->b << 16) & 0x00ff0000) | \
2090 ( (desc)->b & 0xff000000) )
2091
2092#define GET_LIMIT(desc) ( \
2093 ((desc)->a & 0x0ffff) | \
2094 ((desc)->b & 0xf0000) )
2095
2096#define GET_32BIT(desc) (((desc)->b >> 22) & 1)
2097#define GET_CONTENTS(desc) (((desc)->b >> 10) & 3)
2098#define GET_WRITABLE(desc) (((desc)->b >> 9) & 1)
2099#define GET_LIMIT_PAGES(desc) (((desc)->b >> 23) & 1)
2100#define GET_PRESENT(desc) (((desc)->b >> 15) & 1)
2101#define GET_USEABLE(desc) (((desc)->b >> 20) & 1)
2102
2103static void fill_user_desc(struct ia32_user_desc *info, int idx,
2104 const struct desc_struct *desc)
2105{
2106 info->entry_number = idx;
2107 info->base_addr = GET_BASE(desc);
2108 info->limit = GET_LIMIT(desc);
2109 info->seg_32bit = GET_32BIT(desc);
2110 info->contents = GET_CONTENTS(desc);
2111 info->read_exec_only = !GET_WRITABLE(desc);
2112 info->limit_in_pages = GET_LIMIT_PAGES(desc);
2113 info->seg_not_present = !GET_PRESENT(desc);
2114 info->useable = GET_USEABLE(desc);
2115}
2116
2117asmlinkage int
2118sys32_get_thread_area (struct ia32_user_desc __user *u_info)
2119{
2120 struct ia32_user_desc info;
2121 struct desc_struct *desc;
2122 int idx;
2123
2124 if (get_user(idx, &u_info->entry_number))
2125 return -EFAULT;
2126 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2127 return -EINVAL;
2128
2129 desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
2130 fill_user_desc(&info, idx, desc);
2131
2132 if (copy_to_user(u_info, &info, sizeof(info)))
2133 return -EFAULT;
2134 return 0;
2135}
2136
2137struct regset_get {
2138 void *kbuf;
2139 void __user *ubuf;
2140};
2141
2142struct regset_set {
2143 const void *kbuf;
2144 const void __user *ubuf;
2145};
2146
2147struct regset_getset {
2148 struct task_struct *target;
2149 const struct user_regset *regset;
2150 union {
2151 struct regset_get get;
2152 struct regset_set set;
2153 } u;
2154 unsigned int pos;
2155 unsigned int count;
2156 int ret;
2157};
2158
2159static void getfpreg(struct task_struct *task, int regno, int *val)
2160{
2161 switch (regno / sizeof(int)) {
2162 case 0:
2163 *val = task->thread.fcr & 0xffff;
2164 break;
2165 case 1:
2166 *val = task->thread.fsr & 0xffff;
2167 break;
2168 case 2:
2169 *val = (task->thread.fsr>>16) & 0xffff;
2170 break;
2171 case 3:
2172 *val = task->thread.fir;
2173 break;
2174 case 4:
2175 *val = (task->thread.fir>>32) & 0xffff;
2176 break;
2177 case 5:
2178 *val = task->thread.fdr;
2179 break;
2180 case 6:
2181 *val = (task->thread.fdr >> 32) & 0xffff;
2182 break;
2183 }
2184}
2185
2186static void setfpreg(struct task_struct *task, int regno, int val)
2187{
2188 switch (regno / sizeof(int)) {
2189 case 0:
2190 task->thread.fcr = (task->thread.fcr & (~0x1f3f))
2191 | (val & 0x1f3f);
2192 break;
2193 case 1:
2194 task->thread.fsr = (task->thread.fsr & (~0xffff)) | val;
2195 break;
2196 case 2:
2197 task->thread.fsr = (task->thread.fsr & (~0xffff0000))
2198 | (val << 16);
2199 break;
2200 case 3:
2201 task->thread.fir = (task->thread.fir & (~0xffffffff)) | val;
2202 break;
2203 case 5:
2204 task->thread.fdr = (task->thread.fdr & (~0xffffffff)) | val;
2205 break;
2206 }
2207}
2208
2209static void access_fpreg_ia32(int regno, void *reg,
2210 struct pt_regs *pt, struct switch_stack *sw,
2211 int tos, int write)
2212{
2213 void *f;
2214
2215 if ((regno += tos) >= 8)
2216 regno -= 8;
2217 if (regno < 4)
2218 f = &pt->f8 + regno;
2219 else if (regno <= 7)
2220 f = &sw->f12 + (regno - 4);
2221 else {
2222 printk(KERN_ERR "regno must be less than 7 \n");
2223 return;
2224 }
2225
2226 if (write)
2227 memcpy(f, reg, sizeof(struct _fpreg_ia32));
2228 else
2229 memcpy(reg, f, sizeof(struct _fpreg_ia32));
2230}
2231
2232static void do_fpregs_get(struct unw_frame_info *info, void *arg)
2233{
2234 struct regset_getset *dst = arg;
2235 struct task_struct *task = dst->target;
2236 struct pt_regs *pt;
2237 int start, end, tos;
2238 char buf[80];
2239
2240 if (dst->count == 0 || unw_unwind_to_user(info) < 0)
2241 return;
2242 if (dst->pos < 7 * sizeof(int)) {
2243 end = min((dst->pos + dst->count),
2244 (unsigned int)(7 * sizeof(int)));
2245 for (start = dst->pos; start < end; start += sizeof(int))
2246 getfpreg(task, start, (int *)(buf + start));
2247 dst->ret = user_regset_copyout(&dst->pos, &dst->count,
2248 &dst->u.get.kbuf, &dst->u.get.ubuf, buf,
2249 0, 7 * sizeof(int));
2250 if (dst->ret || dst->count == 0)
2251 return;
2252 }
2253 if (dst->pos < sizeof(struct ia32_user_i387_struct)) {
2254 pt = task_pt_regs(task);
2255 tos = (task->thread.fsr >> 11) & 7;
2256 end = min(dst->pos + dst->count,
2257 (unsigned int)(sizeof(struct ia32_user_i387_struct)));
2258 start = (dst->pos - 7 * sizeof(int)) /
2259 sizeof(struct _fpreg_ia32);
2260 end = (end - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
2261 for (; start < end; start++)
2262 access_fpreg_ia32(start,
2263 (struct _fpreg_ia32 *)buf + start,
2264 pt, info->sw, tos, 0);
2265 dst->ret = user_regset_copyout(&dst->pos, &dst->count,
2266 &dst->u.get.kbuf, &dst->u.get.ubuf,
2267 buf, 7 * sizeof(int),
2268 sizeof(struct ia32_user_i387_struct));
2269 if (dst->ret || dst->count == 0)
2270 return;
2271 }
2272}
2273
2274static void do_fpregs_set(struct unw_frame_info *info, void *arg)
2275{
2276 struct regset_getset *dst = arg;
2277 struct task_struct *task = dst->target;
2278 struct pt_regs *pt;
2279 char buf[80];
2280 int end, start, tos;
2281
2282 if (dst->count == 0 || unw_unwind_to_user(info) < 0)
2283 return;
2284
2285 if (dst->pos < 7 * sizeof(int)) {
2286 start = dst->pos;
2287 dst->ret = user_regset_copyin(&dst->pos, &dst->count,
2288 &dst->u.set.kbuf, &dst->u.set.ubuf, buf,
2289 0, 7 * sizeof(int));
2290 if (dst->ret)
2291 return;
2292 for (; start < dst->pos; start += sizeof(int))
2293 setfpreg(task, start, *((int *)(buf + start)));
2294 if (dst->count == 0)
2295 return;
2296 }
2297 if (dst->pos < sizeof(struct ia32_user_i387_struct)) {
2298 start = (dst->pos - 7 * sizeof(int)) /
2299 sizeof(struct _fpreg_ia32);
2300 dst->ret = user_regset_copyin(&dst->pos, &dst->count,
2301 &dst->u.set.kbuf, &dst->u.set.ubuf,
2302 buf, 7 * sizeof(int),
2303 sizeof(struct ia32_user_i387_struct));
2304 if (dst->ret)
2305 return;
2306 pt = task_pt_regs(task);
2307 tos = (task->thread.fsr >> 11) & 7;
2308 end = (dst->pos - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
2309 for (; start < end; start++)
2310 access_fpreg_ia32(start,
2311 (struct _fpreg_ia32 *)buf + start,
2312 pt, info->sw, tos, 1);
2313 if (dst->count == 0)
2314 return;
2315 }
2316}
2317
2318#define OFFSET(member) ((int)(offsetof(struct ia32_user_fxsr_struct, member)))
2319static void getfpxreg(struct task_struct *task, int start, int end, char *buf)
2320{
2321 int min_val;
2322
2323 min_val = min(end, OFFSET(fop));
2324 while (start < min_val) {
2325 if (start == OFFSET(cwd))
2326 *((short *)buf) = task->thread.fcr & 0xffff;
2327 else if (start == OFFSET(swd))
2328 *((short *)buf) = task->thread.fsr & 0xffff;
2329 else if (start == OFFSET(twd))
2330 *((short *)buf) = (task->thread.fsr>>16) & 0xffff;
2331 buf += 2;
2332 start += 2;
2333 }
2334 /* skip fop element */
2335 if (start == OFFSET(fop)) {
2336 start += 2;
2337 buf += 2;
2338 }
2339 while (start < end) {
2340 if (start == OFFSET(fip))
2341 *((int *)buf) = task->thread.fir;
2342 else if (start == OFFSET(fcs))
2343 *((int *)buf) = (task->thread.fir>>32) & 0xffff;
2344 else if (start == OFFSET(foo))
2345 *((int *)buf) = task->thread.fdr;
2346 else if (start == OFFSET(fos))
2347 *((int *)buf) = (task->thread.fdr>>32) & 0xffff;
2348 else if (start == OFFSET(mxcsr))
2349 *((int *)buf) = ((task->thread.fcr>>32) & 0xff80)
2350 | ((task->thread.fsr>>32) & 0x3f);
2351 buf += 4;
2352 start += 4;
2353 }
2354}
2355
2356static void setfpxreg(struct task_struct *task, int start, int end, char *buf)
2357{
2358 int min_val, num32;
2359 short num;
2360 unsigned long num64;
2361
2362 min_val = min(end, OFFSET(fop));
2363 while (start < min_val) {
2364 num = *((short *)buf);
2365 if (start == OFFSET(cwd)) {
2366 task->thread.fcr = (task->thread.fcr & (~0x1f3f))
2367 | (num & 0x1f3f);
2368 } else if (start == OFFSET(swd)) {
2369 task->thread.fsr = (task->thread.fsr & (~0xffff)) | num;
2370 } else if (start == OFFSET(twd)) {
2371 task->thread.fsr = (task->thread.fsr & (~0xffff0000))
2372 | (((int)num) << 16);
2373 }
2374 buf += 2;
2375 start += 2;
2376 }
2377 /* skip fop element */
2378 if (start == OFFSET(fop)) {
2379 start += 2;
2380 buf += 2;
2381 }
2382 while (start < end) {
2383 num32 = *((int *)buf);
2384 if (start == OFFSET(fip))
2385 task->thread.fir = (task->thread.fir & (~0xffffffff))
2386 | num32;
2387 else if (start == OFFSET(foo))
2388 task->thread.fdr = (task->thread.fdr & (~0xffffffff))
2389 | num32;
2390 else if (start == OFFSET(mxcsr)) {
2391 num64 = num32 & 0xff10;
2392 task->thread.fcr = (task->thread.fcr &
2393 (~0xff1000000000UL)) | (num64<<32);
2394 num64 = num32 & 0x3f;
2395 task->thread.fsr = (task->thread.fsr &
2396 (~0x3f00000000UL)) | (num64<<32);
2397 }
2398 buf += 4;
2399 start += 4;
2400 }
2401}
2402
2403static void do_fpxregs_get(struct unw_frame_info *info, void *arg)
2404{
2405 struct regset_getset *dst = arg;
2406 struct task_struct *task = dst->target;
2407 struct pt_regs *pt;
2408 char buf[128];
2409 int start, end, tos;
2410
2411 if (dst->count == 0 || unw_unwind_to_user(info) < 0)
2412 return;
2413 if (dst->pos < OFFSET(st_space[0])) {
2414 end = min(dst->pos + dst->count, (unsigned int)32);
2415 getfpxreg(task, dst->pos, end, buf);
2416 dst->ret = user_regset_copyout(&dst->pos, &dst->count,
2417 &dst->u.get.kbuf, &dst->u.get.ubuf, buf,
2418 0, OFFSET(st_space[0]));
2419 if (dst->ret || dst->count == 0)
2420 return;
2421 }
2422 if (dst->pos < OFFSET(xmm_space[0])) {
2423 pt = task_pt_regs(task);
2424 tos = (task->thread.fsr >> 11) & 7;
2425 end = min(dst->pos + dst->count,
2426 (unsigned int)OFFSET(xmm_space[0]));
2427 start = (dst->pos - OFFSET(st_space[0])) / 16;
2428 end = (end - OFFSET(st_space[0])) / 16;
2429 for (; start < end; start++)
2430 access_fpreg_ia32(start, buf + 16 * start, pt,
2431 info->sw, tos, 0);
2432 dst->ret = user_regset_copyout(&dst->pos, &dst->count,
2433 &dst->u.get.kbuf, &dst->u.get.ubuf,
2434 buf, OFFSET(st_space[0]), OFFSET(xmm_space[0]));
2435 if (dst->ret || dst->count == 0)
2436 return;
2437 }
2438 if (dst->pos < OFFSET(padding[0]))
2439 dst->ret = user_regset_copyout(&dst->pos, &dst->count,
2440 &dst->u.get.kbuf, &dst->u.get.ubuf,
2441 &info->sw->f16, OFFSET(xmm_space[0]),
2442 OFFSET(padding[0]));
2443}
2444
2445static void do_fpxregs_set(struct unw_frame_info *info, void *arg)
2446{
2447 struct regset_getset *dst = arg;
2448 struct task_struct *task = dst->target;
2449 char buf[128];
2450 int start, end;
2451
2452 if (dst->count == 0 || unw_unwind_to_user(info) < 0)
2453 return;
2454
2455 if (dst->pos < OFFSET(st_space[0])) {
2456 start = dst->pos;
2457 dst->ret = user_regset_copyin(&dst->pos, &dst->count,
2458 &dst->u.set.kbuf, &dst->u.set.ubuf,
2459 buf, 0, OFFSET(st_space[0]));
2460 if (dst->ret)
2461 return;
2462 setfpxreg(task, start, dst->pos, buf);
2463 if (dst->count == 0)
2464 return;
2465 }
2466 if (dst->pos < OFFSET(xmm_space[0])) {
2467 struct pt_regs *pt;
2468 int tos;
2469 pt = task_pt_regs(task);
2470 tos = (task->thread.fsr >> 11) & 7;
2471 start = (dst->pos - OFFSET(st_space[0])) / 16;
2472 dst->ret = user_regset_copyin(&dst->pos, &dst->count,
2473 &dst->u.set.kbuf, &dst->u.set.ubuf,
2474 buf, OFFSET(st_space[0]), OFFSET(xmm_space[0]));
2475 if (dst->ret)
2476 return;
2477 end = (dst->pos - OFFSET(st_space[0])) / 16;
2478 for (; start < end; start++)
2479 access_fpreg_ia32(start, buf + 16 * start, pt, info->sw,
2480 tos, 1);
2481 if (dst->count == 0)
2482 return;
2483 }
2484 if (dst->pos < OFFSET(padding[0]))
2485 dst->ret = user_regset_copyin(&dst->pos, &dst->count,
2486 &dst->u.set.kbuf, &dst->u.set.ubuf,
2487 &info->sw->f16, OFFSET(xmm_space[0]),
2488 OFFSET(padding[0]));
2489}
2490#undef OFFSET
2491
2492static int do_regset_call(void (*call)(struct unw_frame_info *, void *),
2493 struct task_struct *target,
2494 const struct user_regset *regset,
2495 unsigned int pos, unsigned int count,
2496 const void *kbuf, const void __user *ubuf)
2497{
2498 struct regset_getset info = { .target = target, .regset = regset,
2499 .pos = pos, .count = count,
2500 .u.set = { .kbuf = kbuf, .ubuf = ubuf },
2501 .ret = 0 };
2502
2503 if (target == current)
2504 unw_init_running(call, &info);
2505 else {
2506 struct unw_frame_info ufi;
2507 memset(&ufi, 0, sizeof(ufi));
2508 unw_init_from_blocked_task(&ufi, target);
2509 (*call)(&ufi, &info);
2510 }
2511
2512 return info.ret;
2513}
2514
2515static int ia32_fpregs_get(struct task_struct *target,
2516 const struct user_regset *regset,
2517 unsigned int pos, unsigned int count,
2518 void *kbuf, void __user *ubuf)
2519{
2520 return do_regset_call(do_fpregs_get, target, regset, pos, count,
2521 kbuf, ubuf);
2522}
2523
2524static int ia32_fpregs_set(struct task_struct *target,
2525 const struct user_regset *regset,
2526 unsigned int pos, unsigned int count,
2527 const void *kbuf, const void __user *ubuf)
2528{
2529 return do_regset_call(do_fpregs_set, target, regset, pos, count,
2530 kbuf, ubuf);
2531}
2532
2533static int ia32_fpxregs_get(struct task_struct *target,
2534 const struct user_regset *regset,
2535 unsigned int pos, unsigned int count,
2536 void *kbuf, void __user *ubuf)
2537{
2538 return do_regset_call(do_fpxregs_get, target, regset, pos, count,
2539 kbuf, ubuf);
2540}
2541
2542static int ia32_fpxregs_set(struct task_struct *target,
2543 const struct user_regset *regset,
2544 unsigned int pos, unsigned int count,
2545 const void *kbuf, const void __user *ubuf)
2546{
2547 return do_regset_call(do_fpxregs_set, target, regset, pos, count,
2548 kbuf, ubuf);
2549}
2550
2551static int ia32_genregs_get(struct task_struct *target,
2552 const struct user_regset *regset,
2553 unsigned int pos, unsigned int count,
2554 void *kbuf, void __user *ubuf)
2555{
2556 if (kbuf) {
2557 u32 *kp = kbuf;
2558 while (count > 0) {
2559 *kp++ = getreg(target, pos);
2560 pos += 4;
2561 count -= 4;
2562 }
2563 } else {
2564 u32 __user *up = ubuf;
2565 while (count > 0) {
2566 if (__put_user(getreg(target, pos), up++))
2567 return -EFAULT;
2568 pos += 4;
2569 count -= 4;
2570 }
2571 }
2572 return 0;
2573}
2574
2575static int ia32_genregs_set(struct task_struct *target,
2576 const struct user_regset *regset,
2577 unsigned int pos, unsigned int count,
2578 const void *kbuf, const void __user *ubuf)
2579{
2580 int ret = 0;
2581
2582 if (kbuf) {
2583 const u32 *kp = kbuf;
2584 while (!ret && count > 0) {
2585 putreg(target, pos, *kp++);
2586 pos += 4;
2587 count -= 4;
2588 }
2589 } else {
2590 const u32 __user *up = ubuf;
2591 u32 val;
2592 while (!ret && count > 0) {
2593 ret = __get_user(val, up++);
2594 if (!ret)
2595 putreg(target, pos, val);
2596 pos += 4;
2597 count -= 4;
2598 }
2599 }
2600 return ret;
2601}
2602
2603static int ia32_tls_active(struct task_struct *target,
2604 const struct user_regset *regset)
2605{
2606 struct thread_struct *t = &target->thread;
2607 int n = GDT_ENTRY_TLS_ENTRIES;
2608 while (n > 0 && desc_empty(&t->tls_array[n -1]))
2609 --n;
2610 return n;
2611}
2612
2613static int ia32_tls_get(struct task_struct *target,
2614 const struct user_regset *regset, unsigned int pos,
2615 unsigned int count, void *kbuf, void __user *ubuf)
2616{
2617 const struct desc_struct *tls;
2618
2619 if (pos > GDT_ENTRY_TLS_ENTRIES * sizeof(struct ia32_user_desc) ||
2620 (pos % sizeof(struct ia32_user_desc)) != 0 ||
2621 (count % sizeof(struct ia32_user_desc)) != 0)
2622 return -EINVAL;
2623
2624 pos /= sizeof(struct ia32_user_desc);
2625 count /= sizeof(struct ia32_user_desc);
2626
2627 tls = &target->thread.tls_array[pos];
2628
2629 if (kbuf) {
2630 struct ia32_user_desc *info = kbuf;
2631 while (count-- > 0)
2632 fill_user_desc(info++, GDT_ENTRY_TLS_MIN + pos++,
2633 tls++);
2634 } else {
2635 struct ia32_user_desc __user *u_info = ubuf;
2636 while (count-- > 0) {
2637 struct ia32_user_desc info;
2638 fill_user_desc(&info, GDT_ENTRY_TLS_MIN + pos++, tls++);
2639 if (__copy_to_user(u_info++, &info, sizeof(info)))
2640 return -EFAULT;
2641 }
2642 }
2643
2644 return 0;
2645}
2646
2647static int ia32_tls_set(struct task_struct *target,
2648 const struct user_regset *regset, unsigned int pos,
2649 unsigned int count, const void *kbuf, const void __user *ubuf)
2650{
2651 struct ia32_user_desc infobuf[GDT_ENTRY_TLS_ENTRIES];
2652 const struct ia32_user_desc *info;
2653
2654 if (pos > GDT_ENTRY_TLS_ENTRIES * sizeof(struct ia32_user_desc) ||
2655 (pos % sizeof(struct ia32_user_desc)) != 0 ||
2656 (count % sizeof(struct ia32_user_desc)) != 0)
2657 return -EINVAL;
2658
2659 if (kbuf)
2660 info = kbuf;
2661 else if (__copy_from_user(infobuf, ubuf, count))
2662 return -EFAULT;
2663 else
2664 info = infobuf;
2665
2666 set_tls_desc(target,
2667 GDT_ENTRY_TLS_MIN + (pos / sizeof(struct ia32_user_desc)),
2668 info, count / sizeof(struct ia32_user_desc));
2669
2670 return 0;
2671}
2672
2673/*
2674 * This should match arch/i386/kernel/ptrace.c:native_regsets.
2675 * XXX ioperm? vm86?
2676 */
2677static const struct user_regset ia32_regsets[] = {
2678 {
2679 .core_note_type = NT_PRSTATUS,
2680 .n = sizeof(struct user_regs_struct32)/4,
2681 .size = 4, .align = 4,
2682 .get = ia32_genregs_get, .set = ia32_genregs_set
2683 },
2684 {
2685 .core_note_type = NT_PRFPREG,
2686 .n = sizeof(struct ia32_user_i387_struct) / 4,
2687 .size = 4, .align = 4,
2688 .get = ia32_fpregs_get, .set = ia32_fpregs_set
2689 },
2690 {
2691 .core_note_type = NT_PRXFPREG,
2692 .n = sizeof(struct ia32_user_fxsr_struct) / 4,
2693 .size = 4, .align = 4,
2694 .get = ia32_fpxregs_get, .set = ia32_fpxregs_set
2695 },
2696 {
2697 .core_note_type = NT_386_TLS,
2698 .n = GDT_ENTRY_TLS_ENTRIES,
2699 .bias = GDT_ENTRY_TLS_MIN,
2700 .size = sizeof(struct ia32_user_desc),
2701 .align = sizeof(struct ia32_user_desc),
2702 .active = ia32_tls_active,
2703 .get = ia32_tls_get, .set = ia32_tls_set,
2704 },
2705};
2706
2707const struct user_regset_view user_ia32_view = {
2708 .name = "i386", .e_machine = EM_386,
2709 .regsets = ia32_regsets, .n = ARRAY_SIZE(ia32_regsets)
2710};
2711
2712long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high,
2713 __u32 len_low, __u32 len_high, int advice)
2714{
2715 return sys_fadvise64_64(fd,
2716 (((u64)offset_high)<<32) | offset_low,
2717 (((u64)len_high)<<32) | len_low,
2718 advice);
2719}
2720
2721#ifdef NOTYET /* UNTESTED FOR IA64 FROM HERE DOWN */
2722
2723asmlinkage long sys32_setreuid(compat_uid_t ruid, compat_uid_t euid)
2724{
2725 uid_t sruid, seuid;
2726
2727 sruid = (ruid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)ruid);
2728 seuid = (euid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)euid);
2729 return sys_setreuid(sruid, seuid);
2730}
2731
2732asmlinkage long
2733sys32_setresuid(compat_uid_t ruid, compat_uid_t euid,
2734 compat_uid_t suid)
2735{
2736 uid_t sruid, seuid, ssuid;
2737
2738 sruid = (ruid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)ruid);
2739 seuid = (euid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)euid);
2740 ssuid = (suid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)suid);
2741 return sys_setresuid(sruid, seuid, ssuid);
2742}
2743
2744asmlinkage long
2745sys32_setregid(compat_gid_t rgid, compat_gid_t egid)
2746{
2747 gid_t srgid, segid;
2748
2749 srgid = (rgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)rgid);
2750 segid = (egid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)egid);
2751 return sys_setregid(srgid, segid);
2752}
2753
2754asmlinkage long
2755sys32_setresgid(compat_gid_t rgid, compat_gid_t egid,
2756 compat_gid_t sgid)
2757{
2758 gid_t srgid, segid, ssgid;
2759
2760 srgid = (rgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)rgid);
2761 segid = (egid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)egid);
2762 ssgid = (sgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)sgid);
2763 return sys_setresgid(srgid, segid, ssgid);
2764}
2765#endif /* NOTYET */