From patchwork Sun Oct 7 12:38:12 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Avi Kivity X-Patchwork-Id: 189835 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 155FC2C0315 for ; Mon, 8 Oct 2012 00:51:46 +1100 (EST) Received: from localhost ([::1]:60228 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TKq8e-00082r-Cf for incoming@patchwork.ozlabs.org; Sun, 07 Oct 2012 08:39:20 -0400 Received: from eggs.gnu.org ([208.118.235.92]:58773) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TKq8D-00078W-T4 for qemu-devel@nongnu.org; Sun, 07 Oct 2012 08:38:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TKq8B-0002lj-Qb for qemu-devel@nongnu.org; Sun, 07 Oct 2012 08:38:53 -0400 Received: from mx1.redhat.com ([209.132.183.28]:30931) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TKq8B-0002lY-Ic for qemu-devel@nongnu.org; Sun, 07 Oct 2012 08:38:51 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q97Ccnx5029232 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 7 Oct 2012 08:38:49 -0400 Received: from s01.tlv.redhat.com (s01.tlv.redhat.com [10.35.255.8]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q97CcVYX002159; Sun, 7 Oct 2012 08:38:47 -0400 From: Avi Kivity To: qemu-devel@nongnu.org, Anthony Liguori , liu ping fan , "Michael S. Tsirkin" , Paolo Bonzini , Blue Swirl Date: Sun, 7 Oct 2012 14:38:12 +0200 Message-Id: <1349613508-22980-8-git-send-email-avi@redhat.com> In-Reply-To: <1349613508-22980-1-git-send-email-avi@redhat.com> References: <1349613508-22980-1-git-send-email-avi@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v1 07/23] memory: maintain a list of address spaces 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 Instead of embedding knowledge of the memory and I/O address spaces in the memory core, maintain a list of all address spaces. This list will later be extended dynamically for other bus masters. Reviewed-by: Anthony Liguori Signed-off-by: Avi Kivity --- memory.c | 75 +++++++++++++++++++++++++++++++++++++++------------------------- memory.h | 2 ++ 2 files changed, 48 insertions(+), 29 deletions(-) diff --git a/memory.c b/memory.c index 431a867..b58b97c 100644 --- a/memory.c +++ b/memory.c @@ -28,6 +28,9 @@ static QTAILQ_HEAD(memory_listeners, MemoryListener) memory_listeners = QTAILQ_HEAD_INITIALIZER(memory_listeners); +static QTAILQ_HEAD(, AddressSpace) address_spaces + = QTAILQ_HEAD_INITIALIZER(address_spaces); + typedef struct AddrRange AddrRange; /* @@ -449,14 +452,15 @@ static void memory_region_iorange_destructor(IORange *iorange) static AddressSpace *memory_region_to_address_space(MemoryRegion *mr) { + AddressSpace *as; + while (mr->parent) { mr = mr->parent; } - if (mr == address_space_memory.root) { - return &address_space_memory; - } - if (mr == address_space_io.root) { - return &address_space_io; + QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { + if (mr == as->root) { + return as; + } } abort(); } @@ -729,16 +733,15 @@ void memory_region_transaction_begin(void) void memory_region_transaction_commit(void) { + AddressSpace *as; + assert(memory_region_transaction_depth); --memory_region_transaction_depth; if (!memory_region_transaction_depth) { MEMORY_LISTENER_CALL_GLOBAL(begin, Forward); - if (address_space_memory.root) { - address_space_update_topology(&address_space_memory); - } - if (address_space_io.root) { - address_space_update_topology(&address_space_io); + QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { + address_space_update_topology(as); } MEMORY_LISTENER_CALL_GLOBAL(commit, Forward); @@ -1072,12 +1075,14 @@ void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr, void memory_region_sync_dirty_bitmap(MemoryRegion *mr) { + AddressSpace *as; FlatRange *fr; - FOR_EACH_FLAT_RANGE(fr, address_space_memory.current_map) { - if (fr->mr == mr) { - MEMORY_LISTENER_UPDATE_REGION(fr, &address_space_memory, - Forward, log_sync); + QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { + FOR_EACH_FLAT_RANGE(fr, as->current_map) { + if (fr->mr == mr) { + MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, log_sync); + } } } } @@ -1120,13 +1125,13 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr) return qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK); } -static void memory_region_update_coalesced_range(MemoryRegion *mr) +static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpace *as) { FlatRange *fr; CoalescedMemoryRange *cmr; AddrRange tmp; - FOR_EACH_FLAT_RANGE(fr, address_space_memory.current_map) { + FOR_EACH_FLAT_RANGE(fr, as->current_map) { if (fr->mr == mr) { qemu_unregister_coalesced_mmio(int128_get64(fr->addr.start), int128_get64(fr->addr.size)); @@ -1145,6 +1150,15 @@ static void memory_region_update_coalesced_range(MemoryRegion *mr) } } +static void memory_region_update_coalesced_range(MemoryRegion *mr) +{ + AddressSpace *as; + + QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { + memory_region_update_coalesced_range_as(mr, as); + } +} + void memory_region_set_coalescing(MemoryRegion *mr) { memory_region_clear_coalescing(mr); @@ -1450,10 +1464,6 @@ static void listener_add_address_space(MemoryListener *listener, { FlatRange *fr; - if (!as->root) { - return; - } - if (listener->address_space_filter && listener->address_space_filter != as->root) { return; @@ -1478,6 +1488,7 @@ static void listener_add_address_space(MemoryListener *listener, void memory_listener_register(MemoryListener *listener, MemoryRegion *filter) { MemoryListener *other = NULL; + AddressSpace *as; listener->address_space_filter = filter; if (QTAILQ_EMPTY(&memory_listeners) @@ -1492,8 +1503,10 @@ void memory_listener_register(MemoryListener *listener, MemoryRegion *filter) } QTAILQ_INSERT_BEFORE(other, listener, link); } - listener_add_address_space(listener, &address_space_memory); - listener_add_address_space(listener, &address_space_io); + + QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { + listener_add_address_space(listener, as); + } } void memory_listener_unregister(MemoryListener *listener) @@ -1507,17 +1520,21 @@ void address_space_init(AddressSpace *as, MemoryRegion *root) as->root = root; as->current_map = g_new(FlatView, 1); flatview_init(as->current_map); + QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link); + as->name = NULL; memory_region_transaction_commit(); } void set_system_memory_map(MemoryRegion *mr) { address_space_init(&address_space_memory, mr); + address_space_memory.name = "memory"; } void set_system_io_map(MemoryRegion *mr) { address_space_init(&address_space_io, mr); + address_space_io.name = "I/O"; } uint64_t io_mem_read(MemoryRegion *mr, target_phys_addr_t addr, unsigned size) @@ -1637,16 +1654,16 @@ void mtree_info(fprintf_function mon_printf, void *f) { MemoryRegionListHead ml_head; MemoryRegionList *ml, *ml2; + AddressSpace *as; QTAILQ_INIT(&ml_head); - mon_printf(f, "memory\n"); - mtree_print_mr(mon_printf, f, address_space_memory.root, 0, 0, &ml_head); - - if (address_space_io.root && - !QTAILQ_EMPTY(&address_space_io.root->subregions)) { - mon_printf(f, "I/O\n"); - mtree_print_mr(mon_printf, f, address_space_io.root, 0, 0, &ml_head); + QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { + if (!as->name) { + continue; + } + mon_printf(f, "%s\n", as->name); + mtree_print_mr(mon_printf, f, as->root, 0, 0, &ml_head); } mon_printf(f, "aliases\n"); diff --git a/memory.h b/memory.h index a1d75e7..46bc5e1 100644 --- a/memory.h +++ b/memory.h @@ -164,10 +164,12 @@ typedef struct AddressSpace AddressSpace; */ struct AddressSpace { /* All fields are private. */ + const char *name; MemoryRegion *root; struct FlatView *current_map; int ioeventfd_nb; struct MemoryRegionIoeventfd *ioeventfds; + QTAILQ_ENTRY(AddressSpace) address_spaces_link; }; typedef struct MemoryRegionSection MemoryRegionSection;