From dfde4e6e1a868f60033ece0590b1f75e6c57fa16 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 6 May 2013 10:46:11 +0200 Subject: memory: add ref/unref calls Add ref/unref calls at the following places: - places where memory regions are stashed by a listener and used outside the BQL (including in Xen or KVM). - memory_region_find callsites - creation of aliases and containers (only the aliased/contained region gets a reference to avoid loops) - around calls to del_subregion/add_subregion, where the region could disappear after the first call Signed-off-by: Paolo Bonzini --- hw/display/exynos4210_fimd.c | 6 ++++++ hw/display/framebuffer.c | 12 +++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) (limited to 'hw/display') diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c index d9088d9..b520f52 100644 --- a/hw/display/exynos4210_fimd.c +++ b/hw/display/exynos4210_fimd.c @@ -1126,6 +1126,11 @@ static void fimd_update_memory_section(Exynos4210fimdState *s, unsigned win) /* Total number of bytes of virtual screen used by current window */ w->fb_len = fb_mapped_len = (w->virtpage_width + w->virtpage_offsize) * (w->rightbot_y - w->lefttop_y + 1); + + /* TODO: add .exit and unref the region there. Not needed yet since sysbus + * does not support hot-unplug. + */ + memory_region_unref(w->mem_section.mr); w->mem_section = memory_region_find(sysbus_address_space(&s->busdev), fb_start_addr, w->fb_len); assert(w->mem_section.mr); @@ -1154,6 +1159,7 @@ static void fimd_update_memory_section(Exynos4210fimdState *s, unsigned win) return; error_return: + memory_region_unref(w->mem_section.mr); w->mem_section.mr = NULL; w->mem_section.size = int128_zero(); w->host_fb_addr = NULL; diff --git a/hw/display/framebuffer.c b/hw/display/framebuffer.c index 49c9e59..4546e42 100644 --- a/hw/display/framebuffer.c +++ b/hw/display/framebuffer.c @@ -54,11 +54,11 @@ void framebuffer_update_display( src_len = src_width * rows; mem_section = memory_region_find(address_space, base, src_len); + mem = mem_section.mr; if (int128_get64(mem_section.size) != src_len || !memory_region_is_ram(mem_section.mr)) { - return; + goto out; } - mem = mem_section.mr; assert(mem); assert(mem_section.offset_within_address_space == base); @@ -68,10 +68,10 @@ void framebuffer_update_display( but it's not really worth it as dirty flag tracking will probably already have failed above. */ if (!src_base) - return; + goto out; if (src_len != src_width * rows) { cpu_physical_memory_unmap(src_base, src_len, 0, 0); - return; + goto out; } src = src_base; dest = surface_data(ds); @@ -102,10 +102,12 @@ void framebuffer_update_display( } cpu_physical_memory_unmap(src_base, src_len, 0, 0); if (first < 0) { - return; + goto out; } memory_region_reset_dirty(mem, mem_section.offset_within_region, src_len, DIRTY_MEMORY_VGA); *first_row = first; *last_row = last; +out: + memory_region_unref(mem); } -- cgit v1.1