Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

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