diff options
| author | Michael S. Tsirkin <mst@redhat.com> | 2014-10-22 08:35:56 -0400 |
|---|---|---|
| committer | Michael S. Tsirkin <mst@redhat.com> | 2014-12-09 05:05:24 -0500 |
| commit | eef960a04354d13426c43a4e3750a5e2b383040c (patch) | |
| tree | a5d6e327dbb22c85b2f6592077a544bcc0153471 /include/linux | |
| parent | 4ec22faeb2a165b6ce7009f91309046010b3f282 (diff) | |
virtio: memory access APIs
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.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/virtio_byteorder.h | 59 | ||||
| -rw-r--r-- | include/linux/virtio_config.h | 32 |
2 files changed, 91 insertions, 0 deletions
diff --git a/include/linux/virtio_byteorder.h b/include/linux/virtio_byteorder.h new file mode 100644 index 000000000000..51865d05b267 --- /dev/null +++ b/include/linux/virtio_byteorder.h | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | #ifndef _LINUX_VIRTIO_BYTEORDER_H | ||
| 2 | #define _LINUX_VIRTIO_BYTEORDER_H | ||
| 3 | #include <linux/types.h> | ||
| 4 | #include <uapi/linux/virtio_types.h> | ||
| 5 | |||
| 6 | /* | ||
| 7 | * Low-level memory accessors for handling virtio in modern little endian and in | ||
| 8 | * compatibility native endian format. | ||
| 9 | */ | ||
| 10 | |||
| 11 | static inline u16 __virtio16_to_cpu(bool little_endian, __virtio16 val) | ||
| 12 | { | ||
| 13 | if (little_endian) | ||
| 14 | return le16_to_cpu((__force __le16)val); | ||
| 15 | else | ||
| 16 | return (__force u16)val; | ||
| 17 | } | ||
| 18 | |||
| 19 | static inline __virtio16 __cpu_to_virtio16(bool little_endian, u16 val) | ||
| 20 | { | ||
| 21 | if (little_endian) | ||
| 22 | return (__force __virtio16)cpu_to_le16(val); | ||
| 23 | else | ||
| 24 | return (__force __virtio16)val; | ||
| 25 | } | ||
| 26 | |||
| 27 | static inline u32 __virtio32_to_cpu(bool little_endian, __virtio32 val) | ||
| 28 | { | ||
| 29 | if (little_endian) | ||
| 30 | return le32_to_cpu((__force __le32)val); | ||
| 31 | else | ||
| 32 | return (__force u32)val; | ||
| 33 | } | ||
| 34 | |||
| 35 | static inline __virtio32 __cpu_to_virtio32(bool little_endian, u32 val) | ||
| 36 | { | ||
| 37 | if (little_endian) | ||
| 38 | return (__force __virtio32)cpu_to_le32(val); | ||
| 39 | else | ||
| 40 | return (__force __virtio32)val; | ||
| 41 | } | ||
| 42 | |||
| 43 | static inline u64 __virtio64_to_cpu(bool little_endian, __virtio64 val) | ||
| 44 | { | ||
| 45 | if (little_endian) | ||
| 46 | return le64_to_cpu((__force __le64)val); | ||
| 47 | else | ||
| 48 | return (__force u64)val; | ||
| 49 | } | ||
| 50 | |||
| 51 | static inline __virtio64 __cpu_to_virtio64(bool little_endian, u64 val) | ||
| 52 | { | ||
| 53 | if (little_endian) | ||
| 54 | return (__force __virtio64)cpu_to_le64(val); | ||
| 55 | else | ||
| 56 | return (__force __virtio64)val; | ||
| 57 | } | ||
| 58 | |||
| 59 | #endif /* _LINUX_VIRTIO_BYTEORDER */ | ||
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index f51788439574..02f0acb549d6 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include <linux/err.h> | 4 | #include <linux/err.h> |
| 5 | #include <linux/bug.h> | 5 | #include <linux/bug.h> |
| 6 | #include <linux/virtio.h> | 6 | #include <linux/virtio.h> |
| 7 | #include <linux/virtio_byteorder.h> | ||
| 7 | #include <uapi/linux/virtio_config.h> | 8 | #include <uapi/linux/virtio_config.h> |
| 8 | 9 | ||
| 9 | /** | 10 | /** |
| @@ -199,6 +200,37 @@ int virtqueue_set_affinity(struct virtqueue *vq, int cpu) | |||
| 199 | return 0; | 200 | return 0; |
| 200 | } | 201 | } |
| 201 | 202 | ||
| 203 | /* Memory accessors */ | ||
| 204 | static inline u16 virtio16_to_cpu(struct virtio_device *vdev, __virtio16 val) | ||
| 205 | { | ||
| 206 | return __virtio16_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val); | ||
| 207 | } | ||
| 208 | |||
| 209 | static inline __virtio16 cpu_to_virtio16(struct virtio_device *vdev, u16 val) | ||
| 210 | { | ||
| 211 | return __cpu_to_virtio16(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val); | ||
| 212 | } | ||
| 213 | |||
| 214 | static inline u32 virtio32_to_cpu(struct virtio_device *vdev, __virtio32 val) | ||
| 215 | { | ||
| 216 | return __virtio32_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val); | ||
| 217 | } | ||
| 218 | |||
| 219 | static inline __virtio32 cpu_to_virtio32(struct virtio_device *vdev, u32 val) | ||
| 220 | { | ||
| 221 | return __cpu_to_virtio32(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val); | ||
| 222 | } | ||
| 223 | |||
| 224 | static inline u64 virtio64_to_cpu(struct virtio_device *vdev, __virtio64 val) | ||
| 225 | { | ||
| 226 | return __virtio64_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val); | ||
| 227 | } | ||
| 228 | |||
| 229 | static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val) | ||
| 230 | { | ||
| 231 | return __cpu_to_virtio64(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val); | ||
| 232 | } | ||
| 233 | |||
| 202 | /* Config space accessors. */ | 234 | /* Config space accessors. */ |
| 203 | #define virtio_cread(vdev, structname, member, ptr) \ | 235 | #define virtio_cread(vdev, structname, member, ptr) \ |
| 204 | do { \ | 236 | do { \ |
