diff options
| -rw-r--r-- | Documentation/lguest/lguest.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index a1fca9db788e..31a688e105ca 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c | |||
| @@ -191,6 +191,9 @@ static void *_convert(struct iovec *iov, size_t size, size_t align, | |||
| 191 | return iov->iov_base; | 191 | return iov->iov_base; |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | /* Wrapper for the last available index. Makes it easier to change. */ | ||
| 195 | #define lg_last_avail(vq) ((vq)->last_avail_idx) | ||
| 196 | |||
| 194 | /* The virtio configuration space is defined to be little-endian. x86 is | 197 | /* The virtio configuration space is defined to be little-endian. x86 is |
| 195 | * little-endian too, but it's nice to be explicit so we have these helpers. */ | 198 | * little-endian too, but it's nice to be explicit so we have these helpers. */ |
| 196 | #define cpu_to_le16(v16) (v16) | 199 | #define cpu_to_le16(v16) (v16) |
| @@ -690,19 +693,22 @@ static unsigned get_vq_desc(struct virtqueue *vq, | |||
| 690 | unsigned int *out_num, unsigned int *in_num) | 693 | unsigned int *out_num, unsigned int *in_num) |
| 691 | { | 694 | { |
| 692 | unsigned int i, head; | 695 | unsigned int i, head; |
| 696 | u16 last_avail; | ||
| 693 | 697 | ||
| 694 | /* Check it isn't doing very strange things with descriptor numbers. */ | 698 | /* Check it isn't doing very strange things with descriptor numbers. */ |
| 695 | if ((u16)(vq->vring.avail->idx - vq->last_avail_idx) > vq->vring.num) | 699 | last_avail = lg_last_avail(vq); |
| 700 | if ((u16)(vq->vring.avail->idx - last_avail) > vq->vring.num) | ||
| 696 | errx(1, "Guest moved used index from %u to %u", | 701 | errx(1, "Guest moved used index from %u to %u", |
| 697 | vq->last_avail_idx, vq->vring.avail->idx); | 702 | last_avail, vq->vring.avail->idx); |
| 698 | 703 | ||
| 699 | /* If there's nothing new since last we looked, return invalid. */ | 704 | /* If there's nothing new since last we looked, return invalid. */ |
| 700 | if (vq->vring.avail->idx == vq->last_avail_idx) | 705 | if (vq->vring.avail->idx == last_avail) |
| 701 | return vq->vring.num; | 706 | return vq->vring.num; |
| 702 | 707 | ||
| 703 | /* Grab the next descriptor number they're advertising, and increment | 708 | /* Grab the next descriptor number they're advertising, and increment |
| 704 | * the index we've seen. */ | 709 | * the index we've seen. */ |
| 705 | head = vq->vring.avail->ring[vq->last_avail_idx++ % vq->vring.num]; | 710 | head = vq->vring.avail->ring[last_avail % vq->vring.num]; |
| 711 | lg_last_avail(vq)++; | ||
| 706 | 712 | ||
| 707 | /* If their number is silly, that's a fatal mistake. */ | 713 | /* If their number is silly, that's a fatal mistake. */ |
| 708 | if (head >= vq->vring.num) | 714 | if (head >= vq->vring.num) |
| @@ -980,7 +986,7 @@ static void update_device_status(struct device *dev) | |||
| 980 | for (vq = dev->vq; vq; vq = vq->next) { | 986 | for (vq = dev->vq; vq; vq = vq->next) { |
| 981 | memset(vq->vring.desc, 0, | 987 | memset(vq->vring.desc, 0, |
| 982 | vring_size(vq->config.num, getpagesize())); | 988 | vring_size(vq->config.num, getpagesize())); |
| 983 | vq->last_avail_idx = 0; | 989 | lg_last_avail(vq) = 0; |
| 984 | } | 990 | } |
| 985 | } else if (dev->desc->status & VIRTIO_CONFIG_S_FAILED) { | 991 | } else if (dev->desc->status & VIRTIO_CONFIG_S_FAILED) { |
| 986 | warnx("Device %s configuration FAILED", dev->name); | 992 | warnx("Device %s configuration FAILED", dev->name); |
