aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-18 23:50:30 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-18 23:50:30 -0500
commit64ec45bff6b3dade2643ed4c0f688a15ecf46ea2 (patch)
tree29816f500d80a64c84455778918d94ff3ddf02e4
parentc0f486fde3f353232c1cc2fd4d62783ac782a467 (diff)
parent5ff16110c637726111662c1df41afd9df7ef36bd (diff)
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
Pull virtio fixes from Michael S Tsirkin: "virtio 1.0 related fixes Most importantly, this fixes using virtio_pci as a module. Further, the big virtio 1.0 conversion missed a couple of places. This fixes them up. This isn't 100% sparse-clean yet because on many architectures get_user triggers sparse warnings when used with __bitwise tag (when same tag is on both pointer and value read). I posted a patchset to fix it up by adding __force on all arches that don't already have it (many do), when that's merged these warnings will go away" * tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost: virtio_pci: restore module attributes mic/host: fix up virtio 1.0 APIs vringh: update for virtio 1.0 APIs vringh: 64 bit features tools/virtio: add virtio 1.0 in vringh_test tools/virtio: add virtio 1.0 in virtio_test tools/virtio: enable -Werror tools/virtio: 64 bit features tools/virtio: fix vringh test tools/virtio: more stubs virtio: core support for config generation virtio_pci: add VIRTIO_PCI_NO_LEGACY virtio_pci: move probe to common file virtio_pci_common.h: drop VIRTIO_PCI_NO_LEGACY virtio_config: fix virtio_cread_bytes virtio: set VIRTIO_CONFIG_S_FEATURES_OK on restore
-rw-r--r--drivers/misc/mic/host/mic_debugfs.c18
-rw-r--r--drivers/vhost/vringh.c125
-rw-r--r--drivers/virtio/virtio.c37
-rw-r--r--drivers/virtio/virtio_pci_common.c39
-rw-r--r--drivers/virtio/virtio_pci_common.h7
-rw-r--r--drivers/virtio/virtio_pci_legacy.c24
-rw-r--r--include/linux/virtio_config.h29
-rw-r--r--include/linux/vringh.h37
-rw-r--r--include/uapi/linux/virtio_pci.h15
-rw-r--r--tools/virtio/Makefile2
-rw-r--r--tools/virtio/linux/virtio.h1
-rw-r--r--tools/virtio/linux/virtio_byteorder.h8
-rw-r--r--tools/virtio/linux/virtio_config.h70
-rw-r--r--tools/virtio/uapi/linux/virtio_types.h1
-rw-r--r--tools/virtio/virtio_test.c15
-rw-r--r--tools/virtio/vringh_test.c5
16 files changed, 324 insertions, 109 deletions
diff --git a/drivers/misc/mic/host/mic_debugfs.c b/drivers/misc/mic/host/mic_debugfs.c
index 028ba5d6fd1c..687e9aacf3bb 100644
--- a/drivers/misc/mic/host/mic_debugfs.c
+++ b/drivers/misc/mic/host/mic_debugfs.c
@@ -326,21 +326,27 @@ static int mic_vdev_info_show(struct seq_file *s, void *unused)
326 } 326 }
327 avail = vrh->vring.avail; 327 avail = vrh->vring.avail;
328 seq_printf(s, "avail flags 0x%x idx %d\n", 328 seq_printf(s, "avail flags 0x%x idx %d\n",
329 avail->flags, avail->idx & (num - 1)); 329 vringh16_to_cpu(vrh, avail->flags),
330 vringh16_to_cpu(vrh, avail->idx) & (num - 1));
330 seq_printf(s, "avail flags 0x%x idx %d\n", 331 seq_printf(s, "avail flags 0x%x idx %d\n",
331 avail->flags, avail->idx); 332 vringh16_to_cpu(vrh, avail->flags),
333 vringh16_to_cpu(vrh, avail->idx));
332 for (j = 0; j < num; j++) 334 for (j = 0; j < num; j++)
333 seq_printf(s, "avail ring[%d] %d\n", 335 seq_printf(s, "avail ring[%d] %d\n",
334 j, avail->ring[j]); 336 j, avail->ring[j]);
335 used = vrh->vring.used; 337 used = vrh->vring.used;
336 seq_printf(s, "used flags 0x%x idx %d\n", 338 seq_printf(s, "used flags 0x%x idx %d\n",
337 used->flags, used->idx & (num - 1)); 339 vringh16_to_cpu(vrh, used->flags),
340 vringh16_to_cpu(vrh, used->idx) & (num - 1));
338 seq_printf(s, "used flags 0x%x idx %d\n", 341 seq_printf(s, "used flags 0x%x idx %d\n",
339 used->flags, used->idx); 342 vringh16_to_cpu(vrh, used->flags),
343 vringh16_to_cpu(vrh, used->idx));
340 for (j = 0; j < num; j++) 344 for (j = 0; j < num; j++)
341 seq_printf(s, "used ring[%d] id %d len %d\n", 345 seq_printf(s, "used ring[%d] id %d len %d\n",
342 j, used->ring[j].id, 346 j, vringh32_to_cpu(vrh,
343 used->ring[j].len); 347 used->ring[j].id),
348 vringh32_to_cpu(vrh,
349 used->ring[j].len));
344 } 350 }
345 } 351 }
346 mutex_unlock(&mdev->mic_mutex); 352 mutex_unlock(&mdev->mic_mutex);
diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
index 5174ebac288d..3bb02c60a2f5 100644
--- a/drivers/vhost/vringh.c
+++ b/drivers/vhost/vringh.c
@@ -11,6 +11,7 @@
11#include <linux/uaccess.h> 11#include <linux/uaccess.h>
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/export.h> 13#include <linux/export.h>
14#include <uapi/linux/virtio_config.h>
14 15
15static __printf(1,2) __cold void vringh_bad(const char *fmt, ...) 16static __printf(1,2) __cold void vringh_bad(const char *fmt, ...)
16{ 17{
@@ -28,13 +29,14 @@ static __printf(1,2) __cold void vringh_bad(const char *fmt, ...)
28 29
29/* Returns vring->num if empty, -ve on error. */ 30/* Returns vring->num if empty, -ve on error. */
30static inline int __vringh_get_head(const struct vringh *vrh, 31static inline int __vringh_get_head(const struct vringh *vrh,
31 int (*getu16)(u16 *val, const u16 *p), 32 int (*getu16)(const struct vringh *vrh,
33 u16 *val, const __virtio16 *p),
32 u16 *last_avail_idx) 34 u16 *last_avail_idx)
33{ 35{
34 u16 avail_idx, i, head; 36 u16 avail_idx, i, head;
35 int err; 37 int err;
36 38
37 err = getu16(&avail_idx, &vrh->vring.avail->idx); 39 err = getu16(vrh, &avail_idx, &vrh->vring.avail->idx);
38 if (err) { 40 if (err) {
39 vringh_bad("Failed to access avail idx at %p", 41 vringh_bad("Failed to access avail idx at %p",
40 &vrh->vring.avail->idx); 42 &vrh->vring.avail->idx);
@@ -49,7 +51,7 @@ static inline int __vringh_get_head(const struct vringh *vrh,
49 51
50 i = *last_avail_idx & (vrh->vring.num - 1); 52 i = *last_avail_idx & (vrh->vring.num - 1);
51 53
52 err = getu16(&head, &vrh->vring.avail->ring[i]); 54 err = getu16(vrh, &head, &vrh->vring.avail->ring[i]);
53 if (err) { 55 if (err) {
54 vringh_bad("Failed to read head: idx %d address %p", 56 vringh_bad("Failed to read head: idx %d address %p",
55 *last_avail_idx, &vrh->vring.avail->ring[i]); 57 *last_avail_idx, &vrh->vring.avail->ring[i]);
@@ -144,28 +146,32 @@ static inline bool no_range_check(struct vringh *vrh, u64 addr, size_t *len,
144} 146}
145 147
146/* No reason for this code to be inline. */ 148/* No reason for this code to be inline. */
147static int move_to_indirect(int *up_next, u16 *i, void *addr, 149static int move_to_indirect(const struct vringh *vrh,
150 int *up_next, u16 *i, void *addr,
148 const struct vring_desc *desc, 151 const struct vring_desc *desc,
149 struct vring_desc **descs, int *desc_max) 152 struct vring_desc **descs, int *desc_max)
150{ 153{
154 u32 len;
155
151 /* Indirect tables can't have indirect. */ 156 /* Indirect tables can't have indirect. */
152 if (*up_next != -1) { 157 if (*up_next != -1) {
153 vringh_bad("Multilevel indirect %u->%u", *up_next, *i); 158 vringh_bad("Multilevel indirect %u->%u", *up_next, *i);
154 return -EINVAL; 159 return -EINVAL;
155 } 160 }
156 161
157 if (unlikely(desc->len % sizeof(struct vring_desc))) { 162 len = vringh32_to_cpu(vrh, desc->len);
163 if (unlikely(len % sizeof(struct vring_desc))) {
158 vringh_bad("Strange indirect len %u", desc->len); 164 vringh_bad("Strange indirect len %u", desc->len);
159 return -EINVAL; 165 return -EINVAL;
160 } 166 }
161 167
162 /* We will check this when we follow it! */ 168 /* We will check this when we follow it! */
163 if (desc->flags & VRING_DESC_F_NEXT) 169 if (desc->flags & cpu_to_vringh16(vrh, VRING_DESC_F_NEXT))
164 *up_next = desc->next; 170 *up_next = vringh16_to_cpu(vrh, desc->next);
165 else 171 else
166 *up_next = -2; 172 *up_next = -2;
167 *descs = addr; 173 *descs = addr;
168 *desc_max = desc->len / sizeof(struct vring_desc); 174 *desc_max = len / sizeof(struct vring_desc);
169 175
170 /* Now, start at the first indirect. */ 176 /* Now, start at the first indirect. */
171 *i = 0; 177 *i = 0;
@@ -287,22 +293,25 @@ __vringh_iov(struct vringh *vrh, u16 i,
287 if (unlikely(err)) 293 if (unlikely(err))
288 goto fail; 294 goto fail;
289 295
290 if (unlikely(desc.flags & VRING_DESC_F_INDIRECT)) { 296 if (unlikely(desc.flags &
297 cpu_to_vringh16(vrh, VRING_DESC_F_INDIRECT))) {
298 u64 a = vringh64_to_cpu(vrh, desc.addr);
299
291 /* Make sure it's OK, and get offset. */ 300 /* Make sure it's OK, and get offset. */
292 len = desc.len; 301 len = vringh32_to_cpu(vrh, desc.len);
293 if (!rcheck(vrh, desc.addr, &len, &range, getrange)) { 302 if (!rcheck(vrh, a, &len, &range, getrange)) {
294 err = -EINVAL; 303 err = -EINVAL;
295 goto fail; 304 goto fail;
296 } 305 }
297 306
298 if (unlikely(len != desc.len)) { 307 if (unlikely(len != vringh32_to_cpu(vrh, desc.len))) {
299 slow = true; 308 slow = true;
300 /* We need to save this range to use offset */ 309 /* We need to save this range to use offset */
301 slowrange = range; 310 slowrange = range;
302 } 311 }
303 312
304 addr = (void *)(long)(desc.addr + range.offset); 313 addr = (void *)(long)(a + range.offset);
305 err = move_to_indirect(&up_next, &i, addr, &desc, 314 err = move_to_indirect(vrh, &up_next, &i, addr, &desc,
306 &descs, &desc_max); 315 &descs, &desc_max);
307 if (err) 316 if (err)
308 goto fail; 317 goto fail;
@@ -315,7 +324,7 @@ __vringh_iov(struct vringh *vrh, u16 i,
315 goto fail; 324 goto fail;
316 } 325 }
317 326
318 if (desc.flags & VRING_DESC_F_WRITE) 327 if (desc.flags & cpu_to_vringh16(vrh, VRING_DESC_F_WRITE))
319 iov = wiov; 328 iov = wiov;
320 else { 329 else {
321 iov = riov; 330 iov = riov;
@@ -336,12 +345,14 @@ __vringh_iov(struct vringh *vrh, u16 i,
336 345
337 again: 346 again:
338 /* Make sure it's OK, and get offset. */ 347 /* Make sure it's OK, and get offset. */
339 len = desc.len; 348 len = vringh32_to_cpu(vrh, desc.len);
340 if (!rcheck(vrh, desc.addr, &len, &range, getrange)) { 349 if (!rcheck(vrh, vringh64_to_cpu(vrh, desc.addr), &len, &range,
350 getrange)) {
341 err = -EINVAL; 351 err = -EINVAL;
342 goto fail; 352 goto fail;
343 } 353 }
344 addr = (void *)(unsigned long)(desc.addr + range.offset); 354 addr = (void *)(unsigned long)(vringh64_to_cpu(vrh, desc.addr) +
355 range.offset);
345 356
346 if (unlikely(iov->used == (iov->max_num & ~VRINGH_IOV_ALLOCATED))) { 357 if (unlikely(iov->used == (iov->max_num & ~VRINGH_IOV_ALLOCATED))) {
347 err = resize_iovec(iov, gfp); 358 err = resize_iovec(iov, gfp);
@@ -353,14 +364,16 @@ __vringh_iov(struct vringh *vrh, u16 i,
353 iov->iov[iov->used].iov_len = len; 364 iov->iov[iov->used].iov_len = len;
354 iov->used++; 365 iov->used++;
355 366
356 if (unlikely(len != desc.len)) { 367 if (unlikely(len != vringh32_to_cpu(vrh, desc.len))) {
357 desc.len -= len; 368 desc.len = cpu_to_vringh32(vrh,
358 desc.addr += len; 369 vringh32_to_cpu(vrh, desc.len) - len);
370 desc.addr = cpu_to_vringh64(vrh,
371 vringh64_to_cpu(vrh, desc.addr) + len);
359 goto again; 372 goto again;
360 } 373 }
361 374
362 if (desc.flags & VRING_DESC_F_NEXT) { 375 if (desc.flags & cpu_to_vringh16(vrh, VRING_DESC_F_NEXT)) {
363 i = desc.next; 376 i = vringh16_to_cpu(vrh, desc.next);
364 } else { 377 } else {
365 /* Just in case we need to finish traversing above. */ 378 /* Just in case we need to finish traversing above. */
366 if (unlikely(up_next > 0)) { 379 if (unlikely(up_next > 0)) {
@@ -387,7 +400,8 @@ fail:
387static inline int __vringh_complete(struct vringh *vrh, 400static inline int __vringh_complete(struct vringh *vrh,
388 const struct vring_used_elem *used, 401 const struct vring_used_elem *used,
389 unsigned int num_used, 402 unsigned int num_used,
390 int (*putu16)(u16 *p, u16 val), 403 int (*putu16)(const struct vringh *vrh,
404 __virtio16 *p, u16 val),
391 int (*putused)(struct vring_used_elem *dst, 405 int (*putused)(struct vring_used_elem *dst,
392 const struct vring_used_elem 406 const struct vring_used_elem
393 *src, unsigned num)) 407 *src, unsigned num))
@@ -420,7 +434,7 @@ static inline int __vringh_complete(struct vringh *vrh,
420 /* Make sure buffer is written before we update index. */ 434 /* Make sure buffer is written before we update index. */
421 virtio_wmb(vrh->weak_barriers); 435 virtio_wmb(vrh->weak_barriers);
422 436
423 err = putu16(&vrh->vring.used->idx, used_idx + num_used); 437 err = putu16(vrh, &vrh->vring.used->idx, used_idx + num_used);
424 if (err) { 438 if (err) {
425 vringh_bad("Failed to update used index at %p", 439 vringh_bad("Failed to update used index at %p",
426 &vrh->vring.used->idx); 440 &vrh->vring.used->idx);
@@ -433,7 +447,9 @@ static inline int __vringh_complete(struct vringh *vrh,
433 447
434 448
435static inline int __vringh_need_notify(struct vringh *vrh, 449static inline int __vringh_need_notify(struct vringh *vrh,
436 int (*getu16)(u16 *val, const u16 *p)) 450 int (*getu16)(const struct vringh *vrh,
451 u16 *val,
452 const __virtio16 *p))
437{ 453{
438 bool notify; 454 bool notify;
439 u16 used_event; 455 u16 used_event;
@@ -447,7 +463,7 @@ static inline int __vringh_need_notify(struct vringh *vrh,
447 /* Old-style, without event indices. */ 463 /* Old-style, without event indices. */
448 if (!vrh->event_indices) { 464 if (!vrh->event_indices) {
449 u16 flags; 465 u16 flags;
450 err = getu16(&flags, &vrh->vring.avail->flags); 466 err = getu16(vrh, &flags, &vrh->vring.avail->flags);
451 if (err) { 467 if (err) {
452 vringh_bad("Failed to get flags at %p", 468 vringh_bad("Failed to get flags at %p",
453 &vrh->vring.avail->flags); 469 &vrh->vring.avail->flags);
@@ -457,7 +473,7 @@ static inline int __vringh_need_notify(struct vringh *vrh,
457 } 473 }
458 474
459 /* Modern: we know when other side wants to know. */ 475 /* Modern: we know when other side wants to know. */
460 err = getu16(&used_event, &vring_used_event(&vrh->vring)); 476 err = getu16(vrh, &used_event, &vring_used_event(&vrh->vring));
461 if (err) { 477 if (err) {
462 vringh_bad("Failed to get used event idx at %p", 478 vringh_bad("Failed to get used event idx at %p",
463 &vring_used_event(&vrh->vring)); 479 &vring_used_event(&vrh->vring));
@@ -478,20 +494,22 @@ static inline int __vringh_need_notify(struct vringh *vrh,
478} 494}
479 495
480static inline bool __vringh_notify_enable(struct vringh *vrh, 496static inline bool __vringh_notify_enable(struct vringh *vrh,
481 int (*getu16)(u16 *val, const u16 *p), 497 int (*getu16)(const struct vringh *vrh,
482 int (*putu16)(u16 *p, u16 val)) 498 u16 *val, const __virtio16 *p),
499 int (*putu16)(const struct vringh *vrh,
500 __virtio16 *p, u16 val))
483{ 501{
484 u16 avail; 502 u16 avail;
485 503
486 if (!vrh->event_indices) { 504 if (!vrh->event_indices) {
487 /* Old-school; update flags. */ 505 /* Old-school; update flags. */
488 if (putu16(&vrh->vring.used->flags, 0) != 0) { 506 if (putu16(vrh, &vrh->vring.used->flags, 0) != 0) {
489 vringh_bad("Clearing used flags %p", 507 vringh_bad("Clearing used flags %p",
490 &vrh->vring.used->flags); 508 &vrh->vring.used->flags);
491 return true; 509 return true;
492 } 510 }
493 } else { 511 } else {
494 if (putu16(&vring_avail_event(&vrh->vring), 512 if (putu16(vrh, &vring_avail_event(&vrh->vring),
495 vrh->last_avail_idx) != 0) { 513 vrh->last_avail_idx) != 0) {
496 vringh_bad("Updating avail event index %p", 514 vringh_bad("Updating avail event index %p",
497 &vring_avail_event(&vrh->vring)); 515 &vring_avail_event(&vrh->vring));
@@ -503,7 +521,7 @@ static inline bool __vringh_notify_enable(struct vringh *vrh,
503 * sure it's written, then check again. */ 521 * sure it's written, then check again. */
504 virtio_mb(vrh->weak_barriers); 522 virtio_mb(vrh->weak_barriers);
505 523
506 if (getu16(&avail, &vrh->vring.avail->idx) != 0) { 524 if (getu16(vrh, &avail, &vrh->vring.avail->idx) != 0) {
507 vringh_bad("Failed to check avail idx at %p", 525 vringh_bad("Failed to check avail idx at %p",
508 &vrh->vring.avail->idx); 526 &vrh->vring.avail->idx);
509 return true; 527 return true;
@@ -516,11 +534,13 @@ static inline bool __vringh_notify_enable(struct vringh *vrh,
516} 534}
517 535
518static inline void __vringh_notify_disable(struct vringh *vrh, 536static inline void __vringh_notify_disable(struct vringh *vrh,
519 int (*putu16)(u16 *p, u16 val)) 537 int (*putu16)(const struct vringh *vrh,
538 __virtio16 *p, u16 val))
520{ 539{
521 if (!vrh->event_indices) { 540 if (!vrh->event_indices) {
522 /* Old-school; update flags. */ 541 /* Old-school; update flags. */
523 if (putu16(&vrh->vring.used->flags, VRING_USED_F_NO_NOTIFY)) { 542 if (putu16(vrh, &vrh->vring.used->flags,
543 VRING_USED_F_NO_NOTIFY)) {
524 vringh_bad("Setting used flags %p", 544 vringh_bad("Setting used flags %p",
525 &vrh->vring.used->flags); 545 &vrh->vring.used->flags);
526 } 546 }
@@ -528,14 +548,18 @@ static inline void __vringh_notify_disable(struct vringh *vrh,
528} 548}
529 549
530/* Userspace access helpers: in this case, addresses are really userspace. */ 550/* Userspace access helpers: in this case, addresses are really userspace. */
531static inline int getu16_user(u16 *val, const u16 *p) 551static inline int getu16_user(const struct vringh *vrh, u16 *val, const __virtio16 *p)
532{ 552{
533 return get_user(*val, (__force u16 __user *)p); 553 __virtio16 v = 0;
554 int rc = get_user(v, (__force __virtio16 __user *)p);
555 *val = vringh16_to_cpu(vrh, v);
556 return rc;
534} 557}
535 558
536static inline int putu16_user(u16 *p, u16 val) 559static inline int putu16_user(const struct vringh *vrh, __virtio16 *p, u16 val)
537{ 560{
538 return put_user(val, (__force u16 __user *)p); 561 __virtio16 v = cpu_to_vringh16(vrh, val);
562 return put_user(v, (__force __virtio16 __user *)p);
539} 563}
540 564
541static inline int copydesc_user(void *dst, const void *src, size_t len) 565static inline int copydesc_user(void *dst, const void *src, size_t len)
@@ -577,7 +601,7 @@ static inline int xfer_to_user(void *dst, void *src, size_t len)
577 * Returns an error if num is invalid: you should check pointers 601 * Returns an error if num is invalid: you should check pointers
578 * yourself! 602 * yourself!
579 */ 603 */
580int vringh_init_user(struct vringh *vrh, u32 features, 604int vringh_init_user(struct vringh *vrh, u64 features,
581 unsigned int num, bool weak_barriers, 605 unsigned int num, bool weak_barriers,
582 struct vring_desc __user *desc, 606 struct vring_desc __user *desc,
583 struct vring_avail __user *avail, 607 struct vring_avail __user *avail,
@@ -589,6 +613,7 @@ int vringh_init_user(struct vringh *vrh, u32 features,
589 return -EINVAL; 613 return -EINVAL;
590 } 614 }
591 615
616 vrh->little_endian = (features & (1ULL << VIRTIO_F_VERSION_1));
592 vrh->event_indices = (features & (1 << VIRTIO_RING_F_EVENT_IDX)); 617 vrh->event_indices = (features & (1 << VIRTIO_RING_F_EVENT_IDX));
593 vrh->weak_barriers = weak_barriers; 618 vrh->weak_barriers = weak_barriers;
594 vrh->completed = 0; 619 vrh->completed = 0;
@@ -729,8 +754,8 @@ int vringh_complete_user(struct vringh *vrh, u16 head, u32 len)
729{ 754{
730 struct vring_used_elem used; 755 struct vring_used_elem used;
731 756
732 used.id = head; 757 used.id = cpu_to_vringh32(vrh, head);
733 used.len = len; 758 used.len = cpu_to_vringh32(vrh, len);
734 return __vringh_complete(vrh, &used, 1, putu16_user, putused_user); 759 return __vringh_complete(vrh, &used, 1, putu16_user, putused_user);
735} 760}
736EXPORT_SYMBOL(vringh_complete_user); 761EXPORT_SYMBOL(vringh_complete_user);
@@ -792,15 +817,16 @@ int vringh_need_notify_user(struct vringh *vrh)
792EXPORT_SYMBOL(vringh_need_notify_user); 817EXPORT_SYMBOL(vringh_need_notify_user);
793 818
794/* Kernelspace access helpers. */ 819/* Kernelspace access helpers. */
795static inline int getu16_kern(u16 *val, const u16 *p) 820static inline int getu16_kern(const struct vringh *vrh,
821 u16 *val, const __virtio16 *p)
796{ 822{
797 *val = ACCESS_ONCE(*p); 823 *val = vringh16_to_cpu(vrh, ACCESS_ONCE(*p));
798 return 0; 824 return 0;
799} 825}
800 826
801static inline int putu16_kern(u16 *p, u16 val) 827static inline int putu16_kern(const struct vringh *vrh, __virtio16 *p, u16 val)
802{ 828{
803 ACCESS_ONCE(*p) = val; 829 ACCESS_ONCE(*p) = cpu_to_vringh16(vrh, val);
804 return 0; 830 return 0;
805} 831}
806 832
@@ -836,7 +862,7 @@ static inline int xfer_kern(void *src, void *dst, size_t len)
836 * 862 *
837 * Returns an error if num is invalid. 863 * Returns an error if num is invalid.
838 */ 864 */
839int vringh_init_kern(struct vringh *vrh, u32 features, 865int vringh_init_kern(struct vringh *vrh, u64 features,
840 unsigned int num, bool weak_barriers, 866 unsigned int num, bool weak_barriers,
841 struct vring_desc *desc, 867 struct vring_desc *desc,
842 struct vring_avail *avail, 868 struct vring_avail *avail,
@@ -848,6 +874,7 @@ int vringh_init_kern(struct vringh *vrh, u32 features,
848 return -EINVAL; 874 return -EINVAL;
849 } 875 }
850 876
877 vrh->little_endian = (features & (1ULL << VIRTIO_F_VERSION_1));
851 vrh->event_indices = (features & (1 << VIRTIO_RING_F_EVENT_IDX)); 878 vrh->event_indices = (features & (1 << VIRTIO_RING_F_EVENT_IDX));
852 vrh->weak_barriers = weak_barriers; 879 vrh->weak_barriers = weak_barriers;
853 vrh->completed = 0; 880 vrh->completed = 0;
@@ -962,8 +989,8 @@ int vringh_complete_kern(struct vringh *vrh, u16 head, u32 len)
962{ 989{
963 struct vring_used_elem used; 990 struct vring_used_elem used;
964 991
965 used.id = head; 992 used.id = cpu_to_vringh32(vrh, head);
966 used.len = len; 993 used.len = cpu_to_vringh32(vrh, len);
967 994
968 return __vringh_complete(vrh, &used, 1, putu16_kern, putused_kern); 995 return __vringh_complete(vrh, &used, 1, putu16_kern, putused_kern);
969} 996}
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index f22665868781..b9f70dfc4751 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -162,6 +162,27 @@ static void virtio_config_enable(struct virtio_device *dev)
162 spin_unlock_irq(&dev->config_lock); 162 spin_unlock_irq(&dev->config_lock);
163} 163}
164 164
165static int virtio_finalize_features(struct virtio_device *dev)
166{
167 int ret = dev->config->finalize_features(dev);
168 unsigned status;
169
170 if (ret)
171 return ret;
172
173 if (!virtio_has_feature(dev, VIRTIO_F_VERSION_1))
174 return 0;
175
176 add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK);
177 status = dev->config->get_status(dev);
178 if (!(status & VIRTIO_CONFIG_S_FEATURES_OK)) {
179 dev_err(&dev->dev, "virtio: device refuses features: %x\n",
180 status);
181 return -ENODEV;
182 }
183 return 0;
184}
185
165static int virtio_dev_probe(struct device *_d) 186static int virtio_dev_probe(struct device *_d)
166{ 187{
167 int err, i; 188 int err, i;
@@ -170,7 +191,6 @@ static int virtio_dev_probe(struct device *_d)
170 u64 device_features; 191 u64 device_features;
171 u64 driver_features; 192 u64 driver_features;
172 u64 driver_features_legacy; 193 u64 driver_features_legacy;
173 unsigned status;
174 194
175 /* We have a driver! */ 195 /* We have a driver! */
176 add_status(dev, VIRTIO_CONFIG_S_DRIVER); 196 add_status(dev, VIRTIO_CONFIG_S_DRIVER);
@@ -208,21 +228,10 @@ static int virtio_dev_probe(struct device *_d)
208 if (device_features & (1ULL << i)) 228 if (device_features & (1ULL << i))
209 __virtio_set_bit(dev, i); 229 __virtio_set_bit(dev, i);
210 230
211 err = dev->config->finalize_features(dev); 231 err = virtio_finalize_features(dev);
212 if (err) 232 if (err)
213 goto err; 233 goto err;
214 234
215 if (virtio_has_feature(dev, VIRTIO_F_VERSION_1)) {
216 add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK);
217 status = dev->config->get_status(dev);
218 if (!(status & VIRTIO_CONFIG_S_FEATURES_OK)) {
219 dev_err(_d, "virtio: device refuses features: %x\n",
220 status);
221 err = -ENODEV;
222 goto err;
223 }
224 }
225
226 err = drv->probe(dev); 235 err = drv->probe(dev);
227 if (err) 236 if (err)
228 goto err; 237 goto err;
@@ -372,7 +381,7 @@ int virtio_device_restore(struct virtio_device *dev)
372 /* We have a driver! */ 381 /* We have a driver! */
373 add_status(dev, VIRTIO_CONFIG_S_DRIVER); 382 add_status(dev, VIRTIO_CONFIG_S_DRIVER);
374 383
375 ret = dev->config->finalize_features(dev); 384 ret = virtio_finalize_features(dev);
376 if (ret) 385 if (ret)
377 goto err; 386 goto err;
378 387
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
index 953057d84185..2ef9529809d8 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -458,7 +458,44 @@ static int virtio_pci_restore(struct device *dev)
458 return virtio_device_restore(&vp_dev->vdev); 458 return virtio_device_restore(&vp_dev->vdev);
459} 459}
460 460
461const struct dev_pm_ops virtio_pci_pm_ops = { 461static const struct dev_pm_ops virtio_pci_pm_ops = {
462 SET_SYSTEM_SLEEP_PM_OPS(virtio_pci_freeze, virtio_pci_restore) 462 SET_SYSTEM_SLEEP_PM_OPS(virtio_pci_freeze, virtio_pci_restore)
463}; 463};
464#endif 464#endif
465
466
467/* Qumranet donated their vendor ID for devices 0x1000 thru 0x10FF. */
468static const struct pci_device_id virtio_pci_id_table[] = {
469 { PCI_DEVICE(0x1af4, PCI_ANY_ID) },
470 { 0 }
471};
472
473MODULE_DEVICE_TABLE(pci, virtio_pci_id_table);
474
475static int virtio_pci_probe(struct pci_dev *pci_dev,
476 const struct pci_device_id *id)
477{
478 return virtio_pci_legacy_probe(pci_dev, id);
479}
480
481static void virtio_pci_remove(struct pci_dev *pci_dev)
482{
483 virtio_pci_legacy_remove(pci_dev);
484}
485
486static struct pci_driver virtio_pci_driver = {
487 .name = "virtio-pci",
488 .id_table = virtio_pci_id_table,
489 .probe = virtio_pci_probe,
490 .remove = virtio_pci_remove,
491#ifdef CONFIG_PM_SLEEP
492 .driver.pm = &virtio_pci_pm_ops,
493#endif
494};
495
496module_pci_driver(virtio_pci_driver);
497
498MODULE_AUTHOR("Anthony Liguori <aliguori@us.ibm.com>");
499MODULE_DESCRIPTION("virtio-pci");
500MODULE_LICENSE("GPL");
501MODULE_VERSION("1");
diff --git a/drivers/virtio/virtio_pci_common.h b/drivers/virtio/virtio_pci_common.h
index d840dad4149d..adddb647b21d 100644
--- a/drivers/virtio/virtio_pci_common.h
+++ b/drivers/virtio/virtio_pci_common.h
@@ -27,7 +27,6 @@
27#include <linux/virtio.h> 27#include <linux/virtio.h>
28#include <linux/virtio_config.h> 28#include <linux/virtio_config.h>
29#include <linux/virtio_ring.h> 29#include <linux/virtio_ring.h>
30#define VIRTIO_PCI_NO_LEGACY
31#include <linux/virtio_pci.h> 30#include <linux/virtio_pci.h>
32#include <linux/highmem.h> 31#include <linux/highmem.h>
33#include <linux/spinlock.h> 32#include <linux/spinlock.h>
@@ -129,8 +128,8 @@ const char *vp_bus_name(struct virtio_device *vdev);
129int vp_set_vq_affinity(struct virtqueue *vq, int cpu); 128int vp_set_vq_affinity(struct virtqueue *vq, int cpu);
130void virtio_pci_release_dev(struct device *); 129void virtio_pci_release_dev(struct device *);
131 130
132#ifdef CONFIG_PM_SLEEP 131int virtio_pci_legacy_probe(struct pci_dev *pci_dev,
133extern const struct dev_pm_ops virtio_pci_pm_ops; 132 const struct pci_device_id *id);
134#endif 133void virtio_pci_legacy_remove(struct pci_dev *pci_dev);
135 134
136#endif 135#endif
diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci_legacy.c
index 2588252e5c1c..6c76f0f5658c 100644
--- a/drivers/virtio/virtio_pci_legacy.c
+++ b/drivers/virtio/virtio_pci_legacy.c
@@ -19,14 +19,6 @@
19 19
20#include "virtio_pci_common.h" 20#include "virtio_pci_common.h"
21 21
22/* Qumranet donated their vendor ID for devices 0x1000 thru 0x10FF. */
23static const struct pci_device_id virtio_pci_id_table[] = {
24 { PCI_DEVICE(0x1af4, PCI_ANY_ID) },
25 { 0 }
26};
27
28MODULE_DEVICE_TABLE(pci, virtio_pci_id_table);
29
30/* virtio config->get_features() implementation */ 22/* virtio config->get_features() implementation */
31static u64 vp_get_features(struct virtio_device *vdev) 23static u64 vp_get_features(struct virtio_device *vdev)
32{ 24{
@@ -220,7 +212,7 @@ static const struct virtio_config_ops virtio_pci_config_ops = {
220}; 212};
221 213
222/* the PCI probing function */ 214/* the PCI probing function */
223static int virtio_pci_probe(struct pci_dev *pci_dev, 215int virtio_pci_legacy_probe(struct pci_dev *pci_dev,
224 const struct pci_device_id *id) 216 const struct pci_device_id *id)
225{ 217{
226 struct virtio_pci_device *vp_dev; 218 struct virtio_pci_device *vp_dev;
@@ -300,7 +292,7 @@ out:
300 return err; 292 return err;
301} 293}
302 294
303static void virtio_pci_remove(struct pci_dev *pci_dev) 295void virtio_pci_legacy_remove(struct pci_dev *pci_dev)
304{ 296{
305 struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); 297 struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
306 298
@@ -312,15 +304,3 @@ static void virtio_pci_remove(struct pci_dev *pci_dev)
312 pci_disable_device(pci_dev); 304 pci_disable_device(pci_dev);
313 kfree(vp_dev); 305 kfree(vp_dev);
314} 306}
315
316static struct pci_driver virtio_pci_driver = {
317 .name = "virtio-pci",
318 .id_table = virtio_pci_id_table,
319 .probe = virtio_pci_probe,
320 .remove = virtio_pci_remove,
321#ifdef CONFIG_PM_SLEEP
322 .driver.pm = &virtio_pci_pm_ops,
323#endif
324};
325
326module_pci_driver(virtio_pci_driver);
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index 7979f850e7ac..ca3ed78e5ec7 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -19,6 +19,9 @@
19 * offset: the offset of the configuration field 19 * offset: the offset of the configuration field
20 * buf: the buffer to read the field value from. 20 * buf: the buffer to read the field value from.
21 * len: the length of the buffer 21 * len: the length of the buffer
22 * @generation: config generation counter
23 * vdev: the virtio_device
24 * Returns the config generation counter
22 * @get_status: read the status byte 25 * @get_status: read the status byte
23 * vdev: the virtio_device 26 * vdev: the virtio_device
24 * Returns the status byte 27 * Returns the status byte
@@ -60,6 +63,7 @@ struct virtio_config_ops {
60 void *buf, unsigned len); 63 void *buf, unsigned len);
61 void (*set)(struct virtio_device *vdev, unsigned offset, 64 void (*set)(struct virtio_device *vdev, unsigned offset,
62 const void *buf, unsigned len); 65 const void *buf, unsigned len);
66 u32 (*generation)(struct virtio_device *vdev);
63 u8 (*get_status)(struct virtio_device *vdev); 67 u8 (*get_status)(struct virtio_device *vdev);
64 void (*set_status)(struct virtio_device *vdev, u8 status); 68 void (*set_status)(struct virtio_device *vdev, u8 status);
65 void (*reset)(struct virtio_device *vdev); 69 void (*reset)(struct virtio_device *vdev);
@@ -301,11 +305,33 @@ static inline u8 virtio_cread8(struct virtio_device *vdev, unsigned int offset)
301 return ret; 305 return ret;
302} 306}
303 307
308/* Read @count fields, @bytes each. */
309static inline void __virtio_cread_many(struct virtio_device *vdev,
310 unsigned int offset,
311 void *buf, size_t count, size_t bytes)
312{
313 u32 old, gen = vdev->config->generation ?
314 vdev->config->generation(vdev) : 0;
315 int i;
316
317 do {
318 old = gen;
319
320 for (i = 0; i < count; i++)
321 vdev->config->get(vdev, offset + bytes * i,
322 buf + i * bytes, bytes);
323
324 gen = vdev->config->generation ?
325 vdev->config->generation(vdev) : 0;
326 } while (gen != old);
327}
328
329
304static inline void virtio_cread_bytes(struct virtio_device *vdev, 330static inline void virtio_cread_bytes(struct virtio_device *vdev,
305 unsigned int offset, 331 unsigned int offset,
306 void *buf, size_t len) 332 void *buf, size_t len)
307{ 333{
308 vdev->config->get(vdev, offset, buf, len); 334 __virtio_cread_many(vdev, offset, buf, len, 1);
309} 335}
310 336
311static inline void virtio_cwrite8(struct virtio_device *vdev, 337static inline void virtio_cwrite8(struct virtio_device *vdev,
@@ -349,6 +375,7 @@ static inline u64 virtio_cread64(struct virtio_device *vdev,
349{ 375{
350 u64 ret; 376 u64 ret;
351 vdev->config->get(vdev, offset, &ret, sizeof(ret)); 377 vdev->config->get(vdev, offset, &ret, sizeof(ret));
378 __virtio_cread_many(vdev, offset, &ret, 1, sizeof(ret));
352 return virtio64_to_cpu(vdev, (__force __virtio64)ret); 379 return virtio64_to_cpu(vdev, (__force __virtio64)ret);
353} 380}
354 381
diff --git a/include/linux/vringh.h b/include/linux/vringh.h
index 749cde28728b..a3fa537e717a 100644
--- a/include/linux/vringh.h
+++ b/include/linux/vringh.h
@@ -24,12 +24,16 @@
24#ifndef _LINUX_VRINGH_H 24#ifndef _LINUX_VRINGH_H
25#define _LINUX_VRINGH_H 25#define _LINUX_VRINGH_H
26#include <uapi/linux/virtio_ring.h> 26#include <uapi/linux/virtio_ring.h>
27#include <linux/virtio_byteorder.h>
27#include <linux/uio.h> 28#include <linux/uio.h>
28#include <linux/slab.h> 29#include <linux/slab.h>
29#include <asm/barrier.h> 30#include <asm/barrier.h>
30 31
31/* virtio_ring with information needed for host access. */ 32/* virtio_ring with information needed for host access. */
32struct vringh { 33struct vringh {
34 /* Everything is little endian */
35 bool little_endian;
36
33 /* Guest publishes used event idx (note: we always do). */ 37 /* Guest publishes used event idx (note: we always do). */
34 bool event_indices; 38 bool event_indices;
35 39
@@ -105,7 +109,7 @@ struct vringh_kiov {
105#define VRINGH_IOV_ALLOCATED 0x8000000 109#define VRINGH_IOV_ALLOCATED 0x8000000
106 110
107/* Helpers for userspace vrings. */ 111/* Helpers for userspace vrings. */
108int vringh_init_user(struct vringh *vrh, u32 features, 112int vringh_init_user(struct vringh *vrh, u64 features,
109 unsigned int num, bool weak_barriers, 113 unsigned int num, bool weak_barriers,
110 struct vring_desc __user *desc, 114 struct vring_desc __user *desc,
111 struct vring_avail __user *avail, 115 struct vring_avail __user *avail,
@@ -167,7 +171,7 @@ bool vringh_notify_enable_user(struct vringh *vrh);
167void vringh_notify_disable_user(struct vringh *vrh); 171void vringh_notify_disable_user(struct vringh *vrh);
168 172
169/* Helpers for kernelspace vrings. */ 173/* Helpers for kernelspace vrings. */
170int vringh_init_kern(struct vringh *vrh, u32 features, 174int vringh_init_kern(struct vringh *vrh, u64 features,
171 unsigned int num, bool weak_barriers, 175 unsigned int num, bool weak_barriers,
172 struct vring_desc *desc, 176 struct vring_desc *desc,
173 struct vring_avail *avail, 177 struct vring_avail *avail,
@@ -222,4 +226,33 @@ static inline void vringh_notify(struct vringh *vrh)
222 vrh->notify(vrh); 226 vrh->notify(vrh);
223} 227}
224 228
229static inline u16 vringh16_to_cpu(const struct vringh *vrh, __virtio16 val)
230{
231 return __virtio16_to_cpu(vrh->little_endian, val);
232}
233
234static inline __virtio16 cpu_to_vringh16(const struct vringh *vrh, u16 val)
235{
236 return __cpu_to_virtio16(vrh->little_endian, val);
237}
238
239static inline u32 vringh32_to_cpu(const struct vringh *vrh, __virtio32 val)
240{
241 return __virtio32_to_cpu(vrh->little_endian, val);
242}
243
244static inline __virtio32 cpu_to_vringh32(const struct vringh *vrh, u32 val)
245{
246 return __cpu_to_virtio32(vrh->little_endian, val);
247}
248
249static inline u64 vringh64_to_cpu(const struct vringh *vrh, __virtio64 val)
250{
251 return __virtio64_to_cpu(vrh->little_endian, val);
252}
253
254static inline __virtio64 cpu_to_vringh64(const struct vringh *vrh, u64 val)
255{
256 return __cpu_to_virtio64(vrh->little_endian, val);
257}
225#endif /* _LINUX_VRINGH_H */ 258#endif /* _LINUX_VRINGH_H */
diff --git a/include/uapi/linux/virtio_pci.h b/include/uapi/linux/virtio_pci.h
index e5ec1caab82a..35b552c7f330 100644
--- a/include/uapi/linux/virtio_pci.h
+++ b/include/uapi/linux/virtio_pci.h
@@ -41,6 +41,8 @@
41 41
42#include <linux/virtio_config.h> 42#include <linux/virtio_config.h>
43 43
44#ifndef VIRTIO_PCI_NO_LEGACY
45
44/* A 32-bit r/o bitmask of the features supported by the host */ 46/* A 32-bit r/o bitmask of the features supported by the host */
45#define VIRTIO_PCI_HOST_FEATURES 0 47#define VIRTIO_PCI_HOST_FEATURES 0
46 48
@@ -67,16 +69,11 @@
67 * a read-and-acknowledge. */ 69 * a read-and-acknowledge. */
68#define VIRTIO_PCI_ISR 19 70#define VIRTIO_PCI_ISR 19
69 71
70/* The bit of the ISR which indicates a device configuration change. */
71#define VIRTIO_PCI_ISR_CONFIG 0x2
72
73/* MSI-X registers: only enabled if MSI-X is enabled. */ 72/* MSI-X registers: only enabled if MSI-X is enabled. */
74/* A 16-bit vector for configuration changes. */ 73/* A 16-bit vector for configuration changes. */
75#define VIRTIO_MSI_CONFIG_VECTOR 20 74#define VIRTIO_MSI_CONFIG_VECTOR 20
76/* A 16-bit vector for selected queue notifications. */ 75/* A 16-bit vector for selected queue notifications. */
77#define VIRTIO_MSI_QUEUE_VECTOR 22 76#define VIRTIO_MSI_QUEUE_VECTOR 22
78/* Vector value used to disable MSI for queue */
79#define VIRTIO_MSI_NO_VECTOR 0xffff
80 77
81/* The remaining space is defined by each driver as the per-driver 78/* The remaining space is defined by each driver as the per-driver
82 * configuration space */ 79 * configuration space */
@@ -94,4 +91,12 @@
94/* The alignment to use between consumer and producer parts of vring. 91/* The alignment to use between consumer and producer parts of vring.
95 * x86 pagesize again. */ 92 * x86 pagesize again. */
96#define VIRTIO_PCI_VRING_ALIGN 4096 93#define VIRTIO_PCI_VRING_ALIGN 4096
94
95#endif /* VIRTIO_PCI_NO_LEGACY */
96
97/* The bit of the ISR which indicates a device configuration change. */
98#define VIRTIO_PCI_ISR_CONFIG 0x2
99/* Vector value used to disable MSI for queue */
100#define VIRTIO_MSI_NO_VECTOR 0xffff
101
97#endif 102#endif
diff --git a/tools/virtio/Makefile b/tools/virtio/Makefile
index 9325f4693821..505ad51b3b51 100644
--- a/tools/virtio/Makefile
+++ b/tools/virtio/Makefile
@@ -3,7 +3,7 @@ test: virtio_test vringh_test
3virtio_test: virtio_ring.o virtio_test.o 3virtio_test: virtio_ring.o virtio_test.o
4vringh_test: vringh_test.o vringh.o virtio_ring.o 4vringh_test: vringh_test.o vringh.o virtio_ring.o
5 5
6CFLAGS += -g -O2 -Wall -I. -I../include/ -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE 6CFLAGS += -g -O2 -Werror -Wall -I. -I../include/ -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE
7vpath %.c ../../drivers/virtio ../../drivers/vhost 7vpath %.c ../../drivers/virtio ../../drivers/vhost
8mod: 8mod:
9 ${MAKE} -C `pwd`/../.. M=`pwd`/vhost_test 9 ${MAKE} -C `pwd`/../.. M=`pwd`/vhost_test
diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h
index 8eb6421761cd..a3e07016a440 100644
--- a/tools/virtio/linux/virtio.h
+++ b/tools/virtio/linux/virtio.h
@@ -6,6 +6,7 @@
6/* TODO: empty stubs for now. Broken but enough for virtio_ring.c */ 6/* TODO: empty stubs for now. Broken but enough for virtio_ring.c */
7#define list_add_tail(a, b) do {} while (0) 7#define list_add_tail(a, b) do {} while (0)
8#define list_del(a) do {} while (0) 8#define list_del(a) do {} while (0)
9#define list_for_each_entry(a, b, c) while (0)
9/* end of stubs */ 10/* end of stubs */
10 11
11struct virtio_device { 12struct virtio_device {
diff --git a/tools/virtio/linux/virtio_byteorder.h b/tools/virtio/linux/virtio_byteorder.h
new file mode 100644
index 000000000000..9de9e6ac1d10
--- /dev/null
+++ b/tools/virtio/linux/virtio_byteorder.h
@@ -0,0 +1,8 @@
1#ifndef _LINUX_VIRTIO_BYTEORDER_STUB_H
2#define _LINUX_VIRTIO_BYTEORDER_STUB_H
3
4#include <asm/byteorder.h>
5#include "../../include/linux/byteorder/generic.h"
6#include "../../include/linux/virtio_byteorder.h"
7
8#endif
diff --git a/tools/virtio/linux/virtio_config.h b/tools/virtio/linux/virtio_config.h
index 83b27e8e9d72..806d683ab107 100644
--- a/tools/virtio/linux/virtio_config.h
+++ b/tools/virtio/linux/virtio_config.h
@@ -1,6 +1,72 @@
1#define VIRTIO_TRANSPORT_F_START 28 1#include <linux/virtio_byteorder.h>
2#define VIRTIO_TRANSPORT_F_END 32 2#include <linux/virtio.h>
3#include <uapi/linux/virtio_config.h>
4
5/*
6 * __virtio_test_bit - helper to test feature bits. For use by transports.
7 * Devices should normally use virtio_has_feature,
8 * which includes more checks.
9 * @vdev: the device
10 * @fbit: the feature bit
11 */
12static inline bool __virtio_test_bit(const struct virtio_device *vdev,
13 unsigned int fbit)
14{
15 return vdev->features & (1ULL << fbit);
16}
17
18/**
19 * __virtio_set_bit - helper to set feature bits. For use by transports.
20 * @vdev: the device
21 * @fbit: the feature bit
22 */
23static inline void __virtio_set_bit(struct virtio_device *vdev,
24 unsigned int fbit)
25{
26 vdev->features |= (1ULL << fbit);
27}
28
29/**
30 * __virtio_clear_bit - helper to clear feature bits. For use by transports.
31 * @vdev: the device
32 * @fbit: the feature bit
33 */
34static inline void __virtio_clear_bit(struct virtio_device *vdev,
35 unsigned int fbit)
36{
37 vdev->features &= ~(1ULL << fbit);
38}
3 39
4#define virtio_has_feature(dev, feature) \ 40#define virtio_has_feature(dev, feature) \
5 (__virtio_test_bit((dev), feature)) 41 (__virtio_test_bit((dev), feature))
6 42
43static inline u16 virtio16_to_cpu(struct virtio_device *vdev, __virtio16 val)
44{
45 return __virtio16_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
46}
47
48static inline __virtio16 cpu_to_virtio16(struct virtio_device *vdev, u16 val)
49{
50 return __cpu_to_virtio16(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
51}
52
53static inline u32 virtio32_to_cpu(struct virtio_device *vdev, __virtio32 val)
54{
55 return __virtio32_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
56}
57
58static inline __virtio32 cpu_to_virtio32(struct virtio_device *vdev, u32 val)
59{
60 return __cpu_to_virtio32(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
61}
62
63static inline u64 virtio64_to_cpu(struct virtio_device *vdev, __virtio64 val)
64{
65 return __virtio64_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
66}
67
68static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val)
69{
70 return __cpu_to_virtio64(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
71}
72
diff --git a/tools/virtio/uapi/linux/virtio_types.h b/tools/virtio/uapi/linux/virtio_types.h
new file mode 100644
index 000000000000..e7a1096e7c97
--- /dev/null
+++ b/tools/virtio/uapi/linux/virtio_types.h
@@ -0,0 +1 @@
#include "../../include/uapi/linux/virtio_types.h"
diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c
index db3437c641a6..e0445898f08f 100644
--- a/tools/virtio/virtio_test.c
+++ b/tools/virtio/virtio_test.c
@@ -11,6 +11,7 @@
11#include <sys/types.h> 11#include <sys/types.h>
12#include <fcntl.h> 12#include <fcntl.h>
13#include <stdbool.h> 13#include <stdbool.h>
14#include <linux/virtio_types.h>
14#include <linux/vhost.h> 15#include <linux/vhost.h>
15#include <linux/virtio.h> 16#include <linux/virtio.h>
16#include <linux/virtio_ring.h> 17#include <linux/virtio_ring.h>
@@ -227,6 +228,14 @@ const struct option longopts[] = {
227 .val = 'i', 228 .val = 'i',
228 }, 229 },
229 { 230 {
231 .name = "virtio-1",
232 .val = '1',
233 },
234 {
235 .name = "no-virtio-1",
236 .val = '0',
237 },
238 {
230 .name = "delayed-interrupt", 239 .name = "delayed-interrupt",
231 .val = 'D', 240 .val = 'D',
232 }, 241 },
@@ -243,6 +252,7 @@ static void help(void)
243 fprintf(stderr, "Usage: virtio_test [--help]" 252 fprintf(stderr, "Usage: virtio_test [--help]"
244 " [--no-indirect]" 253 " [--no-indirect]"
245 " [--no-event-idx]" 254 " [--no-event-idx]"
255 " [--no-virtio-1]"
246 " [--delayed-interrupt]" 256 " [--delayed-interrupt]"
247 "\n"); 257 "\n");
248} 258}
@@ -251,7 +261,7 @@ int main(int argc, char **argv)
251{ 261{
252 struct vdev_info dev; 262 struct vdev_info dev;
253 unsigned long long features = (1ULL << VIRTIO_RING_F_INDIRECT_DESC) | 263 unsigned long long features = (1ULL << VIRTIO_RING_F_INDIRECT_DESC) |
254 (1ULL << VIRTIO_RING_F_EVENT_IDX); 264 (1ULL << VIRTIO_RING_F_EVENT_IDX) | (1ULL << VIRTIO_F_VERSION_1);
255 int o; 265 int o;
256 bool delayed = false; 266 bool delayed = false;
257 267
@@ -272,6 +282,9 @@ int main(int argc, char **argv)
272 case 'i': 282 case 'i':
273 features &= ~(1ULL << VIRTIO_RING_F_INDIRECT_DESC); 283 features &= ~(1ULL << VIRTIO_RING_F_INDIRECT_DESC);
274 break; 284 break;
285 case '0':
286 features &= ~(1ULL << VIRTIO_F_VERSION_1);
287 break;
275 case 'D': 288 case 'D':
276 delayed = true; 289 delayed = true;
277 break; 290 break;
diff --git a/tools/virtio/vringh_test.c b/tools/virtio/vringh_test.c
index 9d4b1bca54be..5f94f5105678 100644
--- a/tools/virtio/vringh_test.c
+++ b/tools/virtio/vringh_test.c
@@ -7,6 +7,7 @@
7#include <linux/virtio.h> 7#include <linux/virtio.h>
8#include <linux/vringh.h> 8#include <linux/vringh.h>
9#include <linux/virtio_ring.h> 9#include <linux/virtio_ring.h>
10#include <linux/virtio_config.h>
10#include <linux/uaccess.h> 11#include <linux/uaccess.h>
11#include <sys/types.h> 12#include <sys/types.h>
12#include <sys/stat.h> 13#include <sys/stat.h>
@@ -131,7 +132,7 @@ static inline int vringh_get_head(struct vringh *vrh, u16 *head)
131 return 1; 132 return 1;
132} 133}
133 134
134static int parallel_test(unsigned long features, 135static int parallel_test(u64 features,
135 bool (*getrange)(struct vringh *vrh, 136 bool (*getrange)(struct vringh *vrh,
136 u64 addr, struct vringh_range *r), 137 u64 addr, struct vringh_range *r),
137 bool fast_vringh) 138 bool fast_vringh)
@@ -456,6 +457,8 @@ int main(int argc, char *argv[])
456 __virtio_set_bit(&vdev, VIRTIO_RING_F_INDIRECT_DESC); 457 __virtio_set_bit(&vdev, VIRTIO_RING_F_INDIRECT_DESC);
457 else if (strcmp(argv[1], "--eventidx") == 0) 458 else if (strcmp(argv[1], "--eventidx") == 0)
458 __virtio_set_bit(&vdev, VIRTIO_RING_F_EVENT_IDX); 459 __virtio_set_bit(&vdev, VIRTIO_RING_F_EVENT_IDX);
460 else if (strcmp(argv[1], "--virtio-1") == 0)
461 __virtio_set_bit(&vdev, VIRTIO_F_VERSION_1);
459 else if (strcmp(argv[1], "--slow-range") == 0) 462 else if (strcmp(argv[1], "--slow-range") == 0)
460 getrange = getrange_slow; 463 getrange = getrange_slow;
461 else if (strcmp(argv[1], "--fast-vringh") == 0) 464 else if (strcmp(argv[1], "--fast-vringh") == 0)