qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [patch v4 13/16] e1000: add busy flag to anti broken device


From: Liu Ping Fan
Subject: [Qemu-devel] [patch v4 13/16] e1000: add busy flag to anti broken device state
Date: Mon, 22 Oct 2012 17:23:56 +0800

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 <address@hidden>
---
 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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]