From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:41614) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TQEG0-00032m-3J for qemu-devel@nongnu.org; Mon, 22 Oct 2012 05:25:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TQEFv-000732-Er for qemu-devel@nongnu.org; Mon, 22 Oct 2012 05:25:12 -0400 Received: from e28smtp09.in.ibm.com ([122.248.162.9]:53636) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TQEFu-000715-RY for qemu-devel@nongnu.org; Mon, 22 Oct 2012 05:25:07 -0400 Received: from /spool/local by e28smtp09.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 22 Oct 2012 14:55:05 +0530 Received: from d28av01.in.ibm.com (d28av01.in.ibm.com [9.184.220.63]) by d28relay03.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q9M9ORlP32768168 for ; Mon, 22 Oct 2012 14:54:27 +0530 Received: from d28av01.in.ibm.com (loopback [127.0.0.1]) by d28av01.in.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q9MEsJdP028907 for ; Mon, 22 Oct 2012 14:54:19 GMT From: Liu Ping Fan Date: Mon, 22 Oct 2012 17:23:56 +0800 Message-Id: <1350897839-29593-14-git-send-email-pingfank@linux.vnet.ibm.com> In-Reply-To: <1350897839-29593-1-git-send-email-pingfank@linux.vnet.ibm.com> References: <1350897839-29593-1-git-send-email-pingfank@linux.vnet.ibm.com> Subject: [Qemu-devel] [patch v4 13/16] e1000: add busy flag to anti broken device state List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Stefan Hajnoczi , Marcelo Tosatti , Avi Kivity , Anthony Liguori , Jan Kiszka , Paolo Bonzini The broken device state is caused by releasing local lock before acquiring big lock. To fix this issue, we have two choice: 1.use busy flag to protect the state The drawback is that we will introduce independent busy flag for each independent device's logic unit. 2.reload the device's state The drawback is if the call chain is too deep, the action to reload will touch each layer. Also the reloading means to recaculate the intermediate result based on device's regs. This patch adopt the solution 1 to fix the issue. Signed-off-by: Liu Ping Fan --- hw/e1000.c | 23 ++++++++++++++++++++--- 1 files changed, 20 insertions(+), 3 deletions(-) diff --git a/hw/e1000.c b/hw/e1000.c index 5eddab5..0b4fce5 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -86,6 +86,7 @@ typedef struct E1000State_st { MemoryRegion mmio; MemoryRegion io; QemuMutex e1000_lock; + int busy; uint32_t mac_reg[0x8000]; uint16_t phy_reg[0x20]; @@ -1033,6 +1034,11 @@ e1000_mmio_write(void *opaque, target_phys_addr_t addr, uint64_t val, E1000State *s = opaque; unsigned int index = (addr & 0x1ffff) >> 2; + if (s->busy) { + return; + } else { + s->busy = 1; + } if (index < NWRITEOPS && macreg_writeops[index]) { macreg_writeops[index](s, index, val); } else if (index < NREADOPS && macreg_readops[index]) { @@ -1041,6 +1047,7 @@ e1000_mmio_write(void *opaque, target_phys_addr_t addr, uint64_t val, DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08"PRIx64"\n", index<<2, val); } + s->busy = 0; } static uint64_t @@ -1048,13 +1055,22 @@ e1000_mmio_read(void *opaque, target_phys_addr_t addr, unsigned size) { E1000State *s = opaque; unsigned int index = (addr & 0x1ffff) >> 2; + uint64_t ret = 0; + + if (s->busy) { + return ret; + } else { + s->busy = 1; + } if (index < NREADOPS && macreg_readops[index]) { - return macreg_readops[index](s, index); + ret = macreg_readops[index](s, index); + } else { + DBGOUT(UNKNOWN, "MMIO unknown read addr=0x%08x\n", index<<2); } - DBGOUT(UNKNOWN, "MMIO unknown read addr=0x%08x\n", index<<2); - return 0; + s->busy = 0; + return ret; } static const MemoryRegionOps e1000_mmio_ops = { @@ -1242,6 +1258,7 @@ static int pci_e1000_init(PCIDevice *pci_dev) uint8_t *macaddr; qemu_mutex_init(&d->e1000_lock); + d->busy = 0; pci_conf = d->dev.config; -- 1.7.4.4