From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45156) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UjARa-0000KE-Qq for qemu-devel@nongnu.org; Sun, 02 Jun 2013 11:43:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UjARZ-0000OG-Pw for qemu-devel@nongnu.org; Sun, 02 Jun 2013 11:43:42 -0400 Received: from mail-wg0-x22f.google.com ([2a00:1450:400c:c00::22f]:48471) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UjARZ-0000OA-Ka for qemu-devel@nongnu.org; Sun, 02 Jun 2013 11:43:41 -0400 Received: by mail-wg0-f47.google.com with SMTP id e11so2452303wgh.26 for ; Sun, 02 Jun 2013 08:43:40 -0700 (PDT) Sender: Paolo Bonzini From: Paolo Bonzini Date: Sun, 2 Jun 2013 17:43:18 +0200 Message-Id: <1370187812-13191-2-git-send-email-pbonzini@redhat.com> In-Reply-To: <1370187812-13191-1-git-send-email-pbonzini@redhat.com> References: <1370187812-13191-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 01/15] memory: add getter/setter for owner List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: peter.maydell@linaro.org, Liu Ping Fan , jan.kiszka@siemens.com Whenever memory regions are accessed outside the BQL, they need to be preserved against hot-unplug. MemoryRegions actually do not have their own reference count; they piggyback on a QOM object, their "owner". Add two functions to retrieve and specify the owner. The setter function will affect the owner recursively on a whole tree of contained regions, but without crossing (a) aliases (b) regions that are already owned by another device. This is so that a device can create a complex tree of regions and a single call to memory_region_set_owner (perhaps even within a bus-specific function, e.g. pci_register_bar) will affect the entire tree. Signed-off-by: Paolo Bonzini --- include/exec/memory.h | 18 ++++++++++++++++++ memory.c | 21 +++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/include/exec/memory.h b/include/exec/memory.h index 3598c4f..457a53c 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -150,6 +150,7 @@ struct MemoryRegion { const MemoryRegionIOMMUOps *iommu_ops; void *opaque; MemoryRegion *parent; + struct Object *owner; Int128 size; hwaddr addr; void (*destructor)(MemoryRegion *mr); @@ -388,6 +389,23 @@ void memory_region_init_iommu(MemoryRegion *mr, void memory_region_destroy(MemoryRegion *mr); /** + * memory_region_owner: get a memory region's owner. + * + * @mr: the memory region being queried. + */ +struct Object *memory_region_owner(MemoryRegion *mr); + +/** + * memory_region_set_owner: set the owner for a memory region and all + * the unowned regions below it. + * + * @mr: the memory region being set. + * @owner: the object that acts as the owner + */ +void memory_region_set_owner(MemoryRegion *mr, + struct Object *owner); + +/** * memory_region_size: get a memory region's size. * * @mr: the memory region being queried. diff --git a/memory.c b/memory.c index 49371ee..e855105 100644 --- a/memory.c +++ b/memory.c @@ -826,6 +826,7 @@ void memory_region_init(MemoryRegion *mr, mr->opaque = NULL; mr->iommu_ops = NULL; mr->parent = NULL; + mr->owner = NULL; mr->size = int128_make64(size); if (size == UINT64_MAX) { mr->size = int128_2_64(); @@ -1092,6 +1093,26 @@ void memory_region_destroy(MemoryRegion *mr) g_free(mr->ioeventfds); } +Object *memory_region_owner(MemoryRegion *mr) +{ + return mr->owner; +} + +void memory_region_set_owner(MemoryRegion *mr, + Object *owner) +{ + MemoryRegion *child; + + assert(mr->owner == NULL || mr->owner == owner); + mr->owner = owner; + + QTAILQ_FOREACH(child, &mr->subregions, subregions_link) { + if (child->owner == NULL || child->owner == owner) { + memory_region_set_owner(child, owner); + } + } +} + uint64_t memory_region_size(MemoryRegion *mr) { if (int128_eq(mr->size, int128_2_64())) { -- 1.8.1.4