diff mbox series

[PULL,1/3] hw/display/ramfb: fix guest memory un-mapping

Message ID 20190524085717.3493-2-kraxel@redhat.com (mailing list archive)
State New, archived
Headers show
Series [PULL,1/3] hw/display/ramfb: fix guest memory un-mapping | expand

Commit Message

Gerd Hoffmann May 24, 2019, 8:57 a.m. UTC
From: Hou Qiming <hqm03ster@gmail.com>

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>
---
 hw/display/ramfb.c | 51 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 38 insertions(+), 13 deletions(-)
diff mbox series

Patch

diff --git a/hw/display/ramfb.c b/hw/display/ramfb.c
index 25c8ad7c252e..1955b048dd24 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)