virtio 1.0 makes all memory structures LE, so we need APIs to conditionally do a byteswap on BE architectures. To make it easier to check code statically, add virtio specific types for multi-byte integers in memory. Add low level wrappers that do a byteswap conditionally, these will be useful e.g. for vhost. Add high level wrappers that query device endian-ness and act accordingly.
Showing the changes to include/uapi/linux (3 of 5 files). Show all
Unified · Split
| @@ -423,6 +423,7 @@ header-y += virtio_blk.h · 422 unmodified lines | ||
| 423 | 423 | header-y += virtio_config.h |
| 424 | 424 | header-y += virtio_console.h |
| 425 | 425 | header-y += virtio_ids.h |
| 426 | +header-y += virtio_types.h | |
| 426 | 427 | header-y += virtio_net.h |
| 427 | 428 | header-y += virtio_pci.h |
| 428 | 429 | header-y += virtio_ring.h |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | * |
| 33 | 33 | * Copyright Rusty Russell IBM Corporation 2007. */ |
| 34 | 34 | #include <linux/types.h> |
| 35 | +#include <linux/virtio_types.h> | |
| 35 | 36 | |
| 36 | 37 | /* This marks a buffer as continuing via the next field. */ |
| 37 | 38 | #define VRING_DESC_F_NEXT 1 |
| @@ -61,32 +62,32 @@ · 23 unmodified lines | ||
| 61 | 62 | /* Virtio ring descriptors: 16 bytes. These can chain together via "next". */ |
| 62 | 63 | struct vring_desc { |
| 63 | 64 | /* Address (guest-physical). */ |
| 64 | − __u64 addr; | |
| 65 | + __virtio64 addr; | |
| 65 | 66 | /* Length. */ |
| 66 | − __u32 len; | |
| 67 | + __virtio32 len; | |
| 67 | 68 | /* The flags as indicated above. */ |
| 68 | − __u16 flags; | |
| 69 | + __virtio16 flags; | |
| 69 | 70 | /* We chain unused descriptors via this, too */ |
| 70 | − __u16 next; | |
| 71 | + __virtio16 next; | |
| 71 | 72 | }; |
| 72 | 73 | |
| 73 | 74 | struct vring_avail { |
| 74 | − __u16 flags; | |
| 75 | − __u16 idx; | |
| 76 | − __u16 ring[]; | |
| 75 | + __virtio16 flags; | |
| 76 | + __virtio16 idx; | |
| 77 | + __virtio16 ring[]; | |
| 77 | 78 | }; |
| 78 | 79 | |
| 79 | 80 | /* u32 is used here for ids for padding reasons. */ |
| 80 | 81 | struct vring_used_elem { |
| 81 | 82 | /* Index of start of used descriptor chain. */ |
| 82 | − __u32 id; | |
| 83 | + __virtio32 id; | |
| 83 | 84 | /* Total length of the descriptor chain which was used (written to) */ |
| 84 | − __u32 len; | |
| 85 | + __virtio32 len; | |
| 85 | 86 | }; |
| 86 | 87 | |
| 87 | 88 | struct vring_used { |
| 88 | − __u16 flags; | |
| 89 | − __u16 idx; | |
| 89 | + __virtio16 flags; | |
| 90 | + __virtio16 idx; | |
| 90 | 91 | struct vring_used_elem ring[]; |
| 91 | 92 | }; |
| 92 | 93 | |
| @@ -109,25 +110,25 @@ struct vring { · 16 unmodified lines | ||
| 109 | 110 | * struct vring_desc desc[num]; |
| 110 | 111 | * |
| 111 | 112 | * // A ring of available descriptor heads with free-running index. |
| 112 | − * __u16 avail_flags; | |
| 113 | − * __u16 avail_idx; | |
| 114 | − * __u16 available[num]; | |
| 115 | − * __u16 used_event_idx; | |
| 113 | + * __virtio16 avail_flags; | |
| 114 | + * __virtio16 avail_idx; | |
| 115 | + * __virtio16 available[num]; | |
| 116 | + * __virtio16 used_event_idx; | |
| 116 | 117 | * |
| 117 | 118 | * // Padding to the next align boundary. |
| 118 | 119 | * char pad[]; |
| 119 | 120 | * |
| 120 | 121 | * // A ring of used descriptor heads with free-running index. |
| 121 | − * __u16 used_flags; | |
| 122 | − * __u16 used_idx; | |
| 122 | + * __virtio16 used_flags; | |
| 123 | + * __virtio16 used_idx; | |
| 123 | 124 | * struct vring_used_elem used[num]; |
| 124 | − * __u16 avail_event_idx; | |
| 125 | + * __virtio16 avail_event_idx; | |
| 125 | 126 | * }; |
| 126 | 127 | */ |
| 127 | 128 | /* We publish the used event index at the end of the available ring, and vice |
| 128 | 129 | * versa. They are at the end for backwards compatibility. */ |
| 129 | 130 | #define vring_used_event(vr) ((vr)->avail->ring[(vr)->num]) |
| 130 | −#define vring_avail_event(vr) (*(__u16 *)&(vr)->used->ring[(vr)->num]) | |
| 131 | +#define vring_avail_event(vr) (*(__virtio16 *)&(vr)->used->ring[(vr)->num]) | |
| 131 | 132 | |
| 132 | 133 | static inline void vring_init(struct vring *vr, unsigned int num, void *p, |
| 133 | 134 | unsigned long align) |
| @@ -135,15 +136,15 @@ static inline void vring_init(struct vring *vr, unsigned int num, void *p, · 1 unmodified line | ||
| 135 | 136 | vr->num = num; |
| 136 | 137 | vr->desc = p; |
| 137 | 138 | vr->avail = p + num*sizeof(struct vring_desc); |
| 138 | − vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + sizeof(__u16) | |
| 139 | + vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + sizeof(__virtio16) | |
| 139 | 140 | + align-1) & ~(align - 1)); |
| 140 | 141 | } |
| 141 | 142 | |
| 142 | 143 | static inline unsigned vring_size(unsigned int num, unsigned long align) |
| 143 | 144 | { |
| 144 | − return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (3 + num) | |
| 145 | + return ((sizeof(struct vring_desc) * num + sizeof(__virtio16) * (3 + num) | |
| 145 | 146 | + align - 1) & ~(align - 1)) |
| 146 | − + sizeof(__u16) * 3 + sizeof(struct vring_used_elem) * num; | |
| 147 | + + sizeof(__virtio16) * 3 + sizeof(struct vring_used_elem) * num; | |
| 147 | 148 | } |
| 148 | 149 | |
| 149 | 150 | /* The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX */ |
| @@ -0,0 +1,46 @@ | ||
| 1 | +#ifndef _UAPI_LINUX_VIRTIO_TYPES_H | |
| 2 | +#define _UAPI_LINUX_VIRTIO_TYPES_H | |
| 3 | +/* Type definitions for virtio implementations. | |
| 4 | + * | |
| 5 | + * This header is BSD licensed so anyone can use the definitions to implement | |
| 6 | + * compatible drivers/servers. | |
| 7 | + * | |
| 8 | + * Redistribution and use in source and binary forms, with or without | |
| 9 | + * modification, are permitted provided that the following conditions | |
| 10 | + * are met: | |
| 11 | + * 1. Redistributions of source code must retain the above copyright | |
| 12 | + * notice, this list of conditions and the following disclaimer. | |
| 13 | + * 2. Redistributions in binary form must reproduce the above copyright | |
| 14 | + * notice, this list of conditions and the following disclaimer in the | |
| 15 | + * documentation and/or other materials provided with the distribution. | |
| 16 | + * 3. Neither the name of IBM nor the names of its contributors | |
| 17 | + * may be used to endorse or promote products derived from this software | |
| 18 | + * without specific prior written permission. | |
| 19 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | |
| 20 | + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 21 | + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 22 | + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | |
| 23 | + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| 24 | + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
| 25 | + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 26 | + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| 27 | + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
| 28 | + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| 29 | + * SUCH DAMAGE. | |
| 30 | + * | |
| 31 | + * Copyright (C) 2014 Red Hat, Inc. | |
| 32 | + * Author: Michael S. Tsirkin <mst@redhat.com> | |
| 33 | + */ | |
| 34 | +#include <linux/types.h> | |
| 35 | + | |
| 36 | +/* | |
| 37 | + * __virtio{16,32,64} have the following meaning: | |
| 38 | + * - __u{16,32,64} for virtio devices in legacy mode, accessed in native endian | |
| 39 | + * - __le{16,32,64} for standard-compliant virtio devices | |
| 40 | + */ | |
| 41 | + | |
| 42 | +typedef __u16 __bitwise__ __virtio16; | |
| 43 | +typedef __u32 __bitwise__ __virtio32; | |
| 44 | +typedef __u64 __bitwise__ __virtio64; | |
| 45 | + | |
| 46 | +#endif /* _UAPI_LINUX_VIRTIO_TYPES_H */ | |