diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-14 23:28:47 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-14 23:28:47 -0500 |
| commit | b746f9c7941f227ad582b4f0bc981f3adcbc46b2 (patch) | |
| tree | fe3da3dedfe8d66f90cdcfa3d9ce847fdc411c20 /include/linux | |
| parent | ce6513f758b1852a2f24f76f07d0fae304d24ad3 (diff) | |
| parent | 2bf4fd31394a3f875ea093ee8a209f30b378cbf3 (diff) | |
Merge tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux
Pull virtio updates from Rusty Russell:
"Nothing really exciting: some groundwork for changing virtio endian,
and some robustness fixes for broken virtio devices, plus minor
tweaks"
* tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux:
virtio_scsi: verify if queue is broken after virtqueue_get_buf()
x86, asmlinkage, lguest: Pass in globals into assembler statement
virtio: mmio: fix signature checking for BE guests
virtio_ring: adapt to notify() returning bool
virtio_net: verify if queue is broken after virtqueue_get_buf()
virtio_console: verify if queue is broken after virtqueue_get_buf()
virtio_blk: verify if queue is broken after virtqueue_get_buf()
virtio_ring: add new function virtqueue_is_broken()
virtio_test: verify if virtqueue_kick() succeeded
virtio_net: verify if virtqueue_kick() succeeded
virtio_ring: let virtqueue_{kick()/notify()} return a bool
virtio_ring: change host notification API
virtio_config: remove virtio_config_val
virtio: use size-based config accessors.
virtio_config: introduce size-based accessors.
virtio_ring: plug kmemleak false positive.
virtio: pm: use CONFIG_PM_SLEEP instead of CONFIG_PM
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/virtio.h | 6 | ||||
| -rw-r--r-- | include/linux/virtio_config.h | 161 | ||||
| -rw-r--r-- | include/linux/virtio_ring.h | 2 |
3 files changed, 139 insertions, 30 deletions
diff --git a/include/linux/virtio.h b/include/linux/virtio.h index 36d36cc89329..e4abb84199be 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h | |||
| @@ -51,11 +51,11 @@ int virtqueue_add_sgs(struct virtqueue *vq, | |||
| 51 | void *data, | 51 | void *data, |
| 52 | gfp_t gfp); | 52 | gfp_t gfp); |
| 53 | 53 | ||
| 54 | void virtqueue_kick(struct virtqueue *vq); | 54 | bool virtqueue_kick(struct virtqueue *vq); |
| 55 | 55 | ||
| 56 | bool virtqueue_kick_prepare(struct virtqueue *vq); | 56 | bool virtqueue_kick_prepare(struct virtqueue *vq); |
| 57 | 57 | ||
| 58 | void virtqueue_notify(struct virtqueue *vq); | 58 | bool virtqueue_notify(struct virtqueue *vq); |
| 59 | 59 | ||
| 60 | void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len); | 60 | void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len); |
| 61 | 61 | ||
| @@ -73,6 +73,8 @@ void *virtqueue_detach_unused_buf(struct virtqueue *vq); | |||
| 73 | 73 | ||
| 74 | unsigned int virtqueue_get_vring_size(struct virtqueue *vq); | 74 | unsigned int virtqueue_get_vring_size(struct virtqueue *vq); |
| 75 | 75 | ||
| 76 | bool virtqueue_is_broken(struct virtqueue *vq); | ||
| 77 | |||
| 76 | /** | 78 | /** |
| 77 | * virtio_device - representation of a device using virtio | 79 | * virtio_device - representation of a device using virtio |
| 78 | * @index: unique position on the virtio bus | 80 | * @index: unique position on the virtio bus |
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index 29b9104232b4..e8f8f71e843c 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h | |||
| @@ -96,33 +96,6 @@ static inline bool virtio_has_feature(const struct virtio_device *vdev, | |||
| 96 | return test_bit(fbit, vdev->features); | 96 | return test_bit(fbit, vdev->features); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | /** | ||
| 100 | * virtio_config_val - look for a feature and get a virtio config entry. | ||
| 101 | * @vdev: the virtio device | ||
| 102 | * @fbit: the feature bit | ||
| 103 | * @offset: the type to search for. | ||
| 104 | * @v: a pointer to the value to fill in. | ||
| 105 | * | ||
| 106 | * The return value is -ENOENT if the feature doesn't exist. Otherwise | ||
| 107 | * the config value is copied into whatever is pointed to by v. */ | ||
| 108 | #define virtio_config_val(vdev, fbit, offset, v) \ | ||
| 109 | virtio_config_buf((vdev), (fbit), (offset), (v), sizeof(*v)) | ||
| 110 | |||
| 111 | #define virtio_config_val_len(vdev, fbit, offset, v, len) \ | ||
| 112 | virtio_config_buf((vdev), (fbit), (offset), (v), (len)) | ||
| 113 | |||
| 114 | static inline int virtio_config_buf(struct virtio_device *vdev, | ||
| 115 | unsigned int fbit, | ||
| 116 | unsigned int offset, | ||
| 117 | void *buf, unsigned len) | ||
| 118 | { | ||
| 119 | if (!virtio_has_feature(vdev, fbit)) | ||
| 120 | return -ENOENT; | ||
| 121 | |||
| 122 | vdev->config->get(vdev, offset, buf, len); | ||
| 123 | return 0; | ||
| 124 | } | ||
| 125 | |||
| 126 | static inline | 99 | static inline |
| 127 | struct virtqueue *virtio_find_single_vq(struct virtio_device *vdev, | 100 | struct virtqueue *virtio_find_single_vq(struct virtio_device *vdev, |
| 128 | vq_callback_t *c, const char *n) | 101 | vq_callback_t *c, const char *n) |
| @@ -162,5 +135,139 @@ int virtqueue_set_affinity(struct virtqueue *vq, int cpu) | |||
| 162 | return 0; | 135 | return 0; |
| 163 | } | 136 | } |
| 164 | 137 | ||
| 138 | /* Config space accessors. */ | ||
| 139 | #define virtio_cread(vdev, structname, member, ptr) \ | ||
| 140 | do { \ | ||
| 141 | /* Must match the member's type, and be integer */ \ | ||
| 142 | if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \ | ||
| 143 | (*ptr) = 1; \ | ||
| 144 | \ | ||
| 145 | switch (sizeof(*ptr)) { \ | ||
| 146 | case 1: \ | ||
| 147 | *(ptr) = virtio_cread8(vdev, \ | ||
| 148 | offsetof(structname, member)); \ | ||
| 149 | break; \ | ||
| 150 | case 2: \ | ||
| 151 | *(ptr) = virtio_cread16(vdev, \ | ||
| 152 | offsetof(structname, member)); \ | ||
| 153 | break; \ | ||
| 154 | case 4: \ | ||
| 155 | *(ptr) = virtio_cread32(vdev, \ | ||
| 156 | offsetof(structname, member)); \ | ||
| 157 | break; \ | ||
| 158 | case 8: \ | ||
| 159 | *(ptr) = virtio_cread64(vdev, \ | ||
| 160 | offsetof(structname, member)); \ | ||
| 161 | break; \ | ||
| 162 | default: \ | ||
| 163 | BUG(); \ | ||
| 164 | } \ | ||
| 165 | } while(0) | ||
| 166 | |||
| 167 | /* Config space accessors. */ | ||
| 168 | #define virtio_cwrite(vdev, structname, member, ptr) \ | ||
| 169 | do { \ | ||
| 170 | /* Must match the member's type, and be integer */ \ | ||
| 171 | if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \ | ||
| 172 | BUG_ON((*ptr) == 1); \ | ||
| 173 | \ | ||
| 174 | switch (sizeof(*ptr)) { \ | ||
| 175 | case 1: \ | ||
| 176 | virtio_cwrite8(vdev, \ | ||
| 177 | offsetof(structname, member), \ | ||
| 178 | *(ptr)); \ | ||
| 179 | break; \ | ||
| 180 | case 2: \ | ||
| 181 | virtio_cwrite16(vdev, \ | ||
| 182 | offsetof(structname, member), \ | ||
| 183 | *(ptr)); \ | ||
| 184 | break; \ | ||
| 185 | case 4: \ | ||
| 186 | virtio_cwrite32(vdev, \ | ||
| 187 | offsetof(structname, member), \ | ||
| 188 | *(ptr)); \ | ||
| 189 | break; \ | ||
| 190 | case 8: \ | ||
| 191 | virtio_cwrite64(vdev, \ | ||
| 192 | offsetof(structname, member), \ | ||
| 193 | *(ptr)); \ | ||
| 194 | break; \ | ||
| 195 | default: \ | ||
| 196 | BUG(); \ | ||
| 197 | } \ | ||
| 198 | } while(0) | ||
| 199 | |||
| 200 | static inline u8 virtio_cread8(struct virtio_device *vdev, unsigned int offset) | ||
| 201 | { | ||
| 202 | u8 ret; | ||
| 203 | vdev->config->get(vdev, offset, &ret, sizeof(ret)); | ||
| 204 | return ret; | ||
| 205 | } | ||
| 206 | |||
| 207 | static inline void virtio_cread_bytes(struct virtio_device *vdev, | ||
| 208 | unsigned int offset, | ||
| 209 | void *buf, size_t len) | ||
| 210 | { | ||
| 211 | vdev->config->get(vdev, offset, buf, len); | ||
| 212 | } | ||
| 213 | |||
| 214 | static inline void virtio_cwrite8(struct virtio_device *vdev, | ||
| 215 | unsigned int offset, u8 val) | ||
| 216 | { | ||
| 217 | vdev->config->set(vdev, offset, &val, sizeof(val)); | ||
| 218 | } | ||
| 219 | |||
| 220 | static inline u16 virtio_cread16(struct virtio_device *vdev, | ||
| 221 | unsigned int offset) | ||
| 222 | { | ||
| 223 | u16 ret; | ||
| 224 | vdev->config->get(vdev, offset, &ret, sizeof(ret)); | ||
| 225 | return ret; | ||
| 226 | } | ||
| 227 | |||
| 228 | static inline void virtio_cwrite16(struct virtio_device *vdev, | ||
| 229 | unsigned int offset, u16 val) | ||
| 230 | { | ||
| 231 | vdev->config->set(vdev, offset, &val, sizeof(val)); | ||
| 232 | } | ||
| 233 | |||
| 234 | static inline u32 virtio_cread32(struct virtio_device *vdev, | ||
| 235 | unsigned int offset) | ||
| 236 | { | ||
| 237 | u32 ret; | ||
| 238 | vdev->config->get(vdev, offset, &ret, sizeof(ret)); | ||
| 239 | return ret; | ||
| 240 | } | ||
| 241 | |||
| 242 | static inline void virtio_cwrite32(struct virtio_device *vdev, | ||
| 243 | unsigned int offset, u32 val) | ||
| 244 | { | ||
| 245 | vdev->config->set(vdev, offset, &val, sizeof(val)); | ||
| 246 | } | ||
| 247 | |||
| 248 | static inline u64 virtio_cread64(struct virtio_device *vdev, | ||
| 249 | unsigned int offset) | ||
| 250 | { | ||
| 251 | u64 ret; | ||
| 252 | vdev->config->get(vdev, offset, &ret, sizeof(ret)); | ||
| 253 | return ret; | ||
| 254 | } | ||
| 255 | |||
| 256 | static inline void virtio_cwrite64(struct virtio_device *vdev, | ||
| 257 | unsigned int offset, u64 val) | ||
| 258 | { | ||
| 259 | vdev->config->set(vdev, offset, &val, sizeof(val)); | ||
| 260 | } | ||
| 261 | |||
| 262 | /* Conditional config space accessors. */ | ||
| 263 | #define virtio_cread_feature(vdev, fbit, structname, member, ptr) \ | ||
| 264 | ({ \ | ||
| 265 | int _r = 0; \ | ||
| 266 | if (!virtio_has_feature(vdev, fbit)) \ | ||
| 267 | _r = -ENOENT; \ | ||
| 268 | else \ | ||
| 269 | virtio_cread((vdev), structname, member, ptr); \ | ||
| 270 | _r; \ | ||
| 271 | }) | ||
| 165 | 272 | ||
| 166 | #endif /* _LINUX_VIRTIO_CONFIG_H */ | 273 | #endif /* _LINUX_VIRTIO_CONFIG_H */ |
diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h index b300787af8e0..67e06fe18c03 100644 --- a/include/linux/virtio_ring.h +++ b/include/linux/virtio_ring.h | |||
| @@ -71,7 +71,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int index, | |||
| 71 | struct virtio_device *vdev, | 71 | struct virtio_device *vdev, |
| 72 | bool weak_barriers, | 72 | bool weak_barriers, |
| 73 | void *pages, | 73 | void *pages, |
| 74 | void (*notify)(struct virtqueue *vq), | 74 | bool (*notify)(struct virtqueue *vq), |
| 75 | void (*callback)(struct virtqueue *vq), | 75 | void (*callback)(struct virtqueue *vq), |
| 76 | const char *name); | 76 | const char *name); |
| 77 | void vring_del_virtqueue(struct virtqueue *vq); | 77 | void vring_del_virtqueue(struct virtqueue *vq); |
