/* Copyright (c) 2009, 2010 The Regents of the University of California
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details. */

#include <event.h>
#include <arch/arch.h>
#include <bitmask.h>
#include <process.h>
#include <atomic.h>
#include <smp.h>
#include <pmap.h>
#include <trap.h>
#include <umem.h>
#include <schedule.h>
#include <manager.h>
#include <stdio.h>
#include <assert.h>
#include <time.h>
#include <hashtable.h>
#include <slab.h>
#include <sys/queue.h>
#include <frontend.h>
#include <monitor.h>
#include <elf.h>
#include <arsc_server.h>
#include <kmalloc.h>
#include <ros/procinfo.h>
#include <init.h>

struct kmem_cache *proc_cache;

/* Other helpers, implemented later. */
static bool is_mapped_vcore(struct proc *p, uint32_t pcoreid);
static uint32_t get_vcoreid(struct proc *p, uint32_t pcoreid);
static uint32_t try_get_pcoreid(struct proc *p, uint32_t vcoreid);
static uint32_t get_pcoreid(struct proc *p, uint32_t vcoreid);
static void __proc_free(struct kref *kref);
static bool scp_is_vcctx_ready(struct preempt_data *vcpd);
static void save_vc_fp_state(struct preempt_data *vcpd);
static void restore_vc_fp_state(struct preempt_data *vcpd);

/* PID management. */
#define PID_MAX 32767 // goes from 0 to 32767, with 0 reserved
static DECL_BITMASK(pid_bmask, PID_MAX + 1);
spinlock_t pid_bmask_lock = SPINLOCK_INITIALIZER;
struct hashtable *pid_hash;
spinlock_t pid_hash_lock; // initialized in proc_init

/* Finds the next free entry (zero) entry in the pid_bitmask.  Set means busy.
 * PID 0 is reserved (in proc_init).  A return value of 0 is a failure (and
 * you'll also see a warning, for now).  Consider doing this with atomics. */
static pid_t get_free_pid(void)
{
	static pid_t next_free_pid = 1;
	pid_t my_pid = 0;

	spin_lock(&pid_bmask_lock);
	// atomically (can lock for now, then change to atomic_and_return
	FOR_CIRC_BUFFER(next_free_pid, PID_MAX + 1, i) {
		// always points to the next to test
		next_free_pid = (next_free_pid + 1) % (PID_MAX + 1);
		if (!GET_BITMASK_BIT(pid_bmask, i)) {
			SET_BITMASK_BIT(pid_bmask, i);
			my_pid = i;
			break;
		}
	}
	spin_unlock(&pid_bmask_lock);
	if (!my_pid)
		warn("Shazbot!  Unable to find a PID!  You need to deal with this!\n");
	return my_pid;
}

/* Return a pid to the pid bitmask */
static void put_free_pid(pid_t pid)
{
	spin_lock(&pid_bmask_lock);
	CLR_BITMASK_BIT(pid_bmask, pid);
	spin_unlock(&pid_bmask_lock);
}

/* 'resume' is the time int ticks of the most recent onlining.  'total' is the
 * amount of time in ticks consumed up to and including the current offlining.
 *
 * We could move these to the map and unmap of vcores, though not every place
 * uses that (SCPs, in particular).  However, maps/unmaps happen remotely;
 * something to consider.  If we do it remotely, we can batch them up and do one
 * rdtsc() for all of them.  For now, I want to do them on the core, around when
 * we do the context change.  It'll also parallelize the accounting a bit. */
void vcore_account_online(struct proc *p, uint32_t vcoreid)
{
	struct vcore *vc = &p->procinfo->vcoremap[vcoreid];
	vc->resume_ticks = read_tsc();
}

void vcore_account_offline(struct proc *p, uint32_t vcoreid)
{
	struct vcore *vc = &p->procinfo->vcoremap[vcoreid];
	vc->total_ticks += read_tsc() - vc->resume_ticks;
}

uint64_t vcore_account_gettotal(struct proc *p, uint32_t vcoreid)
{
	struct vcore *vc = &p->procinfo->vcoremap[vcoreid];
	return vc->total_ticks;
}

/* While this could be done with just an assignment, this gives us the
 * opportunity to check for bad transitions.  Might compile these out later, so
 * we shouldn't rely on them for sanity checking from userspace.  */
int __proc_set_state(struct proc *p, uint32_t state)
{
	uint32_t curstate = p->state;
	/* Valid transitions:
	 * C   -> RBS
	 * C   -> D
	 * RBS -> RGS
	 * RGS -> RBS
	 * RGS -> W
	 * RGM -> W
	 * W   -> RBS
	 * W   -> RGS
	 * W   -> RBM
	 * W   -> D
	 * RGS -> RBM
	 * RBM -> RGM
	 * RGM -> RBM
	 * RGM -> RBS
	 * RGS -> D
	 * RGM -> D
	 * D   -> DA
	 *
	 * These ought to be implemented later (allowed, not thought through yet).
	 * RBS -> D
	 * RBM -> D
	 */
	#if 1 // some sort of correctness flag
	switch (curstate) {
		case PROC_CREATED:
			if (!(state & (PROC_RUNNABLE_S | PROC_DYING)))
				panic("Invalid State Transition! PROC_CREATED to %02x", state);
			break;
		case PROC_RUNNABLE_S:
			if (!(state & (PROC_RUNNING_S | PROC_DYING)))
				panic("Invalid State Transition! PROC_RUNNABLE_S to %02x", state);
			break;
		case PROC_RUNNING_S:
			if (!(state & (PROC_RUNNABLE_S | PROC_RUNNABLE_M | PROC_WAITING |
			               PROC_DYING)))
				panic("Invalid State Transition! PROC_RUNNING_S to %02x", state);
			break;
		case PROC_WAITING:
			if (!(state & (PROC_RUNNABLE_S | PROC_RUNNING_S | PROC_RUNNABLE_M |
			               PROC_DYING)))
				panic("Invalid State Transition! PROC_WAITING to %02x", state);
			break;
		case PROC_DYING:
			if (state != PROC_DYING_ABORT)
				panic("Invalid State Transition! PROC_DYING to %02x", state);
			break;
		case PROC_DYING_ABORT:
			panic("Invalid State Transition! PROC_DYING to %02x", state);
			break;
		case PROC_RUNNABLE_M:
			if (!(state & (PROC_RUNNING_M | PROC_DYING)))
				panic("Invalid State Transition! PROC_RUNNABLE_M to %02x", state);
			break;
		case PROC_RUNNING_M:
			if (!(state & (PROC_RUNNABLE_S | PROC_RUNNABLE_M | PROC_WAITING |
			               PROC_DYING)))
				panic("Invalid State Transition! PROC_RUNNING_M to %02x", state);
			break;
	}
	#endif
	p->state = state;
	return 0;
}

/* Returns a pointer to the proc with the given pid, or 0 if there is none.
 * This uses get_not_zero, since it is possible the refcnt is 0, which means the
 * process is dying and we should not have the ref (and thus return 0).  We need
 * to lock to protect us from getting p, (someone else removes and frees p),
 * then get_not_zero() on p.
 * Don't push the locking into the hashtable without dealing with this. */
struct proc *pid2proc(pid_t pid)
{
	spin_lock(&pid_hash_lock);
	struct proc *p = hashtable_search(pid_hash, (void*)(long)pid);
	if (p)
		if (!kref_get_not_zero(&p->p_kref, 1))
			p = 0;
	spin_unlock(&pid_hash_lock);
	return p;
}

/* Used by devproc for successive reads of the proc table.
 * Returns a pointer to the nth proc, or 0 if there is none.
 * This uses get_not_zero, since it is possible the refcnt is 0, which means the
 * process is dying and we should not have the ref (and thus return 0).  We need
 * to lock to protect us from getting p, (someone else removes and frees p),
 * then get_not_zero() on p.
 * Don't push the locking into the hashtable without dealing with this. */
struct proc *pid_nth(unsigned int n)
{
	struct proc *p;
	spin_lock(&pid_hash_lock);
	if (!hashtable_count(pid_hash)) {
		spin_unlock(&pid_hash_lock);
		return NULL;
	}
	struct hashtable_itr *iter = hashtable_iterator(pid_hash);
	p = hashtable_iterator_value(iter);

	while (p) {
		/* if this process is not valid, it doesn't count,
		 * so continue
		 */

		if (kref_get_not_zero(&p->p_kref, 1)) {
			/* this one counts */
			if (! n){
				printd("pid_nth: at end, p %p\n", p);
				break;
			}
			kref_put(&p->p_kref);
			n--;
		}
		if (!hashtable_iterator_advance(iter)) {
			p = NULL;
			break;
		}
		p = hashtable_iterator_value(iter);
	}

	spin_unlock(&pid_hash_lock);
	kfree(iter);
	return p;
}

/* Performs any initialization related to processes, such as create the proc
 * cache, prep the scheduler, etc.  When this returns, we should be ready to use
 * any process related function. */
void proc_init(void)
{
	/* Catch issues with the vcoremap and TAILQ_ENTRY sizes */
	static_assert(sizeof(TAILQ_ENTRY(vcore)) == sizeof(void*) * 2);
	proc_cache = kmem_cache_create("proc", sizeof(struct proc),
				       MAX(ARCH_CL_SIZE,
				       __alignof__(struct proc)), 0, NULL, 0,
				       0, NULL);
	/* Init PID mask and hash.  pid 0 is reserved. */
	SET_BITMASK_BIT(pid_bmask, 0);
	spinlock_init(&pid_hash_lock);
	spin_lock(&pid_hash_lock);
	pid_hash = create_hashtable(100, __generic_hash, __generic_eq);
	spin_unlock(&pid_hash_lock);
	schedule_init();

	atomic_init(&num_envs, 0);
}

void proc_set_progname(struct proc *p, char *name)
{
	if (name == NULL)
		name = DEFAULT_PROGNAME;

	/* might have an issue if a dentry name isn't null terminated, and we'd get
	 * extra junk up to progname_sz. Or crash. */
	strlcpy(p->progname, name, PROC_PROGNAME_SZ);
}

void proc_replace_binary_path(struct proc *p, char *path)
{
	if (p->binary_path)
		free_path(p, p->binary_path);
	p->binary_path = path;
}

/* Be sure you init'd the vcore lists before calling this. */
void proc_init_procinfo(struct proc* p)
{
	p->procinfo->pid = p->pid;
	p->procinfo->ppid = p->ppid;
	p->procinfo->max_vcores = max_vcores(p);
	p->procinfo->tsc_freq = __proc_global_info.tsc_freq;
	p->procinfo->timing_overhead = __proc_global_info.tsc_overhead;
	p->procinfo->program_end = 0;
	/* 0'ing the arguments.  Some higher function will need to set them */
	memset(p->procinfo->res_grant, 0, sizeof(p->procinfo->res_grant));
	/* 0'ing the vcore/pcore map.  Will link the vcores later. */
	memset(&p->procinfo->vcoremap, 0, sizeof(p->procinfo->vcoremap));
	memset(&p->procinfo->pcoremap, 0, sizeof(p->procinfo->pcoremap));
	p->procinfo->num_vcores = 0;
	p->procinfo->is_mcp = FALSE;
	p->procinfo->coremap_seqctr = SEQCTR_INITIALIZER;
	/* It's a bug in the kernel if we let them ask for more than max */
	for (int i = 0; i < p->procinfo->max_vcores; i++) {
		TAILQ_INSERT_TAIL(&p->inactive_vcs, &p->procinfo->vcoremap[i], list);
	}
}

void proc_init_procdata(struct proc *p)
{
	memset(p->procdata, 0, sizeof(struct procdata));
	/* processes can't go into vc context on vc 0 til they unset this.  This is
	 * for processes that block before initing uthread code (like rtld). */
	atomic_set(&p->procdata->vcore_preempt_data[0].flags, VC_SCP_NOVCCTX);
}

static void proc_open_stdfds(struct proc *p)
{
	int fd;
	struct proc *old_current = current;

	/* Due to the way the syscall helpers assume the target process is current,
	 * we need to set current temporarily.  We don't use switch_to, since that
	 * actually loads the process's address space, which might be empty or
	 * incomplete.  These syscalls shouldn't access user memory, especially
	 * considering how we're probably in the boot pgdir. */
	current = p;
	fd = sysopenat(AT_FDCWD, "#cons/stdin", O_READ);
	assert(fd == 0);
	fd = sysopenat(AT_FDCWD, "#cons/stdout", O_WRITE);
	assert(fd == 1);
	fd = sysopenat(AT_FDCWD, "#cons/stderr", O_WRITE);
	assert(fd == 2);
	current = old_current;
}

/* Allocates and initializes a process, with the given parent.  Currently
 * writes the *p into **pp, and returns 0 on success, < 0 for an error.
 * Errors include:
 *  - ENOFREEPID if it can't get a PID
 *  - ENOMEM on memory exhaustion */
error_t proc_alloc(struct proc **pp, struct proc *parent, int flags)
{
	error_t r;
	struct proc *p;

	if (!(p = kmem_cache_alloc(proc_cache, 0)))
		return -ENOMEM;
	/* zero everything by default, other specific items are set below */
	memset(p, 0, sizeof(*p));

	/* only one ref, which we pass back.  the old 'existence' ref is managed by
	 * the ksched */
	kref_init(&p->p_kref, __proc_free, 1);
	/* Initialize the address space */
	if ((r = env_setup_vm(p)) < 0) {
		kmem_cache_free(proc_cache, p);
		return r;
	}
	if (!(p->pid = get_free_pid())) {
		kmem_cache_free(proc_cache, p);
		return -ENOFREEPID;
	}
	if (parent && parent->binary_path)
		kstrdup(&p->binary_path, parent->binary_path);
	/* Set the basic status variables. */
	spinlock_init(&p->proc_lock);
	p->exitcode = 1337;	/* so we can see processes killed by the kernel */
	if (parent) {
		p->ppid = parent->pid;
		proc_incref(p, 1);	/* storing a ref in the parent */
		/* using the CV's lock to protect anything related to child waiting */
		cv_lock(&parent->child_wait);
		TAILQ_INSERT_TAIL(&parent->children, p, sibling_link);
		cv_unlock(&parent->child_wait);
	} else {
		p->ppid = 0;
	}
	TAILQ_INIT(&p->children);
	cv_init(&p->child_wait);
	p->state = PROC_CREATED; /* shouldn't go through state machine for init */
	p->env_flags = 0;
	spinlock_init(&p->vmr_lock);
	spinlock_init(&p->pte_lock);
	TAILQ_INIT(&p->vm_regions); /* could init this in the slab */
	p->vmr_history = 0;
	/* Initialize the vcore lists, we'll build the inactive list so that it
	 * includes all vcores when we initialize procinfo.  Do this before initing
	 * procinfo. */
	TAILQ_INIT(&p->online_vcs);
	TAILQ_INIT(&p->bulk_preempted_vcs);
	TAILQ_INIT(&p->inactive_vcs);
	/* Init procinfo/procdata.  Procinfo's argp/argb are 0'd */
	proc_init_procinfo(p);
	proc_init_procdata(p);

	/* Initialize the generic sysevent ring buffer */
	SHARED_RING_INIT(&p->procdata->syseventring);
	/* Initialize the frontend of the sysevent ring buffer */
	FRONT_RING_INIT(&p->syseventfrontring,
	                &p->procdata->syseventring,
	                SYSEVENTRINGSIZE);

	/* Init FS structures TODO: cleanup (might pull this out) */
	kref_get(&default_ns.kref, 1);
	p->ns = &default_ns;
	spinlock_init(&p->fs_env.lock);
	p->fs_env.umask = parent ? parent->fs_env.umask : S_IWGRP | S_IWOTH;
	p->fs_env.root = p->ns->root->mnt_root;
	kref_get(&p->fs_env.root->d_kref, 1);
	p->fs_env.pwd = parent ? parent->fs_env.pwd : p->fs_env.root;
	kref_get(&p->fs_env.pwd->d_kref, 1);
	memset(&p->open_files, 0, sizeof(p->open_files));	/* slightly ghetto */
	spinlock_init(&p->open_files.lock);
	p->open_files.max_files = NR_OPEN_FILES_DEFAULT;
	p->open_files.max_fdset = NR_FILE_DESC_DEFAULT;
	p->open_files.fd = p->open_files.fd_array;
	p->open_files.open_fds = (struct fd_set*)&p->open_files.open_fds_init;
	if (parent) {
		if (flags & PROC_DUP_FGRP)
			clone_fdt(&parent->open_files, &p->open_files);
	} else {
		/* no parent, we're created from the kernel */
		proc_open_stdfds(p);
	}
	/* Init the ucq hash lock */
	p->ucq_hashlock = (struct hashlock*)&p->ucq_hl_noref;
	hashlock_init_irqsave(p->ucq_hashlock, HASHLOCK_DEFAULT_SZ);

	atomic_inc(&num_envs);
	frontend_proc_init(p);
	plan9setup(p, parent, flags);
	devalarm_init(p);
	TAILQ_INIT(&p->abortable_sleepers);
	spinlock_init_irqsave(&p->abort_list_lock);
	memset(&p->vmm, 0, sizeof(struct vmm));
	spinlock_init(&p->vmm.lock);
	qlock_init(&p->vmm.qlock);
	printd("[%08x] new process %08x\n", current ? current->pid : 0, p->pid);
	*pp = p;
	return 0;
}

/* We have a bunch of different ways to make processes.  Call this once the
 * process is ready to be used by the rest of the system.  For now, this just
 * means when it is ready to be named via the pidhash.  In the future, we might
 * push setting the state to CREATED into here. */
void __proc_ready(struct proc *p)
{
	/* Tell the ksched about us.  TODO: do we need to worry about the ksched
	 * doing stuff to us before we're added to the pid_hash? */
	__sched_proc_register(p);
	spin_lock(&pid_hash_lock);
	hashtable_insert(pid_hash, (void*)(long)p->pid, p);
	spin_unlock(&pid_hash_lock);
}

/* Creates a process from the specified file, argvs, and envps. */
struct proc *proc_create(struct file *prog, char **argv, char **envp)
{
	struct proc *p;
	error_t r;
	if ((r = proc_alloc(&p, current, 0 /* flags */)) < 0)
		panic("proc_create: %d", r);
	int argc = 0, envc = 0;
	if(argv) while(argv[argc]) argc++;
	if(envp) while(envp[envc]) envc++;
	proc_set_progname(p, argc ? argv[0] : NULL);
	assert(load_elf(p, prog, argc, argv, envc, envp) == 0);
	__proc_ready(p);
	return p;
}

static int __cb_assert_no_pg(struct proc *p, pte_t pte, void *va, void *arg)
{
	assert(pte_is_unmapped(pte));
	return 0;
}

/* This is called by kref_put(), once the last reference to the process is
 * gone.  Don't call this otherwise (it will panic).  It will clean up the
 * address space and deallocate any other used memory. */
static void __proc_free(struct kref *kref)
{
	struct proc *p = container_of(kref, struct proc, p_kref);
	void *hash_ret;
	physaddr_t pa;

	printd("[PID %d] freeing proc: %d\n", current ? current->pid : 0, p->pid);
	// All parts of the kernel should have decref'd before __proc_free is called
	assert(kref_refcnt(&p->p_kref) == 0);
	assert(TAILQ_EMPTY(&p->alarmset.list));

	if (p->strace) {
		kref_put(&p->strace->procs);
		kref_put(&p->strace->users);
	}
	__vmm_struct_cleanup(p);
	p->progname[0] = 0;
	free_path(p, p->binary_path);
	cclose(p->dot);
	cclose(p->slash);
	p->dot = p->slash = 0; /* catch bugs */
	kref_put(&p->fs_env.root->d_kref);
	kref_put(&p->fs_env.pwd->d_kref);
	/* now we'll finally decref files for the file-backed vmrs */
	unmap_and_destroy_vmrs(p);
	frontend_proc_free(p);	/* TODO: please remove me one day */
	/* Remove us from the pid_hash and give our PID back (in that order). */
	spin_lock(&pid_hash_lock);
	hash_ret = hashtable_remove(pid_hash, (void*)(long)p->pid);
	spin_unlock(&pid_hash_lock);
	/* might not be in the hash/ready, if we failed during proc creation */
	if (hash_ret)
		put_free_pid(p->pid);
	else
		printd("[kernel] pid %d not in the PID hash in %s\n", p->pid,
		       __FUNCTION__);
	/* All memory below UMAPTOP should have been freed via the VMRs.  The stuff
	 * above is the global info/page and procinfo/procdata.  We free procinfo
	 * and procdata, but not the global memory - that's system wide.  We could
	 * clear the PTEs of the upper stuff (UMAPTOP to UVPT), but we shouldn't
	 * need to. */
	env_user_mem_walk(p, 0, UMAPTOP, __cb_assert_no_pg, 0);
	kpages_free(p->procinfo, PROCINFO_NUM_PAGES * PGSIZE);
	kpages_free(p->procdata, PROCDATA_NUM_PAGES * PGSIZE);

	env_pagetable_free(p);
	arch_pgdir_clear(&p->env_pgdir);
	p->env_cr3 = 0;

	atomic_dec(&num_envs);

	/* Dealloc the struct proc */
	kmem_cache_free(proc_cache, p);
}

/* Whether or not actor can control target.  TODO: do something reasonable here.
 * Just checking for the parent is a bit limiting.  Could walk the parent-child
 * tree, check user ids, or some combination.  Make sure actors can always
 * control themselves. */
bool proc_controls(struct proc *actor, struct proc *target)
{
	return TRUE;
	#if 0 /* Example: */
	return ((actor == target) || (target->ppid == actor->pid));
	#endif
}

/* Helper to incref by val.  Using the helper to help debug/interpose on proc
 * ref counting.  Note that pid2proc doesn't use this interface. */
void proc_incref(struct proc *p, unsigned int val)
{
	kref_get(&p->p_kref, val);
}

/* Helper to decref for debugging.  Don't directly kref_put() for now. */
void proc_decref(struct proc *p)
{
	kref_put(&p->p_kref);
}

/* Helper, makes p the 'current' process, dropping the old current/cr3.  This no
 * longer assumes the passed in reference already counted 'current'.  It will
 * incref internally when needed. */
static void __set_proc_current(struct proc *p)
{
	/* We use the pcpui to access 'current' to cut down on the core_id() calls,
	 * though who know how expensive/painful they are. */
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	/* If the process wasn't here, then we need to load its address space. */
	if (p != pcpui->cur_proc) {
		proc_incref(p, 1);
		lcr3(p->env_cr3);
		/* This is "leaving the process context" of the previous proc.  The
		 * previous lcr3 unloaded the previous proc's context.  This should
		 * rarely happen, since we usually proactively leave process context,
		 * but this is the fallback. */
		if (pcpui->cur_proc)
			proc_decref(pcpui->cur_proc);
		pcpui->cur_proc = p;
	}
}

/* Flag says if vcore context is not ready, which is set in init_procdata.  The
 * process must turn off this flag on vcore0 at some point.  It's off by default
 * on all other vcores. */
static bool scp_is_vcctx_ready(struct preempt_data *vcpd)
{
	return !(atomic_read(&vcpd->flags) & VC_SCP_NOVCCTX);
}

/* Dispatches a _S process to run on the current core.  This should never be
 * called to "restart" a core.
 *
 * This will always return, regardless of whether or not the calling core is
 * being given to a process. (it used to pop the tf directly, before we had
 * cur_ctx).
 *
 * Since it always returns, it will never "eat" your reference (old
 * documentation talks about this a bit). */
void proc_run_s(struct proc *p)
{
	uint32_t coreid = core_id();
	struct per_cpu_info *pcpui = &per_cpu_info[coreid];
	struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[0];
	spin_lock(&p->proc_lock);
	switch (p->state) {
		case (PROC_DYING):
		case (PROC_DYING_ABORT):
			spin_unlock(&p->proc_lock);
			printk("[kernel] _S %d not starting due to async death\n", p->pid);
			return;
		case (PROC_RUNNABLE_S):
			__proc_set_state(p, PROC_RUNNING_S);
			/* SCPs don't have full vcores, but they act like they have vcore 0.
			 * We map the vcore, since we will want to know where this process
			 * is running, even if it is only in RUNNING_S.  We can use the
			 * vcoremap, which makes death easy.  num_vcores is still 0, and we
			 * do account the time online and offline. */
			__seq_start_write(&p->procinfo->coremap_seqctr);
			p->procinfo->num_vcores = 0;
			__map_vcore(p, 0, coreid);
			vcore_account_online(p, 0);
			__seq_end_write(&p->procinfo->coremap_seqctr);
			/* incref, since we're saving a reference in owning proc later */
			proc_incref(p, 1);
			/* lock was protecting the state and VC mapping, not pcpui stuff */
			spin_unlock(&p->proc_lock);
			/* redundant with proc_startcore, might be able to remove that one*/
			__set_proc_current(p);
			/* set us up as owning_proc.  ksched bug if there is already one,
			 * for now.  can simply clear_owning if we want to. */
			assert(!pcpui->owning_proc);
			pcpui->owning_proc = p;
			pcpui->owning_vcoreid = 0;
			restore_vc_fp_state(vcpd);
			/* similar to the old __startcore, start them in vcore context if
			 * they have notifs and aren't already in vcore context.  o/w, start
			 * them wherever they were before (could be either vc ctx or not) */
			if (!vcpd->notif_disabled && vcpd->notif_pending
			                          && scp_is_vcctx_ready(vcpd)) {
				vcpd->notif_disabled = TRUE;
				/* save the _S's ctx in the uthread slot, build and pop a new
				 * one in actual/cur_ctx. */
				vcpd->uthread_ctx = p->scp_ctx;
				pcpui->cur_ctx = &pcpui->actual_ctx;
				memset(pcpui->cur_ctx, 0, sizeof(struct user_context));
				proc_init_ctx(pcpui->cur_ctx, 0, vcpd->vcore_entry,
				              vcpd->vcore_stack, vcpd->vcore_tls_desc);
			} else {
				/* If they have no transition stack, then they can't receive
				 * events.  The most they are getting is a wakeup from the
				 * kernel.  They won't even turn off notif_pending, so we'll do
				 * that for them. */
				if (!scp_is_vcctx_ready(vcpd))
					vcpd->notif_pending = FALSE;
				/* this is one of the few times cur_ctx != &actual_ctx */
				pcpui->cur_ctx = &p->scp_ctx;
			}
			/* When the calling core idles, it'll call restartcore and run the
			 * _S process's context. */
			return;
		default:
			spin_unlock(&p->proc_lock);
			panic("Invalid process state %p in %s()!!", p->state, __FUNCTION__);
	}
}

/* Helper: sends preempt messages to all vcores on the bulk preempt list, and
 * moves them to the inactive list. */
static void __send_bulkp_events(struct proc *p)
{
	struct vcore *vc_i, *vc_temp;
	struct event_msg preempt_msg = {0};
	/* Whenever we send msgs with the proc locked, we need at least 1 online */
	assert(!TAILQ_EMPTY(&p->online_vcs));
	/* Send preempt messages for any left on the BP list.  No need to set any
	 * flags, it all was done on the real preempt.  Now we're just telling the
	 * process about any that didn't get restarted and are still preempted. */
	TAILQ_FOREACH_SAFE(vc_i, &p->bulk_preempted_vcs, list, vc_temp) {
		/* Note that if there are no active vcores, send_k_e will post to our
		 * own vcore, the last of which will be put on the inactive list and be
		 * the first to be started.  We could have issues with deadlocking,
		 * since send_k_e() could grab the proclock (if there are no active
		 * vcores) */
		preempt_msg.ev_type = EV_VCORE_PREEMPT;
		preempt_msg.ev_arg2 = vcore2vcoreid(p, vc_i);	/* arg2 is 32 bits */
		send_kernel_event(p, &preempt_msg, 0);
		/* TODO: we may want a TAILQ_CONCAT_HEAD, or something that does that.
		 * We need a loop for the messages, but not necessarily for the list
		 * changes.  */
		TAILQ_REMOVE(&p->bulk_preempted_vcs, vc_i, list);
		TAILQ_INSERT_HEAD(&p->inactive_vcs, vc_i, list);
	}
}

/* Run an _M.  Can be called safely on one that is already running.  Hold the
 * lock before calling.  Other than state checks, this just starts up the _M's
 * vcores, much like the second part of give_cores_running.  More specifically,
 * give_cores_runnable puts cores on the online list, which this then sends
 * messages to.  give_cores_running immediately puts them on the list and sends
 * the message.  the two-step style may go out of fashion soon.
 *
 * This expects that the "instructions" for which core(s) to run this on will be
 * in the vcoremap, which needs to be set externally (give_cores()). */
void __proc_run_m(struct proc *p)
{
	struct vcore *vc_i;
	switch (p->state) {
		case (PROC_WAITING):
		case (PROC_DYING):
		case (PROC_DYING_ABORT):
			warn("ksched tried to run proc %d in state %s\n", p->pid,
			     procstate2str(p->state));
			return;
		case (PROC_RUNNABLE_M):
			/* vcoremap[i] holds the coreid of the physical core allocated to
			 * this process.  It is set outside proc_run. */
			if (p->procinfo->num_vcores) {
				__send_bulkp_events(p);
				__proc_set_state(p, PROC_RUNNING_M);
				/* Up the refcnt, to avoid the n refcnt upping on the
				 * destination cores.  Keep in sync with __startcore */
				proc_incref(p, p->procinfo->num_vcores * 2);
				/* Send kernel messages to all online vcores (which were added
				 * to the list and mapped in __proc_give_cores()), making them
				 * turn online */
				TAILQ_FOREACH(vc_i, &p->online_vcs, list) {
					send_kernel_message(vc_i->pcoreid, __startcore, (long)p,
					                    (long)vcore2vcoreid(p, vc_i),
					                    (long)vc_i->nr_preempts_sent,
					                    KMSG_ROUTINE);
				}
			} else {
				warn("Tried to proc_run() an _M with no vcores!");
			}
			/* There a subtle race avoidance here (when we unlock after sending
			 * the message).  __proc_startcore can handle a death message, but
			 * we can't have the startcore come after the death message.
			 * Otherwise, it would look like a new process.  So we hold the lock
			 * til after we send our message, which prevents a possible death
			 * message.
			 * - Note there is no guarantee this core's interrupts were on, so
			 *   it may not get the message for a while... */
			return;
		case (PROC_RUNNING_M):
			return;
		default:
			/* unlock just so the monitor can call something that might lock*/
			spin_unlock(&p->proc_lock);
			panic("Invalid process state %p in %s()!!", p->state, __FUNCTION__);
	}
}

/* You must disable IRQs and PRKM before calling this.
 *
 * Actually runs the given context (trapframe) of process p on the core this
 * code executes on.  This is called directly by __startcore, which needs to
 * bypass the routine_kmsg check.  Interrupts should be off when you call this.
 *
 * A note on refcnting: this function will not return, and your proc reference
 * will end up stored in current.  This will make no changes to p's refcnt, so
 * do your accounting such that there is only the +1 for current.  This means if
 * it is already in current (like in the trap return path), don't up it.  If
 * it's already in current and you have another reference (like pid2proc or from
 * an IPI), then down it (which is what happens in __startcore()).  If it's not
 * in current and you have one reference, like proc_run(non_current_p), then
 * also do nothing.  The refcnt for your *p will count for the reference stored
 * in current. */
void __proc_startcore(struct proc *p, struct user_context *ctx)
{
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	assert(!irq_is_enabled());
	/* Should never have ktask still set.  If we do, future syscalls could try
	 * to block later and lose track of our address space. */
	assert(!is_ktask(pcpui->cur_kthread));
	__set_proc_current(p);
	__set_cpu_state(pcpui, CPU_STATE_USER);
	proc_pop_ctx(ctx);
}

/* Restarts/runs the current_ctx, which must be for the current process, on the
 * core this code executes on.  Calls an internal function to do the work.
 *
 * In case there are pending routine messages, like __death, __preempt, or
 * __notify, we need to run them.  Alternatively, if there are any, we could
 * self_ipi, and run the messages immediately after popping back to userspace,
 * but that would have crappy overhead. */
void proc_restartcore(void)
{
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];

	assert(!pcpui->cur_kthread->sysc);
	process_routine_kmsg();
	/* If there is no owning process, just idle, since we don't know what to do.
	 * This could be because the process had been restarted a long time ago and
	 * has since left the core, or due to a KMSG like __preempt or __death. */
	if (!pcpui->owning_proc) {
		abandon_core();
		smp_idle();
	}
	assert(pcpui->cur_ctx);
	__proc_startcore(pcpui->owning_proc, pcpui->cur_ctx);
}

/* Destroys the process.  It will destroy the process and return any cores
 * to the ksched via the __sched_proc_destroy() CB.
 *
 * Here's the way process death works:
 * 0. grab the lock (protects state transition and core map)
 * 1. set state to dying.  that keeps the kernel from doing anything for the
 * process (like proc_running it).
 * 2. figure out where the process is running (cross-core/async or RUNNING_M)
 * 3. IPI to clean up those cores (decref, etc).
 * 4. Unlock
 * 5. Clean up your core, if applicable
 * (Last core/kernel thread to decref cleans up and deallocates resources.)
 *
 * Note that some cores can be processing async calls, but will eventually
 * decref.  Should think about this more, like some sort of callback/revocation.
 *
 * This function will now always return (it used to not return if the calling
 * core was dying).  However, when it returns, a kernel message will eventually
 * come in, making you abandon_core, as if you weren't running.  It may be that
 * the only reference to p is the one you passed in, and when you decref, it'll
 * get __proc_free()d. */
void proc_destroy(struct proc *p)
{
	uint32_t nr_cores_revoked = 0;
	struct kthread *sleeper;
	struct proc *child_i, *temp;

	spin_lock(&p->proc_lock);
	/* storage for pc_arr is alloced at decl, which is after grabbing the lock*/
	uint32_t pc_arr[p->procinfo->num_vcores];
	switch (p->state) {
		case PROC_DYING: /* someone else killed this already. */
		case (PROC_DYING_ABORT):
			spin_unlock(&p->proc_lock);
			return;
		case PROC_CREATED:
		case PROC_RUNNABLE_S:
		case PROC_WAITING:
			break;
		case PROC_RUNNABLE_M:
		case PROC_RUNNING_M:
			/* Need to reclaim any cores this proc might have, even if it's not
			 * running yet.  Those running will receive a __death */
			nr_cores_revoked = __proc_take_allcores(p, pc_arr, FALSE);
			break;
		case PROC_RUNNING_S:
			#if 0
			// here's how to do it manually
			if (current == p) {
				lcr3(boot_cr3);
				proc_decref(p);		/* this decref is for the cr3 */
				current = NULL;
			}
			#endif
			send_kernel_message(get_pcoreid(p, 0), __death, 0, 0, 0,
			                    KMSG_ROUTINE);
			__seq_start_write(&p->procinfo->coremap_seqctr);
			__unmap_vcore(p, 0);
			__seq_end_write(&p->procinfo->coremap_seqctr);
			/* If we ever have RUNNING_S run on non-mgmt cores, we'll need to
			 * tell the ksched about this now-idle core (after unlocking) */
			break;
		default:
			warn("Weird state(%s) in %s()", procstate2str(p->state),
			     __FUNCTION__);
			spin_unlock(&p->proc_lock);
			return;
	}
	/* At this point, a death IPI should be on its way, either from the
	 * RUNNING_S one, or from proc_take_cores with a __death.  in general,
	 * interrupts should be on when you call proc_destroy locally, but currently
	 * aren't for all things (like traphandlers). */
	__proc_set_state(p, PROC_DYING);
	/* Disown any children.  If we want to have init inherit or something,
	 * change __disown to set the ppid accordingly and concat this with init's
	 * list (instead of emptying it like disown does).  Careful of lock ordering
	 * between procs (need to lock to protect lists) */
	TAILQ_FOREACH_SAFE(child_i, &p->children, sibling_link, temp) {
		int ret = __proc_disown_child(p, child_i);
		/* should never fail, lock should cover the race.  invariant: any child
		 * on the list should have us as a parent */
		assert(!ret);
	}
	spin_unlock(&p->proc_lock);
	/* Wake any of our kthreads waiting on children, so they can abort */
	cv_broadcast(&p->child_wait);
	/* we need to close files here, and not in free, since we could have a
	 * refcnt indirectly related to one of our files.  specifically, if we have
	 * a parent sleeping on our pipe, that parent won't wake up to decref until
	 * the pipe closes.  And if the parent doesnt decref, we don't free.
	 * Even if we send a SIGCHLD to the parent, that would require that the
	 * parent to never ignores that signal (or we risk never reaping).
	 *
	 * Also note that any mmap'd files will still be mmapped.  You can close the
	 * file after mmapping, with no effect. */
	close_fdt(&p->open_files, FALSE);
	/* Abort any abortable syscalls.  This won't catch every sleeper, but future
	 * abortable sleepers are already prevented via the DYING_ABORT state.
	 * (signalled DYING_ABORT, no new sleepers will block, and now we wake all
	 * old sleepers). */
	__proc_set_state(p, PROC_DYING_ABORT);
	abort_all_sysc(p);
	/* Tell the ksched about our death, and which cores we freed up */
	__sched_proc_destroy(p, pc_arr, nr_cores_revoked);
	/* Tell our parent about our state change (to DYING) */
	proc_signal_parent(p);
}

/* Can use this to signal anything that might cause a parent to wait on the
 * child, such as termination, or signals.  Change the state or whatever before
 * calling. */
void proc_signal_parent(struct proc *child)
{
	struct kthread *sleeper;
	struct proc *parent = pid2proc(child->ppid);
	if (!parent)
		return;
	send_posix_signal(parent, SIGCHLD);
	/* there could be multiple kthreads sleeping for various reasons.  even an
	 * SCP could have multiple async syscalls. */
	cv_broadcast(&parent->child_wait);
	/* if the parent was waiting, there's a __launch kthread KMSG out there */
	proc_decref(parent);
}

/* Called when a parent is done with its child, and no longer wants to track the
 * child, nor to allow the child to track it.  Call with a lock (cv) held.
 * Returns 0 if we disowned, -1 on failure. */
int __proc_disown_child(struct proc *parent, struct proc *child)
{
	/* Bail out if the child has already been reaped */
	if (!child->ppid)
		return -1;
	assert(child->ppid == parent->pid);
	/* lock protects from concurrent inserts / removals from the list */
	TAILQ_REMOVE(&parent->children, child, sibling_link);
	/* After this, the child won't be able to get more refs to us, but it may
	 * still have some references in running code. */
	child->ppid = 0;
	proc_decref(child);	/* ref that was keeping the child alive on the list */
	return 0;
}

/* Turns *p into an MCP.  Needs to be called from a local syscall of a RUNNING_S
 * process.  Returns 0 if it succeeded, an error code otherwise. */
int proc_change_to_m(struct proc *p)
{
	int retval = 0;
	spin_lock(&p->proc_lock);
	/* in case userspace erroneously tries to change more than once */
	if (__proc_is_mcp(p))
		goto error_out;
	switch (p->state) {
		case (PROC_RUNNING_S):
			/* issue with if we're async or not (need to preempt it)
			 * either of these should trip it. TODO: (ACR) async core req */
			if ((current != p) || (get_pcoreid(p, 0) != core_id()))
				panic("We don't handle async RUNNING_S core requests yet.");
			struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[0];
			assert(current_ctx);
			/* Copy uthread0's context to VC 0's uthread slot */
			copy_current_ctx_to(&vcpd->uthread_ctx);
			clear_owning_proc(core_id());	/* so we don't restart */
			save_vc_fp_state(vcpd);
			/* Userspace needs to not fuck with notif_disabled before
			 * transitioning to _M. */
			if (vcpd->notif_disabled) {
				printk("[kernel] user bug: notifs disabled for vcore 0\n");
				vcpd->notif_disabled = FALSE;
			}
			/* in the async case, we'll need to remotely stop and bundle
			 * vcore0's TF.  this is already done for the sync case (local
			 * syscall). */
			/* this process no longer runs on its old location (which is
			 * this core, for now, since we don't handle async calls) */
			__seq_start_write(&p->procinfo->coremap_seqctr);
			// TODO: (ACR) will need to unmap remotely (receive-side)
			__unmap_vcore(p, 0);
			vcore_account_offline(p, 0);
			__seq_end_write(&p->procinfo->coremap_seqctr);
			/* change to runnable_m (it's TF is already saved) */
			__proc_set_state(p, PROC_RUNNABLE_M);
			p->procinfo->is_mcp = TRUE;
			spin_unlock(&p->proc_lock);
			/* Tell the ksched that we're a real MCP now! */
			__sched_proc_change_to_m(p);
			return 0;
		case (PROC_RUNNABLE_S):
			/* Issues: being on the runnable_list, proc_set_state not liking
			 * it, and not clearly thinking through how this would happen.
			 * Perhaps an async call that gets serviced after you're
			 * descheduled? */
			warn("Not supporting RUNNABLE_S -> RUNNABLE_M yet.\n");
			goto error_out;
		case (PROC_DYING):
		case (PROC_DYING_ABORT):
			warn("Dying, core request coming from %d\n", core_id());
			goto error_out;
		default:
			goto error_out;
	}
error_out:
	spin_unlock(&p->proc_lock);
	return -EINVAL;
}

/* Old code to turn a RUNNING_M to a RUNNING_S, with the calling context
 * becoming the new 'thread0'.  Don't use this.  Caller needs to send in a
 * pc_arr big enough for all vcores.  Will return the number of cores given up
 * by the proc. */
uint32_t __proc_change_to_s(struct proc *p, uint32_t *pc_arr)
{
	struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[0];
	uint32_t num_revoked;
	/* Not handling vcore accounting.  Do so if we ever use this */
	printk("[kernel] trying to transition _M -> _S (deprecated)!\n");
	assert(p->state == PROC_RUNNING_M); // TODO: (ACR) async core req
	/* save the context, to be restarted in _S mode */
	assert(current_ctx);
	copy_current_ctx_to(&p->scp_ctx);
	clear_owning_proc(core_id());	/* so we don't restart */
	save_vc_fp_state(vcpd);
	/* sending death, since it's not our job to save contexts or anything in
	 * this case. */
	num_revoked = __proc_take_allcores(p, pc_arr, FALSE);
	__proc_set_state(p, PROC_RUNNABLE_S);
	return num_revoked;
}

/* Helper function.  Is the given pcore a mapped vcore?  No locking involved, be
 * careful. */
static bool is_mapped_vcore(struct proc *p, uint32_t pcoreid)
{
	return p->procinfo->pcoremap[pcoreid].valid;
}

/* Helper function.  Find the vcoreid for a given physical core id for proc p.
 * No locking involved, be careful.  Panics on failure. */
static uint32_t get_vcoreid(struct proc *p, uint32_t pcoreid)
{
	assert(is_mapped_vcore(p, pcoreid));
	return p->procinfo->pcoremap[pcoreid].vcoreid;
}

/* Helper function.  Try to find the pcoreid for a given virtual core id for
 * proc p.  No locking involved, be careful.  Use this when you can tolerate a
 * stale or otherwise 'wrong' answer. */
static uint32_t try_get_pcoreid(struct proc *p, uint32_t vcoreid)
{
	return p->procinfo->vcoremap[vcoreid].pcoreid;
}

/* Helper function.  Find the pcoreid for a given virtual core id for proc p.
 * No locking involved, be careful.  Panics on failure. */
static uint32_t get_pcoreid(struct proc *p, uint32_t vcoreid)
{
	assert(vcore_is_mapped(p, vcoreid));
	return try_get_pcoreid(p, vcoreid);
}

/* Saves the FP state of the calling core into VCPD.  Pairs with
 * restore_vc_fp_state().  On x86, the best case overhead of the flags:
 *		FNINIT: 36 ns
 *		FXSAVE: 46 ns
 *		FXRSTR: 42 ns
 *		Flagged FXSAVE: 50 ns
 *		Flagged FXRSTR: 66 ns
 *		Excess flagged FXRSTR: 42 ns
 * If we don't do it, we'll need to initialize every VCPD at process creation
 * time with a good FPU state (x86 control words are initialized as 0s, like the
 * rest of VCPD). */
static void save_vc_fp_state(struct preempt_data *vcpd)
{
	save_fp_state(&vcpd->preempt_anc);
	vcpd->rflags |= VC_FPU_SAVED;
}

/* Conditionally restores the FP state from VCPD.  If the state was not valid,
 * we don't bother restoring and just initialize the FPU. */
static void restore_vc_fp_state(struct preempt_data *vcpd)
{
	if (vcpd->rflags & VC_FPU_SAVED) {
		restore_fp_state(&vcpd->preempt_anc);
		vcpd->rflags &= ~VC_FPU_SAVED;
	} else {
		init_fp_state();
	}
}

/* Helper for SCPs, saves the core's FPU state into the VCPD vc0 slot */
void __proc_save_fpu_s(struct proc *p)
{
	struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[0];
	save_vc_fp_state(vcpd);
}

/* Helper: saves the SCP's GP tf state and unmaps vcore 0.  This does *not* save
 * the FPU state.
 *
 * In the future, we'll probably use vc0's space for scp_ctx and the silly
 * state.  If we ever do that, we'll need to stop using scp_ctx (soon to be in
 * VCPD) as a location for pcpui->cur_ctx to point (dangerous) */
void __proc_save_context_s(struct proc *p)
{
	copy_current_ctx_to(&p->scp_ctx);
	__seq_start_write(&p->procinfo->coremap_seqctr);
	__unmap_vcore(p, 0);
	__seq_end_write(&p->procinfo->coremap_seqctr);
	vcore_account_offline(p, 0);
}

/* Yields the calling core.  Must be called locally (not async) for now.
 * - If RUNNING_S, you just give up your time slice and will eventually return,
 *   possibly after WAITING on an event.
 * - If RUNNING_M, you give up the current vcore (which never returns), and
 *   adjust the amount of cores wanted/granted.
 * - If you have only one vcore, you switch to WAITING.  There's no 'classic
 *   yield' for MCPs (at least not now).  When you run again, you'll have one
 *   guaranteed core, starting from the entry point.
 *
 * If the call is being nice, it means different things for SCPs and MCPs.  For
 * MCPs, it means that it is in response to a preemption (which needs to be
 * checked).  If there is no preemption pending, just return.  For SCPs, it
 * means the proc wants to give up the core, but still has work to do.  If not,
 * the proc is trying to wait on an event.  It's not being nice to others, it
 * just has no work to do.
 *
 * This usually does not return (smp_idle()), so it will eat your reference.
 * Also note that it needs a non-current/edible reference, since it will abandon
 * and continue to use the *p (current == 0, no cr3, etc).
 *
 * We disable interrupts for most of it too, since we need to protect
 * current_ctx and not race with __notify (which doesn't play well with
 * concurrent yielders). */
void proc_yield(struct proc *p, bool being_nice)
{
	uint32_t vcoreid, pcoreid = core_id();
	struct per_cpu_info *pcpui = &per_cpu_info[pcoreid];
	struct vcore *vc;
	struct preempt_data *vcpd;
	/* Need to lock to prevent concurrent vcore changes (online, inactive, the
	 * mapping, etc).  This plus checking the nr_preempts is enough to tell if
	 * our vcoreid and cur_ctx ought to be here still or if we should abort */
	spin_lock(&p->proc_lock); /* horrible scalability.  =( */
	switch (p->state) {
		case (PROC_RUNNING_S):
			if (!being_nice) {
				/* waiting for an event to unblock us */
				vcpd = &p->procdata->vcore_preempt_data[0];
				/* syncing with event's SCP code.  we set waiting, then check
				 * pending.  they set pending, then check waiting.  it's not
				 * possible for us to miss the notif *and* for them to miss
				 * WAITING.  one (or both) of us will see and make sure the proc
				 * wakes up.  */
				__proc_set_state(p, PROC_WAITING);
				wrmb(); /* don't let the state write pass the notif read */
				if (vcpd->notif_pending) {
					__proc_set_state(p, PROC_RUNNING_S);
					/* they can't handle events, just need to prevent a yield.
					 * (note the notif_pendings are collapsed). */
					if (!scp_is_vcctx_ready(vcpd))
						vcpd->notif_pending = FALSE;
					goto out_failed;
				}
				/* if we're here, we want to sleep.  a concurrent event that
				 * hasn't already written notif_pending will have seen WAITING,
				 * and will be spinning while we do this. */
				__proc_save_context_s(p);
				spin_unlock(&p->proc_lock);
			} else {
				/* yielding to allow other processes to run.  we're briefly
				 * WAITING, til we are woken up */
				__proc_set_state(p, PROC_WAITING);
				__proc_save_context_s(p);
				spin_unlock(&p->proc_lock);
				/* immediately wake up the proc (makes it runnable) */
				proc_wakeup(p);
			}
			goto out_yield_core;
		case (PROC_RUNNING_M):
			break;				/* will handle this stuff below */
		case (PROC_DYING):		/* incoming __death */
		case (PROC_DYING_ABORT):
		case (PROC_RUNNABLE_M):	/* incoming (bulk) preempt/myield TODO:(BULK) */
			goto out_failed;
		default:
			panic("Weird state(%s) in %s()", procstate2str(p->state),
			      __FUNCTION__);
	}
	/* This is which vcore this pcore thinks it is, regardless of any unmappings
	 * that may have happened remotely (with __PRs waiting to run) */
	vcoreid = pcpui->owning_vcoreid;
	vc = vcoreid2vcore(p, vcoreid);
	vcpd = &p->procdata->vcore_preempt_data[vcoreid];
	/* This is how we detect whether or not a __PR happened. */
	if (vc->nr_preempts_sent != vc->nr_preempts_done)
		goto out_failed;
	/* Sanity checks.  If we were preempted or are dying, we should have noticed
	 * by now. */
	assert(is_mapped_vcore(p, pcoreid));
	assert(vcoreid == get_vcoreid(p, pcoreid));
	/* no reason to be nice, return */
	if (being_nice && !vc->preempt_pending)
		goto out_failed;
	/* At this point, AFAIK there should be no preempt/death messages on the
	 * way, and we're on the online list.  So we'll go ahead and do the yielding
	 * business. */
	/* If there's a preempt pending, we don't need to preempt later since we are
	 * yielding (nice or otherwise).  If not, this is just a regular yield. */
	if (vc->preempt_pending) {
		vc->preempt_pending = 0;
	} else {
		/* Optional: on a normal yield, check to see if we are putting them
		 * below amt_wanted (help with user races) and bail. */
		if (p->procdata->res_req[RES_CORES].amt_wanted >=
		                       p->procinfo->num_vcores)
			goto out_failed;
	}
	/* Don't let them yield if they are missing a notification.  Userspace must
	 * not leave vcore context without dealing with notif_pending.
	 * pop_user_ctx() handles leaving via uthread context.  This handles leaving
	 * via a yield.
	 *
	 * This early check is an optimization.  The real check is below when it
	 * works with the online_vcs list (syncing with event.c and INDIR/IPI
	 * posting). */
	if (vcpd->notif_pending)
		goto out_failed;
	/* Now we'll actually try to yield */
	printd("[K] Process %d (%p) is yielding on vcore %d\n", p->pid, p,
	       get_vcoreid(p, pcoreid));
	/* Remove from the online list, add to the yielded list, and unmap
	 * the vcore, which gives up the core. */
	TAILQ_REMOVE(&p->online_vcs, vc, list);
	/* Now that we're off the online list, check to see if an alert made
	 * it through (event.c sets this) */
	wrmb();	/* prev write must hit before reading notif_pending */
	/* Note we need interrupts disabled, since a __notify can come in
	 * and set pending to FALSE */
	if (vcpd->notif_pending) {
		/* We lost, put it back on the list and abort the yield.  If we ever
		 * build an myield, we'll need a way to deal with this for all vcores */
		TAILQ_INSERT_TAIL(&p->online_vcs, vc, list); /* could go HEAD */
		goto out_failed;
	}
	/* Not really a kmsg, but it acts like one w.r.t. proc mgmt */
	pcpui_trace_kmsg(pcpui, (uintptr_t)proc_yield);
	/* We won the race with event sending, we can safely yield */
	TAILQ_INSERT_HEAD(&p->inactive_vcs, vc, list);
	/* Note this protects stuff userspace should look at, which doesn't
	 * include the TAILQs. */
	__seq_start_write(&p->procinfo->coremap_seqctr);
	/* Next time the vcore starts, it starts fresh */
	vcpd->notif_disabled = FALSE;
	__unmap_vcore(p, vcoreid);
	p->procinfo->num_vcores--;
	p->procinfo->res_grant[RES_CORES] = p->procinfo->num_vcores;
	__seq_end_write(&p->procinfo->coremap_seqctr);
	vcore_account_offline(p, vcoreid);
	/* No more vcores?  Then we wait on an event */
	if (p->procinfo->num_vcores == 0) {
		/* consider a ksched op to tell it about us WAITING */
		__proc_set_state(p, PROC_WAITING);
	}
	spin_unlock(&p->proc_lock);
	/* We discard the current context, but we still need to restore the core */
	arch_finalize_ctx(pcpui->cur_ctx);
	/* Hand the now-idle core to the ksched */
	__sched_put_idle_core(p, pcoreid);
	goto out_yield_core;
out_failed:
	/* for some reason we just want to return, either to take a KMSG that cleans
	 * us up, or because we shouldn't yield (ex: notif_pending). */
	spin_unlock(&p->proc_lock);
	return;
out_yield_core:				/* successfully yielded the core */
	proc_decref(p);			/* need to eat the ref passed in */
	/* Clean up the core and idle. */
	clear_owning_proc(pcoreid);	/* so we don't restart */
	abandon_core();
	smp_idle();
}

/* Sends a notification (aka active notification, aka IPI) to p's vcore.  We
 * only send a notification if one they are enabled.  There's a bunch of weird
 * cases with this, and how pending / enabled are signals between the user and
 * kernel - check the documentation.  Note that pending is more about messages.
 * The process needs to be in vcore_context, and the reason is usually a
 * message.  We set pending here in case we were called to prod them into vcore
 * context (like via a sys_self_notify).  Also note that this works for _S
 * procs, if you send to vcore 0 (and the proc is running). */
void proc_notify(struct proc *p, uint32_t vcoreid)
{
	struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[vcoreid];

	/* If you're thinking about checking notif_pending and then returning if it
	 * is already set, note that some callers (e.g. the event system) set
	 * notif_pending when they deliver a message, regardless of whether there is
	 * an IPI or not.  Those callers assume that we don't care about
	 * notif_pending, only notif_disabled.  So don't change this without
	 * changing them (probably can't without a lot of thought - that
	 * notif_pending is about missing messages.  It might be possible to say "no
	 * IPI, but don't let me miss messages that were delivered." */
	vcpd->notif_pending = TRUE;
	wrmb();	/* must write notif_pending before reading notif_disabled */
	if (!vcpd->notif_disabled) {
		/* GIANT WARNING: we aren't using the proc-lock to protect the
		 * vcoremap.  We want to be able to use this from interrupt context,
		 * and don't want the proc_lock to be an irqsave.  Spurious
		 * __notify() kmsgs are okay (it checks to see if the right receiver
		 * is current). */
		if (vcore_is_mapped(p, vcoreid)) {
			printd("[kernel] sending notif to vcore %d\n", vcoreid);
			/* This use of try_get_pcoreid is racy, might be unmapped */
			send_kernel_message(try_get_pcoreid(p, vcoreid), __notify, (long)p,
			                    0, 0, KMSG_ROUTINE);
		}
	}
}

/* Makes sure p is runnable.  Callers may spam this, so it needs to handle
 * repeated calls for the same event.  Callers include event delivery, SCP
 * yield, and new SCPs.  Will trigger __sched_.cp_wakeup() CBs.  Will only
 * trigger the CB once, regardless of how many times we are called, *until* the
 * proc becomes WAITING again, presumably because of something the ksched did.*/
void proc_wakeup(struct proc *p)
{
	spin_lock(&p->proc_lock);
	if (__proc_is_mcp(p)) {
		/* we only wake up WAITING mcps */
		if (p->state != PROC_WAITING) {
			spin_unlock(&p->proc_lock);
			return;
		}
		__proc_set_state(p, PROC_RUNNABLE_M);
		spin_unlock(&p->proc_lock);
		__sched_mcp_wakeup(p);
		return;
	} else {
		/* SCPs can wake up for a variety of reasons.  the only times we need
		 * to do something is if it was waiting or just created.  other cases
		 * are either benign (just go out), or potential bugs (_Ms) */
		switch (p->state) {
			case (PROC_CREATED):
			case (PROC_WAITING):
				__proc_set_state(p, PROC_RUNNABLE_S);
				break;
			case (PROC_RUNNABLE_S):
			case (PROC_RUNNING_S):
			case (PROC_DYING):
			case (PROC_DYING_ABORT):
				spin_unlock(&p->proc_lock);
				return;
			case (PROC_RUNNABLE_M):
			case (PROC_RUNNING_M):
				warn("Weird state(%s) in %s()", procstate2str(p->state),
				     __FUNCTION__);
				spin_unlock(&p->proc_lock);
				return;
		}
		printd("[kernel] FYI, waking up an _S proc\n");	/* thanks, past brho! */
		spin_unlock(&p->proc_lock);
		__sched_scp_wakeup(p);
	}
}

/* Is the process in multi_mode / is an MCP or not?  */
bool __proc_is_mcp(struct proc *p)
{
	/* in lieu of using the amount of cores requested, or having a bunch of
	 * states (like PROC_WAITING_M and _S), I'll just track it with a bool. */
	return p->procinfo->is_mcp;
}

bool proc_is_vcctx_ready(struct proc *p)
{
	struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[0];
	return scp_is_vcctx_ready(vcpd);
}

/************************  Preemption Functions  ******************************
 * Don't rely on these much - I'll be sure to change them up a bit.
 *
 * Careful about what takes a vcoreid and what takes a pcoreid.  Also, there may
 * be weird glitches with setting the state to RUNNABLE_M.  It is somewhat in
 * flux.  The num_vcores is changed after take_cores, but some of the messages
 * (or local traps) may not yet be ready to handle seeing their future state.
 * But they should be, so fix those when they pop up.
 *
 * Another thing to do would be to make the _core functions take a pcorelist,
 * and not just one pcoreid. */

/* Sets a preempt_pending warning for p's vcore, to go off 'when'.  If you care
 * about locking, do it before calling.  Takes a vcoreid! */
void __proc_preempt_warn(struct proc *p, uint32_t vcoreid, uint64_t when)
{
	struct event_msg local_msg = {0};
	/* danger with doing this unlocked: preempt_pending is set, but never 0'd,
	 * since it is unmapped and not dealt with (TODO)*/
	p->procinfo->vcoremap[vcoreid].preempt_pending = when;

	/* Send the event (which internally checks to see how they want it) */
	local_msg.ev_type = EV_PREEMPT_PENDING;
	local_msg.ev_arg1 = vcoreid;
	/* Whenever we send msgs with the proc locked, we need at least 1 online.
	 * Caller needs to make sure the core was online/mapped. */
	assert(!TAILQ_EMPTY(&p->online_vcs));
	send_kernel_event(p, &local_msg, vcoreid);

	/* TODO: consider putting in some lookup place for the alarm to find it.
	 * til then, it'll have to scan the vcoremap (O(n) instead of O(m)) */
}

/* Warns all active vcores of an impending preemption.  Hold the lock if you
 * care about the mapping (and you should). */
void __proc_preempt_warnall(struct proc *p, uint64_t when)
{
	struct vcore *vc_i;
	TAILQ_FOREACH(vc_i, &p->online_vcs, list)
		__proc_preempt_warn(p, vcore2vcoreid(p, vc_i), when);
	/* TODO: consider putting in some lookup place for the alarm to find it.
	 * til then, it'll have to scan the vcoremap (O(n) instead of O(m)) */
}

// TODO: function to set an alarm, if none is outstanding

/* Raw function to preempt a single core.  If you care about locking, do it
 * before calling. */
void __proc_preempt_core(struct proc *p, uint32_t pcoreid)
{
	uint32_t vcoreid = get_vcoreid(p, pcoreid);
	struct event_msg preempt_msg = {0};
	/* works with nr_preempts_done to signal completion of a preemption */
	p->procinfo->vcoremap[vcoreid].nr_preempts_sent++;
	// expects a pcorelist.  assumes pcore is mapped and running_m
	__proc_take_corelist(p, &pcoreid, 1, TRUE);
	/* Only send the message if we have an online core.  o/w, it would fuck
	 * us up (deadlock), and hey don't need a message.  the core we just took
	 * will be the first one to be restarted.  It will look like a notif.  in
	 * the future, we could send the event if we want, but the caller needs to
	 * do that (after unlocking). */
	if (!TAILQ_EMPTY(&p->online_vcs)) {
		preempt_msg.ev_type = EV_VCORE_PREEMPT;
		preempt_msg.ev_arg2 = vcoreid;
		send_kernel_event(p, &preempt_msg, 0);
	}
}

/* Raw function to preempt every vcore.  If you care about locking, do it before
 * calling. */
uint32_t __proc_preempt_all(struct proc *p, uint32_t *pc_arr)
{
	struct vcore *vc_i;
	/* TODO:(BULK) PREEMPT - don't bother with this, set a proc wide flag, or
	 * just make us RUNNABLE_M.  Note this is also used by __map_vcore. */
	TAILQ_FOREACH(vc_i, &p->online_vcs, list)
		vc_i->nr_preempts_sent++;
	return __proc_take_allcores(p, pc_arr, TRUE);
}

/* Warns and preempts a vcore from p.  No delaying / alarming, or anything.  The
 * warning will be for u usec from now.  Returns TRUE if the core belonged to
 * the proc (and thus preempted), False if the proc no longer has the core. */
bool proc_preempt_core(struct proc *p, uint32_t pcoreid, uint64_t usec)
{
	uint64_t warn_time = read_tsc() + usec2tsc(usec);
	bool retval = FALSE;
	if (p->state != PROC_RUNNING_M) {
		/* more of an FYI for brho.  should be harmless to just return. */
		warn("Tried to preempt from a non RUNNING_M proc!");
		return FALSE;
	}
	spin_lock(&p->proc_lock);
	if (is_mapped_vcore(p, pcoreid)) {
		__proc_preempt_warn(p, get_vcoreid(p, pcoreid), warn_time);
		__proc_preempt_core(p, pcoreid);
		/* we might have taken the last core */
		if (!p->procinfo->num_vcores)
			__proc_set_state(p, PROC_RUNNABLE_M);
		retval = TRUE;
	}
	spin_unlock(&p->proc_lock);
	return retval;
}

/* Warns and preempts all from p.  No delaying / alarming, or anything.  The
 * warning will be for u usec from now. */
void proc_preempt_all(struct proc *p, uint64_t usec)
{
	uint64_t warn_time = read_tsc() + usec2tsc(usec);
	uint32_t num_revoked = 0;
	spin_lock(&p->proc_lock);
	/* storage for pc_arr is alloced at decl, which is after grabbing the lock*/
	uint32_t pc_arr[p->procinfo->num_vcores];
	/* DYING could be okay */
	if (p->state != PROC_RUNNING_M) {
		warn("Tried to preempt from a non RUNNING_M proc!");
		spin_unlock(&p->proc_lock);
		return;
	}
	__proc_preempt_warnall(p, warn_time);
	num_revoked = __proc_preempt_all(p, pc_arr);
	assert(!p->procinfo->num_vcores);
	__proc_set_state(p, PROC_RUNNABLE_M);
	spin_unlock(&p->proc_lock);
	/* TODO: when we revise this func, look at __put_idle */
	/* Return the cores to the ksched */
	if (num_revoked)
		__sched_put_idle_cores(p, pc_arr, num_revoked);
}

/* Give the specific pcore to proc p.  Lots of assumptions, so don't really use
 * this.  The proc needs to be _M and prepared for it.  the pcore needs to be
 * free, etc. */
void proc_give(struct proc *p, uint32_t pcoreid)
{
	warn("Your idlecoremap is now screwed up");	/* TODO (IDLE) */
	spin_lock(&p->proc_lock);
	// expects a pcorelist, we give it a list of one
	__proc_give_cores(p, &pcoreid, 1);
	spin_unlock(&p->proc_lock);
}

/* Global version of the helper, for sys_get_vcoreid (might phase that syscall
 * out). */
uint32_t proc_get_vcoreid(struct proc *p)
{
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	if (pcpui->owning_proc == p) {
		return pcpui->owning_vcoreid;
	} else {
		warn("Asked for vcoreid for %p, but %p is pwns", p, pcpui->owning_proc);
		return (uint32_t)-1;
	}
}

/* TODO: make all of these static inlines when we gut the env crap */
bool vcore_is_mapped(struct proc *p, uint32_t vcoreid)
{
	return p->procinfo->vcoremap[vcoreid].valid;
}

/* Can do this, or just create a new field and save it in the vcoremap */
uint32_t vcore2vcoreid(struct proc *p, struct vcore *vc)
{
	return (vc - p->procinfo->vcoremap);
}

struct vcore *vcoreid2vcore(struct proc *p, uint32_t vcoreid)
{
	return &p->procinfo->vcoremap[vcoreid];
}

/********** Core granting (bulk and single) ***********/

/* Helper: gives pcore to the process, mapping it to the next available vcore
 * from list vc_list.  Returns TRUE if we succeeded (non-empty).  If you pass in
 * **vc, we'll tell you which vcore it was. */
static bool __proc_give_a_pcore(struct proc *p, uint32_t pcore,
                                struct vcore_tailq *vc_list, struct vcore **vc)
{
	struct vcore *new_vc;
	new_vc = TAILQ_FIRST(vc_list);
	if (!new_vc)
		return FALSE;
	printd("setting vcore %d to pcore %d\n", vcore2vcoreid(p, new_vc),
	       pcore);
	TAILQ_REMOVE(vc_list, new_vc, list);
	TAILQ_INSERT_TAIL(&p->online_vcs, new_vc, list);
	__map_vcore(p, vcore2vcoreid(p, new_vc), pcore);
	if (vc)
		*vc = new_vc;
	return TRUE;
}

static void __proc_give_cores_runnable(struct proc *p, uint32_t *pc_arr,
                                       uint32_t num)
{
	assert(p->state == PROC_RUNNABLE_M);
	assert(num);	/* catch bugs */
	/* add new items to the vcoremap */
	__seq_start_write(&p->procinfo->coremap_seqctr);/* unncessary if offline */
	p->procinfo->num_vcores += num;
	for (int i = 0; i < num; i++) {
		/* Try from the bulk list first */
		if (__proc_give_a_pcore(p, pc_arr[i], &p->bulk_preempted_vcs, 0))
			continue;
		/* o/w, try from the inactive list.  at one point, i thought there might
		 * be a legit way in which the inactive list could be empty, but that i
		 * wanted to catch it via an assert. */
		assert(__proc_give_a_pcore(p, pc_arr[i], &p->inactive_vcs, 0));
	}
	__seq_end_write(&p->procinfo->coremap_seqctr);
}

static void __proc_give_cores_running(struct proc *p, uint32_t *pc_arr,
                                      uint32_t num)
{
	struct vcore *vc_i;
	/* Up the refcnt, since num cores are going to start using this
	 * process and have it loaded in their owning_proc and 'current'. */
	proc_incref(p, num * 2);	/* keep in sync with __startcore */
	__seq_start_write(&p->procinfo->coremap_seqctr);
	p->procinfo->num_vcores += num;
	assert(TAILQ_EMPTY(&p->bulk_preempted_vcs));
	for (int i = 0; i < num; i++) {
		assert(__proc_give_a_pcore(p, pc_arr[i], &p->inactive_vcs, &vc_i));
		send_kernel_message(pc_arr[i], __startcore, (long)p,
		                    (long)vcore2vcoreid(p, vc_i),
		                    (long)vc_i->nr_preempts_sent, KMSG_ROUTINE);
	}
	__seq_end_write(&p->procinfo->coremap_seqctr);
}

/* Gives process p the additional num cores listed in pcorelist.  If the proc is
 * not RUNNABLE_M or RUNNING_M, this will fail and allocate none of the core
 * (and return -1).  If you're RUNNING_M, this will startup your new cores at
 * the entry point with their virtual IDs (or restore a preemption).  If you're
 * RUNNABLE_M, you should call __proc_run_m after this so that the process can
 * start to use its cores.  In either case, this returns 0.
 *
 * If you're *_S, make sure your core0's TF is set (which is done when coming in
 * via arch/trap.c and we are RUNNING_S), change your state, then call this.
 * Then call __proc_run_m().
 *
 * The reason I didn't bring the _S cases from core_request over here is so we
 * can keep this family of calls dealing with only *_Ms, to avoiding caring if
 * this is called from another core, and to avoid the _S -> _M transition.
 *
 * WARNING: You must hold the proc_lock before calling this! */
int __proc_give_cores(struct proc *p, uint32_t *pc_arr, uint32_t num)
{
	/* should never happen: */
	assert(num + p->procinfo->num_vcores <= MAX_NUM_CORES);
	switch (p->state) {
		case (PROC_RUNNABLE_S):
		case (PROC_RUNNING_S):
			warn("Don't give cores to a process in a *_S state!\n");
			return -1;
		case (PROC_DYING):
		case (PROC_DYING_ABORT):
		case (PROC_WAITING):
			/* can't accept, just fail */
			return -1;
		case (PROC_RUNNABLE_M):
			__proc_give_cores_runnable(p, pc_arr, num);
			break;
		case (PROC_RUNNING_M):
			__proc_give_cores_running(p, pc_arr, num);
			break;
		default:
			panic("Weird state(%s) in %s()", procstate2str(p->state),
			      __FUNCTION__);
	}
	/* TODO: considering moving to the ksched (hard, due to yield) */
	p->procinfo->res_grant[RES_CORES] += num;
	return 0;
}

/********** Core revocation (bulk and single) ***********/

/* Revokes a single vcore from a process (unmaps or sends a KMSG to unmap). */
static void __proc_revoke_core(struct proc *p, uint32_t vcoreid, bool preempt)
{
	uint32_t pcoreid = get_pcoreid(p, vcoreid);
	struct preempt_data *vcpd;
	if (preempt) {
		/* Lock the vcore's state (necessary for preemption recovery) */
		vcpd = &p->procdata->vcore_preempt_data[vcoreid];
		atomic_or(&vcpd->flags, VC_K_LOCK);
		send_kernel_message(pcoreid, __preempt, (long)p, 0, 0, KMSG_ROUTINE);
	} else {
		send_kernel_message(pcoreid, __death, 0, 0, 0, KMSG_ROUTINE);
	}
}

/* Revokes all cores from the process (unmaps or sends a KMSGS). */
static void __proc_revoke_allcores(struct proc *p, bool preempt)
{
	struct vcore *vc_i;
	/* TODO: if we ever get broadcast messaging, use it here (still need to lock
	 * the vcores' states for preemption) */
	TAILQ_FOREACH(vc_i, &p->online_vcs, list)
		__proc_revoke_core(p, vcore2vcoreid(p, vc_i), preempt);
}

/* Might be faster to scan the vcoremap than to walk the list... */
static void __proc_unmap_allcores(struct proc *p)
{
	struct vcore *vc_i;
	TAILQ_FOREACH(vc_i, &p->online_vcs, list)
		__unmap_vcore(p, vcore2vcoreid(p, vc_i));
}

/* Takes (revoke via kmsg or unmap) from process p the num cores listed in
 * pc_arr.  Will preempt if 'preempt' is set.  o/w, no state will be saved, etc.
 * Don't use this for taking all of a process's cores.
 *
 * Make sure you hold the lock when you call this, and make sure that the pcore
 * actually belongs to the proc, non-trivial due to other __preempt messages. */
void __proc_take_corelist(struct proc *p, uint32_t *pc_arr, uint32_t num,
                          bool preempt)
{
	struct vcore *vc;
	uint32_t vcoreid;
	assert(p->state & (PROC_RUNNING_M | PROC_RUNNABLE_M));
	__seq_start_write(&p->procinfo->coremap_seqctr);
	for (int i = 0; i < num; i++) {
		vcoreid = get_vcoreid(p, pc_arr[i]);
		/* Sanity check */
		assert(pc_arr[i] == get_pcoreid(p, vcoreid));
		/* Revoke / unmap core */
		if (p->state == PROC_RUNNING_M)
			__proc_revoke_core(p, vcoreid, preempt);
		__unmap_vcore(p, vcoreid);
		/* Change lists for the vcore.  Note, the vcore is already unmapped
		 * and/or the messages are already in flight.  The only code that looks
		 * at the lists without holding the lock is event code. */
		vc = vcoreid2vcore(p, vcoreid);
		TAILQ_REMOVE(&p->online_vcs, vc, list);
		/* even for single preempts, we use the inactive list.  bulk preempt is
		 * only used for when we take everything. */
		TAILQ_INSERT_HEAD(&p->inactive_vcs, vc, list);
	}
	p->procinfo->num_vcores -= num;
	__seq_end_write(&p->procinfo->coremap_seqctr);
	p->procinfo->res_grant[RES_CORES] -= num;
}

/* Takes all cores from a process (revoke via kmsg or unmap), putting them on
 * the appropriate vcore list, and fills pc_arr with the pcores revoked, and
 * returns the number of entries in pc_arr.
 *
 * Make sure pc_arr is big enough to handle num_vcores().
 * Make sure you hold the lock when you call this. */
uint32_t __proc_take_allcores(struct proc *p, uint32_t *pc_arr, bool preempt)
{
	struct vcore *vc_i, *vc_temp;
	uint32_t num = 0;
	assert(p->state & (PROC_RUNNING_M | PROC_RUNNABLE_M));
	__seq_start_write(&p->procinfo->coremap_seqctr);
	/* Write out which pcores we're going to take */
	TAILQ_FOREACH(vc_i, &p->online_vcs, list)
		pc_arr[num++] = vc_i->pcoreid;
	/* Revoke if they are running, and unmap.  Both of these need the online
	 * list to not be changed yet. */
	if (p->state == PROC_RUNNING_M)
		__proc_revoke_allcores(p, preempt);
	__proc_unmap_allcores(p);
	/* Move the vcores from online to the head of the appropriate list */
	TAILQ_FOREACH_SAFE(vc_i, &p->online_vcs, list, vc_temp) {
		/* TODO: we may want a TAILQ_CONCAT_HEAD, or something that does that */
		TAILQ_REMOVE(&p->online_vcs, vc_i, list);
		/* Put the cores on the appropriate list */
		if (preempt)
			TAILQ_INSERT_HEAD(&p->bulk_preempted_vcs, vc_i, list);
		else
			TAILQ_INSERT_HEAD(&p->inactive_vcs, vc_i, list);
	}
	assert(TAILQ_EMPTY(&p->online_vcs));
	assert(num == p->procinfo->num_vcores);
	p->procinfo->num_vcores = 0;
	__seq_end_write(&p->procinfo->coremap_seqctr);
	p->procinfo->res_grant[RES_CORES] = 0;
	return num;
}

/* Helper to do the vcore->pcore and inverse mapping.  Hold the lock when
 * calling. */
void __map_vcore(struct proc *p, uint32_t vcoreid, uint32_t pcoreid)
{
	p->procinfo->vcoremap[vcoreid].pcoreid = pcoreid;
	p->procinfo->vcoremap[vcoreid].valid = TRUE;
	p->procinfo->pcoremap[pcoreid].vcoreid = vcoreid;
	p->procinfo->pcoremap[pcoreid].valid = TRUE;
}

/* Helper to unmap the vcore->pcore and inverse mapping.  Hold the lock when
 * calling. */
void __unmap_vcore(struct proc *p, uint32_t vcoreid)
{
	p->procinfo->pcoremap[p->procinfo->vcoremap[vcoreid].pcoreid].valid = FALSE;
	p->procinfo->vcoremap[vcoreid].valid = FALSE;
}

/* Stop running whatever context is on this core and load a known-good cr3.
 * Note this leaves no trace of what was running. This "leaves the process's
 * context.
 *
 * This does not clear the owning proc.  Use the other helper for that. */
void abandon_core(void)
{
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	/* Syscalls that don't return will ultimately call abadon_core(), so we need
	 * to make sure we don't think we are still working on a syscall. */
	pcpui->cur_kthread->sysc = 0;
	pcpui->cur_kthread->errbuf = 0;	/* just in case */
	if (pcpui->cur_proc)
		__abandon_core();
}

/* Helper to clear the core's owning processor and manage refcnting.  Pass in
 * core_id() to save a couple core_id() calls. */
void clear_owning_proc(uint32_t coreid)
{
	struct per_cpu_info *pcpui = &per_cpu_info[coreid];
	struct proc *p = pcpui->owning_proc;
	pcpui->owning_proc = 0;
	pcpui->owning_vcoreid = 0xdeadbeef;
	pcpui->cur_ctx = 0;			/* catch bugs for now (may go away) */
	if (p)
		proc_decref(p);
}

/* Switches to the address space/context of new_p, doing nothing if we are
 * already in new_p.  This won't add extra refcnts or anything, and needs to be
 * paired with switch_back() at the end of whatever function you are in.
 * Specifically, the uncounted refs are one for the old_proc, which is passed
 * back to the caller, and new_p is getting placed in cur_proc. */
uintptr_t switch_to(struct proc *new_p)
{
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	struct kthread *kth = pcpui->cur_kthread;
	struct proc *old_proc;
	uintptr_t ret;

	old_proc = pcpui->cur_proc;					/* uncounted ref */
	/* If we aren't the proc already, then switch to it */
	if (old_proc != new_p) {
		pcpui->cur_proc = new_p;				/* uncounted ref */
		if (new_p)
			lcr3(new_p->env_cr3);
		else
			lcr3(boot_cr3);
	}
	ret = (uintptr_t)old_proc;
	if (is_ktask(kth)) {
		if (!(kth->flags & KTH_SAVE_ADDR_SPACE)) {
			kth->flags |= KTH_SAVE_ADDR_SPACE;
			/* proc pointers are aligned; we can use the lower bit as a signal
			 * to turn off SAVE_ADDR_SPACE. */
			ret |= 0x1;
		}
	}
	return ret;
}

/* This switches back from new_p to the original process.  Pair it with
 * switch_to(), and pass in its return value for old_ret. */
void switch_back(struct proc *new_p, uintptr_t old_ret)
{
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	struct kthread *kth = pcpui->cur_kthread;
	struct proc *old_proc;

	if (is_ktask(kth)) {
		if (old_ret & 0x1) {
			kth->flags &= ~KTH_SAVE_ADDR_SPACE;
			old_ret &= ~0x1;
		}
	}
	old_proc = (struct proc*)old_ret;
	if (old_proc != new_p) {
		pcpui->cur_proc = old_proc;
		if (old_proc)
			lcr3(old_proc->env_cr3);
		else
			lcr3(boot_cr3);
	}
}

/* Will send a TLB shootdown message to every vcore in the main address space
 * (aka, all vcores for now).  The message will take the start and end virtual
 * addresses as well, in case we want to be more clever about how much we
 * shootdown and batching our messages.  Should do the sanity about rounding up
 * and down in this function too.
 *
 * Would be nice to have a broadcast kmsg at this point.  Note this may send a
 * message to the calling core (interrupting it, possibly while holding the
 * proc_lock).  We don't need to process routine messages since it's an
 * immediate message. */
void proc_tlbshootdown(struct proc *p, uintptr_t start, uintptr_t end)
{
	/* TODO: need a better way to find cores running our address space.  we can
	 * have kthreads running syscalls, async calls, processes being created. */
	struct vcore *vc_i;
	/* TODO: we might be able to avoid locking here in the future (we must hit
	 * all online, and we can check __mapped).  it'll be complicated. */
	spin_lock(&p->proc_lock);
	switch (p->state) {
		case (PROC_RUNNING_S):
			tlbflush();
			break;
		case (PROC_RUNNING_M):
			/* TODO: (TLB) sanity checks and rounding on the ranges.
			 *
			 * We need to make sure that once a core that was online has been
			 * removed from the online list, then it must receive a TLB flush
			 * (abandon_core()) before running the process again.  Either that,
			 * or make other decisions about who to TLB-shootdown. */
			TAILQ_FOREACH(vc_i, &p->online_vcs, list) {
				send_kernel_message(vc_i->pcoreid, __tlbshootdown, start, end,
				                    0, KMSG_IMMEDIATE);
			}
			break;
		default:
			/* TODO: til we fix shootdowns, there are some odd cases where we
			 * have the address space loaded, but the state is in transition. */
			if (p == current)
				tlbflush();
	}
	spin_unlock(&p->proc_lock);
}

/* Helper, used by __startcore and __set_curctx, which sets up cur_ctx to run a
 * given process's vcore.  Caller needs to set up things like owning_proc and
 * whatnot.  Note that we might not have p loaded as current. */
static void __set_curctx_to_vcoreid(struct proc *p, uint32_t vcoreid,
                                    uint32_t old_nr_preempts_sent)
{
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[vcoreid];
	struct vcore *vc = vcoreid2vcore(p, vcoreid);
	/* Spin until our vcore's old preemption is done.  When __SC was sent, we
	 * were told what the nr_preempts_sent was at that time.  Once that many are
	 * done, it is time for us to run.  This forces a 'happens-before' ordering
	 * on a __PR of our VC before this __SC of the VC.  Note the nr_done should
	 * not exceed old_nr_sent, since further __PR are behind this __SC in the
	 * KMSG queue. */
	while (old_nr_preempts_sent != vc->nr_preempts_done)
		cpu_relax();
	cmb();	/* read nr_done before any other rd or wr.  CPU mb in the atomic. */
	/* Mark that this vcore as no longer preempted.  No danger of clobbering
	 * other writes, since this would get turned on in __preempt (which can't be
	 * concurrent with this function on this core), and the atomic is just
	 * toggling the one bit (a concurrent VC_K_LOCK will work) */
	atomic_and(&vcpd->flags, ~VC_PREEMPTED);
	/* Once the VC is no longer preempted, we allow it to receive msgs.  We
	 * could let userspace do it, but handling it here makes it easier for them
	 * to handle_indirs (when they turn this flag off).  Note the atomics
	 * provide the needed barriers (cmb and mb on flags). */
	atomic_or(&vcpd->flags, VC_CAN_RCV_MSG);
	printd("[kernel] startcore on physical core %d for process %d's vcore %d\n",
	       core_id(), p->pid, vcoreid);
	/* If notifs are disabled, the vcore was in vcore context and we need to
	 * restart the vcore_ctx.  o/w, we give them a fresh vcore (which is also
	 * what happens the first time a vcore comes online).  No matter what,
	 * they'll restart in vcore context.  It's just a matter of whether or not
	 * it is the old, interrupted vcore context. */
	if (vcpd->notif_disabled) {
		/* copy-in the tf we'll pop, then set all security-related fields */
		pcpui->actual_ctx = vcpd->vcore_ctx;
		proc_secure_ctx(&pcpui->actual_ctx);
	} else { /* not restarting from a preemption, use a fresh vcore */
		assert(vcpd->vcore_stack);
		proc_init_ctx(&pcpui->actual_ctx, vcoreid, vcpd->vcore_entry,
		              vcpd->vcore_stack, vcpd->vcore_tls_desc);
		/* Disable/mask active notifications for fresh vcores */
		vcpd->notif_disabled = TRUE;
	}
	/* Regardless of whether or not we have a 'fresh' VC, we need to restore the
	 * FPU state for the VC according to VCPD (which means either a saved FPU
	 * state or a brand new init).  Starting a fresh VC is just referring to the
	 * GP context we run.  The vcore itself needs to have the FPU state loaded
	 * from when it previously ran and was saved (or a fresh FPU if it wasn't
	 * saved).  For fresh FPUs, the main purpose is for limiting info leakage.
	 * I think VCs that don't need FPU state for some reason (like having a
	 * current_uthread) can handle any sort of FPU state, since it gets sorted
	 * when they pop their next uthread.
	 *
	 * Note this can cause a GP fault on x86 if the state is corrupt.  In lieu
	 * of reading in the huge FP state and mucking with mxcsr_mask, we should
	 * handle this like a KPF on user code. */
	restore_vc_fp_state(vcpd);
	/* cur_ctx was built above (in actual_ctx), now use it */
	pcpui->cur_ctx = &pcpui->actual_ctx;
	/* this cur_ctx will get run when the kernel returns / idles */
	vcore_account_online(p, vcoreid);
}

/* Changes calling vcore to be vcoreid.  enable_my_notif tells us about how the
 * state calling vcore wants to be left in.  It will look like caller_vcoreid
 * was preempted.  Note we don't care about notif_pending.
 *
 * Will return:
 * 		0 if we successfully changed to the target vcore.
 * 		-EBUSY if the target vcore is already mapped (a good kind of failure)
 * 		-EAGAIN if we failed for some other reason and need to try again.  For
 * 		example, the caller could be preempted, and we never even attempted to
 * 		change.
 * 		-EINVAL some userspace bug */
int proc_change_to_vcore(struct proc *p, uint32_t new_vcoreid,
                         bool enable_my_notif)
{
	uint32_t caller_vcoreid, pcoreid = core_id();
	struct per_cpu_info *pcpui = &per_cpu_info[pcoreid];
	struct preempt_data *caller_vcpd;
	struct vcore *caller_vc, *new_vc;
	struct event_msg preempt_msg = {0};
	int retval = -EAGAIN;	/* by default, try again */
	/* Need to not reach outside the vcoremap, which might be smaller in the
	 * future, but should always be as big as max_vcores */
	if (new_vcoreid >= p->procinfo->max_vcores)
		return -EINVAL;
	/* Need to lock to prevent concurrent vcore changes, like in yield. */
	spin_lock(&p->proc_lock);
	/* new_vcoreid is already runing, abort */
	if (vcore_is_mapped(p, new_vcoreid)) {
		retval = -EBUSY;
		goto out_locked;
	}
	/* Need to make sure our vcore is allowed to switch.  We might have a
	 * __preempt, __death, etc, coming in.  Similar to yield. */
	switch (p->state) {
		case (PROC_RUNNING_M):
			break;				/* the only case we can proceed */
		case (PROC_RUNNING_S):	/* user bug, just return */
		case (PROC_DYING):		/* incoming __death */
		case (PROC_DYING_ABORT):
		case (PROC_RUNNABLE_M):	/* incoming (bulk) preempt/myield TODO:(BULK) */
			goto out_locked;
		default:
			panic("Weird state(%s) in %s()", procstate2str(p->state),
			      __FUNCTION__);
	}
	/* This is which vcore this pcore thinks it is, regardless of any unmappings
	 * that may have happened remotely (with __PRs waiting to run) */
	caller_vcoreid = pcpui->owning_vcoreid;
	caller_vc = vcoreid2vcore(p, caller_vcoreid);
	caller_vcpd = &p->procdata->vcore_preempt_data[caller_vcoreid];
	/* This is how we detect whether or not a __PR happened.  If it did, just
	 * abort and handle the kmsg.  No new __PRs are coming since we hold the
	 * lock.  This also detects a __PR followed by a __SC for the same VC. */
	if (caller_vc->nr_preempts_sent != caller_vc->nr_preempts_done)
		goto out_locked;
	/* Sanity checks.  If we were preempted or are dying, we should have noticed
	 * by now. */
	assert(is_mapped_vcore(p, pcoreid));
	assert(caller_vcoreid == get_vcoreid(p, pcoreid));
	/* Should only call from vcore context */
	if (!caller_vcpd->notif_disabled) {
		retval = -EINVAL;
		printk("[kernel] You tried to change vcores from uthread ctx\n");
		goto out_locked;
	}
	/* Ok, we're clear to do the switch.  Lets figure out who the new one is */
	new_vc = vcoreid2vcore(p, new_vcoreid);
	printd("[kernel] changing vcore %d to vcore %d\n", caller_vcoreid,
	       new_vcoreid);
	/* enable_my_notif signals how we'll be restarted */
	if (enable_my_notif) {
		/* if they set this flag, then the vcore can just restart from scratch,
		 * and we don't care about either the uthread_ctx or the vcore_ctx. */
		caller_vcpd->notif_disabled = FALSE;
		/* Don't need to save the FPU.  There should be no uthread or other
		 * reason to return to the FPU state.  But we do need to finalize the
		 * context, even though we are throwing it away.  We need to return the
		 * pcore to a state where it can run any context and not be bound to
		 * the old context. */
		arch_finalize_ctx(pcpui->cur_ctx);
	} else {
		/* need to set up the calling vcore's ctx so that it'll get restarted by
		 * __startcore, to make the caller look like it was preempted. */
		copy_current_ctx_to(&caller_vcpd->vcore_ctx);
		save_vc_fp_state(caller_vcpd);
	}
	/* Mark our core as preempted (for userspace recovery).  Userspace checks
	 * this in handle_indirs, and it needs to check the mbox regardless of
	 * enable_my_notif.  This does mean cores that change-to with no intent to
	 * return will be tracked as PREEMPTED until they start back up (maybe
	 * forever). */
	atomic_or(&caller_vcpd->flags, VC_PREEMPTED);
	/* Either way, unmap and offline our current vcore */
	/* Move the caller from online to inactive */
	TAILQ_REMOVE(&p->online_vcs, caller_vc, list);
	/* We don't bother with the notif_pending race.  note that notif_pending
	 * could still be set.  this was a preempted vcore, and userspace will need
	 * to deal with missed messages (preempt_recover() will handle that) */
	TAILQ_INSERT_HEAD(&p->inactive_vcs, caller_vc, list);
	/* Move the new one from inactive to online */
	TAILQ_REMOVE(&p->inactive_vcs, new_vc, list);
	TAILQ_INSERT_TAIL(&p->online_vcs, new_vc, list);
	/* Change the vcore map */
	__seq_start_write(&p->procinfo->coremap_seqctr);
	__unmap_vcore(p, caller_vcoreid);
	__map_vcore(p, new_vcoreid, pcoreid);
	__seq_end_write(&p->procinfo->coremap_seqctr);
	vcore_account_offline(p, caller_vcoreid);
	/* Send either a PREEMPT msg or a CHECK_MSGS msg.  If they said to
	 * enable_my_notif, then all userspace needs is to check messages, not a
	 * full preemption recovery. */
	preempt_msg.ev_type = (enable_my_notif ? EV_CHECK_MSGS : EV_VCORE_PREEMPT);
	preempt_msg.ev_arg2 = caller_vcoreid;	/* arg2 is 32 bits */
	/* Whenever we send msgs with the proc locked, we need at least 1 online.
	 * In this case, it's the one we just changed to. */
	assert(!TAILQ_EMPTY(&p->online_vcs));
	send_kernel_event(p, &preempt_msg, new_vcoreid);
	/* So this core knows which vcore is here. (cur_proc and owning_proc are
	 * already correct): */
	pcpui->owning_vcoreid = new_vcoreid;
	/* Until we set_curctx, we don't really have a valid current tf.  The stuff
	 * in that old one is from our previous vcore, not the current
	 * owning_vcoreid.  This matters for other KMSGS that will run before
	 * __set_curctx (like __notify). */
	pcpui->cur_ctx = 0;
	/* Need to send a kmsg to finish.  We can't set_curctx til the __PR is done,
	 * but we can't spin right here while holding the lock (can't spin while
	 * waiting on a message, roughly) */
	send_kernel_message(pcoreid, __set_curctx, (long)p, (long)new_vcoreid,
	                    (long)new_vc->nr_preempts_sent, KMSG_ROUTINE);
	retval = 0;
	/* Fall through to exit */
out_locked:
	spin_unlock(&p->proc_lock);
	return retval;
}

/* Kernel message handler to start a process's context on this core, when the
 * core next considers running a process.  Tightly coupled with __proc_run_m().
 * Interrupts are disabled. */
void __startcore(uint32_t srcid, long a0, long a1, long a2)
{
	uint32_t vcoreid = (uint32_t)a1;
	uint32_t coreid = core_id();
	struct per_cpu_info *pcpui = &per_cpu_info[coreid];
	struct proc *p_to_run = (struct proc *)a0;
	uint32_t old_nr_preempts_sent = (uint32_t)a2;

	assert(p_to_run);
	/* Can not be any TF from a process here already */
	assert(!pcpui->owning_proc);
	/* the sender of the kmsg increfed already for this saved ref to p_to_run */
	pcpui->owning_proc = p_to_run;
	pcpui->owning_vcoreid = vcoreid;
	/* sender increfed again, assuming we'd install to cur_proc.  only do this
	 * if no one else is there.  this is an optimization, since we expect to
	 * send these __startcores to idles cores, and this saves a scramble to
	 * incref when all of the cores restartcore/startcore later.  Keep in sync
	 * with __proc_give_cores() and __proc_run_m(). */
	if (!pcpui->cur_proc) {
		pcpui->cur_proc = p_to_run;	/* install the ref to cur_proc */
		lcr3(p_to_run->env_cr3);	/* load the page tables to match cur_proc */
	} else {
		proc_decref(p_to_run);		/* can't install, decref the extra one */
	}
	/* Note we are not necessarily in the cr3 of p_to_run */
	/* Now that we sorted refcnts and know p / which vcore it should be, set up
	 * pcpui->cur_ctx so that it will run that particular vcore */
	__set_curctx_to_vcoreid(p_to_run, vcoreid, old_nr_preempts_sent);
}

/* Kernel message handler to load a proc's vcore context on this core.  Similar
 * to __startcore, except it is used when p already controls the core (e.g.
 * change_to).  Since the core is already controlled, pcpui such as owning proc,
 * vcoreid, and cur_proc are all already set. */
void __set_curctx(uint32_t srcid, long a0, long a1, long a2)
{
	struct proc *p = (struct proc*)a0;
	uint32_t vcoreid = (uint32_t)a1;
	uint32_t old_nr_preempts_sent = (uint32_t)a2;
	__set_curctx_to_vcoreid(p, vcoreid, old_nr_preempts_sent);
}

/* Bail out if it's the wrong process, or if they no longer want a notif.  Try
 * not to grab locks or write access to anything that isn't per-core in here. */
void __notify(uint32_t srcid, long a0, long a1, long a2)
{
	uint32_t vcoreid, coreid = core_id();
	struct per_cpu_info *pcpui = &per_cpu_info[coreid];
	struct preempt_data *vcpd;
	struct proc *p = (struct proc*)a0;

	/* Not the right proc */
	if (p != pcpui->owning_proc)
		return;
	/* the core might be owned, but not have a valid cur_ctx (if we're in the
	 * process of changing */
	if (!pcpui->cur_ctx)
		return;
	/* Common cur_ctx sanity checks.  Note cur_ctx could be an _S's scp_ctx */
	vcoreid = pcpui->owning_vcoreid;
	vcpd = &p->procdata->vcore_preempt_data[vcoreid];
	/* for SCPs that haven't (and might never) call vc_event_init, like rtld.
	 * this is harmless for MCPS to check this */
	if (!scp_is_vcctx_ready(vcpd))
		return;
	printd("received active notification for proc %d's vcore %d on pcore %d\n",
	       p->procinfo->pid, vcoreid, coreid);
	/* sort signals.  notifs are now masked, like an interrupt gate */
	if (vcpd->notif_disabled)
		return;
	vcpd->notif_disabled = TRUE;
	/* save the old ctx in the uthread slot, build and pop a new one.  Note that
	 * silly state isn't our business for a notification. */
	copy_current_ctx_to(&vcpd->uthread_ctx);
	memset(pcpui->cur_ctx, 0, sizeof(struct user_context));
	proc_init_ctx(pcpui->cur_ctx, vcoreid, vcpd->vcore_entry,
	              vcpd->vcore_stack, vcpd->vcore_tls_desc);
	/* this cur_ctx will get run when the kernel returns / idles */
}

void __preempt(uint32_t srcid, long a0, long a1, long a2)
{
	uint32_t vcoreid, coreid = core_id();
	struct per_cpu_info *pcpui = &per_cpu_info[coreid];
	struct preempt_data *vcpd;
	struct proc *p = (struct proc*)a0;

	assert(p);
	if (p != pcpui->owning_proc) {
		panic("__preempt arrived for a process (%p) that was not owning (%p)!",
		      p, pcpui->owning_proc);
	}
	/* Common cur_ctx sanity checks */
	assert(pcpui->cur_ctx);
	assert(pcpui->cur_ctx == &pcpui->actual_ctx);
	vcoreid = pcpui->owning_vcoreid;
	vcpd = &p->procdata->vcore_preempt_data[vcoreid];
	printd("[kernel] received __preempt for proc %d's vcore %d on pcore %d\n",
	       p->procinfo->pid, vcoreid, coreid);
	/* if notifs are disabled, the vcore is in vcore context (as far as we're
	 * concerned), and we save it in the vcore slot. o/w, we save the process's
	 * cur_ctx in the uthread slot, and it'll appear to the vcore when it comes
	 * back up the uthread just took a notification. */
	if (vcpd->notif_disabled)
		copy_current_ctx_to(&vcpd->vcore_ctx);
	else
		copy_current_ctx_to(&vcpd->uthread_ctx);
	/* Userspace in a preemption handler on another core might be copying FP
	 * state from memory (VCPD) at the moment, and if so we don't want to
	 * clobber it.  In this rare case, our current core's FPU state should be
	 * the same as whatever is in VCPD, so this shouldn't be necessary, but the
	 * arch-specific save function might do something other than write out
	 * bit-for-bit the exact same data.  Checking STEALING suffices, since we
	 * hold the K_LOCK (preventing userspace from starting a fresh STEALING
	 * phase concurrently). */
	if (!(atomic_read(&vcpd->flags) & VC_UTHREAD_STEALING))
		save_vc_fp_state(vcpd);
	/* Mark the vcore as preempted and unlock (was locked by the sender). */
	atomic_or(&vcpd->flags, VC_PREEMPTED);
	atomic_and(&vcpd->flags, ~VC_K_LOCK);
	/* either __preempt or proc_yield() ends the preempt phase. */
	p->procinfo->vcoremap[vcoreid].preempt_pending = 0;
	vcore_account_offline(p, vcoreid);
	wmb();	/* make sure everything else hits before we finish the preempt */
	/* up the nr_done, which signals the next __startcore for this vc */
	p->procinfo->vcoremap[vcoreid].nr_preempts_done++;
	/* We won't restart the process later.  current gets cleared later when we
	 * notice there is no owning_proc and we have nothing to do (smp_idle,
	 * restartcore, etc) */
	clear_owning_proc(coreid);
}

/* Kernel message handler to clean up the core when a process is dying.
 * Note this leaves no trace of what was running.
 * It's okay if death comes to a core that's already idling and has no current.
 * It could happen if a process decref'd before __proc_startcore could incref. */
void __death(uint32_t srcid, long a0, long a1, long a2)
{
	uint32_t vcoreid, coreid = core_id();
	struct per_cpu_info *pcpui = &per_cpu_info[coreid];
	struct proc *p = pcpui->owning_proc;
	if (p) {
		vcoreid = pcpui->owning_vcoreid;
		printd("[kernel] death on physical core %d for process %d's vcore %d\n",
		       coreid, p->pid, vcoreid);
		vcore_account_offline(p, vcoreid);	/* in case anyone is counting */
		/* We won't restart the process later.  current gets cleared later when
		 * we notice there is no owning_proc and we have nothing to do
		 * (smp_idle, restartcore, etc). */
		arch_finalize_ctx(pcpui->cur_ctx);
		clear_owning_proc(coreid);
	}
}

/* Kernel message handler, usually sent IMMEDIATE, to shoot down virtual
 * addresses from a0 to a1. */
void __tlbshootdown(uint32_t srcid, long a0, long a1, long a2)
{
	/* TODO: (TLB) something more intelligent with the range */
	tlbflush();
}

void print_allpids(void)
{
	void print_proc_state(void *item, void *opaque)
	{
		struct proc *p = (struct proc*)item;
		assert(p);
		/* this actually adds an extra space, since no progname is ever
		 * PROGNAME_SZ bytes, due to the \0 counted in PROGNAME. */
		printk("%8d %-*s %-10s %6d\n", p->pid, PROC_PROGNAME_SZ, p->progname,
		       procstate2str(p->state), p->ppid);
	}
	char dashes[PROC_PROGNAME_SZ];
	memset(dashes, '-', PROC_PROGNAME_SZ);
	dashes[PROC_PROGNAME_SZ - 1] = '\0';
	/* -5, for 'Name ' */
	printk("     PID Name %-*s State      Parent    \n",
	       PROC_PROGNAME_SZ - 5, "");
	printk("------------------------------%s\n", dashes);
	spin_lock(&pid_hash_lock);
	hash_for_each(pid_hash, print_proc_state, NULL);
	spin_unlock(&pid_hash_lock);
}

void proc_get_set(struct process_set *pset)
{
	void enum_proc(void *item, void *opaque)
	{
		struct proc *p = (struct proc*) item;
		struct process_set *pset = (struct process_set *) opaque;

		if (pset->num_processes < pset->size) {
			proc_incref(p, 1);

			pset->procs[pset->num_processes] = p;
			pset->num_processes++;
		}
	}

	static const size_t num_extra_alloc = 16;

	pset->procs = NULL;
	do {
		if (pset->procs)
			proc_free_set(pset);
		pset->size = atomic_read(&num_envs) + num_extra_alloc;
		pset->num_processes = 0;
		pset->procs = (struct proc **)
			kzmalloc(pset->size * sizeof(struct proc *), MEM_WAIT);
		if (!pset->procs)
			error(-ENOMEM, ERROR_FIXME);

		spin_lock(&pid_hash_lock);
		hash_for_each(pid_hash, enum_proc, pset);
		spin_unlock(&pid_hash_lock);

	} while (pset->num_processes == pset->size);
}

void proc_free_set(struct process_set *pset)
{
	for (size_t i = 0; i < pset->num_processes; i++)
		proc_decref(pset->procs[i]);
	kfree(pset->procs);
}

void print_proc_info(pid_t pid)
{
	int j = 0;
	uint64_t total_time = 0;
	struct proc *child, *p = pid2proc(pid);
	struct vcore *vc_i;
	if (!p) {
		printk("Bad PID.\n");
		return;
	}
	spinlock_debug(&p->proc_lock);
	//spin_lock(&p->proc_lock); // No locking!!
	printk("struct proc: %p\n", p);
	printk("Program name: %s\n", p->progname);
	printk("PID: %d\n", p->pid);
	printk("PPID: %d\n", p->ppid);
	printk("State: %s (%p)\n", procstate2str(p->state), p->state);
	printk("\tIs %san MCP\n", p->procinfo->is_mcp ? "" : "not ");
	printk("Refcnt: %d\n", atomic_read(&p->p_kref.refcount) - 1);
	printk("Flags: 0x%08x\n", p->env_flags);
	printk("CR3(phys): %p\n", p->env_cr3);
	printk("Num Vcores: %d\n", p->procinfo->num_vcores);
	printk("Vcore Lists (may be in flux w/o locking):\n----------------------\n");
	printk("Online:\n");
	TAILQ_FOREACH(vc_i, &p->online_vcs, list)
		printk("\tVcore %d -> Pcore %d\n", vcore2vcoreid(p, vc_i), vc_i->pcoreid);
	printk("Bulk Preempted:\n");
	TAILQ_FOREACH(vc_i, &p->bulk_preempted_vcs, list)
		printk("\tVcore %d\n", vcore2vcoreid(p, vc_i));
	printk("Inactive / Yielded:\n");
	TAILQ_FOREACH(vc_i, &p->inactive_vcs, list)
		printk("\tVcore %d\n", vcore2vcoreid(p, vc_i));
	printk("Nsec Online, up to the last offlining:\n------------------------");
	for (int i = 0; i < p->procinfo->max_vcores; i++) {
		uint64_t vc_time = tsc2nsec(vcore_account_gettotal(p, i));
		if (i % 4 == 0)
			printk("\n");
		printk("  VC %3d: %14llu", i, vc_time);
		total_time += vc_time;
	}
	printk("\n");
	printk("Total CPU-NSEC: %llu\n", total_time);
	printk("Resources:\n------------------------\n");
	for (int i = 0; i < MAX_NUM_RESOURCES; i++)
		printk("\tRes type: %02d, amt wanted: %08d, amt granted: %08d\n", i,
		       p->procdata->res_req[i].amt_wanted, p->procinfo->res_grant[i]);
	printk("Open Files:\n");
	struct fd_table *files = &p->open_files;
	if (spin_locked(&files->lock)) {
		spinlock_debug(&files->lock);
		printk("FILE LOCK HELD, ABORTING\n");
		proc_decref(p);
		return;
	}
	spin_lock(&files->lock);
	for (int i = 0; i < files->max_files; i++) {
		if (GET_BITMASK_BIT(files->open_fds->fds_bits, i)) {
			printk("\tFD: %02d, ", i);
			if (files->fd[i].fd_file) {
				printk("File: %p, File name: %s\n", files->fd[i].fd_file,
				       file_name(files->fd[i].fd_file));
			} else {
				assert(files->fd[i].fd_chan);
				print_chaninfo(files->fd[i].fd_chan);
			}
		}
	}
	spin_unlock(&files->lock);
	printk("Children: (PID (struct proc *))\n");
	TAILQ_FOREACH(child, &p->children, sibling_link)
		printk("\t%d (%p)\n", child->pid, child);
	/* no locking / unlocking or refcnting */
	// spin_unlock(&p->proc_lock);
	proc_decref(p);
}

/* Debugging function, checks what (process, vcore) is supposed to run on this
 * pcore.  Meant to be called from smp_idle() before halting. */
void check_my_owner(void)
{
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	void shazbot(void *item, void *opaque)
	{
		struct proc *p = (struct proc*)item;
		struct vcore *vc_i;
		assert(p);
		spin_lock(&p->proc_lock);
		TAILQ_FOREACH(vc_i, &p->online_vcs, list) {
			/* this isn't true, a __startcore could be on the way and we're
			 * already "online" */
			if (vc_i->pcoreid == core_id()) {
				/* Immediate message was sent, we should get it when we enable
				 * interrupts, which should cause us to skip cpu_halt() */
				if (!STAILQ_EMPTY(&pcpui->immed_amsgs))
					continue;
				printk("Owned pcore (%d) has no owner, by %p, vc %d!\n",
				       core_id(), p, vcore2vcoreid(p, vc_i));
				spin_unlock(&p->proc_lock);
				spin_unlock(&pid_hash_lock);
				monitor(0);
			}
		}
		spin_unlock(&p->proc_lock);
	}
	assert(!irq_is_enabled());
	if (!booting && !pcpui->owning_proc) {
		spin_lock(&pid_hash_lock);
		hash_for_each(pid_hash, shazbot, NULL);
		spin_unlock(&pid_hash_lock);
	}
}
