mirror of https://github.com/xemu-project/xemu.git
dataplane: do not free VirtQueueElement in vring_push()
VirtQueueElement is allocated in vring_pop() so it seems to make sense that vring_push() should free it. Alas, virtio-blk frees VirtQueueElement itself in virtio_blk_free_request(). This patch solves a double-free assertion in glib's g_slice_free(). Rename vring_free_element() to vring_unmap_element() since it no longer frees the VirtQueueElement. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Tested-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
0a21ea3289
commit
abd764250f
|
@ -272,7 +272,7 @@ static int get_indirect(Vring *vring, VirtQueueElement *elem,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vring_free_element(VirtQueueElement *elem)
|
static void vring_unmap_element(VirtQueueElement *elem)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -287,8 +287,6 @@ void vring_free_element(VirtQueueElement *elem)
|
||||||
for (i = 0; i < elem->in_num; i++) {
|
for (i = 0; i < elem->in_num; i++) {
|
||||||
vring_unmap(elem->in_sg[i].iov_base, true);
|
vring_unmap(elem->in_sg[i].iov_base, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_slice_free(VirtQueueElement, elem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This looks in the virtqueue and for the first available buffer, and converts
|
/* This looks in the virtqueue and for the first available buffer, and converts
|
||||||
|
@ -402,7 +400,8 @@ out:
|
||||||
vring->broken = true;
|
vring->broken = true;
|
||||||
}
|
}
|
||||||
if (elem) {
|
if (elem) {
|
||||||
vring_free_element(elem);
|
vring_unmap_element(elem);
|
||||||
|
g_slice_free(VirtQueueElement, elem);
|
||||||
}
|
}
|
||||||
*p_elem = NULL;
|
*p_elem = NULL;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -418,7 +417,7 @@ void vring_push(Vring *vring, VirtQueueElement *elem, int len)
|
||||||
unsigned int head = elem->index;
|
unsigned int head = elem->index;
|
||||||
uint16_t new;
|
uint16_t new;
|
||||||
|
|
||||||
vring_free_element(elem);
|
vring_unmap_element(elem);
|
||||||
|
|
||||||
/* Don't touch vring if a fatal error occurred */
|
/* Don't touch vring if a fatal error occurred */
|
||||||
if (vring->broken) {
|
if (vring->broken) {
|
||||||
|
|
|
@ -55,6 +55,5 @@ bool vring_enable_notification(VirtIODevice *vdev, Vring *vring);
|
||||||
bool vring_should_notify(VirtIODevice *vdev, Vring *vring);
|
bool vring_should_notify(VirtIODevice *vdev, Vring *vring);
|
||||||
int vring_pop(VirtIODevice *vdev, Vring *vring, VirtQueueElement **elem);
|
int vring_pop(VirtIODevice *vdev, Vring *vring, VirtQueueElement **elem);
|
||||||
void vring_push(Vring *vring, VirtQueueElement *elem, int len);
|
void vring_push(Vring *vring, VirtQueueElement *elem, int len);
|
||||||
void vring_free_element(VirtQueueElement *elem);
|
|
||||||
|
|
||||||
#endif /* VRING_H */
|
#endif /* VRING_H */
|
||||||
|
|
Loading…
Reference in New Issue