qemu/hw/dataplane/vring.h
Stefan Hajnoczi 88807f89d9 dataplane: add virtqueue vring code
The virtio-blk-data-plane cannot access memory using the usual QEMU
functions since it executes outside the global mutex and the memory APIs
are this time are not thread-safe.

This patch introduces a virtqueue module based on the kernel's vhost
vring code.  The trick is that we map guest memory ahead of time and
access it cheaply outside the global mutex.

Once the hardware emulation code can execute outside the global mutex it
will be possible to drop this code.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2013-01-02 15:55:47 +01:00

63 lines
2.0 KiB
C

/* Copyright 2012 Red Hat, Inc. and/or its affiliates
* Copyright IBM, Corp. 2012
*
* Based on Linux 2.6.39 vhost code:
* Copyright (C) 2009 Red Hat, Inc.
* Copyright (C) 2006 Rusty Russell IBM Corporation
*
* Author: Michael S. Tsirkin <mst@redhat.com>
* Stefan Hajnoczi <stefanha@redhat.com>
*
* Inspiration, some code, and most witty comments come from
* Documentation/virtual/lguest/lguest.c, by Rusty Russell
*
* This work is licensed under the terms of the GNU GPL, version 2.
*/
#ifndef VRING_H
#define VRING_H
#include <linux/virtio_ring.h>
#include "qemu-common.h"
#include "hw/dataplane/hostmem.h"
#include "hw/virtio.h"
typedef struct {
HostMem hostmem; /* guest memory mapper */
struct vring vr; /* virtqueue vring mapped to host memory */
uint16_t last_avail_idx; /* last processed avail ring index */
uint16_t last_used_idx; /* last processed used ring index */
uint16_t signalled_used; /* EVENT_IDX state */
bool signalled_used_valid;
bool broken; /* was there a fatal error? */
} Vring;
static inline unsigned int vring_get_num(Vring *vring)
{
return vring->vr.num;
}
/* Are there more descriptors available? */
static inline bool vring_more_avail(Vring *vring)
{
return vring->vr.avail->idx != vring->last_avail_idx;
}
/* Fail future vring_pop() and vring_push() calls until reset */
static inline void vring_set_broken(Vring *vring)
{
vring->broken = true;
}
bool vring_setup(Vring *vring, VirtIODevice *vdev, int n);
void vring_teardown(Vring *vring);
void vring_disable_notification(VirtIODevice *vdev, Vring *vring);
bool vring_enable_notification(VirtIODevice *vdev, Vring *vring);
bool vring_should_notify(VirtIODevice *vdev, Vring *vring);
int vring_pop(VirtIODevice *vdev, Vring *vring,
struct iovec iov[], struct iovec *iov_end,
unsigned int *out_num, unsigned int *in_num);
void vring_push(Vring *vring, unsigned int head, int len);
#endif /* VRING_H */