diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2015-02-13 06:43:42 (GMT) |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2015-02-13 06:45:50 (GMT) |
commit | 3afe3e0f8db10a41a5923e1d7498318877473f33 (patch) | |
tree | 4da04fb2dde7e05c298e8a481c6cc5d6eb096c69 | |
parent | c97eb679ef70dbb4482e66b9d192fc9e5bc6e0d6 (diff) | |
download | linux-3afe3e0f8db10a41a5923e1d7498318877473f33.tar.xz |
tools/lguest: handle indirect partway through chain.
Linux doesn't generate these, but it's perfectly valid according to
a close reading of the spec. I opened virtio spec bug VIRTIO-134 to
make this clearer there, too.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r-- | tools/lguest/lguest.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c index 80dc634..990671e 100644 --- a/tools/lguest/lguest.c +++ b/tools/lguest/lguest.c @@ -769,20 +769,21 @@ static unsigned wait_for_vq_desc(struct virtqueue *vq, * that: no rmb() required. */ - /* - * If this is an indirect entry, then this buffer contains a descriptor - * table which we handle as if it's any normal descriptor chain. - */ - if (desc[i].flags & VRING_DESC_F_INDIRECT) { - if (desc[i].len % sizeof(struct vring_desc)) - errx(1, "Invalid size for indirect buffer table"); + do { + /* + * If this is an indirect entry, then this buffer contains a + * descriptor table which we handle as if it's any normal + * descriptor chain. + */ + if (desc[i].flags & VRING_DESC_F_INDIRECT) { + if (desc[i].len % sizeof(struct vring_desc)) + errx(1, "Invalid size for indirect buffer table"); - max = desc[i].len / sizeof(struct vring_desc); - desc = check_pointer(desc[i].addr, desc[i].len); - i = 0; - } + max = desc[i].len / sizeof(struct vring_desc); + desc = check_pointer(desc[i].addr, desc[i].len); + i = 0; + } - do { /* Grab the first descriptor, and check it's OK. */ iov[*out_num + *in_num].iov_len = desc[i].len; iov[*out_num + *in_num].iov_base |