diff options
Diffstat (limited to 'drivers/vhost/vringh.c')
-rw-r--r-- | drivers/vhost/vringh.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c index 4653de001e26..264cbe385a63 100644 --- a/drivers/vhost/vringh.c +++ b/drivers/vhost/vringh.c @@ -264,7 +264,7 @@ __vringh_iov(struct vringh *vrh, u16 i, gfp_t gfp, int (*copy)(void *dst, const void *src, size_t len)) { - int err, count = 0, up_next, desc_max; + int err, count = 0, indirect_count = 0, up_next, desc_max; struct vring_desc desc, *descs; struct vringh_range range = { -1ULL, 0 }, slowrange; bool slow = false; @@ -321,7 +321,12 @@ __vringh_iov(struct vringh *vrh, u16 i, continue; } - if (count++ == vrh->vring.num) { + if (up_next == -1) + count++; + else + indirect_count++; + + if (count > vrh->vring.num || indirect_count > desc_max) { vringh_bad("Descriptor loop in %p", descs); err = -ELOOP; goto fail; @@ -383,6 +388,7 @@ __vringh_iov(struct vringh *vrh, u16 i, i = return_from_indirect(vrh, &up_next, &descs, &desc_max); slow = false; + indirect_count = 0; } else break; } |