const char *name,
uint64_t size)
{
- if (!owner) {
- owner = container_get(qdev_get_machine(), "/unattached");
- }
-
object_initialize(mr, sizeof(*mr), TYPE_MEMORY_REGION);
mr->size = int128_make64(size);
if (size == UINT64_MAX) {
mr->size = int128_2_64();
}
mr->name = g_strdup(name);
+ mr->owner = owner;
if (name) {
char *escaped_name = memory_region_escape_name(name);
char *name_array = g_strdup_printf("%s[*]", escaped_name);
+
+ if (!owner) {
+ owner = container_get(qdev_get_machine(), "/unattached");
+ }
+
object_property_add_child(owner, name_array, OBJECT(mr), &error_abort);
object_unref(OBJECT(mr));
g_free(name_array);
* The memory region is a child of its owner. As long as the
* owner doesn't call unparent itself on the memory region,
* ref-ing the owner will also keep the memory region alive.
- * Memory regions without an owner are supposed to never go away,
- * but we still ref/unref them for debugging purposes.
+ * Memory regions without an owner are supposed to never go away;
+ * we do not ref/unref them because it slows down DMA sensibly.
*/
- Object *obj = OBJECT(mr);
- if (obj && obj->parent) {
- object_ref(obj->parent);
- } else {
- object_ref(obj);
+ if (mr && mr->owner) {
+ object_ref(mr->owner);
}
}
void memory_region_unref(MemoryRegion *mr)
{
- Object *obj = OBJECT(mr);
- if (obj && obj->parent) {
- object_unref(obj->parent);
- } else {
- object_unref(obj);
+ if (mr && mr->owner) {
+ object_unref(mr->owner);
}
}
return mr->name;
}
-bool memory_region_is_ram(MemoryRegion *mr)
-{
- return mr->ram;
-}
-
bool memory_region_is_skip_dump(MemoryRegion *mr)
{
return mr->skip_dump;
return memory_region_get_dirty_log_mask(mr) & (1 << client);
}
-bool memory_region_is_rom(MemoryRegion *mr)
-{
- return mr->ram && mr->readonly;
-}
-
-bool memory_region_is_iommu(MemoryRegion *mr)
-{
- return mr->iommu_ops;
-}
-
void memory_region_register_iommu_notifier(MemoryRegion *mr, Notifier *n)
{
notifier_list_add(&mr->iommu_notify, n);
void *memory_region_get_ram_ptr(MemoryRegion *mr)
{
- if (mr->alias) {
- return memory_region_get_ram_ptr(mr->alias) + mr->alias_offset;
- }
+ void *ptr;
+ uint64_t offset = 0;
+ rcu_read_lock();
+ while (mr->alias) {
+ offset += mr->alias_offset;
+ mr = mr->alias;
+ }
assert(mr->ram_addr != RAM_ADDR_INVALID);
+ ptr = qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK);
+ rcu_read_unlock();
- return qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK);
+ return ptr + offset;
}
void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp)
memory_region_transaction_commit();
}
-ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr)
-{
- return mr->ram_addr;
-}
-
uint64_t memory_region_get_alignment(const MemoryRegion *mr)
{
return mr->align;