@ -148,6 +148,7 @@ static bool memory_listener_match(MemoryListener *listener,
} \
} while ( 0 )
/* No need to ref/unref .mr, the FlatRange keeps it alive. */
# define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback) \
MEMORY_LISTENER_CALL ( callback , dir , ( & ( MemoryRegionSection ) { \
. mr = ( fr ) - > mr , \
@ -263,11 +264,17 @@ static void flatview_insert(FlatView *view, unsigned pos, FlatRange *range)
memmove ( view - > ranges + pos + 1 , view - > ranges + pos ,
( view - > nr - pos ) * sizeof ( FlatRange ) ) ;
view - > ranges [ pos ] = * range ;
memory_region_ref ( range - > mr ) ;
+ + view - > nr ;
}
static void flatview_destroy ( FlatView * view )
{
int i ;
for ( i = 0 ; i < view - > nr ; i + + ) {
memory_region_unref ( view - > ranges [ i ] . mr ) ;
}
g_free ( view - > ranges ) ;
}
@ -709,6 +716,11 @@ static void memory_region_destructor_ram(MemoryRegion *mr)
qemu_ram_free ( mr - > ram_addr ) ;
}
static void memory_region_destructor_alias ( MemoryRegion * mr )
{
memory_region_unref ( mr - > alias ) ;
}
static void memory_region_destructor_ram_from_ptr ( MemoryRegion * mr )
{
qemu_ram_free_from_ptr ( mr - > ram_addr ) ;
@ -964,6 +976,8 @@ void memory_region_init_alias(MemoryRegion *mr,
uint64_t size )
{
memory_region_init ( mr , owner , name , size ) ;
memory_region_ref ( orig ) ;
mr - > destructor = memory_region_destructor_alias ;
mr - > alias = orig ;
mr - > alias_offset = offset ;
}
@ -1342,6 +1356,7 @@ static void memory_region_add_subregion_common(MemoryRegion *mr,
memory_region_transaction_begin ( ) ;
assert ( ! subregion - > parent ) ;
memory_region_ref ( subregion ) ;
subregion - > parent = mr ;
subregion - > addr = offset ;
QTAILQ_FOREACH ( other , & mr - > subregions , subregions_link ) {
@ -1404,6 +1419,7 @@ void memory_region_del_subregion(MemoryRegion *mr,
assert ( subregion - > parent = = mr ) ;
subregion - > parent = NULL ;
QTAILQ_REMOVE ( & mr - > subregions , subregion , subregions_link ) ;
memory_region_unref ( subregion ) ;
memory_region_update_pending | = mr - > enabled & & subregion - > enabled ;
memory_region_transaction_commit ( ) ;
}
@ -1431,12 +1447,14 @@ void memory_region_set_address(MemoryRegion *mr, hwaddr addr)
}
memory_region_transaction_begin ( ) ;
memory_region_ref ( mr ) ;
memory_region_del_subregion ( parent , mr ) ;
if ( may_overlap ) {
memory_region_add_subregion_overlap ( parent , addr , mr , priority ) ;
} else {
memory_region_add_subregion ( parent , addr , mr ) ;
}
memory_region_unref ( mr ) ;
memory_region_transaction_commit ( ) ;
}
@ -1484,6 +1502,7 @@ bool memory_region_present(MemoryRegion *parent, hwaddr addr)
if ( ! mr ) {
return false ;
}
memory_region_unref ( mr ) ;
return true ;
}
@ -1523,6 +1542,8 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr,
ret . size = range . size ;
ret . offset_within_address_space = int128_get64 ( range . start ) ;
ret . readonly = fr - > readonly ;
memory_region_ref ( ret . mr ) ;
return ret ;
}