/* Copyright (c) 2011 The Regents of the University of California
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * Kernel utility functions for sending events and notifications (IPIs) to
 * processes. */

#include <ucq.h>
#include <bitmask.h>
#include <event.h>
#include <atomic.h>
#include <process.h>
#include <smp.h>
#include <umem.h>
#include <stdio.h>
#include <assert.h>
#include <pmap.h>
#include <schedule.h>

/* Userspace could give us a vcoreid that causes us to compute a vcpd that is
 * outside procdata.  If we hit UWLIM, then we've gone farther than we should.
 * We check the vcoreid, instead of the resulting address, to avoid issues like
 * address wrap-around. */
static bool vcoreid_is_safe(uint32_t vcoreid)
{
	/* MAX_NUM_VCORES == MAX_NUM_CPUS (check procinfo/procdata) */
	return vcoreid < MAX_NUM_CPUS;
}

/* Note these three helpers return the user address of the mbox, not the KVA.
 * Load current to access this, and it will work for any process. */
static struct event_mbox *get_vcpd_mbox_priv(uint32_t vcoreid)
{
	return &__procdata.vcore_preempt_data[vcoreid].ev_mbox_private;
}

static struct event_mbox *get_vcpd_mbox_pub(uint32_t vcoreid)
{
	return &__procdata.vcore_preempt_data[vcoreid].ev_mbox_public;
}

static struct event_mbox *get_vcpd_mbox(uint32_t vcoreid, int ev_flags)
{
	if (ev_flags & EVENT_VCORE_PRIVATE)
		return get_vcpd_mbox_priv(vcoreid);
	else
		return get_vcpd_mbox_pub(vcoreid);
}

/* Can we message the vcore?  (Will it check its messages).  Note this checks
 * procdata via the user pointer. */
static bool can_msg_vcore(uint32_t vcoreid)
{
	struct preempt_data *vcpd = &__procdata.vcore_preempt_data[vcoreid];
	return atomic_read(&vcpd->flags) & VC_CAN_RCV_MSG;
}

/* Says a vcore can be messaged.  Only call this once you are sure this is true
 * (holding the proc_lock, etc). */
static void set_vcore_msgable(uint32_t vcoreid)
{
	struct preempt_data *vcpd = &__procdata.vcore_preempt_data[vcoreid];
	atomic_or(&vcpd->flags, VC_CAN_RCV_MSG);
}

/* Posts a message to the mbox, subject to flags.  Feel free to send 0 for the
 * flags if you don't want to give them the option of EVENT_NOMSG (which is what
 * we do when sending an indirection event).  Make sure that if mbox is a user
 * pointer, that you've checked it *and* have that processes address space
 * loaded.  This can get called with a KVA for mbox. */
static void post_ev_msg(struct proc *p, struct event_mbox *mbox,
                        struct event_msg *msg, int ev_flags)
{
	printd("[kernel] Sending event type %d to mbox %p\n", msg->ev_type, mbox);
	/* Sanity check */
	assert(p);
	/* If they just want a bit (NOMSG), just set the bit */
	if (ev_flags & EVENT_NOMSG) {
		SET_BITMASK_BIT_ATOMIC(mbox->ev_bitmap, msg->ev_type);
		wmb();
		mbox->ev_check_bits = TRUE;
	} else {
		send_ucq_msg(&mbox->ev_msgs, p, msg);
	}
}

/* Helper: use this when sending a message to a VCPD mbox.  It just posts to the
 * ev_mbox and sets notif pending.  Note this uses a userspace address for the
 * VCPD (though not a user's pointer). */
static void post_vc_msg(struct proc *p, uint32_t vcoreid,
                        struct event_mbox *ev_mbox, struct event_msg *ev_msg,
                        int ev_flags)
{
	struct preempt_data *vcpd = &__procdata.vcore_preempt_data[vcoreid];
	post_ev_msg(p, ev_mbox, ev_msg, ev_flags);
	/* Set notif pending so userspace doesn't miss the message while yielding */
	wmb(); /* Ensure ev_msg write is before notif_pending */
	/* proc_notify() also sets this, but the ev_q might not have requested an
	 * IPI, so we have to do it here too. */
	vcpd->notif_pending = TRUE;
}

/* Helper: will IPI / proc_notify if the flags say so.  We also check to make
 * sure it is mapped (slight optimization) */
static void try_notify(struct proc *p, uint32_t vcoreid, int ev_flags)
{
	/* Note this is an unlocked-peek at the vcoremap */
	if ((ev_flags & EVENT_IPI) && vcore_is_mapped(p, vcoreid))
		proc_notify(p, vcoreid);
}

/* Helper: sends the message and an optional IPI to the vcore.  Sends to the
 * public mbox.  This is meant for spammy messages. */
static void spam_vcore(struct proc *p, uint32_t vcoreid,
                       struct event_msg *ev_msg, int ev_flags)
{
	post_vc_msg(p, vcoreid, get_vcpd_mbox_pub(vcoreid), ev_msg, ev_flags);
	try_notify(p, vcoreid, ev_flags);
}

/* Attempts to message a vcore that may or may not have VC_CAN_RCV_MSG set.  If
 * so, we'll post the message and the message will eventually get dealt with
 * (when the vcore runs or when it is preempte-recovered). */
static bool try_spam_vcore(struct proc *p, uint32_t vcoreid,
                           struct event_msg *ev_msg, int ev_flags)
{
	/* Not sure if we can or not, so check before spamming.  Technically, the
	 * only critical part is that we __alert, then check can_alert. */
	if (can_msg_vcore(vcoreid)) {
		spam_vcore(p, vcoreid, ev_msg, ev_flags);
		wrmb();	/* prev write (notif_pending) must come before following reads*/
		if (can_msg_vcore(vcoreid))
			return TRUE;
	}
	return FALSE;
}

/* Helper: will try to message (INDIR/IPI) a list member (lists of vcores).  We
 * use this on the online and bulk_preempted vcore lists.  If this succeeds in
 * alerting a vcore on the list, it'll return TRUE.  We need to be careful here,
 * since we're reading a list that could be concurrently modified.  The
 * important thing is that we can always fail if we're unsure (such as with
 * lists being temporarily empty).  The caller will be able to deal with it via
 * the ultimate fallback. */
static bool spam_list_member(struct vcore_tailq *list, struct proc *p,
                             struct event_msg *ev_msg, int ev_flags)
{
	struct vcore *vc, *vc_first;
	uint32_t vcoreid;
	int loops = 0;
	vc = TAILQ_FIRST(list);
	/* If the list appears empty, we'll bail out (failing) after the loop. */
	while (vc) {
		vcoreid = vcore2vcoreid(p, vc);
		/* post the alert.  Not using the try_spam_vcore() helper since I want
		 * something more customized for the lists. */
		spam_vcore(p, vcoreid, ev_msg, ev_flags);
		wrmb();	/* prev write (notif_pending) must come before following reads*/
		/* if they are still alertable after we sent the msg, then they'll get
		 * it before yielding (racing with userspace yield here).  This check is
		 * not as critical as the next one, but will allow us to alert vcores
		 * that happen to concurrently be moved from the active to the
		 * bulk_preempt list. */
		if (can_msg_vcore(vcoreid))
			return TRUE;
		/* As a backup, if they are still the first on the list, then they are
		 * still going to get the message.  For the online list, proc_yield()
		 * will return them to userspace (where they will get the message)
		 * because __alert_vcore() set notif_pending.  For the BP list, they
		 * will either be turned on later, or have a preempt message sent about
		 * their demise.
		 *
		 * We race on list membership (and not exclusively VC_CAN_RCV_MSG, so
		 * that when it fails we can get a new vcore to try (or know WHP there
		 * are none). */
		vc_first = TAILQ_FIRST(list);
		if (vc == vc_first)
			return TRUE;
		/* At this point, the list has changed and the vcore we tried yielded,
		 * so we try the *new* list head.  Track loops for sanity reasons. */
		if (loops++ > 10) {
			warn("Too many (%d) attempts to find a vcore, failing!", loops);
			return FALSE;	/* always safe to fail! */
		}
		/* Get set up for your attack run! */
		vc = vc_first;
	}
	return FALSE;
}

/* This makes sure ev_msg is sent to some vcore, preferring vcoreid.
 *
 * One of the goals of FALLBACK (and this func) is to allow processes to yield
 * cores without fear of losing messages.  Even when yielding and getting
 * preempted, if your message is spammed, it will get to some vcore.  If
 * MUST_RUN is set, it'll get to a running vcore.  Messages that you send like
 * this must be able to handle spurious reads, since more than one vcore is
 * likely to get the message and handle it.
 *
 * We try the desired vcore, using VC_CAN_RCV_MSG.  Failing that, we'll search
 * the online and then the bulk_preempted lists.  These lists serve as a way to
 * find likely messageable vcores.  spam_list_member() helps us with them,
 * failing if anything seems to go wrong.  At which point we just lock and try
 * to deal with things.  In that scenario, we most likely would need to lock
 * anyway to wake up the process (was WAITING).
 *
 * One tricky thing with sending to the bulk_preempt list is that we may want to
 * send a message about a (bulk) preemption to someone on that list.  This works
 * since a given vcore that was preempted will be removed from that list before
 * we try to send_event() (in theory, there isn't code that can send that event
 * yet).  Someone else will get the event and wake up the preempted vcore. */
static void spam_public_msg(struct proc *p, struct event_msg *ev_msg,
							uint32_t vcoreid, int ev_flags)
{
	struct vcore *vc;
	/* First, try posting to the desired vcore (so long as we don't have to send
	 * it to a vcore that will run, like we do for preempt messages). */
	if (!(ev_flags & EVENT_VCORE_MUST_RUN) &&
	   (try_spam_vcore(p, vcoreid, ev_msg, ev_flags)))
		return;
	/* If the process is WAITING, let's just jump to the fallback */
	if (p->state == PROC_WAITING)
		goto ultimate_fallback;
	/* If we're here, the desired vcore is unreachable, but the process is
	 * probably RUNNING_M (online_vs) or RUNNABLE_M (bulk preempted or recently
	 * woken up), so we'll need to find another vcore. */
	if (spam_list_member(&p->online_vcs, p, ev_msg, ev_flags))
		return;
	if (spam_list_member(&p->bulk_preempted_vcs, p, ev_msg, ev_flags))
		return;
	/* Last chance, let's check the head of the inactives.  It might be
	 * alertable (the kernel set it earlier due to an event, or it was a
	 * bulk_preempt that didn't restart), and we can avoid grabbing the
	 * proc_lock. */
	vc = TAILQ_FIRST(&p->inactive_vcs);
	if (vc) {	/* might be none in rare circumstances */
		if (try_spam_vcore(p, vcore2vcoreid(p, vc), ev_msg, ev_flags)) {
			/* Need to ensure the proc wakes up, but only if it was WAITING.
			 * One way for this to happen is if a normal vcore was preempted
			 * right as another vcore was yielding, and the preempted
			 * message was sent after the last vcore yielded (which caused
			 * us to be WAITING */
			if (p->state == PROC_WAITING)
				proc_wakeup(p);	/* internally, this double-checks WAITING */
			return;
		}
	}
ultimate_fallback:
	/* At this point, we can't find one.  This could be due to a (hopefully
	 * rare) weird yield/request storm, or more commonly because the lists were
	 * empty and the process is simply WAITING (yielded all of its vcores and is
	 * waiting on an event).  Time for the ultimate fallback: locking.  Note
	 * that when we __alert_vcore(), there is a chance we need to mmap, which
	 * grabs the vmr_lock and pte_lock. */
	spin_lock(&p->proc_lock);
	if (p->state != PROC_WAITING) {
		/* We need to check the online and bulk_preempt lists again, now that we are
		 * sure no one is messing with them.  If we're WAITING, we can skip
		 * these (or assert they are empty!). */
		vc = TAILQ_FIRST(&p->online_vcs);
		if (vc) {
			/* there's an online vcore, so just alert it (we know it isn't going
			 * anywhere), and return */
			spam_vcore(p, vcore2vcoreid(p, vc), ev_msg, ev_flags);
			spin_unlock(&p->proc_lock);
			return;
		}
		vc = TAILQ_FIRST(&p->bulk_preempted_vcs);
		if (vc) {
			/* the process is bulk preempted, similar deal to above */
			spam_vcore(p, vcore2vcoreid(p, vc), ev_msg, ev_flags);
			spin_unlock(&p->proc_lock);
			return;
		}
	}
	/* At this point, we're sure all vcores are yielded, though we might not be
	 * WAITING.  Post to the first on the inactive list (which is the one that
	 * will definitely be woken up) */
	vc = TAILQ_FIRST(&p->inactive_vcs);
	assert(vc);
	spam_vcore(p, vcore2vcoreid(p, vc), ev_msg, ev_flags);
	/* Set the vcore's alertable flag, to short circuit our last ditch effort
	 * above */
	set_vcore_msgable(vcore2vcoreid(p, vc));
	/* The first event to catch the process with no online/bp vcores will need
	 * to wake it up.  (We could be RUNNABLE_M here if another event already woke
	 * us.) and we didn't get lucky with the penultimate fallback.
	 * proc_wakeup (and __proc_wakeup()) will check for WAITING. */
	spin_unlock(&p->proc_lock);
	proc_wakeup(p);
	return;
}

/* Helper: sends an indirection event for an ev_q, preferring vcoreid */
static void send_indir(struct proc *p, struct event_queue *ev_q,
                       uint32_t vcoreid)
{
	struct event_msg local_msg = {0};
	/* If an alert is already pending and they don't want repeats, just return.
	 * One of the few uses of NOTHROTTLE will be for preempt_msg ev_qs.  Ex: an
	 * INDIR was already sent to the preempted vcore, then alert throttling
	 * would stop another vcore from getting the message about the original
	 * vcore. */
	if (!(ev_q->ev_flags & EVENT_NOTHROTTLE) && (ev_q->ev_alert_pending))
		return;
	/* We'll eventually get an INDIR through, so don't send any more til
	 * userspace toggles this.  Regardless of other writers to this flag, we
	 * eventually send an alert that causes userspace to turn throttling off
	 * again (before handling all of the ev_q's events).
	 *
	 * This will also squelch IPIs, since there's no reason to send the IPI if
	 * the INDIR is still un-acknowledged.  The vcore is either in vcore
	 * context, attempting to deal with the INDIR, or offline.  This statement
	 * is probably true. */
	ev_q->ev_alert_pending = TRUE;
	wmb();	/* force this write to happen before any event writes */
	local_msg.ev_type = EV_EVENT;
	local_msg.ev_arg3 = ev_q;
	/* Don't care about FALLBACK, just send and be done with it.  TODO:
	 * considering getting rid of FALLBACK as an option and making it mandatory
	 * when you want an INDIR.  Having trouble thinking of when you'd want an
	 * INDIR but not a FALLBACK. */
	if (!(ev_q->ev_flags & EVENT_FALLBACK)) {
		printk("[kernel] INDIR requested without FALLBACK, prob a bug.\n");
		spam_vcore(p, vcoreid, &local_msg, ev_q->ev_flags);
		return;
	}
	/* At this point, we actually want to send an INDIR (with FALLBACK).
	 * This will guarantee the message makes it to some vcore.  For flags, we
	 * only want to send flags relevant to spamming messages. */
	spam_public_msg(p, &local_msg, vcoreid, ev_q->ev_flags & EVENT_SPAM_FLAGS);
}

/* Send an event to ev_q, based on the parameters in ev_q's flag.  We don't
 * accept null ev_qs, since the caller ought to be checking before bothering to
 * make a msg and send it to the event_q.  Vcoreid is who the kernel thinks the
 * message ought to go to (for IPIs).  Appropriate for things like
 * EV_PREEMPT_PENDING, where we tell the affected vcore.  To have the message go
 * where the kernel suggests, set EVENT_VCORE_APPRO(priate). */
void send_event(struct proc *p, struct event_queue *ev_q, struct event_msg *msg,
                uint32_t vcoreid)
{
	struct proc *old_proc;
	struct event_mbox *ev_mbox = 0;
	assert(!in_irq_ctx(&per_cpu_info[core_id()]));
	assert(p);
	if (p->state == PROC_DYING)
		return;
	printd("[kernel] sending msg to proc %p, ev_q %p\n", p, ev_q);
	if (!ev_q) {
		warn("[kernel] Null ev_q - kernel code should check before sending!");
		return;
	}
	if (!is_user_rwaddr(ev_q, sizeof(struct event_queue))) {
		/* Ought to kill them, just warn for now */
		printk("[kernel] Illegal addr for ev_q\n");
		return;
	}
	/* This should be caught by "future technology" that can tell when the
	 * kernel PFs on the user's behalf.  For now, we catch common userspace bugs
	 * (had this happen a few times). */
	if (!PTE_ADDR(ev_q)) {
		printk("[kernel] Bad addr %p for ev_q\n", ev_q);
		return;
	}
	/* ev_q is a user pointer, so we need to make sure we're in the right
	 * address space */
	old_proc = switch_to(p);
	/* If we're an _S, just spam vcore0, and wake up if necessary. */
	if (!__proc_is_mcp(p)) {
		spam_vcore(p, 0, msg, ev_q->ev_flags);
		wrmb();	/* don't let the notif_pending write pass the state read */
		/* using the same pattern as in spam_public (which can have multiple
		 * unblock callbacks */
		if (p->state == PROC_WAITING)
			proc_wakeup(p);
		goto out;
	}
	/* Get the vcoreid that we'll message (if appropriate).  For INDIR and
	 * SPAMMING, this is the first choice of a vcore, but other vcores might get
	 * it.  Common case is !APPRO and !ROUNDROBIN.  Note we are clobbering the
	 * vcoreid parameter. */
	if (!(ev_q->ev_flags & EVENT_VCORE_APPRO))
		vcoreid = ev_q->ev_vcore;	/* use the ev_q's vcoreid */
	/* Note that RR overwrites APPRO */
	if (ev_q->ev_flags & EVENT_ROUNDROBIN) {
		/* Pick a vcore, round-robin style.  Assuming ev_vcore was the previous
		 * one used.  Note that round-robin overrides the passed-in vcoreid.
		 * Also note this may be 'wrong' if num_vcores changes. */
		vcoreid = (ev_q->ev_vcore + 1) % p->procinfo->num_vcores;
		ev_q->ev_vcore = vcoreid;
	}
	if (!vcoreid_is_safe(vcoreid)) {
		/* Ought to kill them, just warn for now */
		printk("[kernel] Vcoreid %d unsafe! (too big?)\n", vcoreid);
		goto out;
	}
	/* If we're a SPAM_PUBLIC, they just want us to spam the message.  Note we
	 * don't care about the mbox, since it'll go to VCPD public mboxes, and
	 * we'll prefer to send it to whatever vcoreid we determined at this point
	 * (via APPRO or whatever). */
	if (ev_q->ev_flags & EVENT_SPAM_PUBLIC) {
		spam_public_msg(p, msg, vcoreid, ev_q->ev_flags & EVENT_SPAM_FLAGS);
		goto out;
	}
	/* We aren't spamming and we know the default vcore, and now we need to
	 * figure out which mbox to use.  If they provided an mbox, we'll use it.
	 * If not, we'll use a VCPD mbox (public or private, depending on the
	 * flags). */
	ev_mbox = ev_q->ev_mbox;
	if (!ev_mbox)
		ev_mbox = get_vcpd_mbox(vcoreid, ev_q->ev_flags);
	/* At this point, we ought to have the right mbox to send the msg to, and
	 * which vcore to alert (IPI/INDIR) (if applicable).  The mbox could be the
	 * vcore's vcpd ev_mbox. */
	if (!ev_mbox) {
		/* This shouldn't happen any more, this is more for sanity's sake */
		warn("[kernel] ought to have an mbox by now!");
		goto out;
	}
	/* Even if we're using an mbox in procdata (VCPD), we want a user pointer */
	if (!is_user_rwaddr(ev_mbox, sizeof(struct event_mbox))) {
		/* Ought to kill them, just warn for now */
		printk("[kernel] Illegal addr for ev_mbox\n");
		goto out;
	}
	/* We used to support no msgs, but quit being lazy and send a 'msg'.  If the
	 * ev_q is a NOMSG, we won't actually memcpy or anything, it'll just be a
	 * vehicle for sending the ev_type. */
	assert(msg);
	post_ev_msg(p, ev_mbox, msg, ev_q->ev_flags);
	wmb();	/* ensure ev_msg write is before alerting the vcore */
	/* Prod/alert a vcore with an IPI or INDIR, if desired.  INDIR will also
	 * call try_notify (IPI) later */
	if (ev_q->ev_flags & EVENT_INDIR) {
		send_indir(p, ev_q, vcoreid);
	} else {
		/* they may want an IPI despite not wanting an INDIR */
		try_notify(p, vcoreid, ev_q->ev_flags);
	}
	/* Fall through */
out:
	/* Return to the old address space. */
	switch_back(p, old_proc);
}

/* Send an event for the kernel event ev_num.  These are the "one sided" kernel
 * initiated events, that require a lookup of the ev_q in procdata.  This is
 * roughly equivalent to the old "proc_notify()" */
void send_kernel_event(struct proc *p, struct event_msg *msg, uint32_t vcoreid)
{
	uint16_t ev_num = msg->ev_type;
	assert(ev_num < MAX_NR_EVENT);		/* events start at 0 */
	struct event_queue *ev_q = p->procdata->kernel_evts[ev_num];
	/* linux would put a rmb_depends() here too, i think. */
	if (ev_q)
		send_event(p, ev_q, msg, vcoreid);
}

/* Writes the msg to the vcpd mbox of the vcore.  If you want the private mbox,
 * send in the ev_flag EVENT_VCORE_PRIVATE.  If not, the message could
 * be received by other vcores if the given vcore is offline/preempted/etc.
 * Whatever other flags you pass in will get sent to post_ev_msg.  Currently,
 * the only one that will get looked at is NO_MSG (set a bit).
 *
 * This needs to load current (switch_to), but doesn't need to care about what
 * the process wants.  Note this isn't commonly used - just the monitor and
 * sys_self_notify(). */
void post_vcore_event(struct proc *p, struct event_msg *msg, uint32_t vcoreid,
                      int ev_flags)
{
	/* Need to set p as current to post the event */
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	struct proc *old_proc = switch_to(p);
	/* *ev_mbox is the user address of the vcpd mbox */
	post_vc_msg(p, vcoreid, get_vcpd_mbox(vcoreid, ev_flags), msg, ev_flags);
	switch_back(p, old_proc);
}

/* Attempts to send a posix signal to the process.  If they do not have an ev_q
 * registered for EV_POSIX_SIGNAL, then nothing will happen. */
void send_posix_signal(struct proc *p, int sig_nr)
{
	struct event_msg local_msg = {0};
	local_msg.ev_type = EV_POSIX_SIGNAL;
	local_msg.ev_arg1 = sig_nr;
	send_kernel_event(p, &local_msg, 0);
}
