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

Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus

* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus:
virtio_net: delay TX callbacks
virtio: add api for delayed callbacks
virtio_test: support event index
vhost: support event index
virtio_ring: support event idx feature
virtio ring: inline function to check for events
virtio: event index interface
virtio: add full three-clause BSD text to headers.
virtio balloon: kill tell-host-first logic
virtio console: don't manually set or finalize VIRTIO_CONSOLE_F_MULTIPORT.
drivers, block: virtio_blk: Replace cryptic number with the macro
virtio_blk: allow re-reading config space at runtime
lguest: remove support for VIRTIO_F_NOTIFY_ON_EMPTY.
lguest: fix up compilation after move
lguest: fix timer interrupt setup

+539 -113
+1 -1
Documentation/virtual/lguest/Makefile
··· 1 1 # This creates the demonstration utility "lguest" which runs a Linux guest. 2 - # Missing headers? Add "-I../../include -I../../arch/x86/include" 2 + # Missing headers? Add "-I../../../include -I../../../arch/x86/include" 3 3 CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE 4 4 5 5 all: lguest
+2 -20
Documentation/virtual/lguest/lguest.c
··· 49 49 #include <linux/virtio_rng.h> 50 50 #include <linux/virtio_ring.h> 51 51 #include <asm/bootparam.h> 52 - #include "../../include/linux/lguest_launcher.h" 52 + #include "../../../include/linux/lguest_launcher.h" 53 53 /*L:110 54 54 * We can ignore the 42 include files we need for this program, but I do want 55 55 * to draw attention to the use of kernel-style types. ··· 134 134 135 135 /* Is it operational */ 136 136 bool running; 137 - 138 - /* Does Guest want an intrrupt on empty? */ 139 - bool irq_on_empty; 140 137 141 138 /* Device-specific data. */ 142 139 void *priv; ··· 634 637 635 638 /* If they don't want an interrupt, don't send one... */ 636 639 if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) { 637 - /* ... unless they've asked us to force one on empty. */ 638 - if (!vq->dev->irq_on_empty 639 - || lg_last_avail(vq) != vq->vring.avail->idx) 640 - return; 640 + return; 641 641 } 642 642 643 643 /* Send the Guest an interrupt tell them we used something up. */ ··· 1051 1057 close(vq->eventfd); 1052 1058 } 1053 1059 1054 - static bool accepted_feature(struct device *dev, unsigned int bit) 1055 - { 1056 - const u8 *features = get_feature_bits(dev) + dev->feature_len; 1057 - 1058 - if (dev->feature_len < bit / CHAR_BIT) 1059 - return false; 1060 - return features[bit / CHAR_BIT] & (1 << (bit % CHAR_BIT)); 1061 - } 1062 - 1063 1060 static void start_device(struct device *dev) 1064 1061 { 1065 1062 unsigned int i; ··· 1063 1078 for (i = 0; i < dev->feature_len; i++) 1064 1079 verbose(" %02x", get_feature_bits(dev) 1065 1080 [dev->feature_len+i]); 1066 - 1067 - dev->irq_on_empty = accepted_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY); 1068 1081 1069 1082 for (vq = dev->vq; vq; vq = vq->next) { 1070 1083 if (vq->service) ··· 1547 1564 /* Set up the tun device. */ 1548 1565 configure_device(ipfd, tapif, ip); 1549 1566 1550 - add_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY); 1551 1567 /* Expect Guest to handle everything except UFO */ 1552 1568 add_feature(dev, VIRTIO_NET_F_CSUM); 1553 1569 add_feature(dev, VIRTIO_NET_F_GUEST_CSUM);
+1
arch/x86/lguest/boot.c
··· 993 993 static void lguest_time_init(void) 994 994 { 995 995 /* Set up the timer interrupt (0) to go to our simple timer routine */ 996 + lguest_setup_irq(0); 996 997 irq_set_handler(0, lguest_time_irq); 997 998 998 999 clocksource_register_hz(&lguest_clock, NSEC_PER_SEC);
+80 -11
drivers/block/virtio_blk.c
··· 6 6 #include <linux/virtio.h> 7 7 #include <linux/virtio_blk.h> 8 8 #include <linux/scatterlist.h> 9 + #include <linux/string_helpers.h> 10 + #include <scsi/scsi_cmnd.h> 9 11 10 12 #define PART_BITS 4 11 13 12 14 static int major, index; 15 + struct workqueue_struct *virtblk_wq; 13 16 14 17 struct virtio_blk 15 18 { ··· 28 25 struct list_head reqs; 29 26 30 27 mempool_t *pool; 28 + 29 + /* Process context for config space updates */ 30 + struct work_struct config_work; 31 31 32 32 /* What host tells us, plus 2 for header & tailer. */ 33 33 unsigned int sg_elems; ··· 147 141 num = blk_rq_map_sg(q, vbr->req, vblk->sg + out); 148 142 149 143 if (vbr->req->cmd_type == REQ_TYPE_BLOCK_PC) { 150 - sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, 96); 144 + sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, SCSI_SENSE_BUFFERSIZE); 151 145 sg_set_buf(&vblk->sg[num + out + in++], &vbr->in_hdr, 152 146 sizeof(vbr->in_hdr)); 153 147 } ··· 297 291 } 298 292 DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL); 299 293 294 + static void virtblk_config_changed_work(struct work_struct *work) 295 + { 296 + struct virtio_blk *vblk = 297 + container_of(work, struct virtio_blk, config_work); 298 + struct virtio_device *vdev = vblk->vdev; 299 + struct request_queue *q = vblk->disk->queue; 300 + char cap_str_2[10], cap_str_10[10]; 301 + u64 capacity, size; 302 + 303 + /* Host must always specify the capacity. */ 304 + vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity), 305 + &capacity, sizeof(capacity)); 306 + 307 + /* If capacity is too big, truncate with warning. */ 308 + if ((sector_t)capacity != capacity) { 309 + dev_warn(&vdev->dev, "Capacity %llu too large: truncating\n", 310 + (unsigned long long)capacity); 311 + capacity = (sector_t)-1; 312 + } 313 + 314 + size = capacity * queue_logical_block_size(q); 315 + string_get_size(size, STRING_UNITS_2, cap_str_2, sizeof(cap_str_2)); 316 + string_get_size(size, STRING_UNITS_10, cap_str_10, sizeof(cap_str_10)); 317 + 318 + dev_notice(&vdev->dev, 319 + "new size: %llu %d-byte logical blocks (%s/%s)\n", 320 + (unsigned long long)capacity, 321 + queue_logical_block_size(q), 322 + cap_str_10, cap_str_2); 323 + 324 + set_capacity(vblk->disk, capacity); 325 + } 326 + 327 + static void virtblk_config_changed(struct virtio_device *vdev) 328 + { 329 + struct virtio_blk *vblk = vdev->priv; 330 + 331 + queue_work(virtblk_wq, &vblk->config_work); 332 + } 333 + 300 334 static int __devinit virtblk_probe(struct virtio_device *vdev) 301 335 { 302 336 struct virtio_blk *vblk; ··· 373 327 vblk->vdev = vdev; 374 328 vblk->sg_elems = sg_elems; 375 329 sg_init_table(vblk->sg, vblk->sg_elems); 330 + INIT_WORK(&vblk->config_work, virtblk_config_changed_work); 376 331 377 332 /* We expect one virtqueue, for output. */ 378 333 vblk->vq = virtio_find_single_vq(vdev, blk_done, "requests"); ··· 524 477 { 525 478 struct virtio_blk *vblk = vdev->priv; 526 479 480 + flush_work(&vblk->config_work); 481 + 527 482 /* Nothing should be pending. */ 528 483 BUG_ON(!list_empty(&vblk->reqs)); 529 484 ··· 557 508 * Use __refdata to avoid this warning. 558 509 */ 559 510 static struct virtio_driver __refdata virtio_blk = { 560 - .feature_table = features, 561 - .feature_table_size = ARRAY_SIZE(features), 562 - .driver.name = KBUILD_MODNAME, 563 - .driver.owner = THIS_MODULE, 564 - .id_table = id_table, 565 - .probe = virtblk_probe, 566 - .remove = __devexit_p(virtblk_remove), 511 + .feature_table = features, 512 + .feature_table_size = ARRAY_SIZE(features), 513 + .driver.name = KBUILD_MODNAME, 514 + .driver.owner = THIS_MODULE, 515 + .id_table = id_table, 516 + .probe = virtblk_probe, 517 + .remove = __devexit_p(virtblk_remove), 518 + .config_changed = virtblk_config_changed, 567 519 }; 568 520 569 521 static int __init init(void) 570 522 { 523 + int error; 524 + 525 + virtblk_wq = alloc_workqueue("virtio-blk", 0, 0); 526 + if (!virtblk_wq) 527 + return -ENOMEM; 528 + 571 529 major = register_blkdev(0, "virtblk"); 572 - if (major < 0) 573 - return major; 574 - return register_virtio_driver(&virtio_blk); 530 + if (major < 0) { 531 + error = major; 532 + goto out_destroy_workqueue; 533 + } 534 + 535 + error = register_virtio_driver(&virtio_blk); 536 + if (error) 537 + goto out_unregister_blkdev; 538 + return 0; 539 + 540 + out_unregister_blkdev: 541 + unregister_blkdev(major, "virtblk"); 542 + out_destroy_workqueue: 543 + destroy_workqueue(virtblk_wq); 544 + return error; 575 545 } 576 546 577 547 static void __exit fini(void) 578 548 { 579 549 unregister_blkdev(major, "virtblk"); 580 550 unregister_virtio_driver(&virtio_blk); 551 + destroy_workqueue(virtblk_wq); 581 552 } 582 553 module_init(init); 583 554 module_exit(fini);
-5
drivers/char/virtio_console.c
··· 1677 1677 portdev->config.max_nr_ports = 1; 1678 1678 if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) { 1679 1679 multiport = true; 1680 - vdev->features[0] |= 1 << VIRTIO_CONSOLE_F_MULTIPORT; 1681 - 1682 1680 vdev->config->get(vdev, offsetof(struct virtio_console_config, 1683 1681 max_nr_ports), 1684 1682 &portdev->config.max_nr_ports, 1685 1683 sizeof(portdev->config.max_nr_ports)); 1686 1684 } 1687 - 1688 - /* Let the Host know we support multiple ports.*/ 1689 - vdev->config->finalize_features(vdev); 1690 1685 1691 1686 err = init_vqs(portdev); 1692 1687 if (err < 0) {
+1 -1
drivers/net/virtio_net.c
··· 609 609 * before it gets out of hand. Naturally, this wastes entries. */ 610 610 if (capacity < 2+MAX_SKB_FRAGS) { 611 611 netif_stop_queue(dev); 612 - if (unlikely(!virtqueue_enable_cb(vi->svq))) { 612 + if (unlikely(!virtqueue_enable_cb_delayed(vi->svq))) { 613 613 /* More just got used, free them then recheck. */ 614 614 capacity += free_old_xmit_skbs(vi); 615 615 if (capacity >= 2+MAX_SKB_FRAGS) {
+6 -6
drivers/vhost/net.c
··· 144 144 } 145 145 146 146 mutex_lock(&vq->mutex); 147 - vhost_disable_notify(vq); 147 + vhost_disable_notify(&net->dev, vq); 148 148 149 149 if (wmem < sock->sk->sk_sndbuf / 2) 150 150 tx_poll_stop(net); ··· 166 166 set_bit(SOCK_ASYNC_NOSPACE, &sock->flags); 167 167 break; 168 168 } 169 - if (unlikely(vhost_enable_notify(vq))) { 170 - vhost_disable_notify(vq); 169 + if (unlikely(vhost_enable_notify(&net->dev, vq))) { 170 + vhost_disable_notify(&net->dev, vq); 171 171 continue; 172 172 } 173 173 break; ··· 315 315 return; 316 316 317 317 mutex_lock(&vq->mutex); 318 - vhost_disable_notify(vq); 318 + vhost_disable_notify(&net->dev, vq); 319 319 vhost_hlen = vq->vhost_hlen; 320 320 sock_hlen = vq->sock_hlen; 321 321 ··· 334 334 break; 335 335 /* OK, now we need to know about added descriptors. */ 336 336 if (!headcount) { 337 - if (unlikely(vhost_enable_notify(vq))) { 337 + if (unlikely(vhost_enable_notify(&net->dev, vq))) { 338 338 /* They have slipped one in as we were 339 339 * doing that: check again. */ 340 - vhost_disable_notify(vq); 340 + vhost_disable_notify(&net->dev, vq); 341 341 continue; 342 342 } 343 343 /* Nothing new? Wait for eventfd to tell us
+3 -3
drivers/vhost/test.c
··· 49 49 return; 50 50 51 51 mutex_lock(&vq->mutex); 52 - vhost_disable_notify(vq); 52 + vhost_disable_notify(&n->dev, vq); 53 53 54 54 for (;;) { 55 55 head = vhost_get_vq_desc(&n->dev, vq, vq->iov, ··· 61 61 break; 62 62 /* Nothing new? Wait for eventfd to tell us they refilled. */ 63 63 if (head == vq->num) { 64 - if (unlikely(vhost_enable_notify(vq))) { 65 - vhost_disable_notify(vq); 64 + if (unlikely(vhost_enable_notify(&n->dev, vq))) { 65 + vhost_disable_notify(&n->dev, vq); 66 66 continue; 67 67 } 68 68 break;
+104 -34
drivers/vhost/vhost.c
··· 37 37 VHOST_MEMORY_F_LOG = 0x1, 38 38 }; 39 39 40 + #define vhost_used_event(vq) ((u16 __user *)&vq->avail->ring[vq->num]) 41 + #define vhost_avail_event(vq) ((u16 __user *)&vq->used->ring[vq->num]) 42 + 40 43 static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh, 41 44 poll_table *pt) 42 45 { ··· 164 161 vq->last_avail_idx = 0; 165 162 vq->avail_idx = 0; 166 163 vq->last_used_idx = 0; 164 + vq->signalled_used = 0; 165 + vq->signalled_used_valid = false; 167 166 vq->used_flags = 0; 168 167 vq->log_used = false; 169 168 vq->log_addr = -1ull; ··· 494 489 return 1; 495 490 } 496 491 497 - static int vq_access_ok(unsigned int num, 492 + static int vq_access_ok(struct vhost_dev *d, unsigned int num, 498 493 struct vring_desc __user *desc, 499 494 struct vring_avail __user *avail, 500 495 struct vring_used __user *used) 501 496 { 497 + size_t s = vhost_has_feature(d, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0; 502 498 return access_ok(VERIFY_READ, desc, num * sizeof *desc) && 503 499 access_ok(VERIFY_READ, avail, 504 - sizeof *avail + num * sizeof *avail->ring) && 500 + sizeof *avail + num * sizeof *avail->ring + s) && 505 501 access_ok(VERIFY_WRITE, used, 506 - sizeof *used + num * sizeof *used->ring); 502 + sizeof *used + num * sizeof *used->ring + s); 507 503 } 508 504 509 505 /* Can we log writes? */ ··· 520 514 521 515 /* Verify access for write logging. */ 522 516 /* Caller should have vq mutex and device mutex */ 523 - static int vq_log_access_ok(struct vhost_virtqueue *vq, void __user *log_base) 517 + static int vq_log_access_ok(struct vhost_dev *d, struct vhost_virtqueue *vq, 518 + void __user *log_base) 524 519 { 525 520 struct vhost_memory *mp; 521 + size_t s = vhost_has_feature(d, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0; 526 522 527 523 mp = rcu_dereference_protected(vq->dev->memory, 528 524 lockdep_is_held(&vq->mutex)); ··· 532 524 vhost_has_feature(vq->dev, VHOST_F_LOG_ALL)) && 533 525 (!vq->log_used || log_access_ok(log_base, vq->log_addr, 534 526 sizeof *vq->used + 535 - vq->num * sizeof *vq->used->ring)); 527 + vq->num * sizeof *vq->used->ring + s)); 536 528 } 537 529 538 530 /* Can we start vq? */ 539 531 /* Caller should have vq mutex and device mutex */ 540 532 int vhost_vq_access_ok(struct vhost_virtqueue *vq) 541 533 { 542 - return vq_access_ok(vq->num, vq->desc, vq->avail, vq->used) && 543 - vq_log_access_ok(vq, vq->log_base); 534 + return vq_access_ok(vq->dev, vq->num, vq->desc, vq->avail, vq->used) && 535 + vq_log_access_ok(vq->dev, vq, vq->log_base); 544 536 } 545 537 546 538 static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) ··· 585 577 586 578 if (r) 587 579 return r; 580 + vq->signalled_used_valid = false; 588 581 return get_user(vq->last_used_idx, &used->idx); 589 582 } 590 583 ··· 683 674 * If it is not, we don't as size might not have been setup. 684 675 * We will verify when backend is configured. */ 685 676 if (vq->private_data) { 686 - if (!vq_access_ok(vq->num, 677 + if (!vq_access_ok(d, vq->num, 687 678 (void __user *)(unsigned long)a.desc_user_addr, 688 679 (void __user *)(unsigned long)a.avail_user_addr, 689 680 (void __user *)(unsigned long)a.used_user_addr)) { ··· 827 818 vq = d->vqs + i; 828 819 mutex_lock(&vq->mutex); 829 820 /* If ring is inactive, will check when it's enabled. */ 830 - if (vq->private_data && !vq_log_access_ok(vq, base)) 821 + if (vq->private_data && !vq_log_access_ok(d, vq, base)) 831 822 r = -EFAULT; 832 823 else 833 824 vq->log_base = base; ··· 1228 1219 1229 1220 /* On success, increment avail index. */ 1230 1221 vq->last_avail_idx++; 1222 + 1223 + /* Assume notifications from guest are disabled at this point, 1224 + * if they aren't we would need to update avail_event index. */ 1225 + BUG_ON(!(vq->used_flags & VRING_USED_F_NO_NOTIFY)); 1231 1226 return head; 1232 1227 } 1233 1228 ··· 1280 1267 eventfd_signal(vq->log_ctx, 1); 1281 1268 } 1282 1269 vq->last_used_idx++; 1270 + /* If the driver never bothers to signal in a very long while, 1271 + * used index might wrap around. If that happens, invalidate 1272 + * signalled_used index we stored. TODO: make sure driver 1273 + * signals at least once in 2^16 and remove this. */ 1274 + if (unlikely(vq->last_used_idx == vq->signalled_used)) 1275 + vq->signalled_used_valid = false; 1283 1276 return 0; 1284 1277 } 1285 1278 ··· 1294 1275 unsigned count) 1295 1276 { 1296 1277 struct vring_used_elem __user *used; 1278 + u16 old, new; 1297 1279 int start; 1298 1280 1299 1281 start = vq->last_used_idx % vq->num; ··· 1312 1292 ((void __user *)used - (void __user *)vq->used), 1313 1293 count * sizeof *used); 1314 1294 } 1315 - vq->last_used_idx += count; 1295 + old = vq->last_used_idx; 1296 + new = (vq->last_used_idx += count); 1297 + /* If the driver never bothers to signal in a very long while, 1298 + * used index might wrap around. If that happens, invalidate 1299 + * signalled_used index we stored. TODO: make sure driver 1300 + * signals at least once in 2^16 and remove this. */ 1301 + if (unlikely((u16)(new - vq->signalled_used) < (u16)(new - old))) 1302 + vq->signalled_used_valid = false; 1316 1303 return 0; 1317 1304 } 1318 1305 ··· 1358 1331 return r; 1359 1332 } 1360 1333 1361 - /* This actually signals the guest, using eventfd. */ 1362 - void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq) 1334 + static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) 1363 1335 { 1364 - __u16 flags; 1365 - 1336 + __u16 old, new, event; 1337 + bool v; 1366 1338 /* Flush out used index updates. This is paired 1367 1339 * with the barrier that the Guest executes when enabling 1368 1340 * interrupts. */ 1369 1341 smp_mb(); 1370 1342 1371 - if (__get_user(flags, &vq->avail->flags)) { 1372 - vq_err(vq, "Failed to get flags"); 1373 - return; 1343 + if (vhost_has_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY) && 1344 + unlikely(vq->avail_idx == vq->last_avail_idx)) 1345 + return true; 1346 + 1347 + if (!vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX)) { 1348 + __u16 flags; 1349 + if (__get_user(flags, &vq->avail->flags)) { 1350 + vq_err(vq, "Failed to get flags"); 1351 + return true; 1352 + } 1353 + return !(flags & VRING_AVAIL_F_NO_INTERRUPT); 1374 1354 } 1355 + old = vq->signalled_used; 1356 + v = vq->signalled_used_valid; 1357 + new = vq->signalled_used = vq->last_used_idx; 1358 + vq->signalled_used_valid = true; 1375 1359 1376 - /* If they don't want an interrupt, don't signal, unless empty. */ 1377 - if ((flags & VRING_AVAIL_F_NO_INTERRUPT) && 1378 - (vq->avail_idx != vq->last_avail_idx || 1379 - !vhost_has_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY))) 1380 - return; 1360 + if (unlikely(!v)) 1361 + return true; 1381 1362 1363 + if (get_user(event, vhost_used_event(vq))) { 1364 + vq_err(vq, "Failed to get used event idx"); 1365 + return true; 1366 + } 1367 + return vring_need_event(event, new, old); 1368 + } 1369 + 1370 + /* This actually signals the guest, using eventfd. */ 1371 + void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq) 1372 + { 1382 1373 /* Signal the Guest tell them we used something up. */ 1383 - if (vq->call_ctx) 1374 + if (vq->call_ctx && vhost_notify(dev, vq)) 1384 1375 eventfd_signal(vq->call_ctx, 1); 1385 1376 } 1386 1377 ··· 1421 1376 } 1422 1377 1423 1378 /* OK, now we need to know about added descriptors. */ 1424 - bool vhost_enable_notify(struct vhost_virtqueue *vq) 1379 + bool vhost_enable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) 1425 1380 { 1426 1381 u16 avail_idx; 1427 1382 int r; ··· 1429 1384 if (!(vq->used_flags & VRING_USED_F_NO_NOTIFY)) 1430 1385 return false; 1431 1386 vq->used_flags &= ~VRING_USED_F_NO_NOTIFY; 1432 - r = put_user(vq->used_flags, &vq->used->flags); 1433 - if (r) { 1434 - vq_err(vq, "Failed to enable notification at %p: %d\n", 1435 - &vq->used->flags, r); 1436 - return false; 1387 + if (!vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX)) { 1388 + r = put_user(vq->used_flags, &vq->used->flags); 1389 + if (r) { 1390 + vq_err(vq, "Failed to enable notification at %p: %d\n", 1391 + &vq->used->flags, r); 1392 + return false; 1393 + } 1394 + } else { 1395 + r = put_user(vq->avail_idx, vhost_avail_event(vq)); 1396 + if (r) { 1397 + vq_err(vq, "Failed to update avail event index at %p: %d\n", 1398 + vhost_avail_event(vq), r); 1399 + return false; 1400 + } 1401 + } 1402 + if (unlikely(vq->log_used)) { 1403 + void __user *used; 1404 + /* Make sure data is seen before log. */ 1405 + smp_wmb(); 1406 + used = vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX) ? 1407 + &vq->used->flags : vhost_avail_event(vq); 1408 + /* Log used flags or event index entry write. Both are 16 bit 1409 + * fields. */ 1410 + log_write(vq->log_base, vq->log_addr + 1411 + (used - (void __user *)vq->used), 1412 + sizeof(u16)); 1413 + if (vq->log_ctx) 1414 + eventfd_signal(vq->log_ctx, 1); 1437 1415 } 1438 1416 /* They could have slipped one in as we were doing that: make 1439 1417 * sure it's written, then check again. */ ··· 1472 1404 } 1473 1405 1474 1406 /* We don't need to be notified again. */ 1475 - void vhost_disable_notify(struct vhost_virtqueue *vq) 1407 + void vhost_disable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) 1476 1408 { 1477 1409 int r; 1478 1410 1479 1411 if (vq->used_flags & VRING_USED_F_NO_NOTIFY) 1480 1412 return; 1481 1413 vq->used_flags |= VRING_USED_F_NO_NOTIFY; 1482 - r = put_user(vq->used_flags, &vq->used->flags); 1483 - if (r) 1484 - vq_err(vq, "Failed to enable notification at %p: %d\n", 1485 - &vq->used->flags, r); 1414 + if (!vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX)) { 1415 + r = put_user(vq->used_flags, &vq->used->flags); 1416 + if (r) 1417 + vq_err(vq, "Failed to enable notification at %p: %d\n", 1418 + &vq->used->flags, r); 1419 + } 1486 1420 }
+14 -7
drivers/vhost/vhost.h
··· 84 84 /* Used flags */ 85 85 u16 used_flags; 86 86 87 + /* Last used index value we have signalled on */ 88 + u16 signalled_used; 89 + 90 + /* Last used index value we have signalled on */ 91 + bool signalled_used_valid; 92 + 87 93 /* Log writes to used structure. */ 88 94 bool log_used; 89 95 u64 log_addr; ··· 155 149 void vhost_add_used_and_signal_n(struct vhost_dev *, struct vhost_virtqueue *, 156 150 struct vring_used_elem *heads, unsigned count); 157 151 void vhost_signal(struct vhost_dev *, struct vhost_virtqueue *); 158 - void vhost_disable_notify(struct vhost_virtqueue *); 159 - bool vhost_enable_notify(struct vhost_virtqueue *); 152 + void vhost_disable_notify(struct vhost_dev *, struct vhost_virtqueue *); 153 + bool vhost_enable_notify(struct vhost_dev *, struct vhost_virtqueue *); 160 154 161 155 int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, 162 156 unsigned int log_num, u64 len); ··· 168 162 } while (0) 169 163 170 164 enum { 171 - VHOST_FEATURES = (1 << VIRTIO_F_NOTIFY_ON_EMPTY) | 172 - (1 << VIRTIO_RING_F_INDIRECT_DESC) | 173 - (1 << VHOST_F_LOG_ALL) | 174 - (1 << VHOST_NET_F_VIRTIO_NET_HDR) | 175 - (1 << VIRTIO_NET_F_MRG_RXBUF), 165 + VHOST_FEATURES = (1ULL << VIRTIO_F_NOTIFY_ON_EMPTY) | 166 + (1ULL << VIRTIO_RING_F_INDIRECT_DESC) | 167 + (1ULL << VIRTIO_RING_F_EVENT_IDX) | 168 + (1ULL << VHOST_F_LOG_ALL) | 169 + (1ULL << VHOST_NET_F_VIRTIO_NET_HDR) | 170 + (1ULL << VIRTIO_NET_F_MRG_RXBUF), 176 171 }; 177 172 178 173 static inline int vhost_has_feature(struct vhost_dev *dev, int bit)
+8 -13
drivers/virtio/virtio_balloon.c
··· 40 40 /* Waiting for host to ack the pages we released. */ 41 41 struct completion acked; 42 42 43 - /* Do we have to tell Host *before* we reuse pages? */ 44 - bool tell_host_first; 45 - 46 43 /* The pages we've told the Host we're not using. */ 47 44 unsigned int num_pages; 48 45 struct list_head pages; ··· 148 151 vb->num_pages--; 149 152 } 150 153 151 - if (vb->tell_host_first) { 152 - tell_host(vb, vb->deflate_vq); 153 - release_pages_by_pfn(vb->pfns, vb->num_pfns); 154 - } else { 155 - release_pages_by_pfn(vb->pfns, vb->num_pfns); 156 - tell_host(vb, vb->deflate_vq); 157 - } 154 + 155 + /* 156 + * Note that if 157 + * virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); 158 + * is true, we *have* to do it in this order 159 + */ 160 + tell_host(vb, vb->deflate_vq); 161 + release_pages_by_pfn(vb->pfns, vb->num_pfns); 158 162 } 159 163 160 164 static inline void update_stat(struct virtio_balloon *vb, int idx, ··· 322 324 err = PTR_ERR(vb->thread); 323 325 goto out_del_vqs; 324 326 } 325 - 326 - vb->tell_host_first 327 - = virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); 328 327 329 328 return 0; 330 329
+51 -2
drivers/virtio/virtio_ring.c
··· 82 82 /* Host supports indirect buffers */ 83 83 bool indirect; 84 84 85 + /* Host publishes avail event idx */ 86 + bool event; 87 + 85 88 /* Number of free buffers */ 86 89 unsigned int num_free; 87 90 /* Head of free buffer list. */ ··· 240 237 void virtqueue_kick(struct virtqueue *_vq) 241 238 { 242 239 struct vring_virtqueue *vq = to_vvq(_vq); 240 + u16 new, old; 243 241 START_USE(vq); 244 242 /* Descriptors and available array need to be set before we expose the 245 243 * new available array entries. */ 246 244 virtio_wmb(); 247 245 248 - vq->vring.avail->idx += vq->num_added; 246 + old = vq->vring.avail->idx; 247 + new = vq->vring.avail->idx = old + vq->num_added; 249 248 vq->num_added = 0; 250 249 251 250 /* Need to update avail index before checking if we should notify */ 252 251 virtio_mb(); 253 252 254 - if (!(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY)) 253 + if (vq->event ? 254 + vring_need_event(vring_avail_event(&vq->vring), new, old) : 255 + !(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY)) 255 256 /* Prod other side to tell it about changes. */ 256 257 vq->notify(&vq->vq); 257 258 ··· 331 324 ret = vq->data[i]; 332 325 detach_buf(vq, i); 333 326 vq->last_used_idx++; 327 + /* If we expect an interrupt for the next entry, tell host 328 + * by writing event index and flush out the write before 329 + * the read in the next get_buf call. */ 330 + if (!(vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)) { 331 + vring_used_event(&vq->vring) = vq->last_used_idx; 332 + virtio_mb(); 333 + } 334 + 334 335 END_USE(vq); 335 336 return ret; 336 337 } ··· 360 345 361 346 /* We optimistically turn back on interrupts, then check if there was 362 347 * more to do. */ 348 + /* Depending on the VIRTIO_RING_F_EVENT_IDX feature, we need to 349 + * either clear the flags bit or point the event index at the next 350 + * entry. Always do both to keep code simple. */ 363 351 vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; 352 + vring_used_event(&vq->vring) = vq->last_used_idx; 364 353 virtio_mb(); 365 354 if (unlikely(more_used(vq))) { 366 355 END_USE(vq); ··· 375 356 return true; 376 357 } 377 358 EXPORT_SYMBOL_GPL(virtqueue_enable_cb); 359 + 360 + bool virtqueue_enable_cb_delayed(struct virtqueue *_vq) 361 + { 362 + struct vring_virtqueue *vq = to_vvq(_vq); 363 + u16 bufs; 364 + 365 + START_USE(vq); 366 + 367 + /* We optimistically turn back on interrupts, then check if there was 368 + * more to do. */ 369 + /* Depending on the VIRTIO_RING_F_USED_EVENT_IDX feature, we need to 370 + * either clear the flags bit or point the event index at the next 371 + * entry. Always do both to keep code simple. */ 372 + vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; 373 + /* TODO: tune this threshold */ 374 + bufs = (u16)(vq->vring.avail->idx - vq->last_used_idx) * 3 / 4; 375 + vring_used_event(&vq->vring) = vq->last_used_idx + bufs; 376 + virtio_mb(); 377 + if (unlikely((u16)(vq->vring.used->idx - vq->last_used_idx) > bufs)) { 378 + END_USE(vq); 379 + return false; 380 + } 381 + 382 + END_USE(vq); 383 + return true; 384 + } 385 + EXPORT_SYMBOL_GPL(virtqueue_enable_cb_delayed); 378 386 379 387 void *virtqueue_detach_unused_buf(struct virtqueue *_vq) 380 388 { ··· 484 438 #endif 485 439 486 440 vq->indirect = virtio_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC); 441 + vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX); 487 442 488 443 /* No callback? Tell other side not to bother us. */ 489 444 if (!callback) ··· 518 471 for (i = VIRTIO_TRANSPORT_F_START; i < VIRTIO_TRANSPORT_F_END; i++) { 519 472 switch (i) { 520 473 case VIRTIO_RING_F_INDIRECT_DESC: 474 + break; 475 + case VIRTIO_RING_F_EVENT_IDX: 521 476 break; 522 477 default: 523 478 /* We don't understand this bit. */
+9
include/linux/virtio.h
··· 51 51 * This re-enables callbacks; it returns "false" if there are pending 52 52 * buffers in the queue, to detect a possible race between the driver 53 53 * checking for more work, and enabling callbacks. 54 + * virtqueue_enable_cb_delayed: restart callbacks after disable_cb. 55 + * vq: the struct virtqueue we're talking about. 56 + * This re-enables callbacks but hints to the other side to delay 57 + * interrupts until most of the available buffers have been processed; 58 + * it returns "false" if there are many pending buffers in the queue, 59 + * to detect a possible race between the driver checking for more work, 60 + * and enabling callbacks. 54 61 * virtqueue_detach_unused_buf: detach first unused buffer 55 62 * vq: the struct virtqueue we're talking about. 56 63 * Returns NULL or the "data" token handed to add_buf ··· 92 85 void virtqueue_disable_cb(struct virtqueue *vq); 93 86 94 87 bool virtqueue_enable_cb(struct virtqueue *vq); 88 + 89 + bool virtqueue_enable_cb_delayed(struct virtqueue *vq); 95 90 96 91 void *virtqueue_detach_unused_buf(struct virtqueue *vq); 97 92
+24 -1
include/linux/virtio_9p.h
··· 1 1 #ifndef _LINUX_VIRTIO_9P_H 2 2 #define _LINUX_VIRTIO_9P_H 3 3 /* This header is BSD licensed so anyone can use the definitions to implement 4 - * compatible drivers/servers. */ 4 + * compatible drivers/servers. 5 + * 6 + * Redistribution and use in source and binary forms, with or without 7 + * modification, are permitted provided that the following conditions 8 + * are met: 9 + * 1. Redistributions of source code must retain the above copyright 10 + * notice, this list of conditions and the following disclaimer. 11 + * 2. Redistributions in binary form must reproduce the above copyright 12 + * notice, this list of conditions and the following disclaimer in the 13 + * documentation and/or other materials provided with the distribution. 14 + * 3. Neither the name of IBM nor the names of its contributors 15 + * may be used to endorse or promote products derived from this software 16 + * without specific prior written permission. 17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND 18 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE 21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 + * SUCH DAMAGE. */ 5 28 #include <linux/types.h> 6 29 #include <linux/virtio_ids.h> 7 30 #include <linux/virtio_config.h>
+24 -1
include/linux/virtio_balloon.h
··· 1 1 #ifndef _LINUX_VIRTIO_BALLOON_H 2 2 #define _LINUX_VIRTIO_BALLOON_H 3 3 /* This header is BSD licensed so anyone can use the definitions to implement 4 - * compatible drivers/servers. */ 4 + * compatible drivers/servers. 5 + * 6 + * Redistribution and use in source and binary forms, with or without 7 + * modification, are permitted provided that the following conditions 8 + * are met: 9 + * 1. Redistributions of source code must retain the above copyright 10 + * notice, this list of conditions and the following disclaimer. 11 + * 2. Redistributions in binary form must reproduce the above copyright 12 + * notice, this list of conditions and the following disclaimer in the 13 + * documentation and/or other materials provided with the distribution. 14 + * 3. Neither the name of IBM nor the names of its contributors 15 + * may be used to endorse or promote products derived from this software 16 + * without specific prior written permission. 17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND 18 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE 21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 + * SUCH DAMAGE. */ 5 28 #include <linux/virtio_ids.h> 6 29 #include <linux/virtio_config.h> 7 30
+24 -1
include/linux/virtio_blk.h
··· 1 1 #ifndef _LINUX_VIRTIO_BLK_H 2 2 #define _LINUX_VIRTIO_BLK_H 3 3 /* This header is BSD licensed so anyone can use the definitions to implement 4 - * compatible drivers/servers. */ 4 + * compatible drivers/servers. 5 + * 6 + * Redistribution and use in source and binary forms, with or without 7 + * modification, are permitted provided that the following conditions 8 + * are met: 9 + * 1. Redistributions of source code must retain the above copyright 10 + * notice, this list of conditions and the following disclaimer. 11 + * 2. Redistributions in binary form must reproduce the above copyright 12 + * notice, this list of conditions and the following disclaimer in the 13 + * documentation and/or other materials provided with the distribution. 14 + * 3. Neither the name of IBM nor the names of its contributors 15 + * may be used to endorse or promote products derived from this software 16 + * without specific prior written permission. 17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND 18 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE 21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 + * SUCH DAMAGE. */ 5 28 #include <linux/types.h> 6 29 #include <linux/virtio_ids.h> 7 30 #include <linux/virtio_config.h>
+24 -1
include/linux/virtio_config.h
··· 1 1 #ifndef _LINUX_VIRTIO_CONFIG_H 2 2 #define _LINUX_VIRTIO_CONFIG_H 3 3 /* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so 4 - * anyone can use the definitions to implement compatible drivers/servers. */ 4 + * anyone can use the definitions to implement compatible drivers/servers. 5 + * 6 + * Redistribution and use in source and binary forms, with or without 7 + * modification, are permitted provided that the following conditions 8 + * are met: 9 + * 1. Redistributions of source code must retain the above copyright 10 + * notice, this list of conditions and the following disclaimer. 11 + * 2. Redistributions in binary form must reproduce the above copyright 12 + * notice, this list of conditions and the following disclaimer in the 13 + * documentation and/or other materials provided with the distribution. 14 + * 3. Neither the name of IBM nor the names of its contributors 15 + * may be used to endorse or promote products derived from this software 16 + * without specific prior written permission. 17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND 18 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE 21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 + * SUCH DAMAGE. */ 5 28 6 29 /* Virtio devices use a standardized configuration space to define their 7 30 * features and pass configuration information, but each implementation can
+25 -1
include/linux/virtio_console.h
··· 5 5 #include <linux/virtio_config.h> 6 6 /* 7 7 * This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so 8 - * anyone can use the definitions to implement compatible drivers/servers. 8 + * anyone can use the definitions to implement compatible drivers/servers: 9 + * 10 + * 11 + * Redistribution and use in source and binary forms, with or without 12 + * modification, are permitted provided that the following conditions 13 + * are met: 14 + * 1. Redistributions of source code must retain the above copyright 15 + * notice, this list of conditions and the following disclaimer. 16 + * 2. Redistributions in binary form must reproduce the above copyright 17 + * notice, this list of conditions and the following disclaimer in the 18 + * documentation and/or other materials provided with the distribution. 19 + * 3. Neither the name of IBM nor the names of its contributors 20 + * may be used to endorse or promote products derived from this software 21 + * without specific prior written permission. 22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND 23 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE 26 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 + * SUCH DAMAGE. 9 33 * 10 34 * Copyright (C) Red Hat, Inc., 2009, 2010, 2011 11 35 * Copyright (C) Amit Shah <amit.shah@redhat.com>, 2009, 2010, 2011
+23 -1
include/linux/virtio_ids.h
··· 5 5 * 6 6 * This header is BSD licensed so anyone can use the definitions to implement 7 7 * compatible drivers/servers. 8 - */ 8 + * 9 + * Redistribution and use in source and binary forms, with or without 10 + * modification, are permitted provided that the following conditions 11 + * are met: 12 + * 1. Redistributions of source code must retain the above copyright 13 + * notice, this list of conditions and the following disclaimer. 14 + * 2. Redistributions in binary form must reproduce the above copyright 15 + * notice, this list of conditions and the following disclaimer in the 16 + * documentation and/or other materials provided with the distribution. 17 + * 3. Neither the name of IBM nor the names of its contributors 18 + * may be used to endorse or promote products derived from this software 19 + * without specific prior written permission. 20 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND 21 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE 24 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 + * SUCH DAMAGE. */ 9 31 10 32 #define VIRTIO_ID_NET 1 /* virtio net */ 11 33 #define VIRTIO_ID_BLOCK 2 /* virtio block */
+24 -1
include/linux/virtio_net.h
··· 1 1 #ifndef _LINUX_VIRTIO_NET_H 2 2 #define _LINUX_VIRTIO_NET_H 3 3 /* This header is BSD licensed so anyone can use the definitions to implement 4 - * compatible drivers/servers. */ 4 + * compatible drivers/servers. 5 + * 6 + * Redistribution and use in source and binary forms, with or without 7 + * modification, are permitted provided that the following conditions 8 + * are met: 9 + * 1. Redistributions of source code must retain the above copyright 10 + * notice, this list of conditions and the following disclaimer. 11 + * 2. Redistributions in binary form must reproduce the above copyright 12 + * notice, this list of conditions and the following disclaimer in the 13 + * documentation and/or other materials provided with the distribution. 14 + * 3. Neither the name of IBM nor the names of its contributors 15 + * may be used to endorse or promote products derived from this software 16 + * without specific prior written permission. 17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND 18 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE 21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 + * SUCH DAMAGE. */ 5 28 #include <linux/types.h> 6 29 #include <linux/virtio_ids.h> 7 30 #include <linux/virtio_config.h>
+23
include/linux/virtio_pci.h
··· 11 11 * 12 12 * This header is BSD licensed so anyone can use the definitions to implement 13 13 * compatible drivers/servers. 14 + * 15 + * Redistribution and use in source and binary forms, with or without 16 + * modification, are permitted provided that the following conditions 17 + * are met: 18 + * 1. Redistributions of source code must retain the above copyright 19 + * notice, this list of conditions and the following disclaimer. 20 + * 2. Redistributions in binary form must reproduce the above copyright 21 + * notice, this list of conditions and the following disclaimer in the 22 + * documentation and/or other materials provided with the distribution. 23 + * 3. Neither the name of IBM nor the names of its contributors 24 + * may be used to endorse or promote products derived from this software 25 + * without specific prior written permission. 26 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND 27 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE 30 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 + * SUCH DAMAGE. 14 37 */ 15 38 16 39 #ifndef _LINUX_VIRTIO_PCI_H
+51 -1
include/linux/virtio_ring.h
··· 7 7 * This header is BSD licensed so anyone can use the definitions to implement 8 8 * compatible drivers/servers. 9 9 * 10 + * Redistribution and use in source and binary forms, with or without 11 + * modification, are permitted provided that the following conditions 12 + * are met: 13 + * 1. Redistributions of source code must retain the above copyright 14 + * notice, this list of conditions and the following disclaimer. 15 + * 2. Redistributions in binary form must reproduce the above copyright 16 + * notice, this list of conditions and the following disclaimer in the 17 + * documentation and/or other materials provided with the distribution. 18 + * 3. Neither the name of IBM nor the names of its contributors 19 + * may be used to endorse or promote products derived from this software 20 + * without specific prior written permission. 21 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND 22 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE 25 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 + * SUCH DAMAGE. 32 + * 10 33 * Copyright Rusty Russell IBM Corporation 2007. */ 11 34 #include <linux/types.h> 12 35 ··· 51 28 52 29 /* We support indirect buffer descriptors */ 53 30 #define VIRTIO_RING_F_INDIRECT_DESC 28 31 + 32 + /* The Guest publishes the used index for which it expects an interrupt 33 + * at the end of the avail ring. Host should ignore the avail->flags field. */ 34 + /* The Host publishes the avail index for which it expects a kick 35 + * at the end of the used ring. Guest should ignore the used->flags field. */ 36 + #define VIRTIO_RING_F_EVENT_IDX 29 54 37 55 38 /* Virtio ring descriptors: 16 bytes. These can chain together via "next". */ 56 39 struct vring_desc { ··· 112 83 * __u16 avail_flags; 113 84 * __u16 avail_idx; 114 85 * __u16 available[num]; 86 + * __u16 used_event_idx; 115 87 * 116 88 * // Padding to the next align boundary. 117 89 * char pad[]; ··· 121 91 * __u16 used_flags; 122 92 * __u16 used_idx; 123 93 * struct vring_used_elem used[num]; 94 + * __u16 avail_event_idx; 124 95 * }; 125 96 */ 97 + /* We publish the used event index at the end of the available ring, and vice 98 + * versa. They are at the end for backwards compatibility. */ 99 + #define vring_used_event(vr) ((vr)->avail->ring[(vr)->num]) 100 + #define vring_avail_event(vr) (*(__u16 *)&(vr)->used->ring[(vr)->num]) 101 + 126 102 static inline void vring_init(struct vring *vr, unsigned int num, void *p, 127 103 unsigned long align) 128 104 { ··· 143 107 { 144 108 return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (2 + num) 145 109 + align - 1) & ~(align - 1)) 146 - + sizeof(__u16) * 2 + sizeof(struct vring_used_elem) * num; 110 + + sizeof(__u16) * 3 + sizeof(struct vring_used_elem) * num; 111 + } 112 + 113 + /* The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX */ 114 + /* Assuming a given event_idx value from the other size, if 115 + * we have just incremented index from old to new_idx, 116 + * should we trigger an event? */ 117 + static inline int vring_need_event(__u16 event_idx, __u16 new_idx, __u16 old) 118 + { 119 + /* Note: Xen has similar logic for notification hold-off 120 + * in include/xen/interface/io/ring.h with req_event and req_prod 121 + * corresponding to event_idx + 1 and new_idx respectively. 122 + * Note also that req_event and req_prod in Xen start at 1, 123 + * event indexes in virtio start at 0. */ 124 + return (__u16)(new_idx - event_idx - 1) < (__u16)(new_idx - old); 147 125 } 148 126 149 127 #ifdef __KERNEL__
+17 -2
tools/virtio/virtio_test.c
··· 198 198 .val = 'h', 199 199 }, 200 200 { 201 + .name = "event-idx", 202 + .val = 'E', 203 + }, 204 + { 205 + .name = "no-event-idx", 206 + .val = 'e', 207 + }, 208 + { 201 209 .name = "indirect", 202 210 .val = 'I', 203 211 }, ··· 219 211 220 212 static void help() 221 213 { 222 - fprintf(stderr, "Usage: virtio_test [--help] [--no-indirect]\n"); 214 + fprintf(stderr, "Usage: virtio_test [--help]" 215 + " [--no-indirect]" 216 + " [--no-event-idx]" 217 + "\n"); 223 218 } 224 219 225 220 int main(int argc, char **argv) 226 221 { 227 222 struct vdev_info dev; 228 - unsigned long long features = 1ULL << VIRTIO_RING_F_INDIRECT_DESC; 223 + unsigned long long features = (1ULL << VIRTIO_RING_F_INDIRECT_DESC) | 224 + (1ULL << VIRTIO_RING_F_EVENT_IDX); 229 225 int o; 230 226 231 227 for (;;) { ··· 240 228 case '?': 241 229 help(); 242 230 exit(2); 231 + case 'e': 232 + features &= ~(1ULL << VIRTIO_RING_F_EVENT_IDX); 233 + break; 243 234 case 'h': 244 235 help(); 245 236 goto done;