From 3afe3e0f8db10a41a5923e1d7498318877473f33 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 13 Feb 2015 17:13:42 +1030 Subject: [PATCH] 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 --- tools/lguest/lguest.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c index 80dc6346030e..990671e61f87 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 -- 2.39.5