251 lines · c
1#ifndef _UAPI_LINUX_VIRTIO_RING_H2#define _UAPI_LINUX_VIRTIO_RING_H3/* An interface for efficient virtio implementation, currently for use by KVM,4 * but hopefully others soon. Do NOT change this since it will5 * break existing servers and clients.6 *7 * This header is BSD licensed so anyone can use the definitions to implement8 * compatible drivers/servers.9 *10 * Redistribution and use in source and binary forms, with or without11 * modification, are permitted provided that the following conditions12 * are met:13 * 1. Redistributions of source code must retain the above copyright14 * notice, this list of conditions and the following disclaimer.15 * 2. Redistributions in binary form must reproduce the above copyright16 * notice, this list of conditions and the following disclaimer in the17 * documentation and/or other materials provided with the distribution.18 * 3. Neither the name of IBM nor the names of its contributors19 * may be used to endorse or promote products derived from this software20 * without specific prior written permission.21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE24 * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF31 * SUCH DAMAGE.32 *33 * Copyright Rusty Russell IBM Corporation 2007. */34#ifndef __KERNEL__35#include <stdint.h>36#endif37#include <linux/types.h>38#include <linux/virtio_types.h>39 40/* This marks a buffer as continuing via the next field. */41#define VRING_DESC_F_NEXT 142/* This marks a buffer as write-only (otherwise read-only). */43#define VRING_DESC_F_WRITE 244/* This means the buffer contains a list of buffer descriptors. */45#define VRING_DESC_F_INDIRECT 446 47/*48 * Mark a descriptor as available or used in packed ring.49 * Notice: they are defined as shifts instead of shifted values.50 */51#define VRING_PACKED_DESC_F_AVAIL 752#define VRING_PACKED_DESC_F_USED 1553 54/* The Host uses this in used->flags to advise the Guest: don't kick me when55 * you add a buffer. It's unreliable, so it's simply an optimization. Guest56 * will still kick if it's out of buffers. */57#define VRING_USED_F_NO_NOTIFY 158/* The Guest uses this in avail->flags to advise the Host: don't interrupt me59 * when you consume a buffer. It's unreliable, so it's simply an60 * optimization. */61#define VRING_AVAIL_F_NO_INTERRUPT 162 63/* Enable events in packed ring. */64#define VRING_PACKED_EVENT_FLAG_ENABLE 0x065/* Disable events in packed ring. */66#define VRING_PACKED_EVENT_FLAG_DISABLE 0x167/*68 * Enable events for a specific descriptor in packed ring.69 * (as specified by Descriptor Ring Change Event Offset/Wrap Counter).70 * Only valid if VIRTIO_RING_F_EVENT_IDX has been negotiated.71 */72#define VRING_PACKED_EVENT_FLAG_DESC 0x273 74/*75 * Wrap counter bit shift in event suppression structure76 * of packed ring.77 */78#define VRING_PACKED_EVENT_F_WRAP_CTR 1579 80/* We support indirect buffer descriptors */81#define VIRTIO_RING_F_INDIRECT_DESC 2882 83/* The Guest publishes the used index for which it expects an interrupt84 * at the end of the avail ring. Host should ignore the avail->flags field. */85/* The Host publishes the avail index for which it expects a kick86 * at the end of the used ring. Guest should ignore the used->flags field. */87#define VIRTIO_RING_F_EVENT_IDX 2988 89/* Alignment requirements for vring elements.90 * When using pre-virtio 1.0 layout, these fall out naturally.91 */92#define VRING_AVAIL_ALIGN_SIZE 293#define VRING_USED_ALIGN_SIZE 494#define VRING_DESC_ALIGN_SIZE 1695 96/**97 * struct vring_desc - Virtio ring descriptors,98 * 16 bytes long. These can chain together via @next.99 *100 * @addr: buffer address (guest-physical)101 * @len: buffer length102 * @flags: descriptor flags103 * @next: index of the next descriptor in the chain,104 * if the VRING_DESC_F_NEXT flag is set. We chain unused105 * descriptors via this, too.106 */107struct vring_desc {108 __virtio64 addr;109 __virtio32 len;110 __virtio16 flags;111 __virtio16 next;112};113 114struct vring_avail {115 __virtio16 flags;116 __virtio16 idx;117 __virtio16 ring[];118};119 120/* u32 is used here for ids for padding reasons. */121struct vring_used_elem {122 /* Index of start of used descriptor chain. */123 __virtio32 id;124 /* Total length of the descriptor chain which was used (written to) */125 __virtio32 len;126};127 128typedef struct vring_used_elem __attribute__((aligned(VRING_USED_ALIGN_SIZE)))129 vring_used_elem_t;130 131struct vring_used {132 __virtio16 flags;133 __virtio16 idx;134 vring_used_elem_t ring[];135};136 137/*138 * The ring element addresses are passed between components with different139 * alignments assumptions. Thus, we might need to decrease the compiler-selected140 * alignment, and so must use a typedef to make sure the aligned attribute141 * actually takes hold:142 *143 * https://gcc.gnu.org/onlinedocs//gcc/Common-Type-Attributes.html#Common-Type-Attributes144 *145 * When used on a struct, or struct member, the aligned attribute can only146 * increase the alignment; in order to decrease it, the packed attribute must147 * be specified as well. When used as part of a typedef, the aligned attribute148 * can both increase and decrease alignment, and specifying the packed149 * attribute generates a warning.150 */151typedef struct vring_desc __attribute__((aligned(VRING_DESC_ALIGN_SIZE)))152 vring_desc_t;153typedef struct vring_avail __attribute__((aligned(VRING_AVAIL_ALIGN_SIZE)))154 vring_avail_t;155typedef struct vring_used __attribute__((aligned(VRING_USED_ALIGN_SIZE)))156 vring_used_t;157 158struct vring {159 unsigned int num;160 161 vring_desc_t *desc;162 163 vring_avail_t *avail;164 165 vring_used_t *used;166};167 168#ifndef VIRTIO_RING_NO_LEGACY169 170/* The standard layout for the ring is a continuous chunk of memory which looks171 * like this. We assume num is a power of 2.172 *173 * struct vring174 * {175 * // The actual descriptors (16 bytes each)176 * struct vring_desc desc[num];177 *178 * // A ring of available descriptor heads with free-running index.179 * __virtio16 avail_flags;180 * __virtio16 avail_idx;181 * __virtio16 available[num];182 * __virtio16 used_event_idx;183 *184 * // Padding to the next align boundary.185 * char pad[];186 *187 * // A ring of used descriptor heads with free-running index.188 * __virtio16 used_flags;189 * __virtio16 used_idx;190 * struct vring_used_elem used[num];191 * __virtio16 avail_event_idx;192 * };193 */194/* We publish the used event index at the end of the available ring, and vice195 * versa. They are at the end for backwards compatibility. */196#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])197#define vring_avail_event(vr) (*(__virtio16 *)&(vr)->used->ring[(vr)->num])198 199static inline void vring_init(struct vring *vr, unsigned int num, void *p,200 unsigned long align)201{202 vr->num = num;203 vr->desc = p;204 vr->avail = (struct vring_avail *)((char *)p + num * sizeof(struct vring_desc));205 vr->used = (void *)(((uintptr_t)&vr->avail->ring[num] + sizeof(__virtio16)206 + align-1) & ~(align - 1));207}208 209static inline unsigned vring_size(unsigned int num, unsigned long align)210{211 return ((sizeof(struct vring_desc) * num + sizeof(__virtio16) * (3 + num)212 + align - 1) & ~(align - 1))213 + sizeof(__virtio16) * 3 + sizeof(struct vring_used_elem) * num;214}215 216#endif /* VIRTIO_RING_NO_LEGACY */217 218/* The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX */219/* Assuming a given event_idx value from the other side, if220 * we have just incremented index from old to new_idx,221 * should we trigger an event? */222static inline int vring_need_event(__u16 event_idx, __u16 new_idx, __u16 old)223{224 /* Note: Xen has similar logic for notification hold-off225 * in include/xen/interface/io/ring.h with req_event and req_prod226 * corresponding to event_idx + 1 and new_idx respectively.227 * Note also that req_event and req_prod in Xen start at 1,228 * event indexes in virtio start at 0. */229 return (__u16)(new_idx - event_idx - 1) < (__u16)(new_idx - old);230}231 232struct vring_packed_desc_event {233 /* Descriptor Ring Change Event Offset/Wrap Counter. */234 __le16 off_wrap;235 /* Descriptor Ring Change Event Flags. */236 __le16 flags;237};238 239struct vring_packed_desc {240 /* Buffer Address. */241 __le64 addr;242 /* Buffer Length. */243 __le32 len;244 /* Buffer ID. */245 __le16 id;246 /* The flags depending on descriptor type. */247 __le16 flags;248};249 250#endif /* _UAPI_LINUX_VIRTIO_RING_H */251