ia64/xen-unstable

changeset 9064:034af52f0df7

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@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Feb 28 10:18:34 2006 +0100 (2006-02-28)
parents 79a93530121b
children e77ea156075c
files tools/ioemu/hw/ide.c
line diff
     1.1 --- a/tools/ioemu/hw/ide.c	Tue Feb 28 10:14:32 2006 +0100
     1.2 +++ b/tools/ioemu/hw/ide.c	Tue Feb 28 10:18:34 2006 +0100
     1.3 @@ -669,9 +669,6 @@ static int ide_read_dma_cb(IDEState *s,
     1.4      }
     1.5      if (s->io_buffer_index >= s->io_buffer_size && s->nsector == 0) {
     1.6          s->status = READY_STAT | SEEK_STAT;
     1.7 -        s->bmdma->status &= ~BM_STATUS_DMAING;
     1.8 -        s->bmdma->status |= BM_STATUS_INT;
     1.9 -        ide_set_irq(s);
    1.10  #ifdef DEBUG_IDE_ATAPI
    1.11          printf("dma status=0x%x\n", s->status);
    1.12  #endif
    1.13 @@ -738,9 +735,6 @@ static int ide_write_dma_cb(IDEState *s,
    1.14              if (n == 0) {
    1.15                  /* end of transfer */
    1.16                  s->status = READY_STAT | SEEK_STAT;
    1.17 -                s->bmdma->status &= ~BM_STATUS_DMAING;
    1.18 -                s->bmdma->status |= BM_STATUS_INT;
    1.19 -                ide_set_irq(s);
    1.20                  return 0;
    1.21              }
    1.22              if (n > MAX_MULT_SECTORS)
    1.23 @@ -987,9 +981,6 @@ static int ide_atapi_cmd_read_dma_cb(IDE
    1.24      if (s->packet_transfer_size <= 0) {
    1.25          s->status = READY_STAT;
    1.26          s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
    1.27 -        s->bmdma->status &= ~BM_STATUS_DMAING;
    1.28 -        s->bmdma->status |= BM_STATUS_INT;
    1.29 -        ide_set_irq(s);
    1.30  #ifdef DEBUG_IDE_ATAPI
    1.31          printf("dma status=0x%x\n", s->status);
    1.32  #endif
    1.33 @@ -2025,6 +2016,17 @@ static void ide_map(PCIDevice *pci_dev, 
    1.34      }
    1.35  }
    1.36  
    1.37 +static void ide_dma_finish(BMDMAState *bm)
    1.38 +{
    1.39 +    IDEState *s = bm->ide_if;
    1.40 +
    1.41 +    bm->status &= ~BM_STATUS_DMAING;
    1.42 +    bm->status |= BM_STATUS_INT;
    1.43 +    bm->dma_cb = NULL;
    1.44 +    bm->ide_if = NULL;
    1.45 +    ide_set_irq(s);
    1.46 +}
    1.47 +
    1.48  /* XXX: full callback usage to prepare non blocking I/Os support -
    1.49     error handling */
    1.50  #ifdef DMA_MULTI_THREAD
    1.51 @@ -2070,9 +2072,8 @@ static void ide_dma_loop(BMDMAState *bm)
    1.52          cur_addr += 8;
    1.53      }
    1.54      /* end of transfer */
    1.55 - the_end:
    1.56 -    bm->dma_cb = NULL;
    1.57 -    bm->ide_if = NULL;
    1.58 +the_end:
    1.59 +    ide_dma_finish(bm);
    1.60  }
    1.61  
    1.62  static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb)