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:
parent
8dc7fd56dd
commit
d57f252add
|
@ -32,33 +32,58 @@ struct RAMFBState {
|
||||||
struct RAMFBCfg cfg;
|
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)
|
static void ramfb_fw_cfg_write(void *dev, off_t offset, size_t len)
|
||||||
{
|
{
|
||||||
RAMFBState *s = dev;
|
RAMFBState *s = dev;
|
||||||
void *framebuffer;
|
|
||||||
uint32_t fourcc, format;
|
uint32_t fourcc, format;
|
||||||
hwaddr stride, addr, length;
|
hwaddr stride, addr;
|
||||||
|
|
||||||
s->width = be32_to_cpu(s->cfg.width);
|
s->width = be32_to_cpu(s->cfg.width);
|
||||||
s->height = be32_to_cpu(s->cfg.height);
|
s->height = be32_to_cpu(s->cfg.height);
|
||||||
stride = be32_to_cpu(s->cfg.stride);
|
stride = be32_to_cpu(s->cfg.stride);
|
||||||
fourcc = be32_to_cpu(s->cfg.fourcc);
|
fourcc = be32_to_cpu(s->cfg.fourcc);
|
||||||
addr = be64_to_cpu(s->cfg.addr);
|
addr = be64_to_cpu(s->cfg.addr);
|
||||||
length = stride * s->height;
|
|
||||||
format = qemu_drm_format_to_pixman(fourcc);
|
format = qemu_drm_format_to_pixman(fourcc);
|
||||||
|
|
||||||
fprintf(stderr, "%s: %dx%d @ 0x%" PRIx64 "\n", __func__,
|
fprintf(stderr, "%s: %dx%d @ 0x%" PRIx64 "\n", __func__,
|
||||||
s->width, s->height, addr);
|
s->width, s->height, addr);
|
||||||
framebuffer = address_space_map(&address_space_memory,
|
s->ds = ramfb_create_display_surface(s->width, s->height,
|
||||||
addr, &length, false,
|
format, stride, addr);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ramfb_display_update(QemuConsole *con, RAMFBState *s)
|
void ramfb_display_update(QemuConsole *con, RAMFBState *s)
|
||||||
|
|
Loading…
Reference in a new issue