Blame 0002-exec.c-Fix-subpage-memory-access-to-RAM-MemoryRegion.patch

Justin M. Forbes 45e84a
From 2061800b85ddcc9b34b5ccbfaa87f7e8b94626a6 Mon Sep 17 00:00:00 2001
Justin M. Forbes 45e84a
From: =?UTF-8?q?Andreas=20F=C3=A4rber?= <afaerber@suse.de>
Justin M. Forbes 45e84a
Date: Wed, 30 Nov 2011 16:26:21 +0100
Justin M. Forbes 45e84a
Subject: [PATCH 02/25] exec.c: Fix subpage memory access to RAM MemoryRegion
Justin M. Forbes 45e84a
MIME-Version: 1.0
Justin M. Forbes 45e84a
Content-Type: text/plain; charset=UTF-8
Justin M. Forbes 45e84a
Content-Transfer-Encoding: 8bit
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
Commit 95c318f5e1f88d7e5bcc6deac17330fd4806a2d3 (Fix segfault in mmio
Justin M. Forbes 45e84a
subpage handling code.) prevented a segfault by making all subpage
Justin M. Forbes 45e84a
registrations over an existing memory page perform an unassigned access.
Justin M. Forbes 45e84a
Symptoms were writes not taking effect and reads returning zero.
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
Very small page sizes are not currently supported either,
Justin M. Forbes 45e84a
so subpage memory areas cannot fully be avoided.
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
Therefore change the previous fix to use a new IO_MEM_SUBPAGE_RAM
Justin M. Forbes 45e84a
instead of IO_MEM_UNASSIGNED. Suggested by Avi.
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
Reviewed-by: Avi Kivity <avi@redhat.com>
Justin M. Forbes 45e84a
Signed-off-by: Andreas Färber <afaerber@suse.de>
Justin M. Forbes 45e84a
Cc: Avi Kivity <avi@redhat.com>
Justin M. Forbes 45e84a
Cc: Gleb Natapov <gleb@redhat.com>
Justin M. Forbes 45e84a
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Justin M. Forbes 45e84a
---
Justin M. Forbes 45e84a
 cpu-common.h |    1 +
Justin M. Forbes 45e84a
 exec.c       |   65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Justin M. Forbes 45e84a
 2 files changed, 64 insertions(+), 2 deletions(-)
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
diff --git a/cpu-common.h b/cpu-common.h
Justin M. Forbes 45e84a
index c9878ba..3f45428 100644
Justin M. Forbes 45e84a
--- a/cpu-common.h
Justin M. Forbes 45e84a
+++ b/cpu-common.h
Justin M. Forbes 45e84a
@@ -172,6 +172,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
Justin M. Forbes 45e84a
 #define IO_MEM_ROM         (1 << IO_MEM_SHIFT) /* hardcoded offset */
Justin M. Forbes 45e84a
 #define IO_MEM_UNASSIGNED  (2 << IO_MEM_SHIFT)
Justin M. Forbes 45e84a
 #define IO_MEM_NOTDIRTY    (3 << IO_MEM_SHIFT)
Justin M. Forbes 45e84a
+#define IO_MEM_SUBPAGE_RAM (4 << IO_MEM_SHIFT)
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
 /* Acts like a ROM when read and like a device when written.  */
Justin M. Forbes 45e84a
 #define IO_MEM_ROMD        (1)
Justin M. Forbes 45e84a
diff --git a/exec.c b/exec.c
Justin M. Forbes 45e84a
index 6b92198..6c206ff 100644
Justin M. Forbes 45e84a
--- a/exec.c
Justin M. Forbes 45e84a
+++ b/exec.c
Justin M. Forbes 45e84a
@@ -3570,6 +3570,63 @@ static CPUWriteMemoryFunc * const subpage_write[] = {
Justin M. Forbes 45e84a
     &subpage_writel,
Justin M. Forbes 45e84a
 };
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
+static uint32_t subpage_ram_readb(void *opaque, target_phys_addr_t addr)
Justin M. Forbes 45e84a
+{
Justin M. Forbes 45e84a
+    ram_addr_t raddr = addr;
Justin M. Forbes 45e84a
+    void *ptr = qemu_get_ram_ptr(raddr);
Justin M. Forbes 45e84a
+    return ldub_p(ptr);
Justin M. Forbes 45e84a
+}
Justin M. Forbes 45e84a
+
Justin M. Forbes 45e84a
+static void subpage_ram_writeb(void *opaque, target_phys_addr_t addr,
Justin M. Forbes 45e84a
+                               uint32_t value)
Justin M. Forbes 45e84a
+{
Justin M. Forbes 45e84a
+    ram_addr_t raddr = addr;
Justin M. Forbes 45e84a
+    void *ptr = qemu_get_ram_ptr(raddr);
Justin M. Forbes 45e84a
+    stb_p(ptr, value);
Justin M. Forbes 45e84a
+}
Justin M. Forbes 45e84a
+
Justin M. Forbes 45e84a
+static uint32_t subpage_ram_readw(void *opaque, target_phys_addr_t addr)
Justin M. Forbes 45e84a
+{
Justin M. Forbes 45e84a
+    ram_addr_t raddr = addr;
Justin M. Forbes 45e84a
+    void *ptr = qemu_get_ram_ptr(raddr);
Justin M. Forbes 45e84a
+    return lduw_p(ptr);
Justin M. Forbes 45e84a
+}
Justin M. Forbes 45e84a
+
Justin M. Forbes 45e84a
+static void subpage_ram_writew(void *opaque, target_phys_addr_t addr,
Justin M. Forbes 45e84a
+                               uint32_t value)
Justin M. Forbes 45e84a
+{
Justin M. Forbes 45e84a
+    ram_addr_t raddr = addr;
Justin M. Forbes 45e84a
+    void *ptr = qemu_get_ram_ptr(raddr);
Justin M. Forbes 45e84a
+    stw_p(ptr, value);
Justin M. Forbes 45e84a
+}
Justin M. Forbes 45e84a
+
Justin M. Forbes 45e84a
+static uint32_t subpage_ram_readl(void *opaque, target_phys_addr_t addr)
Justin M. Forbes 45e84a
+{
Justin M. Forbes 45e84a
+    ram_addr_t raddr = addr;
Justin M. Forbes 45e84a
+    void *ptr = qemu_get_ram_ptr(raddr);
Justin M. Forbes 45e84a
+    return ldl_p(ptr);
Justin M. Forbes 45e84a
+}
Justin M. Forbes 45e84a
+
Justin M. Forbes 45e84a
+static void subpage_ram_writel(void *opaque, target_phys_addr_t addr,
Justin M. Forbes 45e84a
+                               uint32_t value)
Justin M. Forbes 45e84a
+{
Justin M. Forbes 45e84a
+    ram_addr_t raddr = addr;
Justin M. Forbes 45e84a
+    void *ptr = qemu_get_ram_ptr(raddr);
Justin M. Forbes 45e84a
+    stl_p(ptr, value);
Justin M. Forbes 45e84a
+}
Justin M. Forbes 45e84a
+
Justin M. Forbes 45e84a
+static CPUReadMemoryFunc * const subpage_ram_read[] = {
Justin M. Forbes 45e84a
+    &subpage_ram_readb,
Justin M. Forbes 45e84a
+    &subpage_ram_readw,
Justin M. Forbes 45e84a
+    &subpage_ram_readl,
Justin M. Forbes 45e84a
+};
Justin M. Forbes 45e84a
+
Justin M. Forbes 45e84a
+static CPUWriteMemoryFunc * const subpage_ram_write[] = {
Justin M. Forbes 45e84a
+    &subpage_ram_writeb,
Justin M. Forbes 45e84a
+    &subpage_ram_writew,
Justin M. Forbes 45e84a
+    &subpage_ram_writel,
Justin M. Forbes 45e84a
+};
Justin M. Forbes 45e84a
+
Justin M. Forbes 45e84a
 static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
Justin M. Forbes 45e84a
                              ram_addr_t memory, ram_addr_t region_offset)
Justin M. Forbes 45e84a
 {
Justin M. Forbes 45e84a
@@ -3583,8 +3640,9 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
Justin M. Forbes 45e84a
     printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %ld\n", __func__,
Justin M. Forbes 45e84a
            mmio, start, end, idx, eidx, memory);
Justin M. Forbes 45e84a
 #endif
Justin M. Forbes 45e84a
-    if ((memory & ~TARGET_PAGE_MASK) == IO_MEM_RAM)
Justin M. Forbes 45e84a
-        memory = IO_MEM_UNASSIGNED;
Justin M. Forbes 45e84a
+    if ((memory & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
Justin M. Forbes 45e84a
+        memory = IO_MEM_SUBPAGE_RAM;
Justin M. Forbes 45e84a
+    }
Justin M. Forbes 45e84a
     memory = (memory >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
Justin M. Forbes 45e84a
     for (; idx <= eidx; idx++) {
Justin M. Forbes 45e84a
         mmio->sub_io_index[idx] = memory;
Justin M. Forbes 45e84a
@@ -3817,6 +3875,9 @@ static void io_mem_init(void)
Justin M. Forbes 45e84a
     cpu_register_io_memory_fixed(IO_MEM_NOTDIRTY, error_mem_read,
Justin M. Forbes 45e84a
                                  notdirty_mem_write, NULL,
Justin M. Forbes 45e84a
                                  DEVICE_NATIVE_ENDIAN);
Justin M. Forbes 45e84a
+    cpu_register_io_memory_fixed(IO_MEM_SUBPAGE_RAM, subpage_ram_read,
Justin M. Forbes 45e84a
+                                 subpage_ram_write, NULL,
Justin M. Forbes 45e84a
+                                 DEVICE_NATIVE_ENDIAN);
Justin M. Forbes 45e84a
     for (i=0; i<5; i++)
Justin M. Forbes 45e84a
         io_mem_used[i] = 1;
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
-- 
Justin M. Forbes 45e84a
1.7.7.5
Justin M. Forbes 45e84a