From patchwork Fri Jul 7 14:42:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 107208 Delivered-To: patches@linaro.org Received: by 10.140.101.44 with SMTP id t41csp147305qge; Fri, 7 Jul 2017 07:43:04 -0700 (PDT) X-Received: by 10.98.69.219 with SMTP id n88mr32235474pfi.192.1499438584786; Fri, 07 Jul 2017 07:43:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1499438584; cv=none; d=google.com; s=arc-20160816; b=eLAr4s1x800/0Wa8843Kx8aR6cLH/Dh39Ct6NrvycY80oBWp+HY6ngKZK3i+A+YAUe 2jF1qQE2PYb4iOwtDlOuoTgSKKrotp6e+gEv5Ej4qt26gI0tM/gp1JbMRanV3xcHyv/O og4KLMsiZMl2mE+YWeR6iaZnj4/EVBUhMI1hhm/+05rve+UBIyIzfth9xP1cTBBKDC8A 7vJ5sxWnJNowwsrsq1kRnPausCwGa74Z1mBIxVTg1rgm4ZhBDQs4B6HCZnb20GTYfZ/w JBU7LYfAh0CN89hYNLVopgbbzKXZ3VXNJ83bi0gXvE8zwuE0ROmzEtB1ZD1tqCvZNYyN wQ8A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=3582pPherCGhdhf48U5pUjHXWNUmi/9ewznmRCJ0Bms=; b=r/R7F/DA54U/6Kl9yJC/jl7vKFNW5SMq/SyQPEsigyhD0vElxsTKCdZsOQzo8Wy1yO mDhiQCnUm6/dbn/CSCW2R5ISNE0KaUdTLPa+cj1O62Z+DuA+VBhZPLfC59mmptTpnlnn hqwEulJjGNMDG0cikIjfHt/VneQOm5srre3QEB+vZThmVqHI+r2pwdHr2qwNDZ0yOpab h43d1nw9MroRiAZF30JoLeat3K0wzM7TeB9MgeVWz5T9kcbyHJhnTjKijNsE5hSlbG7v SHSr0OjAsyfMcJDkp/M0ytxNGB18Ln2kcidR07p4l+XX1PqKlA4f7pOElOXiZ7zmUtYv FEmg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id d71si2388293pgc.68.2017.07.07.07.43.04 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 07 Jul 2017 07:43:04 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.84_2) (envelope-from ) id 1dTUTF-0005tG-B3; Fri, 07 Jul 2017 15:43:01 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Paolo Bonzini , Eduardo Habkost , Marcel Apfelbaum , Igor Mammedov Subject: [PATCH 05/11] memory.h: Add memory_region_init_{ram, rom, rom_device}() handling migration Date: Fri, 7 Jul 2017 15:42:51 +0100 Message-Id: <1499438577-7674-6-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1499438577-7674-1-git-send-email-peter.maydell@linaro.org> References: <1499438577-7674-1-git-send-email-peter.maydell@linaro.org> Add new utility functions which both initialize a RAM MemoryRegion and arrange for its contents to be migrated; we give thes the memory_region_init_ram(), memory_region_init_rom() and memory_region_init_rom_device() names that we just freed up by renaming the old implementations to _nomigrate(). Signed-off-by: Peter Maydell --- include/exec/memory.h | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/hw/boards.h | 3 +- memory.c | 76 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+), 1 deletion(-) -- 2.7.4 diff --git a/include/exec/memory.h b/include/exec/memory.h index d1c6443..b49b81d 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -658,6 +658,94 @@ void memory_region_init_iommu(MemoryRegion *mr, uint64_t size); /** + * memory_region_init_ram - Initialize RAM memory region. Accesses into the + * region will modify memory directly. + * + * @mr: the #MemoryRegion to be initialized + * @owner: the object that tracks the region's reference count (must be + * TYPE_DEVICE or a subclass of TYPE_DEVICE, or NULL) + * @name: name of the memory region + * @size: size of the region in bytes + * @errp: pointer to Error*, to store an error if it happens. + * + * This function allocates RAM for a board model or device, and + * arranges for it to be migrated (by calling vmstate_register_ram() + * if @owner is a DeviceState, or vmstate_register_ram_global() if + * @owner is NULL). + * + * TODO: Currently we restrict @owner to being either NULL (for + * global RAM regions with no owner) or devices, so that we can + * give the RAM block a unique name for migration purposes. + * We should lift this restriction and allow arbitrary Objects. + * If you pass a non-NULL non-device @owner then we will assert. + */ +void memory_region_init_ram(MemoryRegion *mr, + struct Object *owner, + const char *name, + uint64_t size, + Error **errp); + +/** + * memory_region_init_rom: Initialize a ROM memory region. + * + * This has the same effect as calling memory_region_init_ram() + * and then marking the resulting region read-only with + * memory_region_set_readonly(). This includes arranging for the + * contents to be migrated. + * + * TODO: Currently we restrict @owner to being either NULL (for + * global RAM regions with no owner) or devices, so that we can + * give the RAM block a unique name for migration purposes. + * We should lift this restriction and allow arbitrary Objects. + * If you pass a non-NULL non-device @owner then we will assert. + * + * @mr: the #MemoryRegion to be initialized. + * @owner: the object that tracks the region's reference count + * @name: Region name, becomes part of RAMBlock name used in migration stream + * must be unique within any device + * @size: size of the region. + * @errp: pointer to Error*, to store an error if it happens. + */ +void memory_region_init_rom(MemoryRegion *mr, + struct Object *owner, + const char *name, + uint64_t size, + Error **errp); + +/** + * memory_region_init_rom_device: Initialize a ROM memory region. + * Writes are handled via callbacks. + * + * This function initializes a memory region backed by RAM for reads + * and callbacks for writes, and arranges for the RAM backing to + * be migrated (by calling vmstate_register_ram() + * if @owner is a DeviceState, or vmstate_register_ram_global() if + * @owner is NULL). + * + * TODO: Currently we restrict @owner to being either NULL (for + * global RAM regions with no owner) or devices, so that we can + * give the RAM block a unique name for migration purposes. + * We should lift this restriction and allow arbitrary Objects. + * If you pass a non-NULL non-device @owner then we will assert. + * + * @mr: the #MemoryRegion to be initialized. + * @owner: the object that tracks the region's reference count + * @ops: callbacks for write access handling (must not be NULL). + * @name: Region name, becomes part of RAMBlock name used in migration stream + * must be unique within any device + * @size: size of the region. + * @errp: pointer to Error*, to store an error if it happens. + */ +void memory_region_init_rom_device(MemoryRegion *mr, + struct Object *owner, + const MemoryRegionOps *ops, + void *opaque, + const char *name, + uint64_t size, + Error **errp); + + +/** * memory_region_owner: get a memory region's owner. * * @mr: the memory region being queried. diff --git a/include/hw/boards.h b/include/hw/boards.h index 1bc5389..a127a97 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -35,7 +35,8 @@ * * Smaller pieces of memory (display RAM, static RAMs, etc) don't need * to be backed via the -mem-path memory backend and can simply - * be created via memory_region_init_ram(). + * be created via memory_region_allocate_aux_memory() or + * memory_region_init_ram(). */ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner, const char *name, diff --git a/memory.c b/memory.c index 5653d3c..17bca58 100644 --- a/memory.c +++ b/memory.c @@ -32,6 +32,7 @@ #include "sysemu/sysemu.h" #include "hw/misc/mmio_interface.h" #include "hw/qdev-properties.h" +#include "migration/vmstate.h" //#define DEBUG_UNASSIGNED @@ -2817,6 +2818,81 @@ void mtree_info(fprintf_function mon_printf, void *f, bool flatview) } } +void memory_region_init_ram(MemoryRegion *mr, + struct Object *owner, + const char *name, + uint64_t size, + Error **errp) +{ + DeviceState *owner_dev; + Error *err = NULL; + + memory_region_init_ram_nomigrate(mr, owner, name, size, &err); + if (err) { + error_propagate(errp, err); + return; + } + /* This will assert if owner is neither NULL nor a DeviceState. + * We only want the owner here for the purposes of defining a + * unique name for migration. TODO: Ideally we should implement + * a naming scheme for Objects which are not DeviceStates, in + * which case we can relax this restriction. + */ + owner_dev = DEVICE(owner); + vmstate_register_ram(mr, owner_dev); +} + +void memory_region_init_rom(MemoryRegion *mr, + struct Object *owner, + const char *name, + uint64_t size, + Error **errp) +{ + DeviceState *owner_dev; + Error *err = NULL; + + memory_region_init_rom_nomigrate(mr, owner, name, size, &err); + if (err) { + error_propagate(errp, err); + return; + } + /* This will assert if owner is neither NULL nor a DeviceState. + * We only want the owner here for the purposes of defining a + * unique name for migration. TODO: Ideally we should implement + * a naming scheme for Objects which are not DeviceStates, in + * which case we can relax this restriction. + */ + owner_dev = DEVICE(owner); + vmstate_register_ram(mr, owner_dev); +} + +void memory_region_init_rom_device(MemoryRegion *mr, + struct Object *owner, + const MemoryRegionOps *ops, + void *opaque, + const char *name, + uint64_t size, + Error **errp) +{ + DeviceState *owner_dev; + Error *err = NULL; + + memory_region_init_rom_device_nomigrate(mr, owner, ops, opaque, + name, size, &err); + if (err) { + error_propagate(errp, err); + return; + } + /* This will assert if owner is neither NULL nor a DeviceState. + * We only want the owner here for the purposes of defining a + * unique name for migration. TODO: Ideally we should implement + * a naming scheme for Objects which are not DeviceStates, in + * which case we can relax this restriction. + */ + owner_dev = DEVICE(owner); + vmstate_register_ram(mr, owner_dev); +} + static const TypeInfo memory_region_info = { .parent = TYPE_OBJECT, .name = TYPE_MEMORY_REGION,