/*
 * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
 * Licensed under the GPL
 */

#include "linux/stddef.h"
#include "linux/kernel.h"
#include "linux/string.h"
#include "linux/fs.h"
#include "linux/highmem.h"
#include "asm/page.h"
#include "asm/pgtable.h"
#include "asm/uaccess.h"
#include "kern_util.h"
#include "user_util.h"

extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
			     pte_t *pte_out);

static unsigned long maybe_map(unsigned long virt, int is_write)
{
	pte_t pte;
	int err;

	void *phys = um_virt_to_phys(current, virt, &pte);
	int dummy_code;

	if(IS_ERR(phys) || (is_write && !pte_write(pte))){
		err = handle_page_fault(virt, 0, is_write, 1, &dummy_code);
		if(err)
			return(0);
		phys = um_virt_to_phys(current, virt, NULL);
	}
	return((unsigned long) phys);
}

static int do_op(unsigned long addr, int len, int is_write,
		 int (*op)(unsigned long addr, int len, void *arg), void *arg)
{
	struct page *page;
	int n;

	addr = maybe_map(addr, is_write);
	if(addr == -1)
		return(-1);

	page = phys_to_page(addr);
	addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK);
	n = (*op)(addr, len, arg);
	kunmap(page);

	return(n);
}

static void do_buffer_op(void *jmpbuf, void *arg_ptr)
{
	va_list args;
	unsigned long addr;
	int len, is_write, size, remain, n;
	int (*op)(unsigned long, int, void *);
	void *arg;
	int *res;

	/* Some old gccs recognize __va_copy, but not va_copy */
	__va_copy(args, *(va_list *)arg_ptr);
	addr = va_arg(args, unsigned long);
	len = va_arg(args, int);
	is_write = va_arg(args, int);
	op = va_arg(args, void *);
	arg = va_arg(args, void *);
	res = va_arg(args, int *);
	va_end(args);
	size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
	remain = len;

	current->thread.fault_catcher = jmpbuf;
	n = do_op(addr, size, is_write, op, arg);
	if(n != 0){
		*res = (n < 0 ? remain : 0);
		goto out;
	}

	addr += size;
	remain -= size;
	if(remain == 0){
		*res = 0;
		goto out;
	}

	while(addr < ((addr + remain) & PAGE_MASK)){
		n = do_op(addr, PAGE_SIZE, is_write, op, arg);
		if(n != 0){
			*res = (n < 0 ? remain : 0);
			goto out;
		}

		addr += PAGE_SIZE;
		remain -= PAGE_SIZE;
	}
	if(remain == 0){
		*res = 0;
		goto out;
	}

	n = do_op(addr, remain, is_write, op, arg);
	if(n != 0)
		*res = (n < 0 ? remain : 0);
	else *res = 0;
 out:
	current->thread.fault_catcher = NULL;
}

static int buffer_op(unsigned long addr, int len, int is_write,
		     int (*op)(unsigned long addr, int len, void *arg),
		     void *arg)
{
	int faulted, res;

	faulted = setjmp_wrapper(do_buffer_op, addr, len, is_write, op, arg,
				 &res);
	if(!faulted)
		return(res);

	return(addr + len - (unsigned long) current->thread.fault_addr);
}

static int copy_chunk_from_user(unsigned long from, int len, void *arg)
{
	unsigned long *to_ptr = arg, to = *to_ptr;

	memcpy((void *) to, (void *) from, len);
	*to_ptr += len;
	return(0);
}

int copy_from_user_skas(void *to, const void __user *from, int n)
{
	if(segment_eq(get_fs(), KERNEL_DS)){
		memcpy(to, (__force void*)from, n);
		return(0);
	}

	return(access_ok_skas(VERIFY_READ, from, n) ?
	       buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
	       n);
}

static int copy_chunk_to_user(unsigned long to, int len, void *arg)
{
	unsigned long *from_ptr = arg, from = *from_ptr;

	memcpy((void *) to, (void *) from, len);
	*from_ptr += len;
	return(0);
}

int copy_to_user_skas(void __user *to, const void *from, int n)
{
	if(segment_eq(get_fs(), KERNEL_DS)){
		memcpy((__force void*)to, from, n);
		return(0);
	}

	return(access_ok_skas(VERIFY_WRITE, to, n) ?
	       buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
	       n);
}

static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
{
	char **to_ptr = arg, *to = *to_ptr;
	int n;

	strncpy(to, (void *) from, len);
	n = strnlen(to, len);
	*to_ptr += n;

	if(n < len)
	        return(1);
	return(0);
}

int strncpy_from_user_skas(char *dst, const char __user *src, int count)
{
	int n;
	char *ptr = dst;

	if(segment_eq(get_fs(), KERNEL_DS)){
		strncpy(dst, (__force void*)src, count);
		return(strnlen(dst, count));
	}

	if(!access_ok_skas(VERIFY_READ, src, 1))
		return(-EFAULT);

	n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user,
		      &ptr);
	if(n != 0)
		return(-EFAULT);
	return(strnlen(dst, count));
}

static int clear_chunk(unsigned long addr, int len, void *unused)
{
	memset((void *) addr, 0, len);
	return(0);
}

int __clear_user_skas(void __user *mem, int len)
{
	return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL));
}

int clear_user_skas(void __user *mem, int len)
{
	if(segment_eq(get_fs(), KERNEL_DS)){
		memset((__force void*)mem, 0, len);
		return(0);
	}

	return(access_ok_skas(VERIFY_WRITE, mem, len) ?
	       buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len);
}

static int strnlen_chunk(unsigned long str, int len, void *arg)
{
	int *len_ptr = arg, n;

	n = strnlen((void *) str, len);
	*len_ptr += n;

	if(n < len)
		return(1);
	return(0);
}

int strnlen_user_skas(const void __user *str, int len)
{
	int count = 0, n;

	if(segment_eq(get_fs(), KERNEL_DS))
		return(strnlen((__force char*)str, len) + 1);

	n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
	if(n == 0)
		return(count + 1);
	return(-EFAULT);
}

/*
 * Overrides for Emacs so that we follow Linus's tabbing style.
 * Emacs will notice this stuff at the end of the file and automatically
 * adjust the settings for this buffer only.  This must remain at the end
 * of the file.
 * ---------------------------------------------------------------------------
 * Local variables:
 * c-file-style: "linux"
 * End:
 */
