Skip to content

Commit a146af8

Browse files
committed
Merge remote-tracking branch 'remotes/kraxel/tags/vga-20210723-pull-request' into staging
vga: fixes for qxl and virtio-gpu # gpg: Signature made Fri 23 Jul 2021 06:54:34 BST # gpg: using RSA key A0328CFFB93A17A79901FE7D4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <[email protected]>" [full] # gpg: aka "Gerd Hoffmann <[email protected]>" [full] # gpg: aka "Gerd Hoffmann (private) <[email protected]>" [full] # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/vga-20210723-pull-request: hw/display: fix virgl reset regression vl: add virtio-vga-gl to the default_list hw/display: fail early when multiple virgl devices are requested Revert "qxl: add migration blocker to avoid pre-save assert" qxl: remove assert in qxl_pre_save. hw/display/virtio-gpu: Fix memory leak (CID 1453811) Signed-off-by: Peter Maydell <[email protected]>
2 parents 7b7ca8e + 8a13b9b commit a146af8

File tree

7 files changed

+37
-62
lines changed

7 files changed

+37
-62
lines changed

hw/display/qxl.c

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#include "qemu/module.h"
3131
#include "hw/qdev-properties.h"
3232
#include "sysemu/runstate.h"
33-
#include "migration/blocker.h"
3433
#include "migration/vmstate.h"
3534
#include "trace.h"
3635

@@ -666,30 +665,6 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
666665
qxl->guest_primary.commands++;
667666
qxl_track_command(qxl, ext);
668667
qxl_log_command(qxl, "cmd", ext);
669-
{
670-
/*
671-
* Windows 8 drivers place qxl commands in the vram
672-
* (instead of the ram) bar. We can't live migrate such a
673-
* guest, so add a migration blocker in case we detect
674-
* this, to avoid triggering the assert in pre_save().
675-
*
676-
* https://cgit.freedesktop.org/spice/win32/qxl-wddm-dod/commit/?id=f6e099db39e7d0787f294d5fd0dce328b5210faa
677-
*/
678-
void *msg = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
679-
if (msg != NULL && (
680-
msg < (void *)qxl->vga.vram_ptr ||
681-
msg > ((void *)qxl->vga.vram_ptr + qxl->vga.vram_size))) {
682-
if (!qxl->migration_blocker) {
683-
Error *local_err = NULL;
684-
error_setg(&qxl->migration_blocker,
685-
"qxl: guest bug: command not in ram bar");
686-
migrate_add_blocker(qxl->migration_blocker, &local_err);
687-
if (local_err) {
688-
error_report_err(local_err);
689-
}
690-
}
691-
}
692-
}
693668
trace_qxl_ring_command_get(qxl->id, qxl_mode_to_string(qxl->mode));
694669
return true;
695670
default:
@@ -1283,12 +1258,6 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
12831258
qemu_spice_create_host_memslot(&d->ssd);
12841259
qxl_soft_reset(d);
12851260

1286-
if (d->migration_blocker) {
1287-
migrate_del_blocker(d->migration_blocker);
1288-
error_free(d->migration_blocker);
1289-
d->migration_blocker = NULL;
1290-
}
1291-
12921261
if (startstop) {
12931262
qemu_spice_display_start();
12941263
}
@@ -2283,7 +2252,9 @@ static int qxl_pre_save(void *opaque)
22832252
} else {
22842253
d->last_release_offset = (uint8_t *)d->last_release - ram_start;
22852254
}
2286-
assert(d->last_release_offset < d->vga.vram_size);
2255+
if (d->last_release_offset < d->vga.vram_size) {
2256+
return 1;
2257+
}
22872258

22882259
return 0;
22892260
}

hw/display/qxl.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ struct PCIQXLDevice {
3939
uint32_t cmdlog;
4040

4141
uint32_t guest_bug;
42-
Error *migration_blocker;
4342

4443
enum qxl_mode mode;
4544
uint32_t cmdflags;

hw/display/virtio-gpu-gl.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,7 @@ static void virtio_gpu_gl_update_cursor_data(VirtIOGPU *g,
5151
static void virtio_gpu_gl_flushed(VirtIOGPUBase *b)
5252
{
5353
VirtIOGPU *g = VIRTIO_GPU(b);
54-
VirtIOGPUGL *gl = VIRTIO_GPU_GL(b);
5554

56-
if (gl->renderer_reset) {
57-
gl->renderer_reset = false;
58-
virtio_gpu_virgl_reset(g);
59-
}
6055
virtio_gpu_process_cmdq(g);
6156
}
6257

@@ -74,6 +69,10 @@ static void virtio_gpu_gl_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
7469
virtio_gpu_virgl_init(g);
7570
gl->renderer_inited = true;
7671
}
72+
if (gl->renderer_reset) {
73+
gl->renderer_reset = false;
74+
virtio_gpu_virgl_reset(g);
75+
}
7776

7877
cmd = virtqueue_pop(vq, sizeof(struct virtio_gpu_ctrl_command));
7978
while (cmd) {
@@ -95,12 +94,13 @@ static void virtio_gpu_gl_reset(VirtIODevice *vdev)
9594

9695
virtio_gpu_reset(vdev);
9796

98-
if (gl->renderer_inited) {
99-
if (g->parent_obj.renderer_blocked) {
100-
gl->renderer_reset = true;
101-
} else {
102-
virtio_gpu_virgl_reset(g);
103-
}
97+
/*
98+
* GL functions must be called with the associated GL context in main
99+
* thread, and when the renderer is unblocked.
100+
*/
101+
if (gl->renderer_inited && !gl->renderer_reset) {
102+
virtio_gpu_virgl_reset_scanout(g);
103+
gl->renderer_reset = true;
104104
}
105105
}
106106

@@ -113,6 +113,11 @@ static void virtio_gpu_gl_device_realize(DeviceState *qdev, Error **errp)
113113
return;
114114
#endif
115115

116+
if (!object_resolve_path_type("", TYPE_VIRTIO_GPU_GL, NULL)) {
117+
error_setg(errp, "at most one %s device is permitted", TYPE_VIRTIO_GPU_GL);
118+
return;
119+
}
120+
116121
if (!display_opengl) {
117122
error_setg(errp, "opengl is not available");
118123
return;

hw/display/virtio-gpu-virgl.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -588,17 +588,21 @@ void virtio_gpu_virgl_fence_poll(VirtIOGPU *g)
588588
virtio_gpu_fence_poll(g);
589589
}
590590

591-
void virtio_gpu_virgl_reset(VirtIOGPU *g)
591+
void virtio_gpu_virgl_reset_scanout(VirtIOGPU *g)
592592
{
593593
int i;
594594

595-
virgl_renderer_reset();
596595
for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
597596
dpy_gfx_replace_surface(g->parent_obj.scanout[i].con, NULL);
598597
dpy_gl_scanout_disable(g->parent_obj.scanout[i].con);
599598
}
600599
}
601600

601+
void virtio_gpu_virgl_reset(VirtIOGPU *g)
602+
{
603+
virgl_renderer_reset();
604+
}
605+
602606
int virtio_gpu_virgl_init(VirtIOGPU *g)
603607
{
604608
int ret;

hw/display/virtio-gpu.c

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -340,37 +340,31 @@ static void virtio_gpu_resource_create_blob(VirtIOGPU *g,
340340
return;
341341
}
342342

343-
res = virtio_gpu_find_resource(g, cblob.resource_id);
344-
if (res) {
345-
qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n",
346-
__func__, cblob.resource_id);
347-
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
348-
return;
349-
}
350-
351-
res = g_new0(struct virtio_gpu_simple_resource, 1);
352-
res->resource_id = cblob.resource_id;
353-
res->blob_size = cblob.size;
354-
355343
if (cblob.blob_mem != VIRTIO_GPU_BLOB_MEM_GUEST &&
356344
cblob.blob_flags != VIRTIO_GPU_BLOB_FLAG_USE_SHAREABLE) {
357345
qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid memory type\n",
358346
__func__);
359347
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
360-
g_free(res);
361348
return;
362349
}
363350

364-
if (res->iov) {
365-
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
351+
if (virtio_gpu_find_resource(g, cblob.resource_id)) {
352+
qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n",
353+
__func__, cblob.resource_id);
354+
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
366355
return;
367356
}
368357

358+
res = g_new0(struct virtio_gpu_simple_resource, 1);
359+
res->resource_id = cblob.resource_id;
360+
res->blob_size = cblob.size;
361+
369362
ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob),
370363
cmd, &res->addrs, &res->iov,
371364
&res->iov_cnt);
372-
if (ret != 0) {
365+
if (ret != 0 || res->iov) {
373366
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
367+
g_free(res);
374368
return;
375369
}
376370

include/hw/virtio/virtio-gpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ int virtio_gpu_update_dmabuf(VirtIOGPU *g,
279279
void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
280280
struct virtio_gpu_ctrl_command *cmd);
281281
void virtio_gpu_virgl_fence_poll(VirtIOGPU *g);
282+
void virtio_gpu_virgl_reset_scanout(VirtIOGPU *g);
282283
void virtio_gpu_virgl_reset(VirtIOGPU *g);
283284
int virtio_gpu_virgl_init(VirtIOGPU *g);
284285
int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g);

softmmu/vl.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ static struct {
202202
{ .driver = "virtio-vga", .flag = &default_vga },
203203
{ .driver = "ati-vga", .flag = &default_vga },
204204
{ .driver = "vhost-user-vga", .flag = &default_vga },
205+
{ .driver = "virtio-vga-gl", .flag = &default_vga },
205206
};
206207

207208
static QemuOptsList qemu_rtc_opts = {

0 commit comments

Comments
 (0)