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>
This commit is contained in:
Hou Qiming 2019-05-13 14:57:29 +03:00 committed by Gerd Hoffmann
parent 8dc7fd56dd
commit d57f252add

View File

@ -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)