ui/console: Use qemu_dmabuf_new() and free() helpers instead
This commit introduces utility functions for the creation and deallocation of QemuDmaBuf instances. Additionally, it updates all relevant sections of the codebase to utilize these new utility functions. v7: remove prefix, "dpy_gl_" from all helpers qemu_dmabuf_free() returns without doing anything if input is null (Daniel P. Berrangé <berrange@redhat.com>) call G_DEFINE_AUTOPTR_CLEANUP_FUNC for qemu_dmabuf_free() (Daniel P. Berrangé <berrange@redhat.com>) v8: Introduction of helpers was removed as those were already added by the previous commit v9: set dmabuf->allow_fences to 'true' when dmabuf is created in virtio_gpu_create_dmabuf()/virtio-gpu-udmabuf.c removed unnecessary spaces were accidently added in the patch, 'ui/console: Use qemu_dmabuf_new() a...' v11: Calling qemu_dmabuf_close was removed as closing dmabuf->fd will be done in qemu_dmabuf_free anyway. (Daniel P. Berrangé <berrange@redhat.com>) v12: --- Calling qemu_dmabuf_close separately as qemu_dmabuf_free doesn't do it. --- 'dmabuf' is now allocated space so it should be freed at the end of dbus_scanout_texture v13: --- Immediately free dmabuf after it is released to prevent possible leaking of the ptr (Marc-André Lureau <marcandre.lureau@redhat.com>) --- Use g_autoptr macro to define *dmabuf for auto clean up instead of calling qemu_dmabuf_free (Marc-André Lureau <marcandre.lureau@redhat.com>) v14: --- (vhost-user-gpu) Change qemu_dmabuf_free back to g_clear_pointer as it was done because of some misunderstanding (v13). --- (vhost-user-gpu) g->dmabuf[m->scanout_id] needs to be set to NULL to prevent freed dmabuf to be accessed again in case if(fd==-1)break; happens (before new dmabuf is allocated). Otherwise, it would cause invalid memory access when the same function is executed. Also NULL check should be done before qemu_dmabuf_close (it asserts dmabuf!=NULL.). (Marc-André Lureau <marcandre.lureau@redhat.com>) Suggested-by: Marc-André Lureau <marcandre.lureau@redhat.com> Cc: Philippe Mathieu-Daudé <philmd@linaro.org> Cc: Daniel P. Berrangé <berrange@redhat.com> Cc: Vivek Kasireddy <vivek.kasireddy@intel.com> Signed-off-by: Dongwon Kim <dongwon.kim@intel.com> Message-Id: <20240508175403.3399895-6-dongwon.kim@intel.com>
This commit is contained in:
parent
fa6426805b
commit
c0fcd6334f
@ -249,6 +249,7 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg)
|
||||
case VHOST_USER_GPU_DMABUF_SCANOUT: {
|
||||
VhostUserGpuDMABUFScanout *m = &msg->payload.dmabuf_scanout;
|
||||
int fd = qemu_chr_fe_get_msgfd(&g->vhost_chr);
|
||||
uint64_t modifier = 0;
|
||||
QemuDmaBuf *dmabuf;
|
||||
|
||||
if (m->scanout_id >= g->parent_obj.conf.max_outputs) {
|
||||
@ -261,27 +262,33 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg)
|
||||
|
||||
g->parent_obj.enable = 1;
|
||||
con = g->parent_obj.scanout[m->scanout_id].con;
|
||||
dmabuf = &g->dmabuf[m->scanout_id];
|
||||
qemu_dmabuf_close(dmabuf);
|
||||
dpy_gl_release_dmabuf(con, dmabuf);
|
||||
if (fd == -1) {
|
||||
dpy_gl_scanout_disable(con);
|
||||
break;
|
||||
}
|
||||
*dmabuf = (QemuDmaBuf) {
|
||||
.fd = fd,
|
||||
.width = m->fd_width,
|
||||
.height = m->fd_height,
|
||||
.stride = m->fd_stride,
|
||||
.fourcc = m->fd_drm_fourcc,
|
||||
.y0_top = m->fd_flags & VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP,
|
||||
};
|
||||
if (msg->request == VHOST_USER_GPU_DMABUF_SCANOUT2) {
|
||||
VhostUserGpuDMABUFScanout2 *m2 = &msg->payload.dmabuf_scanout2;
|
||||
dmabuf->modifier = m2->modifier;
|
||||
dmabuf = g->dmabuf[m->scanout_id];
|
||||
|
||||
if (dmabuf) {
|
||||
qemu_dmabuf_close(dmabuf);
|
||||
dpy_gl_release_dmabuf(con, dmabuf);
|
||||
g_clear_pointer(&dmabuf, qemu_dmabuf_free);
|
||||
}
|
||||
|
||||
if (fd == -1) {
|
||||
dpy_gl_scanout_disable(con);
|
||||
g->dmabuf[m->scanout_id] = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (msg->request == VHOST_USER_GPU_DMABUF_SCANOUT2) {
|
||||
VhostUserGpuDMABUFScanout2 *m2 = &msg->payload.dmabuf_scanout2;
|
||||
modifier = m2->modifier;
|
||||
}
|
||||
|
||||
dmabuf = qemu_dmabuf_new(m->fd_width, m->fd_height,
|
||||
m->fd_stride, 0, 0, 0, 0,
|
||||
m->fd_drm_fourcc, modifier,
|
||||
fd, false, m->fd_flags &
|
||||
VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP);
|
||||
|
||||
dpy_gl_scanout_dmabuf(con, dmabuf);
|
||||
g->dmabuf[m->scanout_id] = dmabuf;
|
||||
break;
|
||||
}
|
||||
case VHOST_USER_GPU_DMABUF_UPDATE: {
|
||||
|
@ -162,7 +162,8 @@ static void virtio_gpu_free_dmabuf(VirtIOGPU *g, VGPUDMABuf *dmabuf)
|
||||
struct virtio_gpu_scanout *scanout;
|
||||
|
||||
scanout = &g->parent_obj.scanout[dmabuf->scanout_id];
|
||||
dpy_gl_release_dmabuf(scanout->con, &dmabuf->buf);
|
||||
dpy_gl_release_dmabuf(scanout->con, dmabuf->buf);
|
||||
g_clear_pointer(&dmabuf->buf, qemu_dmabuf_free);
|
||||
QTAILQ_REMOVE(&g->dmabuf.bufs, dmabuf, next);
|
||||
g_free(dmabuf);
|
||||
}
|
||||
@ -181,17 +182,10 @@ static VGPUDMABuf
|
||||
}
|
||||
|
||||
dmabuf = g_new0(VGPUDMABuf, 1);
|
||||
dmabuf->buf.width = r->width;
|
||||
dmabuf->buf.height = r->height;
|
||||
dmabuf->buf.stride = fb->stride;
|
||||
dmabuf->buf.x = r->x;
|
||||
dmabuf->buf.y = r->y;
|
||||
dmabuf->buf.backing_width = fb->width;
|
||||
dmabuf->buf.backing_height = fb->height;
|
||||
dmabuf->buf.fourcc = qemu_pixman_to_drm_format(fb->format);
|
||||
dmabuf->buf.fd = res->dmabuf_fd;
|
||||
dmabuf->buf.allow_fences = true;
|
||||
dmabuf->buf.draw_submitted = false;
|
||||
dmabuf->buf = qemu_dmabuf_new(r->width, r->height, fb->stride,
|
||||
r->x, r->y, fb->width, fb->height,
|
||||
qemu_pixman_to_drm_format(fb->format),
|
||||
0, res->dmabuf_fd, true, false);
|
||||
dmabuf->scanout_id = scanout_id;
|
||||
QTAILQ_INSERT_HEAD(&g->dmabuf.bufs, dmabuf, next);
|
||||
|
||||
@ -217,11 +211,11 @@ int virtio_gpu_update_dmabuf(VirtIOGPU *g,
|
||||
old_primary = g->dmabuf.primary[scanout_id];
|
||||
}
|
||||
|
||||
width = qemu_dmabuf_get_width(&new_primary->buf);
|
||||
height = qemu_dmabuf_get_height(&new_primary->buf);
|
||||
width = qemu_dmabuf_get_width(new_primary->buf);
|
||||
height = qemu_dmabuf_get_height(new_primary->buf);
|
||||
g->dmabuf.primary[scanout_id] = new_primary;
|
||||
qemu_console_resize(scanout->con, width, height);
|
||||
dpy_gl_scanout_dmabuf(scanout->con, &new_primary->buf);
|
||||
dpy_gl_scanout_dmabuf(scanout->con, new_primary->buf);
|
||||
|
||||
if (old_primary) {
|
||||
virtio_gpu_free_dmabuf(g, old_primary);
|
||||
|
@ -241,14 +241,11 @@ static VFIODMABuf *vfio_display_get_dmabuf(VFIOPCIDevice *vdev,
|
||||
|
||||
dmabuf = g_new0(VFIODMABuf, 1);
|
||||
dmabuf->dmabuf_id = plane.dmabuf_id;
|
||||
dmabuf->buf.width = plane.width;
|
||||
dmabuf->buf.height = plane.height;
|
||||
dmabuf->buf.backing_width = plane.width;
|
||||
dmabuf->buf.backing_height = plane.height;
|
||||
dmabuf->buf.stride = plane.stride;
|
||||
dmabuf->buf.fourcc = plane.drm_format;
|
||||
dmabuf->buf.modifier = plane.drm_format_mod;
|
||||
dmabuf->buf.fd = fd;
|
||||
dmabuf->buf = qemu_dmabuf_new(plane.width, plane.height,
|
||||
plane.stride, 0, 0, plane.width,
|
||||
plane.height, plane.drm_format,
|
||||
plane.drm_format_mod, fd, false, false);
|
||||
|
||||
if (plane_type == DRM_PLANE_TYPE_CURSOR) {
|
||||
vfio_display_update_cursor(dmabuf, &plane);
|
||||
}
|
||||
@ -261,8 +258,9 @@ static void vfio_display_free_one_dmabuf(VFIODisplay *dpy, VFIODMABuf *dmabuf)
|
||||
{
|
||||
QTAILQ_REMOVE(&dpy->dmabuf.bufs, dmabuf, next);
|
||||
|
||||
qemu_dmabuf_close(&dmabuf->buf);
|
||||
dpy_gl_release_dmabuf(dpy->con, &dmabuf->buf);
|
||||
qemu_dmabuf_close(dmabuf->buf);
|
||||
dpy_gl_release_dmabuf(dpy->con, dmabuf->buf);
|
||||
g_clear_pointer(&dmabuf->buf, qemu_dmabuf_free);
|
||||
g_free(dmabuf);
|
||||
}
|
||||
|
||||
@ -298,13 +296,13 @@ static void vfio_display_dmabuf_update(void *opaque)
|
||||
return;
|
||||
}
|
||||
|
||||
width = qemu_dmabuf_get_width(&primary->buf);
|
||||
height = qemu_dmabuf_get_height(&primary->buf);
|
||||
width = qemu_dmabuf_get_width(primary->buf);
|
||||
height = qemu_dmabuf_get_height(primary->buf);
|
||||
|
||||
if (dpy->dmabuf.primary != primary) {
|
||||
dpy->dmabuf.primary = primary;
|
||||
qemu_console_resize(dpy->con, width, height);
|
||||
dpy_gl_scanout_dmabuf(dpy->con, &primary->buf);
|
||||
dpy_gl_scanout_dmabuf(dpy->con, primary->buf);
|
||||
free_bufs = true;
|
||||
}
|
||||
|
||||
@ -318,7 +316,7 @@ static void vfio_display_dmabuf_update(void *opaque)
|
||||
if (cursor && (new_cursor || cursor->hot_updates)) {
|
||||
bool have_hot = (cursor->hot_x != 0xffffffff &&
|
||||
cursor->hot_y != 0xffffffff);
|
||||
dpy_gl_cursor_dmabuf(dpy->con, &cursor->buf, have_hot,
|
||||
dpy_gl_cursor_dmabuf(dpy->con, cursor->buf, have_hot,
|
||||
cursor->hot_x, cursor->hot_y);
|
||||
cursor->hot_updates = 0;
|
||||
} else if (!cursor && new_cursor) {
|
||||
|
@ -148,7 +148,7 @@ typedef struct VFIOGroup {
|
||||
} VFIOGroup;
|
||||
|
||||
typedef struct VFIODMABuf {
|
||||
QemuDmaBuf buf;
|
||||
QemuDmaBuf *buf;
|
||||
uint32_t pos_x, pos_y, pos_updates;
|
||||
uint32_t hot_x, hot_y, hot_updates;
|
||||
int dmabuf_id;
|
||||
|
@ -169,7 +169,7 @@ struct VirtIOGPUBaseClass {
|
||||
DEFINE_PROP_UINT32("yres", _state, _conf.yres, 800)
|
||||
|
||||
typedef struct VGPUDMABuf {
|
||||
QemuDmaBuf buf;
|
||||
QemuDmaBuf *buf;
|
||||
uint32_t scanout_id;
|
||||
QTAILQ_ENTRY(VGPUDMABuf) next;
|
||||
} VGPUDMABuf;
|
||||
@ -238,7 +238,7 @@ struct VhostUserGPU {
|
||||
VhostUserBackend *vhost;
|
||||
int vhost_gpu_fd; /* closed by the chardev */
|
||||
CharBackend vhost_chr;
|
||||
QemuDmaBuf dmabuf[VIRTIO_GPU_MAX_SCANOUTS];
|
||||
QemuDmaBuf *dmabuf[VIRTIO_GPU_MAX_SCANOUTS];
|
||||
bool backend_blocked;
|
||||
};
|
||||
|
||||
|
@ -442,28 +442,24 @@ static void dbus_scanout_texture(DisplayChangeListener *dcl,
|
||||
trace_dbus_scanout_texture(tex_id, backing_y_0_top,
|
||||
backing_width, backing_height, x, y, w, h);
|
||||
#ifdef CONFIG_GBM
|
||||
QemuDmaBuf dmabuf = {
|
||||
.width = w,
|
||||
.height = h,
|
||||
.y0_top = backing_y_0_top,
|
||||
.x = x,
|
||||
.y = y,
|
||||
.backing_width = backing_width,
|
||||
.backing_height = backing_height,
|
||||
};
|
||||
g_autoptr(QemuDmaBuf) dmabuf = NULL;
|
||||
int fd;
|
||||
uint32_t stride, fourcc;
|
||||
uint64_t modifier;
|
||||
|
||||
assert(tex_id);
|
||||
dmabuf.fd = egl_get_fd_for_texture(
|
||||
tex_id, (EGLint *)&dmabuf.stride,
|
||||
(EGLint *)&dmabuf.fourcc,
|
||||
&dmabuf.modifier);
|
||||
if (dmabuf.fd < 0) {
|
||||
fd = egl_get_fd_for_texture(tex_id, (EGLint *)&stride, (EGLint *)&fourcc,
|
||||
&modifier);
|
||||
if (fd < 0) {
|
||||
error_report("%s: failed to get fd for texture", __func__);
|
||||
return;
|
||||
}
|
||||
dmabuf = qemu_dmabuf_new(w, h, stride, x, y, backing_width,
|
||||
backing_height, fourcc, modifier, fd,
|
||||
false, backing_y_0_top);
|
||||
|
||||
dbus_scanout_dmabuf(dcl, &dmabuf);
|
||||
close(dmabuf.fd);
|
||||
dbus_scanout_dmabuf(dcl, dmabuf);
|
||||
qemu_dmabuf_close(dmabuf);
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
|
Loading…
Reference in New Issue
Block a user