diff options
Diffstat (limited to 'Documentation/lguest/lguest.c')
-rw-r--r-- | Documentation/lguest/lguest.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index 5470b8ed2149..84c471b07c27 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c | |||
@@ -551,6 +551,21 @@ static unsigned next_desc(struct virtqueue *vq, unsigned int i) | |||
551 | return next; | 551 | return next; |
552 | } | 552 | } |
553 | 553 | ||
554 | /* This actually sends the interrupt for this virtqueue */ | ||
555 | static void trigger_irq(struct virtqueue *vq) | ||
556 | { | ||
557 | unsigned long buf[] = { LHREQ_IRQ, vq->config.irq }; | ||
558 | |||
559 | /* If they don't want an interrupt, don't send one, unless empty. */ | ||
560 | if ((vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) | ||
561 | && lg_last_avail(vq) != vq->vring.avail->idx) | ||
562 | return; | ||
563 | |||
564 | /* Send the Guest an interrupt tell them we used something up. */ | ||
565 | if (write(lguest_fd, buf, sizeof(buf)) != 0) | ||
566 | err(1, "Triggering irq %i", vq->config.irq); | ||
567 | } | ||
568 | |||
554 | /* This looks in the virtqueue and for the first available buffer, and converts | 569 | /* This looks in the virtqueue and for the first available buffer, and converts |
555 | * it to an iovec for convenient access. Since descriptors consist of some | 570 | * it to an iovec for convenient access. Since descriptors consist of some |
556 | * number of output then some number of input descriptors, it's actually two | 571 | * number of output then some number of input descriptors, it's actually two |
@@ -567,6 +582,9 @@ static unsigned wait_for_vq_desc(struct virtqueue *vq, | |||
567 | while (last_avail == vq->vring.avail->idx) { | 582 | while (last_avail == vq->vring.avail->idx) { |
568 | u64 event; | 583 | u64 event; |
569 | 584 | ||
585 | /* OK, tell Guest about progress up to now. */ | ||
586 | trigger_irq(vq); | ||
587 | |||
570 | /* Nothing new? Wait for eventfd to tell us they refilled. */ | 588 | /* Nothing new? Wait for eventfd to tell us they refilled. */ |
571 | if (read(vq->eventfd, &event, sizeof(event)) != sizeof(event)) | 589 | if (read(vq->eventfd, &event, sizeof(event)) != sizeof(event)) |
572 | errx(1, "Event read failed?"); | 590 | errx(1, "Event read failed?"); |
@@ -631,21 +649,6 @@ static void add_used(struct virtqueue *vq, unsigned int head, int len) | |||
631 | vq->vring.used->idx++; | 649 | vq->vring.used->idx++; |
632 | } | 650 | } |
633 | 651 | ||
634 | /* This actually sends the interrupt for this virtqueue */ | ||
635 | static void trigger_irq(struct virtqueue *vq) | ||
636 | { | ||
637 | unsigned long buf[] = { LHREQ_IRQ, vq->config.irq }; | ||
638 | |||
639 | /* If they don't want an interrupt, don't send one, unless empty. */ | ||
640 | if ((vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) | ||
641 | && lg_last_avail(vq) != vq->vring.avail->idx) | ||
642 | return; | ||
643 | |||
644 | /* Send the Guest an interrupt tell them we used something up. */ | ||
645 | if (write(lguest_fd, buf, sizeof(buf)) != 0) | ||
646 | err(1, "Triggering irq %i", vq->config.irq); | ||
647 | } | ||
648 | |||
649 | /* And here's the combo meal deal. Supersize me! */ | 652 | /* And here's the combo meal deal. Supersize me! */ |
650 | static void add_used_and_trigger(struct virtqueue *vq, unsigned head, int len) | 653 | static void add_used_and_trigger(struct virtqueue *vq, unsigned head, int len) |
651 | { | 654 | { |
@@ -730,7 +733,7 @@ static void console_output(struct virtqueue *vq) | |||
730 | err(1, "Write to stdout gave %i", len); | 733 | err(1, "Write to stdout gave %i", len); |
731 | iov_consume(iov, out, len); | 734 | iov_consume(iov, out, len); |
732 | } | 735 | } |
733 | add_used_and_trigger(vq, head, 0); | 736 | add_used(vq, head, 0); |
734 | } | 737 | } |
735 | 738 | ||
736 | /* | 739 | /* |
@@ -754,7 +757,7 @@ static void net_output(struct virtqueue *vq) | |||
754 | errx(1, "Input buffers in net output queue?"); | 757 | errx(1, "Input buffers in net output queue?"); |
755 | if (writev(net_info->tunfd, iov, out) < 0) | 758 | if (writev(net_info->tunfd, iov, out) < 0) |
756 | errx(1, "Write to tun failed?"); | 759 | errx(1, "Write to tun failed?"); |
757 | add_used_and_trigger(vq, head, 0); | 760 | add_used(vq, head, 0); |
758 | } | 761 | } |
759 | 762 | ||
760 | /* This is where we handle packets coming in from the tun device to our | 763 | /* This is where we handle packets coming in from the tun device to our |
@@ -1422,7 +1425,7 @@ static void blk_request(struct virtqueue *vq) | |||
1422 | if (out->type & VIRTIO_BLK_T_BARRIER) | 1425 | if (out->type & VIRTIO_BLK_T_BARRIER) |
1423 | fdatasync(vblk->fd); | 1426 | fdatasync(vblk->fd); |
1424 | 1427 | ||
1425 | add_used_and_trigger(vq, head, wlen); | 1428 | add_used(vq, head, wlen); |
1426 | } | 1429 | } |
1427 | 1430 | ||
1428 | /*L:198 This actually sets up a virtual block device. */ | 1431 | /*L:198 This actually sets up a virtual block device. */ |
@@ -1496,7 +1499,7 @@ static void rng_input(struct virtqueue *vq) | |||
1496 | } | 1499 | } |
1497 | 1500 | ||
1498 | /* Tell the Guest about the new input. */ | 1501 | /* Tell the Guest about the new input. */ |
1499 | add_used_and_trigger(vq, head, totlen); | 1502 | add_used(vq, head, totlen); |
1500 | } | 1503 | } |
1501 | 1504 | ||
1502 | /* And this creates a "hardware" random number device for the Guest. */ | 1505 | /* And this creates a "hardware" random number device for the Guest. */ |