public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Rusty Russell <rusty@rustcorp.com.au>
To: Anthony Liguori <anthony@codemonkey.ws>,
	Sasha Levin <levinsasha928@gmail.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>,
	Cyrill Gorcunov <gorcunov@gmail.com>, kvm <kvm@vger.kernel.org>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	Corentin Chary <corentincj@iksaif.net>,
	Asias He <asias.hejun@gmail.com>,
	Marcelo Tosatti <mtosatti@redhat.com>,
	qemu-devel <qemu-devel@nongnu.org>,
	Pekka Enberg <penberg@kernel.org>, Avi Kivity <avi@redhat.com>,
	Ingo Molnar <mingo@elte.hu>
Subject: Re: [Qemu-devel] Secure KVM
Date: Tue, 08 Nov 2011 09:36:44 +1030	[thread overview]
Message-ID: <87mxc7sfaz.fsf@rustcorp.com.au> (raw)
In-Reply-To: <4EB81D7A.4080409@codemonkey.ws>

On Mon, 07 Nov 2011 12:03:38 -0600, Anthony Liguori <anthony@codemonkey.ws> wrote:
> So the sandbox loop would look like:
> 
> void main() {
>    setup_devices();
> 
>    read_from_event_channel(main_channel);
>    for i in vrings:
>       check_vring_notification(i);
> }

lguest uses a model where you attach an eventfd to a given virtqueue.
(If you don't have an eventfd registered for a vq, the main process
 returns from the read() of /dev/lguest with the info).

At the moment we use a process per virtqueue, but you could attach the
same eventfd to multiple vqs.

Since you can't select() inside seccomp, the main process could write to
the eventfd to wake up the thread to respond to IPC.

Here's the net output code:

/*
 * The Network
 *
 * Handling output for network is also simple: we get all the output buffers
 * and write them to /dev/net/tun.
 */
struct net_info {
	int tunfd;
};

static void net_output(struct virtqueue *vq)
{
	struct net_info *net_info = vq->dev->priv;
	unsigned int head, out, in;
	struct iovec iov[vq->vring.num];

	/* We usually wait in here for the Guest to give us a packet. */
	head = wait_for_vq_desc(vq, iov, &out, &in);
	if (in)
		errx(1, "Input buffers in net output queue?");
	/*
	 * Send the whole thing through to /dev/net/tun.  It expects the exact
	 * same format: what a coincidence!
	 */
	if (writev(net_info->tunfd, iov, out) < 0)
		warnx("Write to tun failed (%d)?", errno);

	/*
	 * Done with that one; wait_for_vq_desc() will send the interrupt if
	 * all packets are processed.
	 */
	add_used(vq, head, 0);
}

Here's the input thread:

/*
 * Handling network input is a bit trickier, because I've tried to optimize it.
 *
 * First we have a helper routine which tells is if from this file descriptor
 * (ie. the /dev/net/tun device) will block:
 */
static bool will_block(int fd)
{
	fd_set fdset;
	struct timeval zero = { 0, 0 };
	FD_ZERO(&fdset);
	FD_SET(fd, &fdset);
	return select(fd+1, &fdset, NULL, NULL, &zero) != 1;
}

/*
 * This handles packets coming in from the tun device to our Guest.  Like all
 * service routines, it gets called again as soon as it returns, so you don't
 * see a while(1) loop here.
 */
static void net_input(struct virtqueue *vq)
{
	int len;
	unsigned int head, out, in;
	struct iovec iov[vq->vring.num];
	struct net_info *net_info = vq->dev->priv;

	/*
	 * Get a descriptor to write an incoming packet into.  This will also
	 * send an interrupt if they're out of descriptors.
	 */
	head = wait_for_vq_desc(vq, iov, &out, &in);
	if (out)
		errx(1, "Output buffers in net input queue?");

	/*
	 * If it looks like we'll block reading from the tun device, send them
	 * an interrupt.
	 */
	if (vq->pending_used && will_block(net_info->tunfd))
		trigger_irq(vq);

	/*
	 * Read in the packet.  This is where we normally wait (when there's no
	 * incoming network traffic).
	 */
	len = readv(net_info->tunfd, iov, in);
	if (len <= 0)
		warn("Failed to read from tun (%d).", errno);

	/*
	 * Mark that packet buffer as used, but don't interrupt here.  We want
	 * to wait until we've done as much work as we can.
	 */
	add_used(vq, head, len);
}


  reply	other threads:[~2011-11-08  6:26 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-11-06 20:40 Secure KVM Sasha Levin
2011-11-07  0:07 ` Rusty Russell
2011-11-07  6:29   ` Sasha Levin
2011-11-07  6:37     ` Pekka Enberg
2011-11-07  6:46       ` Sasha Levin
2011-11-07  7:03         ` Pekka Enberg
2011-11-07 22:49     ` Rusty Russell
2011-11-07  9:26 ` Avi Kivity
2011-11-07 10:17   ` Sasha Levin
2011-11-07 10:27     ` Avi Kivity
2011-11-07 11:27     ` Stefan Hajnoczi
2011-11-07 12:40       ` Sasha Levin
2011-11-07 12:51         ` Avi Kivity
2011-11-07 14:56           ` Stefan Hajnoczi
2011-11-07 17:43       ` Anthony Liguori
2011-11-07 18:41         ` Avi Kivity
2011-11-07 17:39   ` Anthony Liguori
2011-11-07 18:43     ` Avi Kivity
2011-11-07 19:07       ` Anthony Liguori
2011-11-07 19:54         ` Avi Kivity
2011-11-07 22:56   ` Rusty Russell
2011-11-07 17:37 ` Anthony Liguori
2011-11-07 17:52   ` Sasha Levin
2011-11-07 18:03     ` [Qemu-devel] " Anthony Liguori
2011-11-07 23:06       ` Rusty Russell [this message]
2011-11-08 19:51       ` Will Drewry

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87mxc7sfaz.fsf@rustcorp.com.au \
    --to=rusty@rustcorp.com.au \
    --cc=aarcange@redhat.com \
    --cc=anthony@codemonkey.ws \
    --cc=asias.hejun@gmail.com \
    --cc=avi@redhat.com \
    --cc=corentincj@iksaif.net \
    --cc=gorcunov@gmail.com \
    --cc=kvm@vger.kernel.org \
    --cc=levinsasha928@gmail.com \
    --cc=mingo@elte.hu \
    --cc=mst@redhat.com \
    --cc=mtosatti@redhat.com \
    --cc=penberg@kernel.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox