/* Copyright (c) 2009, 2010 The Regents of the University of California
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * Virtual memory management functions.  Creation, modification, etc, of virtual
 * memory regions (VMRs) as well as mmap(), mprotect(), and munmap().
 *
 * In general, error checking / bounds checks are done in the main function
 * (e.g. mmap()), and the work is done in a do_ function (e.g. do_mmap()).
 * Versions of those functions that are called when the vmr lock is already held
 * begin with __ (e.g. __do_munmap()).
 *
 * Note that if we were called from kern/src/syscall.c, we probably don't have
 * an edible reference to p. */

#include <ros/common.h>
#include <pmap.h>
#include <mm.h>
#include <process.h>
#include <stdio.h>
#include <syscall.h>
#include <slab.h>
#include <kmalloc.h>
#include <smp.h>
#include <profiler.h>
#include <umem.h>
#include <ns.h>
#include <tree_file.h>

/* These are the only mmap flags that are saved in the VMR.  If we implement
 * more of the mmap interface, we may need to grow this. */
#define MAP_PERSIST_FLAGS	(MAP_SHARED | MAP_PRIVATE | MAP_ANONYMOUS)

struct kmem_cache *vmr_kcache;

static int __vmr_free_pgs(struct proc *p, pte_t pte, void *va, void *arg);
static int populate_pm_va(struct proc *p, uintptr_t va, unsigned long nr_pgs,
                          int pte_prot, struct page_map *pm, size_t offset,
                          int flags, bool exec);

static struct page_map *foc_to_pm(struct file_or_chan *foc)
{
	switch (foc->type) {
	case F_OR_C_CHAN:
		assert(foc->fsf);
		return foc->fsf->pm;
	}
	panic("unknown F_OR_C type");
}

static struct page_map *vmr_to_pm(struct vm_region *vmr)
{
	return foc_to_pm(vmr->__vm_foc);
}

char *foc_to_name(struct file_or_chan *foc)
{
	switch (foc->type) {
	case F_OR_C_CHAN:
		if (foc->fsf)
			return foc->fsf->dir.name;
		else
			return foc->chan->name->s;
	}
	panic("unknown F_OR_C type");
}

char *foc_abs_path(struct file_or_chan *foc)
{
	switch (foc->type) {
	case F_OR_C_CHAN:
		/* Not sure, but I'd like to know if we have externally visible
		 * chans that have no name. */
		assert(foc->chan->name);
		assert(foc->chan->name->s);
		return foc->chan->name->s;
	}
	panic("unknown F_OR_C type");
}

ssize_t foc_read(struct file_or_chan *foc, void *buf, size_t amt, off64_t off)
{
	ERRSTACK(1);
	off64_t fake_off = off;
	ssize_t ret = -1;

	switch (foc->type) {
	case F_OR_C_CHAN:
		if (!qid_is_file(foc->chan->qid))
			return -1;
		if (!waserror())
			ret = devtab[foc->chan->type].read(foc->chan, buf, amt,
							   off);
		poperror();
		return ret;
	}
	panic("unknown F_OR_C type");
}

static void __foc_free_rcu(struct rcu_head *head)
{
	struct file_or_chan *foc = container_of(head, struct file_or_chan, rcu);

	switch (foc->type) {
	case F_OR_C_CHAN:
		cclose(foc->chan);
		break;
	default:
		panic("unknown F_OR_C type, %d", foc->type);
	}
	kfree(foc);
}

static void foc_release(struct kref *kref)
{
	struct file_or_chan *foc = container_of(kref, struct file_or_chan,
						kref);

	/* A lot of places decref while holding a spinlock, but we can't free
	 * then, since the cclose() might block. */
	call_rcu(&foc->rcu, __foc_free_rcu);
}

static struct file_or_chan *foc_alloc(void)
{
	struct file_or_chan *foc;

	foc = kzmalloc(sizeof(struct file_or_chan), MEM_ATOMIC);
	if (!foc)
		return NULL;
	kref_init(&foc->kref, foc_release, 1);
	return foc;
}

struct file_or_chan *foc_open(char *path, int omode, int perm)
{
	ERRSTACK(1);
	struct file_or_chan *foc = foc_alloc();

	if (!foc)
		return NULL;
	if (waserror()) {
		kfree(foc);
		poperror();
		return NULL;
	}
	foc->chan = namec(path, Aopen, omode, perm, NULL);
	foc->type = F_OR_C_CHAN;
	poperror();
	return foc;
}

struct file_or_chan *fd_to_foc(struct fd_table *fdt, int fd)
{
	ERRSTACK(1);
	struct file_or_chan *foc = foc_alloc();

	if (!foc)
		return NULL;
	if (waserror()) {
		kfree(foc);
		poperror();
		return NULL;
	}
	/* We're not checking mode here (-1).  mm code checks later. */
	foc->chan = fdtochan(fdt, fd, -1, true, true);
	foc->type = F_OR_C_CHAN;
	poperror();
	return foc;
}

void foc_incref(struct file_or_chan *foc)
{
	kref_get(&foc->kref, 1);
}

void foc_decref(struct file_or_chan *foc)
{
	kref_put(&foc->kref);
}

void *foc_pointer(struct file_or_chan *foc)
{
	if (!foc)
		return NULL;
	switch (foc->type) {
	case F_OR_C_CHAN:
		return foc->chan;
	default:
		panic("unknown F_OR_C type, %d", foc->type);
	}
}

size_t foc_get_len(struct file_or_chan *foc)
{
	switch (foc->type) {
	case F_OR_C_CHAN:
		assert(foc->fsf);
		return foc->fsf->dir.length;
	}
	panic("unknown F_OR_C type, %d", foc->type);
}

static bool check_chan_perms(struct vm_region *vmr, struct chan *chan, int prot)
{
	/* glibc isn't opening its files O_EXEC */
	prot &= ~PROT_EXEC;
	if (!(chan->mode & O_READ))
		return false;
	if (vmr->vm_flags & MAP_PRIVATE)
		prot &= ~PROT_WRITE;
	return (chan->mode & prot) == prot;
}

static bool check_foc_perms(struct vm_region *vmr, struct file_or_chan *foc,
                            int prot)
{
	switch (foc->type) {
	case F_OR_C_CHAN:
		return check_chan_perms(vmr, foc->chan, prot);
	}
	panic("unknown F_OR_C type");
}

static int foc_dev_mmap(struct file_or_chan *foc, struct vm_region *vmr,
                        int prot, int flags)
{
	if (!check_foc_perms(vmr, foc, prot))
		return -1;
	switch (foc->type) {
	case F_OR_C_CHAN:
		if (!devtab[foc->chan->type].mmap) {
			set_error(ENODEV, "device does not support mmap");
			return -1;
		}
		foc->fsf = devtab[foc->chan->type].mmap(foc->chan, vmr, prot,
							flags);
		return foc->fsf ? 0 : -1;
	}
	panic("unknown F_OR_C type, %d", foc->type);
}

void vmr_init(void)
{
	vmr_kcache = kmem_cache_create("vm_regions",
				       sizeof(struct vm_region),
				       __alignof__(struct vm_region), 0, NULL,
				       0, 0, NULL);
}

static struct vm_region *vmr_zalloc(void)
{
	struct vm_region *vmr;

	vmr = kmem_cache_alloc(vmr_kcache, MEM_WAIT);
	memset(vmr, 0, sizeof(struct vm_region));
	return vmr;
}

static void vmr_free(struct vm_region *vmr)
{
	kmem_cache_free(vmr_kcache, vmr);
}

/* The caller will set the prot, flags, file, and offset.  We find a spot for it
 * in p's address space, set proc, base, and end.  Caller holds p's vmr_lock.
 *
 * TODO: take a look at solari's vmem alloc.  And consider keeping these in a
 * tree of some sort for easier lookups. */
static bool vmr_insert(struct vm_region *vmr, struct proc *p, uintptr_t va,
                       size_t len)
{
	struct vm_region *vm_i, *vm_next;
	uintptr_t gap_end;
	bool ret = false;

	assert(!PGOFF(va));
	assert(!PGOFF(len));
	assert(__is_user_addr((void*)va, len, UMAPTOP));
	/* Is there room before the first one: */
	vm_i = TAILQ_FIRST(&p->vm_regions);
	/* This works for now, but if all we have is BRK_END ones, we'll start
	 * growing backwards (TODO) */
	if (!vm_i || (va + len <= vm_i->vm_base)) {
		vmr->vm_base = va;
		TAILQ_INSERT_HEAD(&p->vm_regions, vmr, vm_link);
		ret = true;
	} else {
		TAILQ_FOREACH(vm_i, &p->vm_regions, vm_link) {
			vm_next = TAILQ_NEXT(vm_i, vm_link);
			gap_end = vm_next ? vm_next->vm_base : UMAPTOP;
			/* skip til we get past the 'hint' va */
			if (va >= gap_end)
				continue;
			/* Find a gap that is big enough */
			if (gap_end - vm_i->vm_end >= len) {
				/* if we can put it at va, let's do that.  o/w,
				 * put it so it fits */
				if ((gap_end >= va + len) &&
				    (va >= vm_i->vm_end))
					vmr->vm_base = va;
				else
					vmr->vm_base = vm_i->vm_end;
				TAILQ_INSERT_AFTER(&p->vm_regions, vm_i, vmr,
						   vm_link);
				ret = true;
				break;
			}
		}
	}
	/* Finalize the creation, if we got one */
	if (ret) {
		vmr->vm_proc = p;
		vmr->vm_end = vmr->vm_base + len;
	}
	if (!ret)
		warn("Not making a VMR, wanted %p, + %p = %p", va, len, va +
		     len);
	return ret;
}

/* Split a VMR at va, returning the new VMR.  It is set up the same way, with
 * file offsets fixed accordingly.  'va' is the beginning of the new one, and
 * must be page aligned. */
static struct vm_region *split_vmr(struct vm_region *old_vmr, uintptr_t va)
{
	struct vm_region *new_vmr;

	assert(!PGOFF(va));
	if ((old_vmr->vm_base >= va) || (old_vmr->vm_end <= va))
		return 0;
	new_vmr = kmem_cache_alloc(vmr_kcache, 0);
	assert(new_vmr);
	TAILQ_INSERT_AFTER(&old_vmr->vm_proc->vm_regions, old_vmr, new_vmr,
	                   vm_link);
	new_vmr->vm_proc = old_vmr->vm_proc;
	new_vmr->vm_base = va;
	new_vmr->vm_end = old_vmr->vm_end;
	old_vmr->vm_end = va;
	new_vmr->vm_prot = old_vmr->vm_prot;
	new_vmr->vm_flags = old_vmr->vm_flags;
	if (vmr_has_file(old_vmr)) {
		foc_incref(old_vmr->__vm_foc);
		new_vmr->__vm_foc = old_vmr->__vm_foc;
		new_vmr->vm_foff = old_vmr->vm_foff +
		                      old_vmr->vm_end - old_vmr->vm_base;
		pm_add_vmr(vmr_to_pm(old_vmr), new_vmr);
	} else {
		new_vmr->__vm_foc = NULL;
		new_vmr->vm_foff = 0;
	}
	return new_vmr;
}

/* Called by the unmapper, just cleans up.  Whoever calls this will need to sort
 * out the page table entries. */
static void destroy_vmr(struct vm_region *vmr)
{
	if (vmr_has_file(vmr)) {
		pm_remove_vmr(vmr_to_pm(vmr), vmr);
		foc_decref(vmr->__vm_foc);
	}
	TAILQ_REMOVE(&vmr->vm_proc->vm_regions, vmr, vm_link);
	vmr_free(vmr);
}

/* Merges two vm regions.  For now, it will check to make sure they are the
 * same.  The second one will be destroyed. */
static int merge_vmr(struct vm_region *first, struct vm_region *second)
{
	assert(first->vm_proc == second->vm_proc);
	if ((first->vm_end != second->vm_base) ||
	    (first->vm_prot != second->vm_prot) ||
	    (first->vm_flags != second->vm_flags) ||
	    (first->__vm_foc != second->__vm_foc))
		return -1;
	if (vmr_has_file(first) && (second->vm_foff != first->vm_foff +
	                            first->vm_end - first->vm_base))
		return -1;
	first->vm_end = second->vm_end;
	destroy_vmr(second);
	return 0;
}

/* Attempts to merge vmr with adjacent VMRs, returning a ptr to be used for vmr.
 * It could be the same struct vmr, or possibly another one (usually lower in
 * the address space. */
static struct vm_region *merge_me(struct vm_region *vmr)
{
	struct vm_region *vmr_temp;

	/* Merge will fail if it cannot do it.  If it succeeds, the second VMR
	 * is destroyed, so we need to be a bit careful. */
	vmr_temp = TAILQ_PREV(vmr, vmr_tailq, vm_link);
	if (vmr_temp)
		if (!merge_vmr(vmr_temp, vmr))
			vmr = vmr_temp;
	vmr_temp = TAILQ_NEXT(vmr, vm_link);
	if (vmr_temp)
		merge_vmr(vmr, vmr_temp);
	return vmr;
}

/* Grows the vm region up to (and not including) va.  Fails if another is in the
 * way, etc. */
static int grow_vmr(struct vm_region *vmr, uintptr_t va)
{
	assert(!PGOFF(va));
	struct vm_region *next = TAILQ_NEXT(vmr, vm_link);
	if (next && next->vm_base < va)
		return -1;
	if (va <= vmr->vm_end)
		return -1;
	vmr->vm_end = va;
	return 0;
}

/* Shrinks the vm region down to (and not including) va.  Whoever calls this
 * will need to sort out the page table entries. */
static int shrink_vmr(struct vm_region *vmr, uintptr_t va)
{
	assert(!PGOFF(va));
	if ((va < vmr->vm_base) || (va > vmr->vm_end))
		return -1;
	vmr->vm_end = va;
	return 0;
}

/* Given a va and a proc (later an mm, possibly), returns the owning vmr, or 0
 * if there is none. */
static struct vm_region *find_vmr(struct proc *p, uintptr_t va)
{
	struct vm_region *vmr;

	/* ugly linear seach */
	TAILQ_FOREACH(vmr, &p->vm_regions, vm_link) {
		if ((vmr->vm_base <= va) && (vmr->vm_end > va))
			return vmr;
	}
	return 0;
}

/* Finds the first vmr after va (including the one holding va), or 0 if there is
 * none. */
static struct vm_region *find_first_vmr(struct proc *p, uintptr_t va)
{
	struct vm_region *vmr;

	/* ugly linear seach */
	TAILQ_FOREACH(vmr, &p->vm_regions, vm_link) {
		if ((vmr->vm_base <= va) && (vmr->vm_end > va))
			return vmr;
		if (vmr->vm_base > va)
			return vmr;
	}
	return 0;
}

/* Makes sure that no VMRs cross either the start or end of the given region
 * [va, va + len), splitting any VMRs that are on the endpoints. */
static void isolate_vmrs(struct proc *p, uintptr_t va, size_t len)
{
	struct vm_region *vmr;
	if ((vmr = find_vmr(p, va)))
		split_vmr(vmr, va);
	/* TODO: don't want to do another find (linear search) */
	if ((vmr = find_vmr(p, va + len)))
		split_vmr(vmr, va + len);
}

void unmap_and_destroy_vmrs(struct proc *p)
{
	struct vm_region *vmr_i, *vmr_temp;

	/* this only gets called from __proc_free, so there should be no sync
	 * concerns.  still, better safe than sorry. */
	spin_lock(&p->vmr_lock);
	p->vmr_history++;
	spin_lock(&p->pte_lock);
	TAILQ_FOREACH(vmr_i, &p->vm_regions, vm_link) {
		/* note this CB sets the PTE = 0, regardless of if it was P or
		 * not */
		env_user_mem_walk(p, (void*)vmr_i->vm_base,
				  vmr_i->vm_end - vmr_i->vm_base,
				  __vmr_free_pgs, 0);
	}
	spin_unlock(&p->pte_lock);
	/* need the safe style, since destroy_vmr modifies the list.  also, we
	 * want to do this outside the pte lock, since it grabs the pm lock. */
	TAILQ_FOREACH_SAFE(vmr_i, &p->vm_regions, vm_link, vmr_temp)
		destroy_vmr(vmr_i);
	spin_unlock(&p->vmr_lock);
}

/* Helper: copies the contents of pages from p to new p.  For pages that aren't
 * present, once we support swapping or CoW, we can do something more
 * intelligent.  0 on success, -ERROR on failure.  Can't handle jumbos. */
static int copy_pages(struct proc *p, struct proc *new_p, uintptr_t va_start,
                      uintptr_t va_end)
{
	int ret;

	/* Sanity checks.  If these fail, we had a screwed up VMR.
	 * Check for: alignment, wraparound, or userspace addresses */
	if ((PGOFF(va_start)) ||
	    (PGOFF(va_end)) ||
	    (va_end < va_start) ||/* now, start > UMAPTOP -> end > UMAPTOP */
	    (va_end > UMAPTOP)) {
		warn("VMR mapping is probably screwed up (%p - %p)", va_start,
		     va_end);
		return -EINVAL;
	}
	int copy_page(struct proc *p, pte_t pte, void *va, void *arg) {
		struct proc *new_p = (struct proc*)arg;
		struct page *pp;

		if (pte_is_unmapped(pte))
			return 0;
		/* pages could be !P, but right now that's only for file backed
		 * VMRs undergoing page removal, which isn't the caller of
		 * copy_pages. */
		if (pte_is_mapped(pte)) {
			/* TODO: check for jumbos */
			if (upage_alloc(new_p, &pp, 0))
				return -ENOMEM;
			memcpy(page2kva(pp), KADDR(pte_get_paddr(pte)), PGSIZE);
			if (page_insert(new_p->env_pgdir, pp, va,
					pte_get_settings(pte))) {
				page_decref(pp);
				return -ENOMEM;
			}
		} else if (pte_is_paged_out(pte)) {
			/* TODO: (SWAP) will need to either make a copy or
			 * CoW/refcnt the backend store.  For now, this PTE will
			 * be the same as the original PTE */
			panic("Swapping not supported!");
		} else {
			panic("Weird PTE %p in %s!", pte_print(pte),
			      __FUNCTION__);
		}
		return 0;
	}
	spin_lock(&p->pte_lock);	/* walking and changing PTEs */
	ret = env_user_mem_walk(p, (void*)va_start, va_end - va_start,
				&copy_page, new_p);
	spin_unlock(&p->pte_lock);
	return ret;
}

static int fill_vmr(struct proc *p, struct proc *new_p, struct vm_region *vmr)
{
	int ret = 0;

	if (!vmr_has_file(vmr) || (vmr->vm_flags & MAP_PRIVATE)) {
		/* We don't support ANON + SHARED yet */
		assert(!(vmr->vm_flags & MAP_SHARED));
		ret = copy_pages(p, new_p, vmr->vm_base, vmr->vm_end);
	} else {
		/* non-private file, i.e. page cacheable.  we have to honor
		 * MAP_LOCKED, (but we might be able to ignore MAP_POPULATE). */
		if (vmr->vm_flags & MAP_LOCKED) {
			/* need to keep the file alive in case we unlock/block
			 */
			foc_incref(vmr->__vm_foc);
			/* math is a bit nasty if vm_base isn't page aligned */
			assert(!PGOFF(vmr->vm_base));
			ret = populate_pm_va(new_p, vmr->vm_base,
					     (vmr->vm_end - vmr->vm_base) >>
					     			       PGSHIFT,
			                     vmr->vm_prot, vmr_to_pm(vmr),
			                     vmr->vm_foff, vmr->vm_flags,
			                     vmr->vm_prot & PROT_EXEC);
			foc_decref(vmr->__vm_foc);
		}
	}
	if (ret < 0) {
		/* Need to undo any mappings we left behind.  We don't know
		 * where we died, but we can just blast the entire region */
		spin_lock(&new_p->pte_lock);
		env_user_mem_walk(new_p, (void*)vmr->vm_base,
				  vmr->vm_end - vmr->vm_base,
				  __vmr_free_pgs, NULL);
		spin_unlock(&new_p->pte_lock);
	}
	return ret;
}

/* This will make new_p have the same VMRs as p, and it will make sure all
 * physical pages are copied over, with the exception of MAP_SHARED files.
 * MAP_SHARED files that are also MAP_LOCKED will be attached to the process -
 * presumably they are in the page cache since the parent locked them.  This is
 * all pretty nasty.
 *
 * This is used by fork().
 *
 * Note that if you are working on a VMR that is a file, you'll want to be
 * careful about how it is mapped (SHARED, PRIVATE, etc). */
int duplicate_vmrs(struct proc *p, struct proc *new_p)
{
	int ret = 0;
	struct vm_region *vmr, *vm_i;

	TAILQ_FOREACH(vm_i, &p->vm_regions, vm_link) {
		vmr = kmem_cache_alloc(vmr_kcache, 0);
		if (!vmr)
			return -ENOMEM;
		vmr->vm_proc = new_p;
		vmr->vm_base = vm_i->vm_base;
		vmr->vm_end = vm_i->vm_end;
		vmr->vm_prot = vm_i->vm_prot;
		vmr->vm_flags = vm_i->vm_flags;
		vmr->__vm_foc = vm_i->__vm_foc;
		vmr->vm_foff = vm_i->vm_foff;
		if (vmr_has_file(vm_i)) {
			foc_incref(vm_i->__vm_foc);
			pm_add_vmr(vmr_to_pm(vm_i), vmr);
		}
		ret = fill_vmr(p, new_p, vmr);
		if (ret) {
			if (vmr_has_file(vm_i)) {
				pm_remove_vmr(vmr_to_pm(vm_i), vmr);
				foc_decref(vm_i->__vm_foc);
			}
			vmr_free(vmr);
			return ret;
		}
		TAILQ_INSERT_TAIL(&new_p->vm_regions, vmr, vm_link);
	}
	return 0;
}

void print_vmrs(struct proc *p)
{
	int count = 0;
	struct vm_region *vmr;

	print_lock();
	printk("VM Regions for proc %d\n", p->pid);
	printk("NR:"
	       "                                     Range:"
	       "       Prot,"
	       "      Flags,"
	       "               File,"
	       "                Off\n");
	TAILQ_FOREACH(vmr, &p->vm_regions, vm_link)
		printk("%02d: (%p - %p): 0x%08x, 0x%08x, %p, %p\n", count++,
		       vmr->vm_base, vmr->vm_end, vmr->vm_prot, vmr->vm_flags,
		       foc_pointer(vmr->__vm_foc), vmr->vm_foff);
	print_unlock();
}

void enumerate_vmrs(struct proc *p, void (*func)(struct vm_region *vmr,
						 void *opaque), void *opaque)
{
	struct vm_region *vmr;

	spin_lock(&p->vmr_lock);
	TAILQ_FOREACH(vmr, &p->vm_regions, vm_link)
		func(vmr, opaque);
	spin_unlock(&p->vmr_lock);
}

static bool mmap_flags_priv_ok(int flags)
{
	return (flags & (MAP_PRIVATE | MAP_SHARED)) == MAP_PRIVATE ||
	       (flags & (MAP_PRIVATE | MAP_SHARED)) == MAP_SHARED;
}

static bool prot_is_valid(int prot)
{
	/* Remember PROT_NONE (0) is valid. */
	return !(prot & ~PROT_VALID_PROTS);
}

static bool prot_has_access(int prot)
{
	return prot & (PROT_READ | PROT_WRITE | PROT_EXEC);
}

/* Error values aren't quite comprehensive - check man mmap() once we do better
 * with the FS.
 *
 * The mmap call's offset is in units of PGSIZE (like Linux's mmap2()), but
 * internally, the offset is tracked in bytes.  The reason for the PGSIZE is for
 * 32bit apps to enumerate large files, but a full 64bit system won't need that.
 * We track things internally in bytes since that is how file pointers work, vmr
 * bases and ends, and similar math.  While it's not a hard change, there's no
 * need for it, and ideally we'll be a fully 64bit system before we deal with
 * files that large. */
void *mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
           int fd, size_t offset)
{
	struct file_or_chan *file = NULL;
	void *result;

	offset <<= PGSHIFT;
	printd("mmap(addr %x, len %x, prot %x, flags %x, fd %x, off %x)\n",
	       addr, len, prot, flags, fd, offset);
	if (!mmap_flags_priv_ok(flags)) {
		set_errno(EINVAL);
		return MAP_FAILED;
	}
	if (!prot_is_valid(prot)) {
		set_error(EINVAL, "invalid prot 0x%x (%x)", prot,
			  PROT_VALID_PROTS);
		return MAP_FAILED;
	}
	if (!len) {
		set_errno(EINVAL);
		return MAP_FAILED;
	}
	if (!(flags & MAP_ANON) && (fd >= 0)) {
		file = fd_to_foc(&p->open_files, fd);
		if (!file) {
			set_errno(EBADF);
			result = MAP_FAILED;
			goto out_ref;
		}
	}
	/* Check for overflow.  This helps do_mmap and populate_va, among
	 * others. */
	if (offset + len < offset) {
		set_errno(EINVAL);
		result = MAP_FAILED;
		goto out_ref;
	}
	/* If they don't care where to put it, we'll start looking after the
	 * break.  We could just have userspace handle this (in glibc's mmap),
	 * so we don't need to know about BRK_END, but this will work for now
	 * (and may avoid bugs).  Note that this limits mmap(0) a bit.  Keep
	 * this in sync with do_mmap()'s check.  (Both are necessary).  */
	if (addr == 0)
		addr = BRK_END;
	/* Still need to enforce this: */
	addr = MAX(addr, MMAP_LOWEST_VA);
	/* Need to check addr + len, after we do our addr adjustments */
	if (!__is_user_addr((void*)addr, len, UMAPTOP)) {
		set_errno(EINVAL);
		result = MAP_FAILED;
		goto out_ref;
	}
	if (PGOFF(addr)) {
		set_errno(EINVAL);
		result = MAP_FAILED;
		goto out_ref;
	}
	result = do_mmap(p, addr, len, prot, flags, file, offset);
out_ref:
	if (file)
		foc_decref(file);
	return result;
}

/* Helper, maps in page at addr, but only if nothing is mapped there.  Returns
 * 0 on success.  Will take ownership of non-pagemap pages, including on error
 * cases.  This just means we free it on error, and notionally store it in the
 * PTE on success, which will get freed later.
 *
 * It's possible that a page has already been mapped here, in which case we'll
 * treat as success.  So when we return 0, *a* page is mapped here, but not
 * necessarily the one you passed in. */
static int map_page_at_addr(struct proc *p, struct page *page, uintptr_t addr,
                            int pte_prot)
{
	pte_t pte;

	spin_lock(&p->pte_lock);	/* walking and changing PTEs */
	/* find offending PTE (prob don't read this in).  This might alloc an
	 * intermediate page table page. */
	pte = pgdir_walk(p->env_pgdir, (void*)addr, TRUE);
	if (!pte_walk_okay(pte)) {
		spin_unlock(&p->pte_lock);
		if (!page_is_pagemap(page))
			page_decref(page);
		return -ENOMEM;
	}
	/* a spurious, valid PF is possible due to a legit race: the page might
	 * have been faulted in by another core already (and raced on the memory
	 * lock), in which case we should just return. */
	if (pte_is_present(pte)) {
		spin_unlock(&p->pte_lock);
		if (!page_is_pagemap(page))
			page_decref(page);
		return 0;
	}
	/* I used to allow clobbering an old entry (contrary to the
	 * documentation), but it's probably a sign of another bug. */
	assert(!pte_is_mapped(pte));
	/* preserve the dirty bit - pm removal could be looking concurrently */
	pte_prot |= (pte_is_dirty(pte) ? PTE_D : 0);
	/* We have a ref to page (for non PMs), which we are storing in the PTE
	 */
	pte_write(pte, page2pa(page), pte_prot);
	spin_unlock(&p->pte_lock);
	return 0;
}

/* Helper: copies *pp's contents to a new page, replacing your page pointer.  If
 * this succeeds, you'll have a non-PM page, which matters for how you put it.*/
static int __copy_and_swap_pmpg(struct proc *p, struct page **pp)
{
	struct page *new_page, *old_page = *pp;

	if (upage_alloc(p, &new_page, FALSE))
		return -ENOMEM;
	memcpy(page2kva(new_page), page2kva(old_page), PGSIZE);
	pm_put_page(old_page);
	*pp = new_page;
	return 0;
}

/* Hold the VMR lock when you call this - it'll assume the entire VA range is
 * mappable, which isn't true if there are concurrent changes to the VMRs. */
static int populate_anon_va(struct proc *p, uintptr_t va, unsigned long nr_pgs,
                            int pte_prot)
{
	struct page *page;
	int ret;

	for (long i = 0; i < nr_pgs; i++) {
		if (upage_alloc(p, &page, TRUE))
			return -ENOMEM;
		/* could imagine doing a memwalk instead of a for loop */
		ret = map_page_at_addr(p, page, va + i * PGSIZE, pte_prot);
		if (ret)
			return ret;
	}
	return 0;
}

/* This will periodically unlock the vmr lock. */
static int populate_pm_va(struct proc *p, uintptr_t va, unsigned long nr_pgs,
                          int pte_prot, struct page_map *pm, size_t offset,
                          int flags, bool exec)
{
	int ret = 0;
	unsigned long pm_idx0 = offset >> PGSHIFT;
	int vmr_history = ACCESS_ONCE(p->vmr_history);
	struct page *page;

	/* This is a racy check - see the comments in fs_file.c.  Also, we're
	 * not even attempting to populate the va, though we could do a partial
	 * if necessary. */
	if (pm_idx0 + nr_pgs > nr_pages(fs_file_get_length(pm->pm_file)))
		return -ESPIPE;
	/* locking rules: start the loop holding the vmr lock, enter and exit
	 * the entire func holding the lock. */
	for (long i = 0; i < nr_pgs; i++) {
		ret = pm_load_page_nowait(pm, pm_idx0 + i, &page);
		if (ret) {
			if (ret != -EAGAIN)
				break;
			spin_unlock(&p->vmr_lock);
			/* might block here, can't hold the spinlock */
			ret = pm_load_page(pm, pm_idx0 + i, &page);
			spin_lock(&p->vmr_lock);
			if (ret)
				break;
			/* while we were sleeping, the VMRs could have changed
			 * on us. */
			if (vmr_history != ACCESS_ONCE(p->vmr_history)) {
				pm_put_page(page);
				printk("[kernel] "
				       "FYI: VMR changed during populate\n");
				break;
			}
		}
		if (flags & MAP_PRIVATE) {
			ret = __copy_and_swap_pmpg(p, &page);
			if (ret) {
				pm_put_page(page);
				break;
			}
		}
		/* if this is an executable page, we might have to flush the
		 * instruction cache if our HW requires it.
		 * TODO: is this still needed?  andrew put this in a while ago*/
		if (exec)
			icache_flush_page(0, page2kva(page));
		/* The page could be either in the PM, or a private, now-anon
		 * page. */
		ret = map_page_at_addr(p, page, va + i * PGSIZE, pte_prot);
		if (page_is_pagemap(page))
			pm_put_page(page);
		if (ret)
			break;
	}
	return ret;
}

void *do_mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
              struct file_or_chan *file, size_t offset)
{
	len = ROUNDUP(len, PGSIZE);
	struct vm_region *vmr, *vmr_temp;

	assert(mmap_flags_priv_ok(flags));
	assert(prot_is_valid(prot));

	vmr = vmr_zalloc();

	/* Sanity check, for callers that bypass mmap().  We want addr for anon
	 * memory to start above the break limit (BRK_END), but not 0.  Keep
	 * this in sync with BRK_END in mmap(). */
	if (addr == 0)
		addr = BRK_END;
	assert(!PGOFF(offset));
	/* MCPs will need their code and data pinned.  This check will start to
	 * fail after uthread_slim_init(), at which point userspace should have
	 * enough control over its mmaps (i.e. no longer done by LD or load_elf)
	 * that it can ask for pinned and populated pages.  Except for
	 * dl_opens(). */
	struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[0];

	if (file && (atomic_read(&vcpd->flags) & VC_SCP_NOVCCTX))
		flags |= MAP_POPULATE | MAP_LOCKED;
	vmr->vm_prot = prot;
	vmr->vm_foff = offset;
	vmr->vm_flags = flags & MAP_PERSIST_FLAGS;
	/* We grab the file early, so we can block.  This is all hokey.  The VMR
	 * isn't ready yet, so the PM code will ignore it. */
	if (file) {
		/* Prep the FS and make sure it can mmap the file.  The
		 * device/FS checks perms, and does whatever else it needs to
		 * make the mmap work. */
		if (foc_dev_mmap(file, vmr, prot, flags & MAP_PERSIST_FLAGS)) {
			vmr_free(vmr);
			set_errno(EACCES);	/* not quite */
			return MAP_FAILED;
		}
		/* TODO: push the PM stuff into the chan/fs_file. */
		pm_add_vmr(foc_to_pm(file), vmr);
		foc_incref(file);
		vmr->__vm_foc = file;
		/* TODO: consider locking the file while checking (not as
		 * manadatory as in handle_page_fault() */
		if (nr_pages(offset + len) > nr_pages(foc_get_len(file))) {
			/* We're allowing them to set up the VMR, though if they
			 * attempt to fault in any pages beyond the file's
			 * limit, they'll fail.  Since they might not access the
			 * region, we need to make sure POPULATE is off.  FYI,
			 * 64 bit glibc shared libs map in an extra 2MB of
			 * unaligned space between their RO and RW sections, but
			 * then immediately mprotect it to PROT_NONE. */
			flags &= ~MAP_POPULATE;
		}
	}
	/* read/write vmr lock (will change the tree) */
	spin_lock(&p->vmr_lock);
	p->vmr_history++;
	/* Need to make sure nothing is in our way when we want a FIXED
	 * location.  We just need to split on the end points (if they exist),
	 * and then remove everything in between.  __do_munmap() will do this.
	 * Careful, this means an mmap can be an implied munmap() (not my
	 * call...). */
	if (flags & MAP_FIXED)
		__do_munmap(p, addr, len);
	if (!vmr_insert(vmr, p, addr, len)) {
		spin_unlock(&p->vmr_lock);
		if (vmr_has_file(vmr)) {
			pm_remove_vmr(vmr_to_pm(vmr), vmr);
			foc_decref(vmr->__vm_foc);
		}
		vmr_free(vmr);
		set_error(ENOMEM, "probably tried to mmap beyond UMAPTOP");
		/* Slightly weird semantics: if we fail and had munmapped the
		 * space, they will have a hole in their VM now. */
		return MAP_FAILED;
	}
	addr = vmr->vm_base;
	vmr->vm_ready = true;

	vmr = merge_me(vmr);		/* attempts to merge with neighbors */

	if (flags & MAP_POPULATE && prot_has_access(prot)) {
		int pte_prot = (prot & PROT_WRITE) ? PTE_USER_RW :
	                   (prot & (PROT_READ|PROT_EXEC)) ? PTE_USER_RO : 0;
		unsigned long nr_pgs = len >> PGSHIFT;
		int ret = 0;
		if (!file) {
			ret = populate_anon_va(p, addr, nr_pgs, pte_prot);
		} else {
			/* Note: this will unlock if it blocks.  our refcnt on
			 * the file keeps the pm alive when we unlock */
			ret = populate_pm_va(p, addr, nr_pgs, pte_prot,
					     foc_to_pm(file), offset, flags,
					     prot & PROT_EXEC);
		}
		if (ret == -ENOMEM) {
			spin_unlock(&p->vmr_lock);
			printk("[kernel] ENOMEM, killing %d\n", p->pid);
			proc_destroy(p);
			/* this will never make it back to userspace */
			return MAP_FAILED;
		}
	}
	spin_unlock(&p->vmr_lock);

	profiler_notify_mmap(p, addr, len, prot, flags, file, offset);

	return (void*)addr;
}

int mprotect(struct proc *p, uintptr_t addr, size_t len, int prot)
{
	int ret;

	printd("mprotect: (addr %p, len %p, prot 0x%x)\n", addr, len, prot);
	if (!prot_is_valid(prot)) {
		set_error(EINVAL, "invalid prot 0x%x (%x)", prot,
			  PROT_VALID_PROTS);
		return -1;
	}
	if (!len)
		return 0;
	len = ROUNDUP(len, PGSIZE);
	if (PGOFF(addr)) {
		set_errno(EINVAL);
		return -1;
	}
	if (!__is_user_addr((void*)addr, len, UMAPTOP)) {
		set_errno(ENOMEM);
		return -1;
	}
	/* read/write lock, will probably change the tree and settings */
	spin_lock(&p->vmr_lock);
	p->vmr_history++;
	ret = __do_mprotect(p, addr, len, prot);
	spin_unlock(&p->vmr_lock);
	return ret;
}

/* This does not care if the region is not mapped.  POSIX says you should return
 * ENOMEM if any part of it is unmapped.  Can do this later if we care, based on
 * the VMRs, not the actual page residency. */
int __do_mprotect(struct proc *p, uintptr_t addr, size_t len, int prot)
{
	struct vm_region *vmr, *next_vmr;
	pte_t pte;
	bool shootdown_needed = FALSE;
	bool file_access_failure = FALSE;
	int pte_prot = (prot & PROT_WRITE) ? PTE_USER_RW :
	               (prot & (PROT_READ|PROT_EXEC)) ? PTE_USER_RO : PTE_NONE;

	assert(prot_is_valid(prot));
	/* TODO: this is aggressively splitting, when we might not need to if
	 * the prots are the same as the previous.  Plus, there are three
	 * excessive scans. */
	isolate_vmrs(p, addr, len);
	vmr = find_first_vmr(p, addr);
	while (vmr && vmr->vm_base < addr + len) {
		if (vmr->vm_prot == prot)
			goto next_vmr;
		if (vmr_has_file(vmr) &&
		    !check_foc_perms(vmr, vmr->__vm_foc, prot)) {
			file_access_failure = TRUE;
			goto next_vmr;
		}
		vmr->vm_prot = prot;
		spin_lock(&p->pte_lock);	/* walking and changing PTEs */
		/* TODO: use a memwalk.  At a minimum, we need to change every
		 * existing PTE that won't trigger a PF (meaning, present PTEs)
		 * to have the new prot.  The others will fault on access, and
		 * we'll change the PTE then.  In the off chance we have a
		 * mapped but not present PTE, we might as well change it too,
		 * since we're already here. */
		for (uintptr_t va = vmr->vm_base; va < vmr->vm_end;
		     va += PGSIZE) {
			pte = pgdir_walk(p->env_pgdir, (void*)va, 0);
			if (pte_walk_okay(pte) && pte_is_mapped(pte)) {
				pte_replace_perm(pte, pte_prot);
				shootdown_needed = TRUE;
			}
		}
		spin_unlock(&p->pte_lock);
next_vmr:
		/* Note that this merger could cause us to not look at the next
		 * one, since we merged with it.  That's ok, since in that case,
		 * the next one already has the right prots.  Also note that
		 * every VMR in the region, including the ones at the endpoints,
		 * attempted to merge left and right. */
		vmr = merge_me(vmr);
		next_vmr = TAILQ_NEXT(vmr, vm_link);
		vmr = next_vmr;
	}
	if (shootdown_needed)
		proc_tlbshootdown(p, addr, addr + len);
	if (file_access_failure) {
		set_errno(EACCES);
		return -1;
	}
	return 0;
}

int munmap(struct proc *p, uintptr_t addr, size_t len)
{
	int ret;

	printd("munmap(addr %x, len %x)\n", addr, len);
	if (!len)
		return 0;
	len = ROUNDUP(len, PGSIZE);
	if (PGOFF(addr)) {
		set_errno(EINVAL);
		return -1;
	}
	if (!__is_user_addr((void*)addr, len, UMAPTOP)) {
		set_errno(EINVAL);
		return -1;
	}
	/* read/write: changing the vmrs (trees, properties, and whatnot) */
	spin_lock(&p->vmr_lock);
	p->vmr_history++;
	ret = __do_munmap(p, addr, len);
	spin_unlock(&p->vmr_lock);
	return ret;
}

static int __munmap_pte(struct proc *p, pte_t pte, void *va, void *arg)
{
	bool *shootdown_needed = (bool*)arg;
	struct page *page;

	/* could put in some checks here for !P and also !0 */
	if (!pte_is_present(pte)) /* unmapped (== 0) *ptes are also not PTE_P */
		return 0;
	if (pte_is_dirty(pte)) {
		page = pa2page(pte_get_paddr(pte));
		atomic_or(&page->pg_flags, PG_DIRTY);
	}
	pte_clear_present(pte);
	*shootdown_needed = TRUE;
	return 0;
}

/* If our page is actually in the PM, we don't do anything.  All a page map
 * really needs is for our VMR to no longer track it (vmr being in the pm's
 * list) and to not point at its pages (mark it 0, dude).
 *
 * But private mappings mess with that a bit.  Luckily, we can tell by looking
 * at a page whether the specific page is in the PM or not.  If it isn't, we
 * still need to free our "VMR local" copy.
 *
 * For pages in a PM, we're racing with PM removers.  Both of us sync with the
 * mm lock, so once we hold the lock, it's a matter of whether or not the PTE is
 * 0 or not.  If it isn't, then we're still okay to look at the page.  Consider
 * the PTE a weak ref on the page.  So long as you hold the mm lock, you can
 * look at the PTE and know the page isn't being freed. */
static int __vmr_free_pgs(struct proc *p, pte_t pte, void *va, void *arg)
{
	struct page *page;
	if (pte_is_unmapped(pte))
		return 0;
	page = pa2page(pte_get_paddr(pte));
	pte_clear(pte);
	if (!page_is_pagemap(page))
		page_decref(page);
	return 0;
}

int __do_munmap(struct proc *p, uintptr_t addr, size_t len)
{
	struct vm_region *vmr, *next_vmr, *first_vmr;
	bool shootdown_needed = FALSE;

	/* TODO: this will be a bit slow, since we end up doing three linear
	 * searches (two in isolate, one in find_first). */
	isolate_vmrs(p, addr, len);
	first_vmr = find_first_vmr(p, addr);
	vmr = first_vmr;
	spin_lock(&p->pte_lock);	/* changing PTEs */
	while (vmr && vmr->vm_base < addr + len) {
		/* It's important that we call __munmap_pte and sync the
		 * PG_DIRTY bit before we unhook the VMR from the PM (in
		 * destroy_vmr). */
		env_user_mem_walk(p, (void*)vmr->vm_base,
				  vmr->vm_end - vmr->vm_base, __munmap_pte,
				  &shootdown_needed);
		vmr = TAILQ_NEXT(vmr, vm_link);
	}
	spin_unlock(&p->pte_lock);
	/* we haven't freed the pages yet; still using the PTEs to store the
	 * them.  There should be no races with inserts/faults, since we still
	 * hold the mm lock since the previous CB. */
	if (shootdown_needed)
		proc_tlbshootdown(p, addr, addr + len);
	vmr = first_vmr;
	while (vmr && vmr->vm_base < addr + len) {
		/* there is rarely more than one VMR in this loop.  o/w, we'll
		 * need to gather up the vmrs and destroy outside the pte_lock.
		 */
		spin_lock(&p->pte_lock);	/* changing PTEs */
		env_user_mem_walk(p, (void*)vmr->vm_base,
				  vmr->vm_end - vmr->vm_base, __vmr_free_pgs,
				  0);
		spin_unlock(&p->pte_lock);
		next_vmr = TAILQ_NEXT(vmr, vm_link);
		destroy_vmr(vmr);
		vmr = next_vmr;
	}
	return 0;
}

/* Helper - drop the page differently based on where it is from */
static void __put_page(struct page *page)
{
	if (page_is_pagemap(page))
		pm_put_page(page);
	else
		page_decref(page);
}

static int __hpf_load_page(struct proc *p, struct page_map *pm,
                           unsigned long idx, struct page **page, bool first)
{
	int ret = 0;
	int coreid = core_id();
	struct per_cpu_info *pcpui = &per_cpu_info[coreid];
	bool wake_scp = FALSE;
	spin_lock(&p->proc_lock);
	switch (p->state) {
	case (PROC_RUNNING_S):
		wake_scp = TRUE;
		__proc_set_state(p, PROC_WAITING);
		/* it's possible for HPF to loop a few times; we can only save
		 * the first time, o/w we could clobber. */
		if (first) {
			__proc_save_context_s(p);
			__proc_save_fpu_s(p);
			/* We clear the owner, since userspace doesn't run here
			 * anymore, but we won't abandon since the fault handler
			 * still runs in our process. */
			clear_owning_proc(coreid);
		}
		/* other notes: we don't currently need to tell the ksched
		 * we switched from running to waiting, though we probably
		 * will later for more generic scheds. */
		break;
	case (PROC_RUNNABLE_M):
	case (PROC_RUNNING_M):
		spin_unlock(&p->proc_lock);
		return -EAGAIN;	/* will get reflected back to userspace */
	case (PROC_DYING):
	case (PROC_DYING_ABORT):
		spin_unlock(&p->proc_lock);
		return -EINVAL;
	default:
		/* shouldn't have any waitings, under the current yield style.
		 * if this becomes an issue, we can branch on is_mcp(). */
		printk("HPF unexpectecd state(%s)", procstate2str(p->state));
		spin_unlock(&p->proc_lock);
		return -EINVAL;
	}
	spin_unlock(&p->proc_lock);
	ret = pm_load_page(pm, idx, page);
	if (wake_scp)
		proc_wakeup(p);
	if (ret) {
		printk("load failed with ret %d\n", ret);
		return ret;
	}
	/* need to put our old ref, next time around HPF will get another. */
	pm_put_page(*page);
	return 0;
}

/* Returns 0 on success, or an appropriate -error code.
 *
 * Notes: if your TLB caches negative results, you'll need to flush the
 * appropriate tlb entry.  Also, you could have a weird race where a present PTE
 * faulted for a different reason (was mprotected on another core), and the
 * shootdown is on its way.  Userspace should have waited for the mprotect to
 * return before trying to write (or whatever), so we don't care and will fault
 * them. */
static int __hpf(struct proc *p, uintptr_t va, int prot, bool file_ok)
{
	struct vm_region *vmr;
	struct file_or_chan *file;
	struct page *a_page;
	unsigned int f_idx;	/* index of the missing page in the file */
	int ret = 0;
	bool first = TRUE;
	va = ROUNDDOWN(va,PGSIZE);

refault:
	/* read access to the VMRs TODO: RCU */
	spin_lock(&p->vmr_lock);
	/* Check the vmr's protection */
	vmr = find_vmr(p, va);
	if (!vmr) {			/* not mapped at all */
		printd("fault: %p not mapped\n", va);
		ret = -EFAULT;
		goto out;
	}
	if (!(vmr->vm_prot & prot)) {	/* wrong prots for this vmr */
		ret = -EPERM;
		goto out;
	}
	if (!vmr_has_file(vmr)) {
		/* No file - just want anonymous memory */
		if (upage_alloc(p, &a_page, TRUE)) {
			ret = -ENOMEM;
			goto out;
		}
	} else {
		if (!file_ok) {
			ret = -EACCES;
			goto out;
		}
		file = vmr->__vm_foc;
		/* If this fails, either something got screwed up with the VMR,
		 * or the permissions changed after mmap/mprotect.  Either way,
		 * I want to know (though it's not critical). */
		if (!check_foc_perms(vmr, file, prot))
			printk("[kernel] "
			       "possible issue with VMR prots on file %s!\n",
			       foc_to_name(file));
		/* Load the file's page in the page cache.
		 * TODO: (BLK) Note, we are holding the mem lock!  We need to
		 * rewrite this stuff so we aren't hold the lock as excessively
		 * as we are, and such that we can block and resume later. */
		assert(!PGOFF(va - vmr->vm_base + vmr->vm_foff));
		f_idx = (va - vmr->vm_base + vmr->vm_foff) >> PGSHIFT;
		/* This is a racy check - see the comments in fs_file.c */
		if (f_idx + 1 > nr_pages(foc_get_len(file))) {
			ret = -ESPIPE; /* linux sends a SIGBUS at access time */
			goto out;
		}
		ret = pm_load_page_nowait(foc_to_pm(file), f_idx, &a_page);
		if (ret) {
			if (ret != -EAGAIN)
				goto out;
			/* keep the file alive after we unlock */
			foc_incref(file);
			spin_unlock(&p->vmr_lock);
			ret = __hpf_load_page(p, foc_to_pm(file), f_idx,
					      &a_page, first);
			first = FALSE;
			foc_decref(file);
			if (ret)
				return ret;
			goto refault;
		}
		/* If we want a private map, we'll preemptively give you a new
		 * page.  We used to just care if it was private and writable,
		 * but were running into issues with libc changing its mapping
		 * (map private, then mprotect to writable...)  In the future,
		 * we want to CoW this anyway, so it's not a big deal. */
		if ((vmr->vm_flags & MAP_PRIVATE)) {
			ret = __copy_and_swap_pmpg(p, &a_page);
			if (ret)
				goto out_put_pg;
		}
		/* if this is an executable page, we might have to flush the
		 * instruction cache if our HW requires it. */
		if (vmr->vm_prot & PROT_EXEC)
			icache_flush_page((void*)va, page2kva(a_page));
	}
	/* update the page table TODO: careful with MAP_PRIVATE etc.  might do
	 * this separately (file, no file) */
	int pte_prot = (vmr->vm_prot & PROT_WRITE) ? PTE_USER_RW :
	               (vmr->vm_prot & (PROT_READ|PROT_EXEC)) ? PTE_USER_RO : 0;
	ret = map_page_at_addr(p, a_page, va, pte_prot);
	/* fall through, even for errors */
out_put_pg:
	/* the VMR's existence in the PM (via the mmap) allows us to have PTE
	 * point to a_page without it magically being reallocated.  For non-PM
	 * memory (anon memory or private pages) we transferred the ref to the
	 * PTE. */
	if (page_is_pagemap(a_page))
		pm_put_page(a_page);
out:
	spin_unlock(&p->vmr_lock);
	return ret;
}

int handle_page_fault(struct proc *p, uintptr_t va, int prot)
{
	return __hpf(p, va, prot, TRUE);
}

int handle_page_fault_nofile(struct proc *p, uintptr_t va, int prot)
{
	return __hpf(p, va, prot, FALSE);
}

/* Attempts to populate the pages, as if there was a page faults.  Bails on
 * errors, and returns the number of pages populated.  */
unsigned long populate_va(struct proc *p, uintptr_t va, unsigned long nr_pgs)
{
	struct vm_region *vmr, vmr_copy;
	struct file_or_chan *file;
	unsigned long nr_pgs_this_vmr;
	unsigned long nr_filled = 0;
	struct page *page;
	int pte_prot;
	int ret;

	/* we can screw around with ways to limit the find_vmr calls (can do the
	 * next in line if we didn't unlock, etc., but i don't expect us to do
	 * this for more than a single VMR in most cases. */
	spin_lock(&p->vmr_lock);
	while (nr_pgs) {
		vmr = find_vmr(p, va);
		if (!vmr)
			break;
		if (!prot_has_access(vmr->vm_prot))
			break;
		pte_prot = (vmr->vm_prot & PROT_WRITE) ? PTE_USER_RW :
		           (vmr->vm_prot & (PROT_READ|PROT_EXEC)) ? PTE_USER_RO
			                                          : 0;
		nr_pgs_this_vmr = MIN(nr_pgs, (vmr->vm_end - va) >> PGSHIFT);
		if (!vmr_has_file(vmr)) {
			if (populate_anon_va(p, va, nr_pgs_this_vmr, pte_prot))
			{
				/* on any error, we can just bail.  we might be
				 * underestimating nr_filled. */
				break;
			}
		} else {
			file = vmr->__vm_foc;
			/* need to keep the file alive in case we unlock/block
			 */
			foc_incref(file);
			/* Regarding foff + (va - base): va - base < len, and
			 * foff + len does not over flow */
			ret = populate_pm_va(p, va, nr_pgs_this_vmr, pte_prot,
			                     foc_to_pm(file),
			                     vmr->vm_foff + (va - vmr->vm_base),
			                     vmr->vm_flags,
					     vmr->vm_prot & PROT_EXEC);
			foc_decref(file);
			if (ret) {
				/* we might have failed if the underlying file
				 * doesn't cover the mmap window, depending on
				 * how we'll deal with truncation. */
				break;
			}
		}
		nr_filled += nr_pgs_this_vmr;
		va += nr_pgs_this_vmr << PGSHIFT;
		nr_pgs -= nr_pgs_this_vmr;
	}
	spin_unlock(&p->vmr_lock);
	return nr_filled;
}

/* Kernel Dynamic Memory Mappings */

static struct arena *vmap_addr_arena;
struct arena *vmap_arena;
static spinlock_t vmap_lock = SPINLOCK_INITIALIZER;
struct vmap_free_tracker {
	void				*addr;
	size_t				nr_bytes;
};
static struct vmap_free_tracker *vmap_to_free;
static size_t vmap_nr_to_free;
/* This value tunes the ratio of global TLB shootdowns to __vmap_free()s. */
#define VMAP_MAX_TO_FREE 1000

/* We don't immediately return the addrs to their source (vmap_addr_arena).
 * Instead, we hold on to them until we have a suitable amount, then free them
 * in a batch.  This amoritizes the cost of the TLB global shootdown.  We can
 * explore other tricks in the future too (like RCU for a certain index in the
 * vmap_to_free array). */
static void __vmap_free(struct arena *source, void *obj, size_t size)
{
	struct vmap_free_tracker *vft;

	spin_lock(&vmap_lock);
	/* All objs get *unmapped* immediately, but we'll shootdown later.  Note
	 * that it is OK (but slightly dangerous) for the kernel to reuse the
	 * paddrs pointed to by the vaddrs before a TLB shootdown. */
	unmap_segment(boot_pgdir, (uintptr_t)obj, size);
	if (vmap_nr_to_free < VMAP_MAX_TO_FREE) {
		vft = &vmap_to_free[vmap_nr_to_free++];
		vft->addr = obj;
		vft->nr_bytes = size;
		spin_unlock(&vmap_lock);
		return;
	}
	tlb_shootdown_global();
	for (int i = 0; i < vmap_nr_to_free; i++) {
		vft = &vmap_to_free[i];
		arena_free(source, vft->addr, vft->nr_bytes);
	}
	/* don't forget to free the one passed in */
	arena_free(source, obj, size);
	vmap_nr_to_free = 0;
	spin_unlock(&vmap_lock);
}

void vmap_init(void)
{
	vmap_addr_arena = arena_create("vmap_addr", (void*)KERN_DYN_BOT,
	                               KERN_DYN_TOP - KERN_DYN_BOT,
	                               PGSIZE, NULL, NULL, NULL, 0, MEM_WAIT);
	vmap_arena = arena_create("vmap", NULL, 0, PGSIZE, arena_alloc,
				  __vmap_free, vmap_addr_arena, 0, MEM_WAIT);
	vmap_to_free = kmalloc(sizeof(struct vmap_free_tracker)
			       * VMAP_MAX_TO_FREE, MEM_WAIT);
	/* This ensures the boot_pgdir's top-most PML (PML4) has entries
	 * pointing to PML3s that cover the dynamic mapping range.  Now, it's
	 * safe to create processes that copy from boot_pgdir and still
	 * dynamically change the kernel mappings. */
	arch_add_intermediate_pts(boot_pgdir, KERN_DYN_BOT,
	                          KERN_DYN_TOP - KERN_DYN_BOT);
}

uintptr_t get_vmap_segment(size_t nr_bytes)
{
	uintptr_t ret;

	ret = (uintptr_t)arena_alloc(vmap_arena, nr_bytes, MEM_ATOMIC);
	assert(ret);
	return ret;
}

void put_vmap_segment(uintptr_t vaddr, size_t nr_bytes)
{
	arena_free(vmap_arena, (void*)vaddr, nr_bytes);
}

/* Map a virtual address chunk to physical addresses.  Make sure you got a vmap
 * segment before actually trying to do the mapping.
 *
 * Careful with more than one 'page', since it will assume your physical pages
 * are also contiguous.  Most callers will only use one page.
 *
 * Finally, note that this does not care whether or not there are real pages
 * being mapped, and will not attempt to incref your page (if there is such a
 * thing).  Handle your own refcnting for pages. */
int map_vmap_segment(uintptr_t vaddr, uintptr_t paddr, unsigned long num_pages,
                     int perm)
{
#ifdef CONFIG_X86
	perm |= PTE_G;
#endif
	spin_lock(&vmap_lock);
	map_segment(boot_pgdir, vaddr, num_pages * PGSIZE, paddr, perm,
	            arch_max_jumbo_page_shift());
	spin_unlock(&vmap_lock);
	return 0;
}

/* This can handle unaligned paddrs */
static uintptr_t vmap_pmem_flags(uintptr_t paddr, size_t nr_bytes, int flags)
{
	uintptr_t vaddr;
	unsigned long nr_pages;

	assert(nr_bytes && paddr);
	nr_bytes += PGOFF(paddr);
	nr_pages = ROUNDUP(nr_bytes, PGSIZE) >> PGSHIFT;
	vaddr = get_vmap_segment(nr_bytes);
	if (!vaddr) {
		warn("Unable to get a vmap segment");	/* probably a bug */
		return 0;
	}
	/* it's not strictly necessary to drop paddr's pgoff, but it might save
	 * some vmap heartache in the future. */
	if (map_vmap_segment(vaddr, PG_ADDR(paddr), nr_pages,
	                     PTE_KERN_RW | flags)) {
		warn("Unable to map a vmap segment");	/* probably a bug */
		return 0;
	}
	return vaddr + PGOFF(paddr);
}

uintptr_t vmap_pmem(uintptr_t paddr, size_t nr_bytes)
{
	return vmap_pmem_flags(paddr, nr_bytes, 0);
}

uintptr_t vmap_pmem_nocache(uintptr_t paddr, size_t nr_bytes)
{
	return vmap_pmem_flags(paddr, nr_bytes, PTE_NOCACHE);
}

uintptr_t vmap_pmem_writecomb(uintptr_t paddr, size_t nr_bytes)
{
	return vmap_pmem_flags(paddr, nr_bytes, PTE_WRITECOMB);
}

int vunmap_vmem(uintptr_t vaddr, size_t nr_bytes)
{
	nr_bytes += PGOFF(vaddr);
	put_vmap_segment(PG_ADDR(vaddr), nr_bytes);
	return 0;
}
