/*
 * sys_ia32.c: Conversion between 32bit and 64bit native syscalls. Derived from sys_sparc32.c.
 *
 * Copyright (C) 2000		VA Linux Co
 * Copyright (C) 2000		Don Dugger <n0ano@valinux.com>
 * Copyright (C) 1999		Arun Sharma <arun.sharma@intel.com>
 * Copyright (C) 1997,1998	Jakub Jelinek (jj@sunsite.mff.cuni.cz)
 * Copyright (C) 1997		David S. Miller (davem@caip.rutgers.edu)
 * Copyright (C) 2000-2003, 2005 Hewlett-Packard Co
 *	David Mosberger-Tang <davidm@hpl.hp.com>
 * Copyright (C) 2004		Gordon Jin <gordon.jin@intel.com>
 *
 * These routines maintain argument size conversion between 32bit and 64bit
 * environment.
 */

#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/sysctl.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/signal.h>
#include <linux/resource.h>
#include <linux/times.h>
#include <linux/utsname.h>
#include <linux/timex.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/mm.h>
#include <linux/shm.h>
#include <linux/slab.h>
#include <linux/uio.h>
#include <linux/nfs_fs.h>
#include <linux/quota.h>
#include <linux/syscalls.h>
#include <linux/sunrpc/svc.h>
#include <linux/nfsd/nfsd.h>
#include <linux/nfsd/cache.h>
#include <linux/nfsd/xdr.h>
#include <linux/nfsd/syscall.h>
#include <linux/poll.h>
#include <linux/eventpoll.h>
#include <linux/personality.h>
#include <linux/ptrace.h>
#include <linux/stat.h>
#include <linux/ipc.h>
#include <linux/compat.h>
#include <linux/vfs.h>
#include <linux/mman.h>

#include <asm/intrinsics.h>
#include <asm/semaphore.h>
#include <asm/types.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>

#include "ia32priv.h"

#include <net/scm.h>
#include <net/sock.h>

#define DEBUG	0

#if DEBUG
# define DBG(fmt...)	printk(KERN_DEBUG fmt)
#else
# define DBG(fmt...)
#endif

#define ROUND_UP(x,a)	((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))

#define OFFSET4K(a)		((a) & 0xfff)
#define PAGE_START(addr)	((addr) & PAGE_MASK)
#define MINSIGSTKSZ_IA32	2048

#define high2lowuid(uid) ((uid) > 65535 ? 65534 : (uid))
#define high2lowgid(gid) ((gid) > 65535 ? 65534 : (gid))

/*
 * Anything that modifies or inspects ia32 user virtual memory must hold this semaphore
 * while doing so.
 */
/* XXX make per-mm: */
static DECLARE_MUTEX(ia32_mmap_sem);

asmlinkage long
sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp,
	      struct pt_regs *regs)
{
	long error;
	char *filename;
	unsigned long old_map_base, old_task_size, tssd;

	filename = getname(name);
	error = PTR_ERR(filename);
	if (IS_ERR(filename))
		return error;

	old_map_base  = current->thread.map_base;
	old_task_size = current->thread.task_size;
	tssd = ia64_get_kr(IA64_KR_TSSD);

	/* we may be exec'ing a 64-bit process: reset map base, task-size, and io-base: */
	current->thread.map_base  = DEFAULT_MAP_BASE;
	current->thread.task_size = DEFAULT_TASK_SIZE;
	ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob);
	ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1);

	error = compat_do_execve(filename, argv, envp, regs);
	putname(filename);

	if (error < 0) {
		/* oops, execve failed, switch back to old values... */
		ia64_set_kr(IA64_KR_IO_BASE, IA32_IOBASE);
		ia64_set_kr(IA64_KR_TSSD, tssd);
		current->thread.map_base  = old_map_base;
		current->thread.task_size = old_task_size;
	}

	return error;
}

int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
{
	int err;

	if ((u64) stat->size > MAX_NON_LFS ||
	    !old_valid_dev(stat->dev) ||
	    !old_valid_dev(stat->rdev))
		return -EOVERFLOW;

	if (clear_user(ubuf, sizeof(*ubuf)))
		return -EFAULT;

	err  = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
	err |= __put_user(stat->ino, &ubuf->st_ino);
	err |= __put_user(stat->mode, &ubuf->st_mode);
	err |= __put_user(stat->nlink, &ubuf->st_nlink);
	err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid);
	err |= __put_user(high2lowgid(stat->gid), &ubuf->st_gid);
	err |= __put_user(old_encode_dev(stat->rdev), &ubuf->st_rdev);
	err |= __put_user(stat->size, &ubuf->st_size);
	err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime);
	err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec);
	err |= __put_user(stat->mtime.tv_sec, &ubuf->st_mtime);
	err |= __put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec);
	err |= __put_user(stat->ctime.tv_sec, &ubuf->st_ctime);
	err |= __put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec);
	err |= __put_user(stat->blksize, &ubuf->st_blksize);
	err |= __put_user(stat->blocks, &ubuf->st_blocks);
	return err;
}

#if PAGE_SHIFT > IA32_PAGE_SHIFT


static int
get_page_prot (struct vm_area_struct *vma, unsigned long addr)
{
	int prot = 0;

	if (!vma || vma->vm_start > addr)
		return 0;

	if (vma->vm_flags & VM_READ)
		prot |= PROT_READ;
	if (vma->vm_flags & VM_WRITE)
		prot |= PROT_WRITE;
	if (vma->vm_flags & VM_EXEC)
		prot |= PROT_EXEC;
	return prot;
}

/*
 * Map a subpage by creating an anonymous page that contains the union of the old page and
 * the subpage.
 */
static unsigned long
mmap_subpage (struct file *file, unsigned long start, unsigned long end, int prot, int flags,
	      loff_t off)
{
	void *page = NULL;
	struct inode *inode;
	unsigned long ret = 0;
	struct vm_area_struct *vma = find_vma(current->mm, start);
	int old_prot = get_page_prot(vma, start);

	DBG("mmap_subpage(file=%p,start=0x%lx,end=0x%lx,prot=%x,flags=%x,off=0x%llx)\n",
	    file, start, end, prot, flags, off);


	/* Optimize the case where the old mmap and the new mmap are both anonymous */
	if ((old_prot & PROT_WRITE) && (flags & MAP_ANONYMOUS) && !vma->vm_file) {
		if (clear_user((void __user *) start, end - start)) {
			ret = -EFAULT;
			goto out;
		}
		goto skip_mmap;
	}

	page = (void *) get_zeroed_page(GFP_KERNEL);
	if (!page)
		return -ENOMEM;

	if (old_prot)
		copy_from_user(page, (void __user *) PAGE_START(start), PAGE_SIZE);

	down_write(&current->mm->mmap_sem);
	{
		ret = do_mmap(NULL, PAGE_START(start), PAGE_SIZE, prot | PROT_WRITE,
			      flags | MAP_FIXED | MAP_ANONYMOUS, 0);
	}
	up_write(&current->mm->mmap_sem);

	if (IS_ERR((void *) ret))
		goto out;

	if (old_prot) {
		/* copy back the old page contents.  */
		if (offset_in_page(start))
			copy_to_user((void __user *) PAGE_START(start), page,
				     offset_in_page(start));
		if (offset_in_page(end))
			copy_to_user((void __user *) end, page + offset_in_page(end),
				     PAGE_SIZE - offset_in_page(end));
	}

	if (!(flags & MAP_ANONYMOUS)) {
		/* read the file contents */
		inode = file->f_dentry->d_inode;
		if (!inode->i_fop || !file->f_op->read
		    || ((*file->f_op->read)(file, (char __user *) start, end - start, &off) < 0))
		{
			ret = -EINVAL;
			goto out;
		}
	}

 skip_mmap:
	if (!(prot & PROT_WRITE))
		ret = sys_mprotect(PAGE_START(start), PAGE_SIZE, prot | old_prot);
  out:
	if (page)
		free_page((unsigned long) page);
	return ret;
}

/* SLAB cache for partial_page structures */
kmem_cache_t *partial_page_cachep;

/*
 * init partial_page_list.
 * return 0 means kmalloc fail.
 */
struct partial_page_list*
ia32_init_pp_list(void)
{
	struct partial_page_list *p;

	if ((p = kmalloc(sizeof(*p), GFP_KERNEL)) == NULL)
		return p;
	p->pp_head = NULL;
	p->ppl_rb = RB_ROOT;
	p->pp_hint = NULL;
	atomic_set(&p->pp_count, 1);
	return p;
}

/*
 * Search for the partial page with @start in partial page list @ppl.
 * If finds the partial page, return the found partial page.
 * Else, return 0 and provide @pprev, @rb_link, @rb_parent to
 * be used by later __ia32_insert_pp().
 */
static struct partial_page *
__ia32_find_pp(struct partial_page_list *ppl, unsigned int start,
	struct partial_page **pprev, struct rb_node ***rb_link,
	struct rb_node **rb_parent)
{
	struct partial_page *pp;
	struct rb_node **__rb_link, *__rb_parent, *rb_prev;

	pp = ppl->pp_hint;
	if (pp && pp->base == start)
		return pp;

	__rb_link = &ppl->ppl_rb.rb_node;
	rb_prev = __rb_parent = NULL;

	while (*__rb_link) {
		__rb_parent = *__rb_link;
		pp = rb_entry(__rb_parent, struct partial_page, pp_rb);

		if (pp->base == start) {
			ppl->pp_hint = pp;
			return pp;
		} else if (pp->base < start) {
			rb_prev = __rb_parent;
			__rb_link = &__rb_parent->rb_right;
		} else {
			__rb_link = &__rb_parent->rb_left;
		}
	}

	*rb_link = __rb_link;
	*rb_parent = __rb_parent;
	*pprev = NULL;
	if (rb_prev)
		*pprev = rb_entry(rb_prev, struct partial_page, pp_rb);
	return NULL;
}

/*
 * insert @pp into @ppl.
 */
static void
__ia32_insert_pp(struct partial_page_list *ppl, struct partial_page *pp,
	 struct partial_page *prev, struct rb_node **rb_link,
	struct rb_node *rb_parent)
{
	/* link list */
	if (prev) {
		pp->next = prev->next;
		prev->next = pp;
	} else {
		ppl->pp_head = pp;
		if (rb_parent)
			pp->next = rb_entry(rb_parent,
				struct partial_page, pp_rb);
		else
			pp->next = NULL;
	}

	/* link rb */
	rb_link_node(&pp->pp_rb, rb_parent, rb_link);
	rb_insert_color(&pp->pp_rb, &ppl->ppl_rb);

	ppl->pp_hint = pp;
}

/*
 * delete @pp from partial page list @ppl.
 */
static void
__ia32_delete_pp(struct partial_page_list *ppl, struct partial_page *pp,
	struct partial_page *prev)
{
	if (prev) {
		prev->next = pp->next;
		if (ppl->pp_hint == pp)
			ppl->pp_hint = prev;
	} else {
		ppl->pp_head = pp->next;
		if (ppl->pp_hint == pp)
			ppl->pp_hint = pp->next;
	}
	rb_erase(&pp->pp_rb, &ppl->ppl_rb);
	kmem_cache_free(partial_page_cachep, pp);
}

static struct partial_page *
__pp_prev(struct partial_page *pp)
{
	struct rb_node *prev = rb_prev(&pp->pp_rb);
	if (prev)
		return rb_entry(prev, struct partial_page, pp_rb);
	else
		return NULL;
}

/*
 * Delete partial pages with address between @start and @end.
 * @start and @end are page aligned.
 */
static void
__ia32_delete_pp_range(unsigned int start, unsigned int end)
{
	struct partial_page *pp, *prev;
	struct rb_node **rb_link, *rb_parent;

	if (start >= end)
		return;

	pp = __ia32_find_pp(current->thread.ppl, start, &prev,
					&rb_link, &rb_parent);
	if (pp)
		prev = __pp_prev(pp);
	else {
		if (prev)
			pp = prev->next;
		else
			pp = current->thread.ppl->pp_head;
	}

	while (pp && pp->base < end) {
		struct partial_page *tmp = pp->next;
		__ia32_delete_pp(current->thread.ppl, pp, prev);
		pp = tmp;
	}
}

/*
 * Set the range between @start and @end in bitmap.
 * @start and @end should be IA32 page aligned and in the same IA64 page.
 */
static int
__ia32_set_pp(unsigned int start, unsigned int end, int flags)
{
	struct partial_page *pp, *prev;
	struct rb_node ** rb_link, *rb_parent;
	unsigned int pstart, start_bit, end_bit, i;

	pstart = PAGE_START(start);
	start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE;
	end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE;
	if (end_bit == 0)
		end_bit = PAGE_SIZE / IA32_PAGE_SIZE;
	pp = __ia32_find_pp(current->thread.ppl, pstart, &prev,
					&rb_link, &rb_parent);
	if (pp) {
		for (i = start_bit; i < end_bit; i++)
			set_bit(i, &pp->bitmap);
		/*
		 * Check: if this partial page has been set to a full page,
		 * then delete it.
		 */
		if (find_first_zero_bit(&pp->bitmap, sizeof(pp->bitmap)*8) >=
				PAGE_SIZE/IA32_PAGE_SIZE) {
			__ia32_delete_pp(current->thread.ppl, pp, __pp_prev(pp));
		}
		return 0;
	}

	/*
	 * MAP_FIXED may lead to overlapping mmap.
	 * In this case, the requested mmap area may already mmaped as a full
	 * page. So check vma before adding a new partial page.
	 */
	if (flags & MAP_FIXED) {
		struct vm_area_struct *vma = find_vma(current->mm, pstart);
		if (vma && vma->vm_start <= pstart)
			return 0;
	}

	/* new a partial_page */
	pp = kmem_cache_alloc(partial_page_cachep, GFP_KERNEL);
	if (!pp)
		return -ENOMEM;
	pp->base = pstart;
	pp->bitmap = 0;
	for (i=start_bit; i<end_bit; i++)
		set_bit(i, &(pp->bitmap));
	pp->next = NULL;
	__ia32_insert_pp(current->thread.ppl, pp, prev, rb_link, rb_parent);
	return 0;
}

/*
 * @start and @end should be IA32 page aligned, but don't need to be in the
 * same IA64 page. Split @start and @end to make sure they're in the same IA64
 * page, then call __ia32_set_pp().
 */
static void
ia32_set_pp(unsigned int start, unsigned int end, int flags)
{
	down_write(&current->mm->mmap_sem);
	if (flags & MAP_FIXED) {
		/*
		 * MAP_FIXED may lead to overlapping mmap. When this happens,
		 * a series of complete IA64 pages results in deletion of
		 * old partial pages in that range.
		 */
		__ia32_delete_pp_range(PAGE_ALIGN(start), PAGE_START(end));
	}

	if (end < PAGE_ALIGN(start)) {
		__ia32_set_pp(start, end, flags);
	} else {
		if (offset_in_page(start))
			__ia32_set_pp(start, PAGE_ALIGN(start), flags);
		if (offset_in_page(end))
			__ia32_set_pp(PAGE_START(end), end, flags);
	}
	up_write(&current->mm->mmap_sem);
}

/*
 * Unset the range between @start and @end in bitmap.
 * @start and @end should be IA32 page aligned and in the same IA64 page.
 * After doing that, if the bitmap is 0, then free the page and return 1,
 * 	else return 0;
 * If not find the partial page in the list, then
 * 	If the vma exists, then the full page is set to a partial page;
 *	Else return -ENOMEM.
 */
static int
__ia32_unset_pp(unsigned int start, unsigned int end)
{
	struct partial_page *pp, *prev;
	struct rb_node ** rb_link, *rb_parent;
	unsigned int pstart, start_bit, end_bit, i;
	struct vm_area_struct *vma;

	pstart = PAGE_START(start);
	start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE;
	end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE;
	if (end_bit == 0)
		end_bit = PAGE_SIZE / IA32_PAGE_SIZE;

	pp = __ia32_find_pp(current->thread.ppl, pstart, &prev,
					&rb_link, &rb_parent);
	if (pp) {
		for (i = start_bit; i < end_bit; i++)
			clear_bit(i, &pp->bitmap);
		if (pp->bitmap == 0) {
			__ia32_delete_pp(current->thread.ppl, pp, __pp_prev(pp));
			return 1;
		}
		return 0;
	}

	vma = find_vma(current->mm, pstart);
	if (!vma || vma->vm_start > pstart) {
		return -ENOMEM;
	}

	/* new a partial_page */
	pp = kmem_cache_alloc(partial_page_cachep, GFP_KERNEL);
	if (!pp)
		return -ENOMEM;
	pp->base = pstart;
	pp->bitmap = 0;
	for (i = 0; i < start_bit; i++)
		set_bit(i, &(pp->bitmap));
	for (i = end_bit; i < PAGE_SIZE / IA32_PAGE_SIZE; i++)
		set_bit(i, &(pp->bitmap));
	pp->next = NULL;
	__ia32_insert_pp(current->thread.ppl, pp, prev, rb_link, rb_parent);
	return 0;
}

/*
 * Delete pp between PAGE_ALIGN(start) and PAGE_START(end) by calling
 * __ia32_delete_pp_range(). Unset possible partial pages by calling
 * __ia32_unset_pp().
 * The returned value see __ia32_unset_pp().
 */
static int
ia32_unset_pp(unsigned int *startp, unsigned int *endp)
{
	unsigned int start = *startp, end = *endp;
	int ret = 0;

	down_write(&current->mm->mmap_sem);

	__ia32_delete_pp_range(PAGE_ALIGN(start), PAGE_START(end));

	if (end < PAGE_ALIGN(start)) {
		ret = __ia32_unset_pp(start, end);
		if (ret == 1) {
			*startp = PAGE_START(start);
			*endp = PAGE_ALIGN(end);
		}
		if (ret == 0) {
			/* to shortcut sys_munmap() in sys32_munmap() */
			*startp = PAGE_START(start);
			*endp = PAGE_START(end);
		}
	} else {
		if (offset_in_page(start)) {
			ret = __ia32_unset_pp(start, PAGE_ALIGN(start));
			if (ret == 1)
				*startp = PAGE_START(start);
			if (ret == 0)
				*startp = PAGE_ALIGN(start);
			if (ret < 0)
				goto out;
		}
		if (offset_in_page(end)) {
			ret = __ia32_unset_pp(PAGE_START(end), end);
			if (ret == 1)
				*endp = PAGE_ALIGN(end);
			if (ret == 0)
				*endp = PAGE_START(end);
		}
	}

 out:
	up_write(&current->mm->mmap_sem);
	return ret;
}

/*
 * Compare the range between @start and @end with bitmap in partial page.
 * @start and @end should be IA32 page aligned and in the same IA64 page.
 */
static int
__ia32_compare_pp(unsigned int start, unsigned int end)
{
	struct partial_page *pp, *prev;
	struct rb_node ** rb_link, *rb_parent;
	unsigned int pstart, start_bit, end_bit, size;
	unsigned int first_bit, next_zero_bit;	/* the first range in bitmap */

	pstart = PAGE_START(start);

	pp = __ia32_find_pp(current->thread.ppl, pstart, &prev,
					&rb_link, &rb_parent);
	if (!pp)
		return 1;

	start_bit = (start % PAGE_SIZE) / IA32_PAGE_SIZE;
	end_bit = (end % PAGE_SIZE) / IA32_PAGE_SIZE;
	size = sizeof(pp->bitmap) * 8;
	first_bit = find_first_bit(&pp->bitmap, size);
	next_zero_bit = find_next_zero_bit(&pp->bitmap, size, first_bit);
	if ((start_bit < first_bit) || (end_bit > next_zero_bit)) {
		/* exceeds the first range in bitmap */
		return -ENOMEM;
	} else if ((start_bit == first_bit) && (end_bit == next_zero_bit)) {
		first_bit = find_next_bit(&pp->bitmap, size, next_zero_bit);
		if ((next_zero_bit < first_bit) && (first_bit < size))
			return 1;	/* has next range */
		else
			return 0; 	/* no next range */
	} else
		return 1;
}

/*
 * @start and @end should be IA32 page aligned, but don't need to be in the
 * same IA64 page. Split @start and @end to make sure they're in the same IA64
 * page, then call __ia32_compare_pp().
 *
 * Take this as example: the range is the 1st and 2nd 4K page.
 * Return 0 if they fit bitmap exactly, i.e. bitmap = 00000011;
 * Return 1 if the range doesn't cover whole bitmap, e.g. bitmap = 00001111;
 * Return -ENOMEM if the range exceeds the bitmap, e.g. bitmap = 00000001 or
 * 	bitmap = 00000101.
 */
static int
ia32_compare_pp(unsigned int *startp, unsigned int *endp)
{
	unsigned int start = *startp, end = *endp;
	int retval = 0;

	down_write(&current->mm->mmap_sem);

	if (end < PAGE_ALIGN(start)) {
		retval = __ia32_compare_pp(start, end);
		if (retval == 0) {
			*startp = PAGE_START(start);
			*endp = PAGE_ALIGN(end);
		}
	} else {
		if (offset_in_page(start)) {
			retval = __ia32_compare_pp(start,
						   PAGE_ALIGN(start));
			if (retval == 0)
				*startp = PAGE_START(start);
			if (retval < 0)
				goto out;
		}
		if (offset_in_page(end)) {
			retval = __ia32_compare_pp(PAGE_START(end), end);
			if (retval == 0)
				*endp = PAGE_ALIGN(end);
		}
	}

 out:
	up_write(&current->mm->mmap_sem);
	return retval;
}

static void
__ia32_drop_pp_list(struct partial_page_list *ppl)
{
	struct partial_page *pp = ppl->pp_head;

	while (pp) {
		struct partial_page *next = pp->next;
		kmem_cache_free(partial_page_cachep, pp);
		pp = next;
	}

	kfree(ppl);
}

void
ia32_drop_partial_page_list(struct task_struct *task)
{
	struct partial_page_list* ppl = task->thread.ppl;

	if (ppl && atomic_dec_and_test(&ppl->pp_count))
		__ia32_drop_pp_list(ppl);
}

/*
 * Copy current->thread.ppl to ppl (already initialized).
 */
static int
__ia32_copy_pp_list(struct partial_page_list *ppl)
{
	struct partial_page *pp, *tmp, *prev;
	struct rb_node **rb_link, *rb_parent;

	ppl->pp_head = NULL;
	ppl->pp_hint = NULL;
	ppl->ppl_rb = RB_ROOT;
	rb_link = &ppl->ppl_rb.rb_node;
	rb_parent = NULL;
	prev = NULL;

	for (pp = current->thread.ppl->pp_head; pp; pp = pp->next) {
		tmp = kmem_cache_alloc(partial_page_cachep, GFP_KERNEL);
		if (!tmp)
			return -ENOMEM;
		*tmp = *pp;
		__ia32_insert_pp(ppl, tmp, prev, rb_link, rb_parent);
		prev = tmp;
		rb_link = &tmp->pp_rb.rb_right;
		rb_parent = &tmp->pp_rb;
	}
	return 0;
}

int
ia32_copy_partial_page_list(struct task_struct *p, unsigned long clone_flags)
{
	int retval = 0;

	if (clone_flags & CLONE_VM) {
		atomic_inc(&current->thread.ppl->pp_count);
		p->thread.ppl = current->thread.ppl;
	} else {
		p->thread.ppl = ia32_init_pp_list();
		if (!p->thread.ppl)
			return -ENOMEM;
		down_write(&current->mm->mmap_sem);
		{
			retval = __ia32_copy_pp_list(p->thread.ppl);
		}
		up_write(&current->mm->mmap_sem);
	}

	return retval;
}

static unsigned long
emulate_mmap (struct file *file, unsigned long start, unsigned long len, int prot, int flags,
	      loff_t off)
{
	unsigned long tmp, end, pend, pstart, ret, is_congruent, fudge = 0;
	struct inode *inode;
	loff_t poff;

	end = start + len;
	pstart = PAGE_START(start);
	pend = PAGE_ALIGN(end);

	if (flags & MAP_FIXED) {
		ia32_set_pp((unsigned int)start, (unsigned int)end, flags);
		if (start > pstart) {
			if (flags & MAP_SHARED)
				printk(KERN_INFO
				       "%s(%d): emulate_mmap() can't share head (addr=0x%lx)\n",
				       current->comm, current->pid, start);
			ret = mmap_subpage(file, start, min(PAGE_ALIGN(start), end), prot, flags,
					   off);
			if (IS_ERR((void *) ret))
				return ret;
			pstart += PAGE_SIZE;
			if (pstart >= pend)
				goto out;	/* done */
		}
		if (end < pend) {
			if (flags & MAP_SHARED)
				printk(KERN_INFO
				       "%s(%d): emulate_mmap() can't share tail (end=0x%lx)\n",
				       current->comm, current->pid, end);
			ret = mmap_subpage(file, max(start, PAGE_START(end)), end, prot, flags,
					   (off + len) - offset_in_page(end));
			if (IS_ERR((void *) ret))
				return ret;
			pend -= PAGE_SIZE;
			if (pstart >= pend)
				goto out;	/* done */
		}
	} else {
		/*
		 * If a start address was specified, use it if the entire rounded out area
		 * is available.
		 */
		if (start && !pstart)
			fudge = 1;	/* handle case of mapping to range (0,PAGE_SIZE) */
		tmp = arch_get_unmapped_area(file, pstart - fudge, pend - pstart, 0, flags);
		if (tmp != pstart) {
			pstart = tmp;
			start = pstart + offset_in_page(off);	/* make start congruent with off */
			end = start + len;
			pend = PAGE_ALIGN(end);
		}
	}

	poff = off + (pstart - start);	/* note: (pstart - start) may be negative */
	is_congruent = (flags & MAP_ANONYMOUS) || (offset_in_page(poff) == 0);

	if ((flags & MAP_SHARED) && !is_congruent)
		printk(KERN_INFO "%s(%d): emulate_mmap() can't share contents of incongruent mmap "
		       "(addr=0x%lx,off=0x%llx)\n", current->comm, current->pid, start, off);

	DBG("mmap_body: mapping [0x%lx-0x%lx) %s with poff 0x%llx\n", pstart, pend,
	    is_congruent ? "congruent" : "not congruent", poff);

	down_write(&current->mm->mmap_sem);
	{
		if (!(flags & MAP_ANONYMOUS) && is_congruent)
			ret = do_mmap(file, pstart, pend - pstart, prot, flags | MAP_FIXED, poff);
		else
			ret = do_mmap(NULL, pstart, pend - pstart,
				      prot | ((flags & MAP_ANONYMOUS) ? 0 : PROT_WRITE),
				      flags | MAP_FIXED | MAP_ANONYMOUS, 0);
	}
	up_write(&current->mm->mmap_sem);

	if (IS_ERR((void *) ret))
		return ret;

	if (!is_congruent) {
		/* read the file contents */
		inode = file->f_dentry->d_inode;
		if (!inode->i_fop || !file->f_op->read
		    || ((*file->f_op->read)(file, (char __user *) pstart, pend - pstart, &poff)
			< 0))
		{
			sys_munmap(pstart, pend - pstart);
			return -EINVAL;
		}
		if (!(prot & PROT_WRITE) && sys_mprotect(pstart, pend - pstart, prot) < 0)
			return -EINVAL;
	}

	if (!(flags & MAP_FIXED))
		ia32_set_pp((unsigned int)start, (unsigned int)end, flags);
out:
	return start;
}

#endif /* PAGE_SHIFT > IA32_PAGE_SHIFT */

static inline unsigned int
get_prot32 (unsigned int prot)
{
	if (prot & PROT_WRITE)
		/* on x86, PROT_WRITE implies PROT_READ which implies PROT_EEC */
		prot |= PROT_READ | PROT_WRITE | PROT_EXEC;
	else if (prot & (PROT_READ | PROT_EXEC))
		/* on x86, there is no distinction between PROT_READ and PROT_EXEC */
		prot |= (PROT_READ | PROT_EXEC);

	return prot;
}

unsigned long
ia32_do_mmap (struct file *file, unsigned long addr, unsigned long len, int prot, int flags,
	      loff_t offset)
{
	DBG("ia32_do_mmap(file=%p,addr=0x%lx,len=0x%lx,prot=%x,flags=%x,offset=0x%llx)\n",
	    file, addr, len, prot, flags, offset);

	if (file && (!file->f_op || !file->f_op->mmap))
		return -ENODEV;

	len = IA32_PAGE_ALIGN(len);
	if (len == 0)
		return addr;

	if (len > IA32_PAGE_OFFSET || addr > IA32_PAGE_OFFSET - len)
	{
		if (flags & MAP_FIXED)
			return -ENOMEM;
		else
		return -EINVAL;
	}

	if (OFFSET4K(offset))
		return -EINVAL;

	prot = get_prot32(prot);

#if PAGE_SHIFT > IA32_PAGE_SHIFT
	down(&ia32_mmap_sem);
	{
		addr = emulate_mmap(file, addr, len, prot, flags, offset);
	}
	up(&ia32_mmap_sem);
#else
	down_write(&current->mm->mmap_sem);
	{
		addr = do_mmap(file, addr, len, prot, flags, offset);
	}
	up_write(&current->mm->mmap_sem);
#endif
	DBG("ia32_do_mmap: returning 0x%lx\n", addr);
	return addr;
}

/*
 * Linux/i386 didn't use to be able to handle more than 4 system call parameters, so these
 * system calls used a memory block for parameter passing..
 */

struct mmap_arg_struct {
	unsigned int addr;
	unsigned int len;
	unsigned int prot;
	unsigned int flags;
	unsigned int fd;
	unsigned int offset;
};

asmlinkage long
sys32_mmap (struct mmap_arg_struct __user *arg)
{
	struct mmap_arg_struct a;
	struct file *file = NULL;
	unsigned long addr;
	int flags;

	if (copy_from_user(&a, arg, sizeof(a)))
		return -EFAULT;

	if (OFFSET4K(a.offset))
		return -EINVAL;

	flags = a.flags;

	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
	if (!(flags & MAP_ANONYMOUS)) {
		file = fget(a.fd);
		if (!file)
			return -EBADF;
	}

	addr = ia32_do_mmap(file, a.addr, a.len, a.prot, flags, a.offset);

	if (file)
		fput(file);
	return addr;
}

asmlinkage long
sys32_mmap2 (unsigned int addr, unsigned int len, unsigned int prot, unsigned int flags,
	     unsigned int fd, unsigned int pgoff)
{
	struct file *file = NULL;
	unsigned long retval;

	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
	if (!(flags & MAP_ANONYMOUS)) {
		file = fget(fd);
		if (!file)
			return -EBADF;
	}

	retval = ia32_do_mmap(file, addr, len, prot, flags,
			      (unsigned long) pgoff << IA32_PAGE_SHIFT);

	if (file)
		fput(file);
	return retval;
}

asmlinkage long
sys32_munmap (unsigned int start, unsigned int len)
{
	unsigned int end = start + len;
	long ret;

#if PAGE_SHIFT <= IA32_PAGE_SHIFT
	ret = sys_munmap(start, end - start);
#else
	if (OFFSET4K(start))
		return -EINVAL;

	end = IA32_PAGE_ALIGN(end);
	if (start >= end)
		return -EINVAL;

	ret = ia32_unset_pp(&start, &end);
	if (ret < 0)
		return ret;

	if (start >= end)
		return 0;

	down(&ia32_mmap_sem);
	{
		ret = sys_munmap(start, end - start);
	}
	up(&ia32_mmap_sem);
#endif
	return ret;
}

#if PAGE_SHIFT > IA32_PAGE_SHIFT

/*
 * When mprotect()ing a partial page, we set the permission to the union of the old
 * settings and the new settings.  In other words, it's only possible to make access to a
 * partial page less restrictive.
 */
static long
mprotect_subpage (unsigned long address, int new_prot)
{
	int old_prot;
	struct vm_area_struct *vma;

	if (new_prot == PROT_NONE)
		return 0;		/* optimize case where nothing changes... */
	vma = find_vma(current->mm, address);
	old_prot = get_page_prot(vma, address);
	return sys_mprotect(address, PAGE_SIZE, new_prot | old_prot);
}

#endif /* PAGE_SHIFT > IA32_PAGE_SHIFT */

asmlinkage long
sys32_mprotect (unsigned int start, unsigned int len, int prot)
{
	unsigned int end = start + len;
#if PAGE_SHIFT > IA32_PAGE_SHIFT
	long retval = 0;
#endif

	prot = get_prot32(prot);

#if PAGE_SHIFT <= IA32_PAGE_SHIFT
	return sys_mprotect(start, end - start, prot);
#else
	if (OFFSET4K(start))
		return -EINVAL;

	end = IA32_PAGE_ALIGN(end);
	if (end < start)
		return -EINVAL;

	retval = ia32_compare_pp(&start, &end);

	if (retval < 0)
		return retval;

	down(&ia32_mmap_sem);
	{
		if (offset_in_page(start)) {
			/* start address is 4KB aligned but not page aligned. */
			retval = mprotect_subpage(PAGE_START(start), prot);
			if (retval < 0)
				goto out;

			start = PAGE_ALIGN(start);
			if (start >= end)
				goto out;	/* retval is already zero... */
		}

		if (offset_in_page(end)) {
			/* end address is 4KB aligned but not page aligned. */
			retval = mprotect_subpage(PAGE_START(end), prot);
			if (retval < 0)
				goto out;

			end = PAGE_START(end);
		}
		retval = sys_mprotect(start, end - start, prot);
	}
  out:
	up(&ia32_mmap_sem);
	return retval;
#endif
}

asmlinkage long
sys32_mremap (unsigned int addr, unsigned int old_len, unsigned int new_len,
		unsigned int flags, unsigned int new_addr)
{
	long ret;

#if PAGE_SHIFT <= IA32_PAGE_SHIFT
	ret = sys_mremap(addr, old_len, new_len, flags, new_addr);
#else
	unsigned int old_end, new_end;

	if (OFFSET4K(addr))
		return -EINVAL;

	old_len = IA32_PAGE_ALIGN(old_len);
	new_len = IA32_PAGE_ALIGN(new_len);
	old_end = addr + old_len;
	new_end = addr + new_len;

	if (!new_len)
		return -EINVAL;

	if ((flags & MREMAP_FIXED) && (OFFSET4K(new_addr)))
		return -EINVAL;

	if (old_len >= new_len) {
		ret = sys32_munmap(addr + new_len, old_len - new_len);
		if (ret && old_len != new_len)
			return ret;
		ret = addr;
		if (!(flags & MREMAP_FIXED) || (new_addr == addr))
			return ret;
		old_len = new_len;
	}

	addr = PAGE_START(addr);
	old_len = PAGE_ALIGN(old_end) - addr;
	new_len = PAGE_ALIGN(new_end) - addr;

	down(&ia32_mmap_sem);
	{
		ret = sys_mremap(addr, old_len, new_len, flags, new_addr);
	}
	up(&ia32_mmap_sem);

	if ((ret >= 0) && (old_len < new_len)) {
		/* mremap expanded successfully */
		ia32_set_pp(old_end, new_end, flags);
	}
#endif
	return ret;
}

asmlinkage long
sys32_pipe (int __user *fd)
{
	int retval;
	int fds[2];

	retval = do_pipe(fds);
	if (retval)
		goto out;
	if (copy_to_user(fd, fds, sizeof(fds)))
		retval = -EFAULT;
  out:
	return retval;
}

static inline long
get_tv32 (struct timeval *o, struct compat_timeval __user *i)
{
	return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
		(__get_user(o->tv_sec, &i->tv_sec) | __get_user(o->tv_usec, &i->tv_usec)));
}

static inline long
put_tv32 (struct compat_timeval __user *o, struct timeval *i)
{
	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
		(__put_user(i->tv_sec, &o->tv_sec) | __put_user(i->tv_usec, &o->tv_usec)));
}

asmlinkage unsigned long
sys32_alarm (unsigned int seconds)
{
	struct itimerval it_new, it_old;
	unsigned int oldalarm;

	it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
	it_new.it_value.tv_sec = seconds;
	it_new.it_value.tv_usec = 0;
	do_setitimer(ITIMER_REAL, &it_new, &it_old);
	oldalarm = it_old.it_value.tv_sec;
	/* ehhh.. We can't return 0 if we have an alarm pending.. */
	/* And we'd better return too much than too little anyway */
	if (it_old.it_value.tv_usec)
		oldalarm++;
	return oldalarm;
}

/* Translations due to time_t size differences.  Which affects all
   sorts of things, like timeval and itimerval.  */

extern struct timezone sys_tz;

asmlinkage long
sys32_gettimeofday (struct compat_timeval __user *tv, struct timezone __user *tz)
{
	if (tv) {
		struct timeval ktv;
		do_gettimeofday(&ktv);
		if (put_tv32(tv, &ktv))
			return -EFAULT;
	}
	if (tz) {
		if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
			return -EFAULT;
	}
	return 0;
}

asmlinkage long
sys32_settimeofday (struct compat_timeval __user *tv, struct timezone __user *tz)
{
	struct timeval ktv;
	struct timespec kts;
	struct timezone ktz;

	if (tv) {
		if (get_tv32(&ktv, tv))
			return -EFAULT;
		kts.tv_sec = ktv.tv_sec;
		kts.tv_nsec = ktv.tv_usec * 1000;
	}
	if (tz) {
		if (copy_from_user(&ktz, tz, sizeof(ktz)))
			return -EFAULT;
	}

	return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
}

struct getdents32_callback {
	struct compat_dirent __user *current_dir;
	struct compat_dirent __user *previous;
	int count;
	int error;
};

struct readdir32_callback {
	struct old_linux32_dirent __user * dirent;
	int count;
};

static int
filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
	   unsigned int d_type)
{
	struct compat_dirent __user * dirent;
	struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
	int reclen = ROUND_UP(offsetof(struct compat_dirent, d_name) + namlen + 1, 4);

	buf->error = -EINVAL;	/* only used if we fail.. */
	if (reclen > buf->count)
		return -EINVAL;
	buf->error = -EFAULT;	/* only used if we fail.. */
	dirent = buf->previous;
	if (dirent)
		if (put_user(offset, &dirent->d_off))
			return -EFAULT;
	dirent = buf->current_dir;
	buf->previous = dirent;
	if (put_user(ino, &dirent->d_ino)
	    || put_user(reclen, &dirent->d_reclen)
	    || copy_to_user(dirent->d_name, name, namlen)
	    || put_user(0, dirent->d_name + namlen))
		return -EFAULT;
	dirent = (struct compat_dirent __user *) ((char __user *) dirent + reclen);
	buf->current_dir = dirent;
	buf->count -= reclen;
	return 0;
}

asmlinkage long
sys32_getdents (unsigned int fd, struct compat_dirent __user *dirent, unsigned int count)
{
	struct file * file;
	struct compat_dirent __user * lastdirent;
	struct getdents32_callback buf;
	int error;

	error = -EBADF;
	file = fget(fd);
	if (!file)
		goto out;

	buf.current_dir = dirent;
	buf.previous = NULL;
	buf.count = count;
	buf.error = 0;

	error = vfs_readdir(file, filldir32, &buf);
	if (error < 0)
		goto out_putf;
	error = buf.error;
	lastdirent = buf.previous;
	if (lastdirent) {
		error = -EINVAL;
		if (put_user(file->f_pos, &lastdirent->d_off))
			goto out_putf;
		error = count - buf.count;
	}

out_putf:
	fput(file);
out:
	return error;
}

static int
fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
	      unsigned int d_type)
{
	struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
	struct old_linux32_dirent __user * dirent;

	if (buf->count)
		return -EINVAL;
	buf->count++;
	dirent = buf->dirent;
	if (put_user(ino, &dirent->d_ino)
	    || put_user(offset, &dirent->d_offset)
	    || put_user(namlen, &dirent->d_namlen)
	    || copy_to_user(dirent->d_name, name, namlen)
	    || put_user(0, dirent->d_name + namlen))
		return -EFAULT;
	return 0;
}

asmlinkage long
sys32_readdir (unsigned int fd, void __user *dirent, unsigned int count)
{
	int error;
	struct file * file;
	struct readdir32_callback buf;

	error = -EBADF;
	file = fget(fd);
	if (!file)
		goto out;

	buf.count = 0;
	buf.dirent = dirent;

	error = vfs_readdir(file, fillonedir32, &buf);
	if (error >= 0)
		error = buf.count;
	fput(file);
out:
	return error;
}

struct sel_arg_struct {
	unsigned int n;
	unsigned int inp;
	unsigned int outp;
	unsigned int exp;
	unsigned int tvp;
};

asmlinkage long
sys32_old_select (struct sel_arg_struct __user *arg)
{
	struct sel_arg_struct a;

	if (copy_from_user(&a, arg, sizeof(a)))
		return -EFAULT;
	return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
				 compat_ptr(a.exp), compat_ptr(a.tvp));
}

#define SEMOP		 1
#define SEMGET		 2
#define SEMCTL		 3
#define SEMTIMEDOP	 4
#define MSGSND		11
#define MSGRCV		12
#define MSGGET		13
#define MSGCTL		14
#define SHMAT		21
#define SHMDT		22
#define SHMGET		23
#define SHMCTL		24

asmlinkage long
sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth)
{
	int version;

	version = call >> 16; /* hack for backward compatibility */
	call &= 0xffff;

	switch (call) {
	      case SEMTIMEDOP:
		if (fifth)
			return compat_sys_semtimedop(first, compat_ptr(ptr),
				second, compat_ptr(fifth));
		/* else fall through for normal semop() */
	      case SEMOP:
		/* struct sembuf is the same on 32 and 64bit :)) */
		return sys_semtimedop(first, compat_ptr(ptr), second,
				      NULL);
	      case SEMGET:
		return sys_semget(first, second, third);
	      case SEMCTL:
		return compat_sys_semctl(first, second, third, compat_ptr(ptr));

	      case MSGSND:
		return compat_sys_msgsnd(first, second, third, compat_ptr(ptr));
	      case MSGRCV:
		return compat_sys_msgrcv(first, second, fifth, third, version, compat_ptr(ptr));
	      case MSGGET:
		return sys_msgget((key_t) first, second);
	      case MSGCTL:
		return compat_sys_msgctl(first, second, compat_ptr(ptr));

	      case SHMAT:
		return compat_sys_shmat(first, second, third, version, compat_ptr(ptr));
		break;
	      case SHMDT:
		return sys_shmdt(compat_ptr(ptr));
	      case SHMGET:
		return sys_shmget(first, (unsigned)second, third);
	      case SHMCTL:
		return compat_sys_shmctl(first, second, compat_ptr(ptr));

	      default:
		return -ENOSYS;
	}
	return -EINVAL;
}

asmlinkage long
compat_sys_wait4 (compat_pid_t pid, compat_uint_t * stat_addr, int options,
		 struct compat_rusage *ru);

asmlinkage long
sys32_waitpid (int pid, unsigned int *stat_addr, int options)
{
	return compat_sys_wait4(pid, stat_addr, options, NULL);
}

static unsigned int
ia32_peek (struct task_struct *child, unsigned long addr, unsigned int *val)
{
	size_t copied;
	unsigned int ret;

	copied = access_process_vm(child, addr, val, sizeof(*val), 0);
	return (copied != sizeof(ret)) ? -EIO : 0;
}

static unsigned int
ia32_poke (struct task_struct *child, unsigned long addr, unsigned int val)
{

	if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val))
		return -EIO;
	return 0;
}

/*
 *  The order in which registers are stored in the ptrace regs structure
 */
#define PT_EBX	0
#define PT_ECX	1
#define PT_EDX	2
#define PT_ESI	3
#define PT_EDI	4
#define PT_EBP	5
#define PT_EAX	6
#define PT_DS	7
#define PT_ES	8
#define PT_FS	9
#define PT_GS	10
#define PT_ORIG_EAX 11
#define PT_EIP	12
#define PT_CS	13
#define PT_EFL	14
#define PT_UESP	15
#define PT_SS	16

static unsigned int
getreg (struct task_struct *child, int regno)
{
	struct pt_regs *child_regs;

	child_regs = ia64_task_regs(child);
	switch (regno / sizeof(int)) {
	      case PT_EBX: return child_regs->r11;
	      case PT_ECX: return child_regs->r9;
	      case PT_EDX: return child_regs->r10;
	      case PT_ESI: return child_regs->r14;
	      case PT_EDI: return child_regs->r15;
	      case PT_EBP: return child_regs->r13;
	      case PT_EAX: return child_regs->r8;
	      case PT_ORIG_EAX: return child_regs->r1; /* see dispatch_to_ia32_handler() */
	      case PT_EIP: return child_regs->cr_iip;
	      case PT_UESP: return child_regs->r12;
	      case PT_EFL: return child->thread.eflag;
	      case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS:
		return __USER_DS;
	      case PT_CS: return __USER_CS;
	      default:
		printk(KERN_ERR "ia32.getreg(): unknown register %d\n", regno);
		break;
	}
	return 0;
}

static void
putreg (struct task_struct *child, int regno, unsigned int value)
{
	struct pt_regs *child_regs;

	child_regs = ia64_task_regs(child);
	switch (regno / sizeof(int)) {
	      case PT_EBX: child_regs->r11 = value; break;
	      case PT_ECX: child_regs->r9 = value; break;
	      case PT_EDX: child_regs->r10 = value; break;
	      case PT_ESI: child_regs->r14 = value; break;
	      case PT_EDI: child_regs->r15 = value; break;
	      case PT_EBP: child_regs->r13 = value; break;
	      case PT_EAX: child_regs->r8 = value; break;
	      case PT_ORIG_EAX: child_regs->r1 = value; break;
	      case PT_EIP: child_regs->cr_iip = value; break;
	      case PT_UESP: child_regs->r12 = value; break;
	      case PT_EFL: child->thread.eflag = value; break;
	      case PT_DS: case PT_ES: case PT_FS: case PT_GS: case PT_SS:
		if (value != __USER_DS)
			printk(KERN_ERR
			       "ia32.putreg: attempt to set invalid segment register %d = %x\n",
			       regno, value);
		break;
	      case PT_CS:
		if (value != __USER_CS)
			printk(KERN_ERR
			       "ia32.putreg: attempt to to set invalid segment register %d = %x\n",
			       regno, value);
		break;
	      default:
		printk(KERN_ERR "ia32.putreg: unknown register %d\n", regno);
		break;
	}
}

static void
put_fpreg (int regno, struct _fpreg_ia32 __user *reg, struct pt_regs *ptp,
	   struct switch_stack *swp, int tos)
{
	struct _fpreg_ia32 *f;
	char buf[32];

	f = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
	if ((regno += tos) >= 8)
		regno -= 8;
	switch (regno) {
	      case 0:
		ia64f2ia32f(f, &ptp->f8);
		break;
	      case 1:
		ia64f2ia32f(f, &ptp->f9);
		break;
	      case 2:
		ia64f2ia32f(f, &ptp->f10);
		break;
	      case 3:
		ia64f2ia32f(f, &ptp->f11);
		break;
	      case 4:
	      case 5:
	      case 6:
	      case 7:
		ia64f2ia32f(f, &swp->f12 + (regno - 4));
		break;
	}
	copy_to_user(reg, f, sizeof(*reg));
}

static void
get_fpreg (int regno, struct _fpreg_ia32 __user *reg, struct pt_regs *ptp,
	   struct switch_stack *swp, int tos)
{

	if ((regno += tos) >= 8)
		regno -= 8;
	switch (regno) {
	      case 0:
		copy_from_user(&ptp->f8, reg, sizeof(*reg));
		break;
	      case 1:
		copy_from_user(&ptp->f9, reg, sizeof(*reg));
		break;
	      case 2:
		copy_from_user(&ptp->f10, reg, sizeof(*reg));
		break;
	      case 3:
		copy_from_user(&ptp->f11, reg, sizeof(*reg));
		break;
	      case 4:
	      case 5:
	      case 6:
	      case 7:
		copy_from_user(&swp->f12 + (regno - 4), reg, sizeof(*reg));
		break;
	}
	return;
}

int
save_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct __user *save)
{
	struct switch_stack *swp;
	struct pt_regs *ptp;
	int i, tos;

	if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
		return -EFAULT;

	__put_user(tsk->thread.fcr & 0xffff, &save->cwd);
	__put_user(tsk->thread.fsr & 0xffff, &save->swd);
	__put_user((tsk->thread.fsr>>16) & 0xffff, &save->twd);
	__put_user(tsk->thread.fir, &save->fip);
	__put_user((tsk->thread.fir>>32) & 0xffff, &save->fcs);
	__put_user(tsk->thread.fdr, &save->foo);
	__put_user((tsk->thread.fdr>>32) & 0xffff, &save->fos);

	/*
	 *  Stack frames start with 16-bytes of temp space
	 */
	swp = (struct switch_stack *)(tsk->thread.ksp + 16);
	ptp = ia64_task_regs(tsk);
	tos = (tsk->thread.fsr >> 11) & 7;
	for (i = 0; i < 8; i++)
		put_fpreg(i, &save->st_space[i], ptp, swp, tos);
	return 0;
}

static int
restore_ia32_fpstate (struct task_struct *tsk, struct ia32_user_i387_struct __user *save)
{
	struct switch_stack *swp;
	struct pt_regs *ptp;
	int i, tos;
	unsigned int fsrlo, fsrhi, num32;

	if (!access_ok(VERIFY_READ, save, sizeof(*save)))
		return(-EFAULT);

	__get_user(num32, (unsigned int __user *)&save->cwd);
	tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f);
	__get_user(fsrlo, (unsigned int __user *)&save->swd);
	__get_user(fsrhi, (unsigned int __user *)&save->twd);
	num32 = (fsrhi << 16) | fsrlo;
	tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32;
	__get_user(num32, (unsigned int __user *)&save->fip);
	tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32;
	__get_user(num32, (unsigned int __user *)&save->foo);
	tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32;

	/*
	 *  Stack frames start with 16-bytes of temp space
	 */
	swp = (struct switch_stack *)(tsk->thread.ksp + 16);
	ptp = ia64_task_regs(tsk);
	tos = (tsk->thread.fsr >> 11) & 7;
	for (i = 0; i < 8; i++)
		get_fpreg(i, &save->st_space[i], ptp, swp, tos);
	return 0;
}

int
save_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __user *save)
{
	struct switch_stack *swp;
	struct pt_regs *ptp;
	int i, tos;
	unsigned long mxcsr=0;
	unsigned long num128[2];

	if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
		return -EFAULT;

	__put_user(tsk->thread.fcr & 0xffff, &save->cwd);
	__put_user(tsk->thread.fsr & 0xffff, &save->swd);
	__put_user((tsk->thread.fsr>>16) & 0xffff, &save->twd);
	__put_user(tsk->thread.fir, &save->fip);
	__put_user((tsk->thread.fir>>32) & 0xffff, &save->fcs);
	__put_user(tsk->thread.fdr, &save->foo);
	__put_user((tsk->thread.fdr>>32) & 0xffff, &save->fos);

        /*
         *  Stack frames start with 16-bytes of temp space
         */
        swp = (struct switch_stack *)(tsk->thread.ksp + 16);
        ptp = ia64_task_regs(tsk);
	tos = (tsk->thread.fsr >> 11) & 7;
        for (i = 0; i < 8; i++)
		put_fpreg(i, (struct _fpreg_ia32 __user *)&save->st_space[4*i], ptp, swp, tos);

	mxcsr = ((tsk->thread.fcr>>32) & 0xff80) | ((tsk->thread.fsr>>32) & 0x3f);
	__put_user(mxcsr & 0xffff, &save->mxcsr);
	for (i = 0; i < 8; i++) {
		memcpy(&(num128[0]), &(swp->f16) + i*2, sizeof(unsigned long));
		memcpy(&(num128[1]), &(swp->f17) + i*2, sizeof(unsigned long));
		copy_to_user(&save->xmm_space[0] + 4*i, num128, sizeof(struct _xmmreg_ia32));
	}
	return 0;
}

static int
restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __user *save)
{
	struct switch_stack *swp;
	struct pt_regs *ptp;
	int i, tos;
	unsigned int fsrlo, fsrhi, num32;
	int mxcsr;
	unsigned long num64;
	unsigned long num128[2];

	if (!access_ok(VERIFY_READ, save, sizeof(*save)))
		return(-EFAULT);

	__get_user(num32, (unsigned int __user *)&save->cwd);
	tsk->thread.fcr = (tsk->thread.fcr & (~0x1f3f)) | (num32 & 0x1f3f);
	__get_user(fsrlo, (unsigned int __user *)&save->swd);
	__get_user(fsrhi, (unsigned int __user *)&save->twd);
	num32 = (fsrhi << 16) | fsrlo;
	tsk->thread.fsr = (tsk->thread.fsr & (~0xffffffff)) | num32;
	__get_user(num32, (unsigned int __user *)&save->fip);
	tsk->thread.fir = (tsk->thread.fir & (~0xffffffff)) | num32;
	__get_user(num32, (unsigned int __user *)&save->foo);
	tsk->thread.fdr = (tsk->thread.fdr & (~0xffffffff)) | num32;

	/*
	 *  Stack frames start with 16-bytes of temp space
	 */
	swp = (struct switch_stack *)(tsk->thread.ksp + 16);
	ptp = ia64_task_regs(tsk);
	tos = (tsk->thread.fsr >> 11) & 7;
	for (i = 0; i < 8; i++)
	get_fpreg(i, (struct _fpreg_ia32 __user *)&save->st_space[4*i], ptp, swp, tos);

	__get_user(mxcsr, (unsigned int __user *)&save->mxcsr);
	num64 = mxcsr & 0xff10;
	tsk->thread.fcr = (tsk->thread.fcr & (~0xff1000000000UL)) | (num64<<32);
	num64 = mxcsr & 0x3f;
	tsk->thread.fsr = (tsk->thread.fsr & (~0x3f00000000UL)) | (num64<<32);

	for (i = 0; i < 8; i++) {
		copy_from_user(num128, &save->xmm_space[0] + 4*i, sizeof(struct _xmmreg_ia32));
		memcpy(&(swp->f16) + i*2, &(num128[0]), sizeof(unsigned long));
		memcpy(&(swp->f17) + i*2, &(num128[1]), sizeof(unsigned long));
	}
	return 0;
}

asmlinkage long
sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data)
{
	struct task_struct *child;
	unsigned int value, tmp;
	long i, ret;

	lock_kernel();
	if (request == PTRACE_TRACEME) {
		ret = sys_ptrace(request, pid, addr, data);
		goto out;
	}

	ret = -ESRCH;
	read_lock(&tasklist_lock);
	child = find_task_by_pid(pid);
	if (child)
		get_task_struct(child);
	read_unlock(&tasklist_lock);
	if (!child)
		goto out;
	ret = -EPERM;
	if (pid == 1)		/* no messing around with init! */
		goto out_tsk;

	if (request == PTRACE_ATTACH) {
		ret = sys_ptrace(request, pid, addr, data);
		goto out_tsk;
	}

	ret = ptrace_check_attach(child, request == PTRACE_KILL);
	if (ret < 0)
		goto out_tsk;

	switch (request) {
	      case PTRACE_PEEKTEXT:
	      case PTRACE_PEEKDATA:	/* read word at location addr */
		ret = ia32_peek(child, addr, &value);
		if (ret == 0)
			ret = put_user(value, (unsigned int __user *) compat_ptr(data));
		else
			ret = -EIO;
		goto out_tsk;

	      case PTRACE_POKETEXT:
	      case PTRACE_POKEDATA:	/* write the word at location addr */
		ret = ia32_poke(child, addr, data);
		goto out_tsk;

	      case PTRACE_PEEKUSR:	/* read word at addr in USER area */
		ret = -EIO;
		if ((addr & 3) || addr > 17*sizeof(int))
			break;

		tmp = getreg(child, addr);
		if (!put_user(tmp, (unsigned int __user *) compat_ptr(data)))
			ret = 0;
		break;

	      case PTRACE_POKEUSR:	/* write word at addr in USER area */
		ret = -EIO;
		if ((addr & 3) || addr > 17*sizeof(int))
			break;

		putreg(child, addr, data);
		ret = 0;
		break;

	      case IA32_PTRACE_GETREGS:
		if (!access_ok(VERIFY_WRITE, compat_ptr(data), 17*sizeof(int))) {
			ret = -EIO;
			break;
		}
		for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) {
			put_user(getreg(child, i), (unsigned int __user *) compat_ptr(data));
			data += sizeof(int);
		}
		ret = 0;
		break;

	      case IA32_PTRACE_SETREGS:
		if (!access_ok(VERIFY_READ, compat_ptr(data), 17*sizeof(int))) {
			ret = -EIO;
			break;
		}
		for (i = 0; i < (int) (17*sizeof(int)); i += sizeof(int) ) {
			get_user(tmp, (unsigned int __user *) compat_ptr(data));
			putreg(child, i, tmp);
			data += sizeof(int);
		}
		ret = 0;
		break;

	      case IA32_PTRACE_GETFPREGS:
		ret = save_ia32_fpstate(child, (struct ia32_user_i387_struct __user *)
					compat_ptr(data));
		break;

	      case IA32_PTRACE_GETFPXREGS:
		ret = save_ia32_fpxstate(child, (struct ia32_user_fxsr_struct __user *)
					 compat_ptr(data));
		break;

	      case IA32_PTRACE_SETFPREGS:
		ret = restore_ia32_fpstate(child, (struct ia32_user_i387_struct __user *)
					   compat_ptr(data));
		break;

	      case IA32_PTRACE_SETFPXREGS:
		ret = restore_ia32_fpxstate(child, (struct ia32_user_fxsr_struct __user *)
					    compat_ptr(data));
		break;

	      case PTRACE_GETEVENTMSG:   
		ret = put_user(child->ptrace_message, (unsigned int __user *) compat_ptr(data));
		break;

	      case PTRACE_SYSCALL:	/* continue, stop after next syscall */
	      case PTRACE_CONT:		/* restart after signal. */
	      case PTRACE_KILL:
	      case PTRACE_SINGLESTEP:	/* execute chile for one instruction */
	      case PTRACE_DETACH:	/* detach a process */
		ret = sys_ptrace(request, pid, addr, data);
		break;

	      default:
		ret = ptrace_request(child, request, addr, data);
		break;

	}
  out_tsk:
	put_task_struct(child);
  out:
	unlock_kernel();
	return ret;
}

typedef struct {
	unsigned int	ss_sp;
	unsigned int	ss_flags;
	unsigned int	ss_size;
} ia32_stack_t;

asmlinkage long
sys32_sigaltstack (ia32_stack_t __user *uss32, ia32_stack_t __user *uoss32,
		   long arg2, long arg3, long arg4, long arg5, long arg6,
		   long arg7, struct pt_regs pt)
{
	stack_t uss, uoss;
	ia32_stack_t buf32;
	int ret;
	mm_segment_t old_fs = get_fs();

	if (uss32) {
		if (copy_from_user(&buf32, uss32, sizeof(ia32_stack_t)))
			return -EFAULT;
		uss.ss_sp = (void __user *) (long) buf32.ss_sp;
		uss.ss_flags = buf32.ss_flags;
		/* MINSIGSTKSZ is different for ia32 vs ia64. We lie here to pass the
	           check and set it to the user requested value later */
		if ((buf32.ss_flags != SS_DISABLE) && (buf32.ss_size < MINSIGSTKSZ_IA32)) {
			ret = -ENOMEM;
			goto out;
		}
		uss.ss_size = MINSIGSTKSZ;
	}
	set_fs(KERNEL_DS);
	ret = do_sigaltstack(uss32 ? (stack_t __user *) &uss : NULL,
			     (stack_t __user *) &uoss, pt.r12);
 	current->sas_ss_size = buf32.ss_size;
	set_fs(old_fs);
out:
	if (ret < 0)
		return(ret);
	if (uoss32) {
		buf32.ss_sp = (long __user) uoss.ss_sp;
		buf32.ss_flags = uoss.ss_flags;
		buf32.ss_size = uoss.ss_size;
		if (copy_to_user(uoss32, &buf32, sizeof(ia32_stack_t)))
			return -EFAULT;
	}
	return ret;
}

asmlinkage int
sys32_pause (void)
{
	current->state = TASK_INTERRUPTIBLE;
	schedule();
	return -ERESTARTNOHAND;
}

asmlinkage int
sys32_msync (unsigned int start, unsigned int len, int flags)
{
	unsigned int addr;

	if (OFFSET4K(start))
		return -EINVAL;
	addr = PAGE_START(start);
	return sys_msync(addr, len + (start - addr), flags);
}

struct sysctl32 {
	unsigned int	name;
	int		nlen;
	unsigned int	oldval;
	unsigned int	oldlenp;
	unsigned int	newval;
	unsigned int	newlen;
	unsigned int	__unused[4];
};

#ifdef CONFIG_SYSCTL
asmlinkage long
sys32_sysctl (struct sysctl32 __user *args)
{
	struct sysctl32 a32;
	mm_segment_t old_fs = get_fs ();
	void __user *oldvalp, *newvalp;
	size_t oldlen;
	int __user *namep;
	long ret;

	if (copy_from_user(&a32, args, sizeof(a32)))
		return -EFAULT;

	/*
	 * We need to pre-validate these because we have to disable address checking
	 * before calling do_sysctl() because of OLDLEN but we can't run the risk of the
	 * user specifying bad addresses here.  Well, since we're dealing with 32 bit
	 * addresses, we KNOW that access_ok() will always succeed, so this is an
	 * expensive NOP, but so what...
	 */
	namep = (int __user *) compat_ptr(a32.name);
	oldvalp = compat_ptr(a32.oldval);
	newvalp = compat_ptr(a32.newval);

	if ((oldvalp && get_user(oldlen, (int __user *) compat_ptr(a32.oldlenp)))
	    || !access_ok(VERIFY_WRITE, namep, 0)
	    || !access_ok(VERIFY_WRITE, oldvalp, 0)
	    || !access_ok(VERIFY_WRITE, newvalp, 0))
		return -EFAULT;

	set_fs(KERNEL_DS);
	lock_kernel();
	ret = do_sysctl(namep, a32.nlen, oldvalp, (size_t __user *) &oldlen,
			newvalp, (size_t) a32.newlen);
	unlock_kernel();
	set_fs(old_fs);

	if (oldvalp && put_user (oldlen, (int __user *) compat_ptr(a32.oldlenp)))
		return -EFAULT;

	return ret;
}
#endif

asmlinkage long
sys32_newuname (struct new_utsname __user *name)
{
	int ret = sys_newuname(name);

	if (!ret)
		if (copy_to_user(name->machine, "i686\0\0\0", 8))
			ret = -EFAULT;
	return ret;
}

asmlinkage long
sys32_getresuid16 (u16 __user *ruid, u16 __user *euid, u16 __user *suid)
{
	uid_t a, b, c;
	int ret;
	mm_segment_t old_fs = get_fs();

	set_fs(KERNEL_DS);
	ret = sys_getresuid((uid_t __user *) &a, (uid_t __user *) &b, (uid_t __user *) &c);
	set_fs(old_fs);

	if (put_user(a, ruid) || put_user(b, euid) || put_user(c, suid))
		return -EFAULT;
	return ret;
}

asmlinkage long
sys32_getresgid16 (u16 __user *rgid, u16 __user *egid, u16 __user *sgid)
{
	gid_t a, b, c;
	int ret;
	mm_segment_t old_fs = get_fs();

	set_fs(KERNEL_DS);
	ret = sys_getresgid((gid_t __user *) &a, (gid_t __user *) &b, (gid_t __user *) &c);
	set_fs(old_fs);

	if (ret)
		return ret;

	return put_user(a, rgid) | put_user(b, egid) | put_user(c, sgid);
}

asmlinkage long
sys32_lseek (unsigned int fd, int offset, unsigned int whence)
{
	/* Sign-extension of "offset" is important here... */
	return sys_lseek(fd, offset, whence);
}

static int
groups16_to_user(short __user *grouplist, struct group_info *group_info)
{
	int i;
	short group;

	for (i = 0; i < group_info->ngroups; i++) {
		group = (short)GROUP_AT(group_info, i);
		if (put_user(group, grouplist+i))
			return -EFAULT;
	}

	return 0;
}

static int
groups16_from_user(struct group_info *group_info, short __user *grouplist)
{
	int i;
	short group;

	for (i = 0; i < group_info->ngroups; i++) {
		if (get_user(group, grouplist+i))
			return  -EFAULT;
		GROUP_AT(group_info, i) = (gid_t)group;
	}

	return 0;
}

asmlinkage long
sys32_getgroups16 (int gidsetsize, short __user *grouplist)
{
	int i;

	if (gidsetsize < 0)
		return -EINVAL;

	get_group_info(current->group_info);
	i = current->group_info->ngroups;
	if (gidsetsize) {
		if (i > gidsetsize) {
			i = -EINVAL;
			goto out;
		}
		if (groups16_to_user(grouplist, current->group_info)) {
			i = -EFAULT;
			goto out;
		}
	}
out:
	put_group_info(current->group_info);
	return i;
}

asmlinkage long
sys32_setgroups16 (int gidsetsize, short __user *grouplist)
{
	struct group_info *group_info;
	int retval;

	if (!capable(CAP_SETGID))
		return -EPERM;
	if ((unsigned)gidsetsize > NGROUPS_MAX)
		return -EINVAL;

	group_info = groups_alloc(gidsetsize);
	if (!group_info)
		return -ENOMEM;
	retval = groups16_from_user(group_info, grouplist);
	if (retval) {
		put_group_info(group_info);
		return retval;
	}

	retval = set_current_groups(group_info);
	put_group_info(group_info);

	return retval;
}

asmlinkage long
sys32_truncate64 (unsigned int path, unsigned int len_lo, unsigned int len_hi)
{
	return sys_truncate(compat_ptr(path), ((unsigned long) len_hi << 32) | len_lo);
}

asmlinkage long
sys32_ftruncate64 (int fd, unsigned int len_lo, unsigned int len_hi)
{
	return sys_ftruncate(fd, ((unsigned long) len_hi << 32) | len_lo);
}

static int
putstat64 (struct stat64 __user *ubuf, struct kstat *kbuf)
{
	int err;
	u64 hdev;

	if (clear_user(ubuf, sizeof(*ubuf)))
		return -EFAULT;

	hdev = huge_encode_dev(kbuf->dev);
	err  = __put_user(hdev, (u32 __user*)&ubuf->st_dev);
	err |= __put_user(hdev >> 32, ((u32 __user*)&ubuf->st_dev) + 1);
	err |= __put_user(kbuf->ino, &ubuf->__st_ino);
	err |= __put_user(kbuf->ino, &ubuf->st_ino_lo);
	err |= __put_user(kbuf->ino >> 32, &ubuf->st_ino_hi);
	err |= __put_user(kbuf->mode, &ubuf->st_mode);
	err |= __put_user(kbuf->nlink, &ubuf->st_nlink);
	err |= __put_user(kbuf->uid, &ubuf->st_uid);
	err |= __put_user(kbuf->gid, &ubuf->st_gid);
	hdev = huge_encode_dev(kbuf->rdev);
	err  = __put_user(hdev, (u32 __user*)&ubuf->st_rdev);
	err |= __put_user(hdev >> 32, ((u32 __user*)&ubuf->st_rdev) + 1);
	err |= __put_user(kbuf->size, &ubuf->st_size_lo);
	err |= __put_user((kbuf->size >> 32), &ubuf->st_size_hi);
	err |= __put_user(kbuf->atime.tv_sec, &ubuf->st_atime);
	err |= __put_user(kbuf->atime.tv_nsec, &ubuf->st_atime_nsec);
	err |= __put_user(kbuf->mtime.tv_sec, &ubuf->st_mtime);
	err |= __put_user(kbuf->mtime.tv_nsec, &ubuf->st_mtime_nsec);
	err |= __put_user(kbuf->ctime.tv_sec, &ubuf->st_ctime);
	err |= __put_user(kbuf->ctime.tv_nsec, &ubuf->st_ctime_nsec);
	err |= __put_user(kbuf->blksize, &ubuf->st_blksize);
	err |= __put_user(kbuf->blocks, &ubuf->st_blocks);
	return err;
}

asmlinkage long
sys32_stat64 (char __user *filename, struct stat64 __user *statbuf)
{
	struct kstat s;
	long ret = vfs_stat(filename, &s);
	if (!ret)
		ret = putstat64(statbuf, &s);
	return ret;
}

asmlinkage long
sys32_lstat64 (char __user *filename, struct stat64 __user *statbuf)
{
	struct kstat s;
	long ret = vfs_lstat(filename, &s);
	if (!ret)
		ret = putstat64(statbuf, &s);
	return ret;
}

asmlinkage long
sys32_fstat64 (unsigned int fd, struct stat64 __user *statbuf)
{
	struct kstat s;
	long ret = vfs_fstat(fd, &s);
	if (!ret)
		ret = putstat64(statbuf, &s);
	return ret;
}

struct sysinfo32 {
	s32 uptime;
	u32 loads[3];
	u32 totalram;
	u32 freeram;
	u32 sharedram;
	u32 bufferram;
	u32 totalswap;
	u32 freeswap;
	u16 procs;
	u16 pad;
	u32 totalhigh;
	u32 freehigh;
	u32 mem_unit;
	char _f[8];
};

asmlinkage long
sys32_sysinfo (struct sysinfo32 __user *info)
{
	struct sysinfo s;
	long ret, err;
	int bitcount = 0;
	mm_segment_t old_fs = get_fs();

	set_fs(KERNEL_DS);
	ret = sys_sysinfo((struct sysinfo __user *) &s);
	set_fs(old_fs);
	/* Check to see if any memory value is too large for 32-bit and
	 * scale down if needed.
	 */
	if ((s.totalram >> 32) || (s.totalswap >> 32)) {
		while (s.mem_unit < PAGE_SIZE) {
			s.mem_unit <<= 1;
			bitcount++;
		}
		s.totalram >>= bitcount;
		s.freeram >>= bitcount;
		s.sharedram >>= bitcount;
		s.bufferram >>= bitcount;
		s.totalswap >>= bitcount;
		s.freeswap >>= bitcount;
		s.totalhigh >>= bitcount;
		s.freehigh >>= bitcount;
	}

	if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
		return -EFAULT;

	err  = __put_user(s.uptime, &info->uptime);
	err |= __put_user(s.loads[0], &info->loads[0]);
	err |= __put_user(s.loads[1], &info->loads[1]);
	err |= __put_user(s.loads[2], &info->loads[2]);
	err |= __put_user(s.totalram, &info->totalram);
	err |= __put_user(s.freeram, &info->freeram);
	err |= __put_user(s.sharedram, &info->sharedram);
	err |= __put_user(s.bufferram, &info->bufferram);
	err |= __put_user(s.totalswap, &info->totalswap);
	err |= __put_user(s.freeswap, &info->freeswap);
	err |= __put_user(s.procs, &info->procs);
	err |= __put_user (s.totalhigh, &info->totalhigh);
	err |= __put_user (s.freehigh, &info->freehigh);
	err |= __put_user (s.mem_unit, &info->mem_unit);
	if (err)
		return -EFAULT;
	return ret;
}

asmlinkage long
sys32_sched_rr_get_interval (pid_t pid, struct compat_timespec __user *interval)
{
	mm_segment_t old_fs = get_fs();
	struct timespec t;
	long ret;

	set_fs(KERNEL_DS);
	ret = sys_sched_rr_get_interval(pid, (struct timespec __user *) &t);
	set_fs(old_fs);
	if (put_compat_timespec(&t, interval))
		return -EFAULT;
	return ret;
}

asmlinkage long
sys32_pread (unsigned int fd, void __user *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
{
	return sys_pread64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
}

asmlinkage long
sys32_pwrite (unsigned int fd, void __user *buf, unsigned int count, u32 pos_lo, u32 pos_hi)
{
	return sys_pwrite64(fd, buf, count, ((unsigned long) pos_hi << 32) | pos_lo);
}

asmlinkage long
sys32_sendfile (int out_fd, int in_fd, int __user *offset, unsigned int count)
{
	mm_segment_t old_fs = get_fs();
	long ret;
	off_t of;

	if (offset && get_user(of, offset))
		return -EFAULT;

	set_fs(KERNEL_DS);
	ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *) &of : NULL, count);
	set_fs(old_fs);

	if (offset && put_user(of, offset))
		return -EFAULT;

	return ret;
}

asmlinkage long
sys32_personality (unsigned int personality)
{
	long ret;

	if (current->personality == PER_LINUX32 && personality == PER_LINUX)
		personality = PER_LINUX32;
	ret = sys_personality(personality);
	if (ret == PER_LINUX32)
		ret = PER_LINUX;
	return ret;
}

asmlinkage unsigned long
sys32_brk (unsigned int brk)
{
	unsigned long ret, obrk;
	struct mm_struct *mm = current->mm;

	obrk = mm->brk;
	ret = sys_brk(brk);
	if (ret < obrk)
		clear_user(compat_ptr(ret), PAGE_ALIGN(ret) - ret);
	return ret;
}

/* Structure for ia32 emulation on ia64 */
struct epoll_event32
{
	u32 events;
	u32 data[2];
};

asmlinkage long
sys32_epoll_ctl(int epfd, int op, int fd, struct epoll_event32 __user *event)
{
	mm_segment_t old_fs = get_fs();
	struct epoll_event event64;
	int error;
	u32 data_halfword;

	if (!access_ok(VERIFY_READ, event, sizeof(struct epoll_event32)))
		return -EFAULT;

	__get_user(event64.events, &event->events);
	__get_user(data_halfword, &event->data[0]);
	event64.data = data_halfword;
	__get_user(data_halfword, &event->data[1]);
 	event64.data |= (u64)data_halfword << 32;

	set_fs(KERNEL_DS);
	error = sys_epoll_ctl(epfd, op, fd, (struct epoll_event __user *) &event64);
	set_fs(old_fs);

	return error;
}

asmlinkage long
sys32_epoll_wait(int epfd, struct epoll_event32 __user * events, int maxevents,
		 int timeout)
{
	struct epoll_event *events64 = NULL;
	mm_segment_t old_fs = get_fs();
	int numevents, size;
	int evt_idx;
	int do_free_pages = 0;

	if (maxevents <= 0) {
		return -EINVAL;
	}

	/* Verify that the area passed by the user is writeable */
	if (!access_ok(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event32)))
		return -EFAULT;

	/*
 	 * Allocate space for the intermediate copy.  If the space needed
	 * is large enough to cause kmalloc to fail, then try again with
	 * __get_free_pages.
	 */
	size = maxevents * sizeof(struct epoll_event);
	events64 = kmalloc(size, GFP_KERNEL);
	if (events64 == NULL) {
		events64 = (struct epoll_event *)
				__get_free_pages(GFP_KERNEL, get_order(size));
		if (events64 == NULL)
			return -ENOMEM;
		do_free_pages = 1;
	}

	/* Do the system call */
	set_fs(KERNEL_DS); /* copy_to/from_user should work on kernel mem*/
	numevents = sys_epoll_wait(epfd, (struct epoll_event __user *) events64,
				   maxevents, timeout);
	set_fs(old_fs);

	/* Don't modify userspace memory if we're returning an error */
	if (numevents > 0) {
		/* Translate the 64-bit structures back into the 32-bit
		   structures */
		for (evt_idx = 0; evt_idx < numevents; evt_idx++) {
			__put_user(events64[evt_idx].events,
				   &events[evt_idx].events);
			__put_user((u32)events64[evt_idx].data,
				   &events[evt_idx].data[0]);
			__put_user((u32)(events64[evt_idx].data >> 32),
				   &events[evt_idx].data[1]);
		}
	}

	if (do_free_pages)
		free_pages((unsigned long) events64, get_order(size));
	else
		kfree(events64);
	return numevents;
}

/*
 * Get a yet unused TLS descriptor index.
 */
static int
get_free_idx (void)
{
	struct thread_struct *t = &current->thread;
	int idx;

	for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
		if (desc_empty(t->tls_array + idx))
			return idx + GDT_ENTRY_TLS_MIN;
	return -ESRCH;
}

/*
 * Set a given TLS descriptor:
 */
asmlinkage int
sys32_set_thread_area (struct ia32_user_desc __user *u_info)
{
	struct thread_struct *t = &current->thread;
	struct ia32_user_desc info;
	struct desc_struct *desc;
	int cpu, idx;

	if (copy_from_user(&info, u_info, sizeof(info)))
		return -EFAULT;
	idx = info.entry_number;

	/*
	 * index -1 means the kernel should try to find and allocate an empty descriptor:
	 */
	if (idx == -1) {
		idx = get_free_idx();
		if (idx < 0)
			return idx;
		if (put_user(idx, &u_info->entry_number))
			return -EFAULT;
	}

	if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
		return -EINVAL;

	desc = t->tls_array + idx - GDT_ENTRY_TLS_MIN;

	cpu = smp_processor_id();

	if (LDT_empty(&info)) {
		desc->a = 0;
		desc->b = 0;
	} else {
		desc->a = LDT_entry_a(&info);
		desc->b = LDT_entry_b(&info);
	}
	load_TLS(t, cpu);
	return 0;
}

/*
 * Get the current Thread-Local Storage area:
 */

#define GET_BASE(desc) (			\
	(((desc)->a >> 16) & 0x0000ffff) |	\
	(((desc)->b << 16) & 0x00ff0000) |	\
	( (desc)->b        & 0xff000000)   )

#define GET_LIMIT(desc) (			\
	((desc)->a & 0x0ffff) |			\
	 ((desc)->b & 0xf0000) )

#define GET_32BIT(desc)		(((desc)->b >> 22) & 1)
#define GET_CONTENTS(desc)	(((desc)->b >> 10) & 3)
#define GET_WRITABLE(desc)	(((desc)->b >>  9) & 1)
#define GET_LIMIT_PAGES(desc)	(((desc)->b >> 23) & 1)
#define GET_PRESENT(desc)	(((desc)->b >> 15) & 1)
#define GET_USEABLE(desc)	(((desc)->b >> 20) & 1)

asmlinkage int
sys32_get_thread_area (struct ia32_user_desc __user *u_info)
{
	struct ia32_user_desc info;
	struct desc_struct *desc;
	int idx;

	if (get_user(idx, &u_info->entry_number))
		return -EFAULT;
	if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
		return -EINVAL;

	desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;

	info.entry_number = idx;
	info.base_addr = GET_BASE(desc);
	info.limit = GET_LIMIT(desc);
	info.seg_32bit = GET_32BIT(desc);
	info.contents = GET_CONTENTS(desc);
	info.read_exec_only = !GET_WRITABLE(desc);
	info.limit_in_pages = GET_LIMIT_PAGES(desc);
	info.seg_not_present = !GET_PRESENT(desc);
	info.useable = GET_USEABLE(desc);

	if (copy_to_user(u_info, &info, sizeof(info)))
		return -EFAULT;
	return 0;
}

asmlinkage long
sys32_timer_create(u32 clock, struct compat_sigevent __user *se32, timer_t __user *timer_id)
{
	struct sigevent se;
	mm_segment_t oldfs;
	timer_t t;
	long err;

	if (se32 == NULL)
		return sys_timer_create(clock, NULL, timer_id);

	if (get_compat_sigevent(&se, se32))
		return -EFAULT;

	if (!access_ok(VERIFY_WRITE,timer_id,sizeof(timer_t)))
		return -EFAULT;

	oldfs = get_fs();
	set_fs(KERNEL_DS);
	err = sys_timer_create(clock, (struct sigevent __user *) &se, (timer_t __user *) &t);
	set_fs(oldfs);

	if (!err)
		err = __put_user (t, timer_id);

	return err;
}

long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high, 
			__u32 len_low, __u32 len_high, int advice)
{ 
	return sys_fadvise64_64(fd,
			       (((u64)offset_high)<<32) | offset_low,
			       (((u64)len_high)<<32) | len_low,
			       advice); 
} 

#ifdef	NOTYET  /* UNTESTED FOR IA64 FROM HERE DOWN */

asmlinkage long sys32_setreuid(compat_uid_t ruid, compat_uid_t euid)
{
	uid_t sruid, seuid;

	sruid = (ruid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)ruid);
	seuid = (euid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)euid);
	return sys_setreuid(sruid, seuid);
}

asmlinkage long
sys32_setresuid(compat_uid_t ruid, compat_uid_t euid,
		compat_uid_t suid)
{
	uid_t sruid, seuid, ssuid;

	sruid = (ruid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)ruid);
	seuid = (euid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)euid);
	ssuid = (suid == (compat_uid_t)-1) ? ((uid_t)-1) : ((uid_t)suid);
	return sys_setresuid(sruid, seuid, ssuid);
}

asmlinkage long
sys32_setregid(compat_gid_t rgid, compat_gid_t egid)
{
	gid_t srgid, segid;

	srgid = (rgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)rgid);
	segid = (egid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)egid);
	return sys_setregid(srgid, segid);
}

asmlinkage long
sys32_setresgid(compat_gid_t rgid, compat_gid_t egid,
		compat_gid_t sgid)
{
	gid_t srgid, segid, ssgid;

	srgid = (rgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)rgid);
	segid = (egid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)egid);
	ssgid = (sgid == (compat_gid_t)-1) ? ((gid_t)-1) : ((gid_t)sgid);
	return sys_setresgid(srgid, segid, ssgid);
}

/* Handle adjtimex compatibility. */

struct timex32 {
	u32 modes;
	s32 offset, freq, maxerror, esterror;
	s32 status, constant, precision, tolerance;
	struct compat_timeval time;
	s32 tick;
	s32 ppsfreq, jitter, shift, stabil;
	s32 jitcnt, calcnt, errcnt, stbcnt;
	s32  :32; s32  :32; s32  :32; s32  :32;
	s32  :32; s32  :32; s32  :32; s32  :32;
	s32  :32; s32  :32; s32  :32; s32  :32;
};

extern int do_adjtimex(struct timex *);

asmlinkage long
sys32_adjtimex(struct timex32 *utp)
{
	struct timex txc;
	int ret;

	memset(&txc, 0, sizeof(struct timex));

	if(get_user(txc.modes, &utp->modes) ||
	   __get_user(txc.offset, &utp->offset) ||
	   __get_user(txc.freq, &utp->freq) ||
	   __get_user(txc.maxerror, &utp->maxerror) ||
	   __get_user(txc.esterror, &utp->esterror) ||
	   __get_user(txc.status, &utp->status) ||
	   __get_user(txc.constant, &utp->constant) ||
	   __get_user(txc.precision, &utp->precision) ||
	   __get_user(txc.tolerance, &utp->tolerance) ||
	   __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
	   __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
	   __get_user(txc.tick, &utp->tick) ||
	   __get_user(txc.ppsfreq, &utp->ppsfreq) ||
	   __get_user(txc.jitter, &utp->jitter) ||
	   __get_user(txc.shift, &utp->shift) ||
	   __get_user(txc.stabil, &utp->stabil) ||
	   __get_user(txc.jitcnt, &utp->jitcnt) ||
	   __get_user(txc.calcnt, &utp->calcnt) ||
	   __get_user(txc.errcnt, &utp->errcnt) ||
	   __get_user(txc.stbcnt, &utp->stbcnt))
		return -EFAULT;

	ret = do_adjtimex(&txc);

	if(put_user(txc.modes, &utp->modes) ||
	   __put_user(txc.offset, &utp->offset) ||
	   __put_user(txc.freq, &utp->freq) ||
	   __put_user(txc.maxerror, &utp->maxerror) ||
	   __put_user(txc.esterror, &utp->esterror) ||
	   __put_user(txc.status, &utp->status) ||
	   __put_user(txc.constant, &utp->constant) ||
	   __put_user(txc.precision, &utp->precision) ||
	   __put_user(txc.tolerance, &utp->tolerance) ||
	   __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
	   __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
	   __put_user(txc.tick, &utp->tick) ||
	   __put_user(txc.ppsfreq, &utp->ppsfreq) ||
	   __put_user(txc.jitter, &utp->jitter) ||
	   __put_user(txc.shift, &utp->shift) ||
	   __put_user(txc.stabil, &utp->stabil) ||
	   __put_user(txc.jitcnt, &utp->jitcnt) ||
	   __put_user(txc.calcnt, &utp->calcnt) ||
	   __put_user(txc.errcnt, &utp->errcnt) ||
	   __put_user(txc.stbcnt, &utp->stbcnt))
		ret = -EFAULT;

	return ret;
}
#endif /* NOTYET */
