/* Copyright (c) 2009, 2010 The Regents of the University of California
 * Barret Rhoden <brho@cs.berkeley.edu>
 * Andrew Waterman <waterman@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * Functions for working with userspace's address space.  The user_mem ones need
 * to involve some form of pinning (TODO), and that global static needs to go. */

#include <ros/common.h>
#include <arch/uaccess.h>
#include <umem.h>
#include <process.h>
#include <error.h>
#include <kmalloc.h>
#include <assert.h>
#include <pmap.h>
#include <smp.h>

static int string_copy_from_user(char *dst, const char *src)
{
	int error;
	const char *top = src + valid_user_rbytes_from(src);

	for (;; dst++, src++) {
		if (unlikely(src >= top))
			return -EFAULT;
		error = __get_user(dst, src, 1);
		if (unlikely(error))
			return error;
		if (unlikely(!*dst))
			break;
	}

	return 0;
}

static int string_copy_to_user(char *dst, const char *src)
{
	int error;
	char *top = dst + valid_user_rwbytes_from(dst);

	for (;; dst++, src++) {
		if (unlikely(dst >= top))
			return -EFAULT;
		error = __put_user(dst, src, 1);
		if (unlikely(error))
			return error;
		if (unlikely(!*src))
			break;
	}

	return 0;
}

int strcpy_from_user(struct proc *p, char *dst, const char *src)
{
	uintptr_t prev = switch_to(p);
	int error = string_copy_from_user(dst, src);

	switch_back(p, prev);

	return error;
}

int strcpy_to_user(struct proc *p, char *dst, const char *src)
{
	uintptr_t prev = switch_to(p);
	int error = string_copy_to_user(dst, src);

	switch_back(p, prev);

	return error;
}

int memcpy_from_user(struct proc *p, void *dest, const void *va, size_t len)
{
	uintptr_t prev = switch_to(p);
	int error = copy_from_user(dest, va, len);

	switch_back(p, prev);

	return error;
}

int memcpy_to_user(struct proc *p, void *dest, const void *src, size_t len)
{
	uintptr_t prev = switch_to(p);
	int error = copy_to_user(dest, src, len);

	switch_back(p, prev);

	return error;
}

/* Same as above, but sets errno */
int memcpy_from_user_errno(struct proc *p, void *dst, const void *src, int len)
{
	int error = memcpy_from_user(p, dst, src, len);

	if (unlikely(error < 0))
		set_errno(-error);

	return error;
}

/* Same as above, but sets errno */
int memcpy_to_user_errno(struct proc *p, void *dst, const void *src, int len)
{
	int error = memcpy_to_user(p, dst, src, len);

	if (unlikely(error < 0))
		set_errno(-error);

	return error;
}

/* Helpers for FSs that don't care if they copy to the user or the kernel.
 *
 * TODO: (KFOP) Probably shouldn't do this.  Either memcpy directly, or split
 * out the is_user_r(w)addr from copy_{to,from}_user().  Or throw from the fault
 * handler.  Right now, we ignore the ret/errors completely. */
void memcpy_to_safe(void *dst, const void *src, size_t amt)
{
	if (!is_ktask(per_cpu_info[core_id()].cur_kthread))
		memcpy_to_user(current, dst, src, amt);
	else
		memcpy(dst, src, amt);
}

void memcpy_from_safe(void *dst, const void *src, size_t amt)
{
	if (!is_ktask(per_cpu_info[core_id()].cur_kthread))
		memcpy_from_user(current, dst, src, amt);
	else
		memcpy(dst, src, amt);
}

/* Creates a buffer (kmalloc) and safely copies into it from va.  Can return an
 * error code.  Check its response with IS_ERR().  Must be paired with
 * user_memdup_free() if this succeeded. */
void *user_memdup(struct proc *p, const void *va, int len)
{
	void* kva = NULL;
	if (len < 0 || (kva = kmalloc(len, 0)) == NULL)
		return ERR_PTR(-ENOMEM);
	if (memcpy_from_user(p, kva, va, len)) {
		kfree(kva);
		return ERR_PTR(-EFAULT);
	}
	return kva;
}

void *user_memdup_errno(struct proc *p, const void *va, int len)
{
	void *kva = user_memdup(p, va, len);
	if (IS_ERR(kva)) {
		set_errno(-PTR_ERR(kva));
		return NULL;
	}
	return kva;
}

void user_memdup_free(struct proc *p, void *va)
{
	kfree(va);
}

/* Same as memdup, but just does strings, and needs to know the actual strlen.
 * Still needs memdup_free()d.  This will enforce that the string is null
 * terminated.  The parameter strlen does not include the \0, though it can if
 * someone else is playing it safe.  Since strlen() doesn't count the \0, we'll
 * play it safe here. */
char *user_strdup(struct proc *p, const char *u_string, size_t strlen)
{
	char *k_string = user_memdup(p, u_string, strlen + 1);
	if (!IS_ERR(k_string))
		k_string[strlen] = '\0';
	return k_string;
}

/* user_strdup, but this handles the errno.  0 on failure, ptr on success */
char *user_strdup_errno(struct proc *p, const char *u_string, size_t strlen)
{
	void *k_string = user_strdup(p, u_string, strlen);
	if (IS_ERR(k_string)) {
		set_errno(-PTR_ERR(k_string));
		return NULL;
	}
	return k_string;
}

void *kmalloc_errno(int len)
{
	void *kva = NULL;
	if (len < 0 || (kva = kmalloc(len, 0)) == NULL)
		set_errno(ENOMEM);
	return kva;
}

/* Returns true if uva and kva both resolve to the same phys addr.  If uva is
 * unmapped, it will return FALSE.  This is probably what you want, since after
 * all uva isn't kva. */
bool uva_is_kva(struct proc *p, void *uva, void *kva)
{
	struct page *u_page;
	assert(kva);				/* catch bugs */
	/* Check offsets first */
	if (PGOFF(uva) != PGOFF(kva))
		return FALSE;
	/* Check to see if it is the same physical page */
	u_page = page_lookup(p->env_pgdir, uva, 0);
	if (!u_page)
		return FALSE;
	return (kva2page(kva) == u_page) ? TRUE : FALSE;
}

/* Given a proc and a user virtual address, gives us the KVA.  Useful for
 * debugging.  Returns 0 if the page is unmapped (page lookup fails).  This
 * doesn't play nice with Jumbo pages. */
uintptr_t uva2kva(struct proc *p, void *uva, size_t len, int prot)
{
	struct page *u_page;
	uintptr_t offset = PGOFF(uva);
	if (!p)
		return 0;
	if (prot & PROT_WRITE) {
		if (!is_user_rwaddr(uva, len))
			return 0;
	} else {
		if (!is_user_raddr(uva, len))
			return 0;
	}
	u_page = page_lookup(p->env_pgdir, uva, 0);
	if (!u_page)
		return 0;
	return (uintptr_t)page2kva(u_page) + offset;
}

/* Helper, copies a pathname from the process into the kernel.  Returns a string
 * on success, which you must free with free_path.  Returns 0 on failure and
 * sets errno. */
char *copy_in_path(struct proc *p, const char *path, size_t path_l)
{
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	char *t_path;

	/* PATH_MAX includes the \0 */
	if (path_l > PATH_MAX) {
		set_errno(ENAMETOOLONG);
		return 0;
	}
	t_path = user_strdup_errno(p, path, path_l);
	if (!t_path)
		return 0;
	return t_path;
}

/* Helper, frees a path that was allocated with copy_in_path. */
void free_path(struct proc *p, char *t_path)
{
	user_memdup_free(p, t_path);
}
