Am 28.10.2015 um 10:17 schrieb Andy Lutomirski: @@ -423,27 +522,42 @@ EXPORT_SYMBOL_GPL(virtqueue_kick); > > static void detach_buf(struct vring_virtqueue *vq, unsigned int head) > { > - unsigned int i; > + unsigned int i, j; > + u16 nextflag = cpu_to_virtio16(vq->vq.vdev, VRING_DESC_F_NEXT); > > /* Clear data ptr. */ > - vq->data[head] = NULL; > + vq->desc_state[head].data = NULL; > > - /* Put back on free list: find end */ > + /* Put back on free list: unmap first-level descriptors and find end */ > i = head; > > - /* Free the indirect table */ > - if (vq->vring.desc[i].flags & cpu_to_virtio16(vq->vq.vdev, VRING_DESC_F_INDIRECT)) > - kfree(phys_to_virt(virtio64_to_cpu(vq->vq.vdev, vq->vring.desc[i].addr))); > - > - while (vq->vring.desc[i].flags & cpu_to_virtio16(vq->vq.vdev, VRING_DESC_F_NEXT)) { > + while (vq->vring.desc[i].flags & nextflag) { > + vring_unmap_one(vq, &vq->vring.desc[i]); > i = virtio16_to_cpu(vq->vq.vdev, vq->vring.desc[i].next); > vq->vq.num_free++; > } > > + vring_unmap_one(vq, &vq->vring.desc[i]); > vq->vring.desc[i].next = cpu_to_virtio16(vq->vq.vdev, vq->free_head); > vq->free_head = head; > + > /* Plus final descriptor */ > vq->vq.num_free++; > + > + /* Free the indirect table, if any, now that it's unmapped. */ > + if (vq->desc_state[head].indir_desc) { > + struct vring_desc *indir_desc = vq->desc_state[head].indir_desc; > + u32 len = vq->vring.desc[head].len; > + > + BUG_ON(!(vq->vring.desc[head].flags & VRING_DESC_F_INDIRECT)); > + BUG_ON(len == 0 || len % sizeof(struct vring_desc)); > + > + for (j = 0; j < len / sizeof(struct vring_desc); j++) > + vring_unmap_one(vq, &indir_desc[j]); > + > + kfree(vq->desc_state[head].indir_desc); > + vq->desc_state[head].indir_desc = NULL; > + } > } something seems to be broken with indirect descriptors with that change [ 1.885451] ------------[ cut here ]------------ [ 1.885454] kernel BUG at drivers/virtio/virtio_ring.c:552! [ 1.885487] illegal operation: 0001 ilc:1 [#1] SMP [ 1.885489] Modules linked in: [ 1.885491] CPU: 0 PID: 2 Comm: kthreadd Not tainted 4.3.0-rc3+ #250 [ 1.885493] task: 000000000be49988 ti: 000000000be54000 task.ti: 000000000be54000 [ 1.885514] Krnl PSW : 0404c00180000000 000000000059b9d2 (detach_buf+0x1ca/0x1d0) [ 1.885519] R:0 T:1 IO:0 EX:0 Key:0 M:1 W:0 P:0 AS:3 CC:0 PM:0 EA:3 Krnl GPRS: 0000000000000000 0000000030000000 000000000c0c8c00 000000000a89c000 [ 1.885522] 000000000059b8fa 0000000000000001 0000000000000000 0000000000000000 [ 1.885523] 0000000000000000 0000000000000000 0000000000000100 000000000a89c000 [ 1.885525] 000000000c082000 000000000c082000 000000000059b8fa 000000000c7fbc88 [ 1.885531] Krnl Code: 000000000059b9c6: a7f4ff40 brc 15,59b846 000000000059b9ca: a7f40001 brc 15,59b9cc #000000000059b9ce: a7f40001 brc 15,59b9d0 >000000000059b9d2: 0707 bcr 0,%r7 000000000059b9d4: 0707 bcr 0,%r7 000000000059b9d6: 0707 bcr 0,%r7 000000000059b9d8: c00400000000 brcl 0,59b9d8 000000000059b9de: ebcff0780024 stmg %r12,%r15,120(%r15) [ 1.885542] Call Trace: [ 1.885544] ([<000000000059b8fa>] detach_buf+0xf2/0x1d0) [ 1.885546] [<000000000059bbb4>] virtqueue_get_buf+0xcc/0x218 [ 1.885549] [<00000000005dd8fe>] virtblk_done+0xa6/0x120 [ 1.885550] [<000000000059b66e>] vring_interrupt+0x7e/0x108 [ 1.885552] [<00000000006c21a4>] virtio_airq_handler+0x7c/0x120 [ 1.885554] [<0000000000657e54>] do_airq_interrupt+0xa4/0xc8 [ 1.885558] [<00000000001b79a0>] handle_irq_event_percpu+0x60/0x1f0 [ 1.885560] [<00000000001bbbea>] handle_percpu_irq+0x72/0xa0 [ 1.885561] [<00000000001b6fa4>] generic_handle_irq+0x4c/0x78 [ 1.885564] [<000000000010cc7c>] do_IRQ+0x64/0x88 [ 1.885566] Btrfs loaded [ 1.885600] [<000000000080e30a>] io_int_handler+0x10a/0x218 [ 1.885603] [<0000000000186b9e>] wake_up_new_task+0x1be/0x260 [ 1.885604] ([<0000000000186b6a>] wake_up_new_task+0x18a/0x260) [ 1.885606] [<0000000000156182>] _do_fork+0xfa/0x338 [ 1.885608] [<000000000015644e>] kernel_thread+0x4e/0x60 [ 1.885609] [<0000000000179202>] kthreadd+0x1a2/0x238 [ 1.885611] [<000000000080e056>] kernel_thread_starter+0x6/0xc [ 1.885613] [<000000000080e050>] kernel_thread_starter+0x0/0xc [ 1.885614] Last Breaking-Event-Address: [ 1.885615] [<000000000059b9ce>] detach_buf+0x1c6/0x1d0 [ 1.885617] [ 1.885618] Kernel panic - not syncing: Fatal exception in interrupt -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html