From patchwork Mon Nov 28 15:06:45 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andreas_F=C3=A4rber?= X-Patchwork-Id: 127999 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 7232EB6F6B for ; Tue, 29 Nov 2011 02:07:52 +1100 (EST) Received: from localhost ([::1]:55230 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RV2o4-0006na-1w for incoming@patchwork.ozlabs.org; Mon, 28 Nov 2011 10:07:44 -0500 Received: from eggs.gnu.org ([140.186.70.92]:45419) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RV2nw-0006nI-84 for qemu-devel@nongnu.org; Mon, 28 Nov 2011 10:07:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RV2nr-0008DE-UK for qemu-devel@nongnu.org; Mon, 28 Nov 2011 10:07:36 -0500 Received: from cantor2.suse.de ([195.135.220.15]:40672 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RV2nr-0008DA-M3 for qemu-devel@nongnu.org; Mon, 28 Nov 2011 10:07:31 -0500 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id B68EF8BB22; Mon, 28 Nov 2011 16:07:29 +0100 (CET) From: =?UTF-8?q?Andreas=20F=C3=A4rber?= To: qemu-devel@nongnu.org Date: Mon, 28 Nov 2011 16:06:45 +0100 Message-Id: <1322492805-5530-1-git-send-email-afaerber@suse.de> X-Mailer: git-send-email 1.7.7 MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4-2.6 X-Received-From: 195.135.220.15 Cc: Blue Swirl , =?UTF-8?q?Andreas=20F=C3=A4rber?= , Gleb Natapov , Avi Kivity Subject: [Qemu-devel] [PATCH] exec.c: Fix subpage memory access to RAM MemoryRegion X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 revert the previous fix and defer recognition of IO_MEM_RAM to subpage_{read,write}len() and translate any access there. Signed-off-by: Andreas Färber Cc: Avi Kivity Cc: Gleb Natapov Cc: Blue Swirl --- exec.c | 33 +++++++++++++++++++++++++++++++-- 1 files changed, 31 insertions(+), 2 deletions(-) diff --git a/exec.c b/exec.c index 6b92198..fba5ba1 100644 --- a/exec.c +++ b/exec.c @@ -3508,6 +3508,21 @@ static inline uint32_t subpage_readlen (subpage_t *mmio, addr += mmio->region_offset[idx]; idx = mmio->sub_io_index[idx]; + if (unlikely(idx == IO_MEM_RAM)) { + ram_addr_t raddr = /*mmio->base |*/ addr; + void *ptr = qemu_get_ram_ptr(raddr); + switch (len) { + default: + case 0: + return ldub_p(ptr); + case 1: + return lduw_p(ptr); + case 2: + return ldl_p(ptr); + case 3: + return ldq_p(ptr); + } + } return io_mem_read[idx][len](io_mem_opaque[idx], addr); } @@ -3522,6 +3537,22 @@ static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr, addr += mmio->region_offset[idx]; idx = mmio->sub_io_index[idx]; + if (unlikely(idx == IO_MEM_RAM)) { + ram_addr_t raddr = /*mmio->base |*/ addr; + void *ptr = qemu_get_ram_ptr(raddr); + switch (len) { + default: + case 0: + stb_p(ptr, value); + case 1: + stw_p(ptr, value); + case 2: + stl_p(ptr, value); + case 3: + stq_p(ptr, value); + } + return; + } io_mem_write[idx][len](io_mem_opaque[idx], addr, value); } @@ -3583,8 +3614,6 @@ 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; memory = (memory >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); for (; idx <= eidx; idx++) { mmio->sub_io_index[idx] = memory;