diff options
author | Hou Qiming <hqm03ster@gmail.com> | 2019-05-13 14:57:29 +0300 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2019-05-24 09:10:29 +0200 |
commit | d57f252addefa0a66db554038b063fd2331bb269 (patch) | |
tree | 8b67bff2598ea2442880abdc4e521fbcc3f7ff49 /hw | |
parent | 8dc7fd56dd4f56ab8ff1df3765ae6b5d3ac11c5e (diff) | |
download | qemu-d57f252addefa0a66db554038b063fd2331bb269.zip qemu-d57f252addefa0a66db554038b063fd2331bb269.tar.gz qemu-d57f252addefa0a66db554038b063fd2331bb269.tar.bz2 |
hw/display/ramfb: fix guest memory un-mapping
Pulled back the `qemu_create_displaysurface_guestmem` function to create
the display surface so that the guest memory gets properly unmapped.
Signed-off-by: HOU Qiming <hqm03ster@gmail.com>
Signed-off-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Message-id: 20190513115731.17588-2-marcel.apfelbaum@gmail.com
[rename the new functions and use QEMU coding style]
Signed-off-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/display/ramfb.c | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/hw/display/ramfb.c b/hw/display/ramfb.c index 25c8ad7..1955b04 100644 --- a/hw/display/ramfb.c +++ b/hw/display/ramfb.c @@ -32,33 +32,58 @@ struct RAMFBState { struct RAMFBCfg cfg; }; +static void ramfb_unmap_display_surface(pixman_image_t *image, void *unused) +{ + void *data = pixman_image_get_data(image); + uint32_t size = pixman_image_get_stride(image) * + pixman_image_get_height(image); + cpu_physical_memory_unmap(data, size, 0, 0); +} + +static DisplaySurface *ramfb_create_display_surface(int width, int height, + pixman_format_code_t format, + int linesize, uint64_t addr) +{ + DisplaySurface *surface; + hwaddr size; + void *data; + + if (linesize == 0) { + linesize = width * PIXMAN_FORMAT_BPP(format) / 8; + } + + size = (hwaddr)linesize * height; + data = cpu_physical_memory_map(addr, &size, 0); + if (size != (hwaddr)linesize * height) { + cpu_physical_memory_unmap(data, size, 0, 0); + return NULL; + } + + surface = qemu_create_displaysurface_from(width, height, + format, linesize, data); + pixman_image_set_destroy_function(surface->image, + ramfb_unmap_display_surface, NULL); + + return surface; +} + static void ramfb_fw_cfg_write(void *dev, off_t offset, size_t len) { RAMFBState *s = dev; - void *framebuffer; uint32_t fourcc, format; - hwaddr stride, addr, length; + hwaddr stride, addr; s->width = be32_to_cpu(s->cfg.width); s->height = be32_to_cpu(s->cfg.height); stride = be32_to_cpu(s->cfg.stride); fourcc = be32_to_cpu(s->cfg.fourcc); addr = be64_to_cpu(s->cfg.addr); - length = stride * s->height; format = qemu_drm_format_to_pixman(fourcc); fprintf(stderr, "%s: %dx%d @ 0x%" PRIx64 "\n", __func__, s->width, s->height, addr); - framebuffer = address_space_map(&address_space_memory, - addr, &length, false, - MEMTXATTRS_UNSPECIFIED); - if (!framebuffer || length < stride * s->height) { - s->width = 0; - s->height = 0; - return; - } - s->ds = qemu_create_displaysurface_from(s->width, s->height, - format, stride, framebuffer); + s->ds = ramfb_create_display_surface(s->width, s->height, + format, stride, addr); } void ramfb_display_update(QemuConsole *con, RAMFBState *s) |