commit b0c44fdfc7f9d1656d718aa2fecac4a81f941c8c
Author: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Date: Wed Oct 7 15:49:32 2009 +0100
Fix DMA API when handling an immediate error from block layer (Avi Kivity)
The block layer may signal an immediate error on an asynchronous request
by returning NULL. The DMA API did not handle this correctly, returning
an AIO request which would never complete (and which would crash if
cancelled).
Fix by detecting the failure and propagating it.
Signed-off-by: Avi Kivity <avi@xxxxxxxxxx>
Signed-off-by: Anthony Liguori <aliguori@xxxxxxxxxx>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6893
c046a42c-6fe2-441c-8c8c-71466251a162
[ Backported from 6bbff9a0b495918309074ac60375be5f9dc868b3
by Stefano Stabellini. ]
Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
---
dma-helpers.c | 27 +++++++++++++++++++++------
1 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/dma-helpers.c b/dma-helpers.c
index a76c618..2a1621b 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -71,20 +71,26 @@ static void continue_after_map_failure(void *opaque)
qemu_bh_schedule(dbs->bh);
}
-static void dma_bdrv_cb(void *opaque, int ret)
+static void dma_bdrv_unmap(DMAAIOCB *dbs)
{
- DMAAIOCB *dbs = (DMAAIOCB *)opaque;
- target_phys_addr_t cur_addr, cur_len;
- void *mem;
int i;
- dbs->acb = NULL;
- dbs->sector_num += dbs->iov.size / 512;
for (i = 0; i < dbs->iov.niov; ++i) {
cpu_physical_memory_unmap(dbs->iov.iov[i].iov_base,
dbs->iov.iov[i].iov_len, !dbs->is_write,
dbs->iov.iov[i].iov_len);
}
+}
+
+void dma_bdrv_cb(void *opaque, int ret)
+{
+ DMAAIOCB *dbs = (DMAAIOCB *)opaque;
+ target_phys_addr_t cur_addr, cur_len;
+ void *mem;
+
+ dbs->acb = NULL;
+ dbs->sector_num += dbs->iov.size / 512;
+ dma_bdrv_unmap(dbs);
qemu_iovec_reset(&dbs->iov);
if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) {
@@ -120,6 +126,11 @@ static void dma_bdrv_cb(void *opaque, int ret)
dbs->acb = bdrv_aio_readv(dbs->bs, dbs->sector_num, &dbs->iov,
dbs->iov.size / 512, dma_bdrv_cb, dbs);
}
+ if (!dbs->acb) {
+ dma_bdrv_unmap(dbs);
+ qemu_iovec_destroy(&dbs->iov);
+ return;
+ }
}
static BlockDriverAIOCB *dma_bdrv_io(
@@ -139,6 +150,10 @@ static BlockDriverAIOCB *dma_bdrv_io(
dbs->bh = NULL;
qemu_iovec_init(&dbs->iov, sg->nsg);
dma_bdrv_cb(dbs, 0);
+ if (!dbs->acb) {
+ qemu_aio_release(dbs);
+ return NULL;
+ }
#ifdef __ia64__
if (!is_write) {
--
generated by git-patchbot for /home/xen/git/qemu-xen-unstable.git
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|