virtio_ring.h 3.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#ifndef _LINUX_VIRTIO_RING_H
#define _LINUX_VIRTIO_RING_H
/* An interface for efficient virtio implementation, currently for use by KVM
 * and lguest, but hopefully others soon.  Do NOT change this since it will
 * break existing servers and clients.
 *
 * This header is BSD licensed so anyone can use the definitions to implement
 * compatible drivers/servers.
 *
 * Copyright Rusty Russell IBM Corporation 2007. */
#include <linux/types.h>

/* This marks a buffer as continuing via the next field. */
#define VRING_DESC_F_NEXT	1
/* This marks a buffer as write-only (otherwise read-only). */
#define VRING_DESC_F_WRITE	2
17 18
/* This means the buffer contains a list of buffer descriptors. */
#define VRING_DESC_F_INDIRECT	4
19

20 21 22
/* The Host uses this in used->flags to advise the Guest: don't kick me when
 * you add a buffer.  It's unreliable, so it's simply an optimization.  Guest
 * will still kick if it's out of buffers. */
23
#define VRING_USED_F_NO_NOTIFY	1
24 25 26
/* The Guest uses this in avail->flags to advise the Host: don't interrupt me
 * when you consume a buffer.  It's unreliable, so it's simply an
 * optimization.  */
27 28
#define VRING_AVAIL_F_NO_INTERRUPT	1

29 30 31
/* We support indirect buffer descriptors */
#define VIRTIO_RING_F_INDIRECT_DESC	28

32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
/* Virtio ring descriptors: 16 bytes.  These can chain together via "next". */
struct vring_desc
{
	/* Address (guest-physical). */
	__u64 addr;
	/* Length. */
	__u32 len;
	/* The flags as indicated above. */
	__u16 flags;
	/* We chain unused descriptors via this, too */
	__u16 next;
};

struct vring_avail
{
	__u16 flags;
	__u16 idx;
	__u16 ring[];
};

/* u32 is used here for ids for padding reasons. */
struct vring_used_elem
{
	/* Index of start of used descriptor chain. */
	__u32 id;
	/* Total length of the descriptor chain which was used (written to) */
	__u32 len;
};

struct vring_used
{
	__u16 flags;
	__u16 idx;
	struct vring_used_elem ring[];
};

struct vring {
	unsigned int num;

	struct vring_desc *desc;

	struct vring_avail *avail;

	struct vring_used *used;
};

/* The standard layout for the ring is a continuous chunk of memory which looks
79
 * like this.  We assume num is a power of 2.
80 81 82 83 84 85 86 87 88 89 90
 *
 * struct vring
 * {
 *	// The actual descriptors (16 bytes each)
 *	struct vring_desc desc[num];
 *
 *	// A ring of available descriptor heads with free-running index.
 *	__u16 avail_flags;
 *	__u16 avail_idx;
 *	__u16 available[num];
 *
91
 *	// Padding to the next align boundary.
92
 *	char pad[];
93 94 95 96 97 98 99
 *
 *	// A ring of used descriptor heads with free-running index.
 *	__u16 used_flags;
 *	__u16 used_idx;
 *	struct vring_used_elem used[num];
 * };
 */
100
static inline void vring_init(struct vring *vr, unsigned int num, void *p,
101
			      unsigned long align)
102 103 104
{
	vr->num = num;
	vr->desc = p;
105
	vr->avail = p + num*sizeof(struct vring_desc);
106 107
	vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + align-1)
			    & ~(align - 1));
108 109
}

110
static inline unsigned vring_size(unsigned int num, unsigned long align)
111
{
112
	return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (2 + num)
113
		 + align - 1) & ~(align - 1))
114
		+ sizeof(__u16) * 2 + sizeof(struct vring_used_elem) * num;
115 116 117 118 119 120 121 122
}

#ifdef __KERNEL__
#include <linux/irqreturn.h>
struct virtio_device;
struct virtqueue;

struct virtqueue *vring_new_virtqueue(unsigned int num,
123
				      unsigned int vring_align,
124 125 126
				      struct virtio_device *vdev,
				      void *pages,
				      void (*notify)(struct virtqueue *vq),
127 128
				      void (*callback)(struct virtqueue *vq),
				      const char *name);
129
void vring_del_virtqueue(struct virtqueue *vq);
130 131
/* Filter out transport-specific feature bits. */
void vring_transport_features(struct virtio_device *vdev);
132 133 134 135

irqreturn_t vring_interrupt(int irq, void *_vq);
#endif /* __KERNEL__ */
#endif /* _LINUX_VIRTIO_RING_H */