Revision efeea6d0 hw/virtio.c

b/hw/virtio.c
293 293

  
294 294
int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes)
295 295
{
296
    target_phys_addr_t desc_pa = vq->vring.desc;
297
    unsigned int idx, max;
298
    int num_bufs, in_total, out_total;
296
    unsigned int idx;
297
    int total_bufs, in_total, out_total;
299 298

  
300 299
    idx = vq->last_avail_idx;
301
    max = vq->vring.num;
302 300

  
303
    num_bufs = in_total = out_total = 0;
301
    total_bufs = in_total = out_total = 0;
304 302
    while (virtqueue_num_heads(vq, idx)) {
303
        unsigned int max, num_bufs, indirect = 0;
304
        target_phys_addr_t desc_pa;
305 305
        int i;
306 306

  
307
        max = vq->vring.num;
308
        num_bufs = total_bufs;
307 309
        i = virtqueue_get_head(vq, idx++);
310
        desc_pa = vq->vring.desc;
311

  
312
        if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_INDIRECT) {
313
            if (vring_desc_len(desc_pa, i) % sizeof(VRingDesc)) {
314
                fprintf(stderr, "Invalid size for indirect buffer table\n");
315
                exit(1);
316
            }
317

  
318
            /* If we've got too many, that implies a descriptor loop. */
319
            if (num_bufs >= max) {
320
                fprintf(stderr, "Looped descriptor");
321
                exit(1);
322
            }
323

  
324
            /* loop over the indirect descriptor table */
325
            indirect = 1;
326
            max = vring_desc_len(desc_pa, i) / sizeof(VRingDesc);
327
            num_bufs = i = 0;
328
            desc_pa = vring_desc_addr(desc_pa, i);
329
        }
330

  
308 331
        do {
309 332
            /* If we've got too many, that implies a descriptor loop. */
310 333
            if (++num_bufs > max) {
......
322 345
                    return 1;
323 346
            }
324 347
        } while ((i = virtqueue_next_desc(desc_pa, i, max)) != max);
348

  
349
        if (!indirect)
350
            total_bufs = num_bufs;
351
        else
352
            total_bufs++;
325 353
    }
326 354

  
327 355
    return 0;
......
342 370
    max = vq->vring.num;
343 371

  
344 372
    i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
373

  
374
    if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_INDIRECT) {
375
        if (vring_desc_len(desc_pa, i) % sizeof(VRingDesc)) {
376
            fprintf(stderr, "Invalid size for indirect buffer table\n");
377
            exit(1);
378
        }
379

  
380
        /* loop over the indirect descriptor table */
381
        max = vring_desc_len(desc_pa, i) / sizeof(VRingDesc);
382
        desc_pa = vring_desc_addr(desc_pa, i);
383
        i = 0;
384
    }
385

  
345 386
    do {
346 387
        struct iovec *sg;
347 388
        int is_write = 0;

Also available in: Unified diff