# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 034af52f0df7d047d585a24233a1e19e0e2ae204
# Parent 79a93530121b77327f307c7cce652984d09819ea
Fix a multi HVM domain issue (bugzilla bug #542):
This issue can be reproduced on SMP platform, while the domain 0
is UP. The reason is, after finishing a dma request, the dma thread will
trigger the interrupt and then clear the call back function. When guest
get the interrupt , it will try to check the call back function, if it
is set, then it will trigger a dma request again. So if the checking for
the callbackfunction happens between trigger interrupt and clear
callback function on dma thread, it will cause NULL function calling.
After with domain 0 UP and smp platform, this situation can be
reproduced easily.
Signed-off-by: Yunhong Jiang <yunhong.jiang@xxxxxxxxx>
diff -r 79a93530121b -r 034af52f0df7 tools/ioemu/hw/ide.c
--- a/tools/ioemu/hw/ide.c Tue Feb 28 09:14:32 2006
+++ b/tools/ioemu/hw/ide.c Tue Feb 28 09:18:34 2006
@@ -669,9 +669,6 @@
}
if (s->io_buffer_index >= s->io_buffer_size && s->nsector == 0) {
s->status = READY_STAT | SEEK_STAT;
- s->bmdma->status &= ~BM_STATUS_DMAING;
- s->bmdma->status |= BM_STATUS_INT;
- ide_set_irq(s);
#ifdef DEBUG_IDE_ATAPI
printf("dma status=0x%x\n", s->status);
#endif
@@ -738,9 +735,6 @@
if (n == 0) {
/* end of transfer */
s->status = READY_STAT | SEEK_STAT;
- s->bmdma->status &= ~BM_STATUS_DMAING;
- s->bmdma->status |= BM_STATUS_INT;
- ide_set_irq(s);
return 0;
}
if (n > MAX_MULT_SECTORS)
@@ -987,9 +981,6 @@
if (s->packet_transfer_size <= 0) {
s->status = READY_STAT;
s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO |
ATAPI_INT_REASON_CD;
- s->bmdma->status &= ~BM_STATUS_DMAING;
- s->bmdma->status |= BM_STATUS_INT;
- ide_set_irq(s);
#ifdef DEBUG_IDE_ATAPI
printf("dma status=0x%x\n", s->status);
#endif
@@ -2025,6 +2016,17 @@
}
}
+static void ide_dma_finish(BMDMAState *bm)
+{
+ IDEState *s = bm->ide_if;
+
+ bm->status &= ~BM_STATUS_DMAING;
+ bm->status |= BM_STATUS_INT;
+ bm->dma_cb = NULL;
+ bm->ide_if = NULL;
+ ide_set_irq(s);
+}
+
/* XXX: full callback usage to prepare non blocking I/Os support -
error handling */
#ifdef DMA_MULTI_THREAD
@@ -2070,9 +2072,8 @@
cur_addr += 8;
}
/* end of transfer */
- the_end:
- bm->dma_cb = NULL;
- bm->ide_if = NULL;
+the_end:
+ ide_dma_finish(bm);
}
static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|