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