qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PULL] Urgent fix for portio / std vga


From: Avi Kivity
Subject: [Qemu-devel] [PULL] Urgent fix for portio / std vga
Date: Tue, 06 Mar 2012 13:18:08 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.1) Gecko/20120216 Thunderbird/10.0.1

The last memory core series completely clobbered -vga std, which has
been annoying people, especially those that have it as the default
adapter.  This patchset fixes the problem.

Please pull from:

  git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git memory/urgent

----------------------------------------------------------------
Avi Kivity (2):
      ioport: add destructor method to IORange
      memory: fix I/O port aliases

 exec.c    |    8 ++++++--
 ioport.c  |   15 +++++++++++++++
 ioport.h  |    1 +
 iorange.h |    1 +
 memory.c  |   26 ++++++++++++++++++++------
 memory.h  |    9 ++++++++-
 6 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/exec.c b/exec.c
index 3ce3539..1e5bbd6 100644
--- a/exec.c
+++ b/exec.c
@@ -3668,9 +3668,13 @@ static void io_commit(MemoryListener *listener)
 static void io_region_add(MemoryListener *listener,
                           MemoryRegionSection *section)
 {
-    iorange_init(&section->mr->iorange, &memory_region_iorange_ops,
+    MemoryRegionIORange *mrio = g_new(MemoryRegionIORange, 1);
+
+    mrio->mr = section->mr;
+    mrio->offset = section->offset_within_region;
+    iorange_init(&mrio->iorange, &memory_region_iorange_ops,
                  section->offset_within_address_space, section->size);
-    ioport_register(&section->mr->iorange);
+    ioport_register(&mrio->iorange);
 }
 
 static void io_region_del(MemoryListener *listener,
diff --git a/ioport.c b/ioport.c
index 8a474d3..78a3b89 100644
--- a/ioport.c
+++ b/ioport.c
@@ -52,6 +52,7 @@
 static void *ioport_opaque[MAX_IOPORTS];
 static IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
 static IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
+static IOPortDestructor *ioport_destructor_table[MAX_IOPORTS];
 
 static IOPortReadFunc default_ioport_readb, default_ioport_readw,
default_ioport_readl;
 static IOPortWriteFunc default_ioport_writeb, default_ioport_writew,
default_ioport_writel;
@@ -225,6 +226,15 @@ static void ioport_writel_thunk(void *opaque,
uint32_t addr, uint32_t data)
     ioport->ops->write(ioport, addr - ioport->base, 4, data);
 }
 
+static void iorange_destructor_thunk(void *opaque)
+{
+    IORange *iorange = opaque;
+
+    if (iorange->ops->destructor) {
+        iorange->ops->destructor(iorange);
+    }
+}
+
 void ioport_register(IORange *ioport)
 {
     register_ioport_read(ioport->base, ioport->len, 1,
@@ -239,12 +249,17 @@ void ioport_register(IORange *ioport)
                           ioport_writew_thunk, ioport);
     register_ioport_write(ioport->base, ioport->len, 4,
                           ioport_writel_thunk, ioport);
+    ioport_destructor_table[ioport->base] = iorange_destructor_thunk;
 }
 
 void isa_unassign_ioport(pio_addr_t start, int length)
 {
     int i;
 
+    if (ioport_destructor_table[start]) {
+        ioport_destructor_table[start](ioport_opaque[start]);
+        ioport_destructor_table[start] = NULL;
+    }
     for(i = start; i < start + length; i++) {
         ioport_read_table[0][i] = NULL;
         ioport_read_table[1][i] = NULL;
diff --git a/ioport.h b/ioport.h
index ab29c89..23441cb 100644
--- a/ioport.h
+++ b/ioport.h
@@ -36,6 +36,7 @@ typedef uint32_t pio_addr_t;
 /* These should really be in isa.h, but are here to make pc.h happy.  */
 typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t
data);
 typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address);
+typedef void (IOPortDestructor)(void *opaque);
 
 void ioport_register(IORange *iorange);
 int register_ioport_read(pio_addr_t start, int length, int size,
diff --git a/iorange.h b/iorange.h
index 9783168..cd980a8 100644
--- a/iorange.h
+++ b/iorange.h
@@ -11,6 +11,7 @@ struct IORangeOps {
                  uint64_t *data);
     void (*write)(IORange *iorange, uint64_t offset, unsigned width,
                   uint64_t data);
+    void (*destructor)(IORange *iorange);
 };
 
 struct IORange {
diff --git a/memory.c b/memory.c
index 6565e2e..4c3dc49 100644
--- a/memory.c
+++ b/memory.c
@@ -382,16 +382,20 @@ static void memory_region_iorange_read(IORange
*iorange,
                                        unsigned width,
                                        uint64_t *data)
 {
-    MemoryRegion *mr = container_of(iorange, MemoryRegion, iorange);
+    MemoryRegionIORange *mrio
+        = container_of(iorange, MemoryRegionIORange, iorange);
+    MemoryRegion *mr = mrio->mr;
 
+    offset += mrio->offset;
     if (mr->ops->old_portio) {
-        const MemoryRegionPortio *mrp = find_portio(mr, offset, width,
false);
+        const MemoryRegionPortio *mrp = find_portio(mr, offset -
mrio->offset,
+                                                    width, false);
 
         *data = ((uint64_t)1 << (width * 8)) - 1;
         if (mrp) {
             *data = mrp->read(mr->opaque, offset);
         } else if (width == 2) {
-            mrp = find_portio(mr, offset, 1, false);
+            mrp = find_portio(mr, offset - mrio->offset, 1, false);
             assert(mrp);
             *data = mrp->read(mr->opaque, offset) |
                     (mrp->read(mr->opaque, offset + 1) << 8);
@@ -410,15 +414,19 @@ static void memory_region_iorange_write(IORange
*iorange,
                                         unsigned width,
                                         uint64_t data)
 {
-    MemoryRegion *mr = container_of(iorange, MemoryRegion, iorange);
+    MemoryRegionIORange *mrio
+        = container_of(iorange, MemoryRegionIORange, iorange);
+    MemoryRegion *mr = mrio->mr;
 
+    offset += mrio->offset;
     if (mr->ops->old_portio) {
-        const MemoryRegionPortio *mrp = find_portio(mr, offset, width,
true);
+        const MemoryRegionPortio *mrp = find_portio(mr, offset -
mrio->offset,
+                                                    width, true);
 
         if (mrp) {
             mrp->write(mr->opaque, offset, data);
         } else if (width == 2) {
-            mrp = find_portio(mr, offset, 1, false);
+            mrp = find_portio(mr, offset - mrio->offset, 1, false);
             assert(mrp);
             mrp->write(mr->opaque, offset, data & 0xff);
             mrp->write(mr->opaque, offset + 1, data >> 8);
@@ -431,9 +439,15 @@ static void memory_region_iorange_write(IORange
*iorange,
                               memory_region_write_accessor, mr);
 }
 
+static void memory_region_iorange_destructor(IORange *iorange)
+{
+    g_free(container_of(iorange, MemoryRegionIORange, iorange));
+}
+
 const IORangeOps memory_region_iorange_ops = {
     .read = memory_region_iorange_read,
     .write = memory_region_iorange_write,
+    .destructor = memory_region_iorange_destructor,
 };
 
 static AddressSpace address_space_io;
diff --git a/memory.h b/memory.h
index b7bccd1..53ff62b 100644
--- a/memory.h
+++ b/memory.h
@@ -43,6 +43,14 @@ struct MemoryRegionMmio {
     CPUWriteMemoryFunc *write[3];
 };
 
+/* Internal use; thunks between old-style IORange and MemoryRegions. */
+typedef struct MemoryRegionIORange MemoryRegionIORange;
+struct MemoryRegionIORange {
+    IORange iorange;
+    MemoryRegion *mr;
+    target_phys_addr_t offset;
+};
+
 /*
  * Memory region callbacks
  */
@@ -117,7 +125,6 @@ struct MemoryRegion {
     target_phys_addr_t addr;
     void (*destructor)(MemoryRegion *mr);
     ram_addr_t ram_addr;
-    IORange iorange;
     bool subpage;
     bool terminates;
     bool readable;

-- 
error compiling committee.c: too many arguments to function




reply via email to

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