xref: /qemu/hw/display/virtio-gpu.c (revision dfbd2768)
1 /*
2  * Virtio GPU Device
3  *
4  * Copyright Red Hat, Inc. 2013-2014
5  *
6  * Authors:
7  *     Dave Airlie <airlied@redhat.com>
8  *     Gerd Hoffmann <kraxel@redhat.com>
9  *
10  * This work is licensed under the terms of the GNU GPL, version 2 or later.
11  * See the COPYING file in the top-level directory.
12  */
13 
14 #include "qemu/osdep.h"
15 #include "qemu-common.h"
16 #include "qemu/iov.h"
17 #include "ui/console.h"
18 #include "trace.h"
19 #include "hw/virtio/virtio.h"
20 #include "hw/virtio/virtio-gpu.h"
21 #include "hw/virtio/virtio-bus.h"
22 #include "migration/migration.h"
23 #include "qemu/log.h"
24 #include "qapi/error.h"
25 
26 #define VIRTIO_GPU_VM_VERSION 1
27 
28 static struct virtio_gpu_simple_resource*
29 virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id);
30 
31 #ifdef CONFIG_VIRGL
32 #include <virglrenderer.h>
33 #define VIRGL(_g, _virgl, _simple, ...)                     \
34     do {                                                    \
35         if (_g->use_virgl_renderer) {                       \
36             _virgl(__VA_ARGS__);                            \
37         } else {                                            \
38             _simple(__VA_ARGS__);                           \
39         }                                                   \
40     } while (0)
41 #else
42 #define VIRGL(_g, _virgl, _simple, ...)                 \
43     do {                                                \
44         _simple(__VA_ARGS__);                           \
45     } while (0)
46 #endif
47 
48 static void update_cursor_data_simple(VirtIOGPU *g,
49                                       struct virtio_gpu_scanout *s,
50                                       uint32_t resource_id)
51 {
52     struct virtio_gpu_simple_resource *res;
53     uint32_t pixels;
54 
55     res = virtio_gpu_find_resource(g, resource_id);
56     if (!res) {
57         return;
58     }
59 
60     if (pixman_image_get_width(res->image)  != s->current_cursor->width ||
61         pixman_image_get_height(res->image) != s->current_cursor->height) {
62         return;
63     }
64 
65     pixels = s->current_cursor->width * s->current_cursor->height;
66     memcpy(s->current_cursor->data,
67            pixman_image_get_data(res->image),
68            pixels * sizeof(uint32_t));
69 }
70 
71 #ifdef CONFIG_VIRGL
72 
73 static void update_cursor_data_virgl(VirtIOGPU *g,
74                                      struct virtio_gpu_scanout *s,
75                                      uint32_t resource_id)
76 {
77     uint32_t width, height;
78     uint32_t pixels, *data;
79 
80     data = virgl_renderer_get_cursor_data(resource_id, &width, &height);
81     if (!data) {
82         return;
83     }
84 
85     if (width != s->current_cursor->width ||
86         height != s->current_cursor->height) {
87         return;
88     }
89 
90     pixels = s->current_cursor->width * s->current_cursor->height;
91     memcpy(s->current_cursor->data, data, pixels * sizeof(uint32_t));
92     free(data);
93 }
94 
95 #endif
96 
97 static void update_cursor(VirtIOGPU *g, struct virtio_gpu_update_cursor *cursor)
98 {
99     struct virtio_gpu_scanout *s;
100     bool move = cursor->hdr.type == VIRTIO_GPU_CMD_MOVE_CURSOR;
101 
102     if (cursor->pos.scanout_id >= g->conf.max_outputs) {
103         return;
104     }
105     s = &g->scanout[cursor->pos.scanout_id];
106 
107     trace_virtio_gpu_update_cursor(cursor->pos.scanout_id,
108                                    cursor->pos.x,
109                                    cursor->pos.y,
110                                    move ? "move" : "update",
111                                    cursor->resource_id);
112 
113     if (!move) {
114         if (!s->current_cursor) {
115             s->current_cursor = cursor_alloc(64, 64);
116         }
117 
118         s->current_cursor->hot_x = cursor->hot_x;
119         s->current_cursor->hot_y = cursor->hot_y;
120 
121         if (cursor->resource_id > 0) {
122             VIRGL(g, update_cursor_data_virgl, update_cursor_data_simple,
123                   g, s, cursor->resource_id);
124         }
125         dpy_cursor_define(s->con, s->current_cursor);
126 
127         s->cursor = *cursor;
128     } else {
129         s->cursor.pos.x = cursor->pos.x;
130         s->cursor.pos.y = cursor->pos.y;
131     }
132     dpy_mouse_set(s->con, cursor->pos.x, cursor->pos.y,
133                   cursor->resource_id ? 1 : 0);
134 }
135 
136 static void virtio_gpu_get_config(VirtIODevice *vdev, uint8_t *config)
137 {
138     VirtIOGPU *g = VIRTIO_GPU(vdev);
139     memcpy(config, &g->virtio_config, sizeof(g->virtio_config));
140 }
141 
142 static void virtio_gpu_set_config(VirtIODevice *vdev, const uint8_t *config)
143 {
144     VirtIOGPU *g = VIRTIO_GPU(vdev);
145     struct virtio_gpu_config vgconfig;
146 
147     memcpy(&vgconfig, config, sizeof(g->virtio_config));
148 
149     if (vgconfig.events_clear) {
150         g->virtio_config.events_read &= ~vgconfig.events_clear;
151     }
152 }
153 
154 static uint64_t virtio_gpu_get_features(VirtIODevice *vdev, uint64_t features,
155                                         Error **errp)
156 {
157     VirtIOGPU *g = VIRTIO_GPU(vdev);
158 
159     if (virtio_gpu_virgl_enabled(g->conf)) {
160         features |= (1 << VIRTIO_GPU_F_VIRGL);
161     }
162     return features;
163 }
164 
165 static void virtio_gpu_set_features(VirtIODevice *vdev, uint64_t features)
166 {
167     static const uint32_t virgl = (1 << VIRTIO_GPU_F_VIRGL);
168     VirtIOGPU *g = VIRTIO_GPU(vdev);
169 
170     g->use_virgl_renderer = ((features & virgl) == virgl);
171     trace_virtio_gpu_features(g->use_virgl_renderer);
172 }
173 
174 static void virtio_gpu_notify_event(VirtIOGPU *g, uint32_t event_type)
175 {
176     g->virtio_config.events_read |= event_type;
177     virtio_notify_config(&g->parent_obj);
178 }
179 
180 static struct virtio_gpu_simple_resource *
181 virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id)
182 {
183     struct virtio_gpu_simple_resource *res;
184 
185     QTAILQ_FOREACH(res, &g->reslist, next) {
186         if (res->resource_id == resource_id) {
187             return res;
188         }
189     }
190     return NULL;
191 }
192 
193 void virtio_gpu_ctrl_response(VirtIOGPU *g,
194                               struct virtio_gpu_ctrl_command *cmd,
195                               struct virtio_gpu_ctrl_hdr *resp,
196                               size_t resp_len)
197 {
198     size_t s;
199 
200     if (cmd->cmd_hdr.flags & VIRTIO_GPU_FLAG_FENCE) {
201         resp->flags |= VIRTIO_GPU_FLAG_FENCE;
202         resp->fence_id = cmd->cmd_hdr.fence_id;
203         resp->ctx_id = cmd->cmd_hdr.ctx_id;
204     }
205     s = iov_from_buf(cmd->elem.in_sg, cmd->elem.in_num, 0, resp, resp_len);
206     if (s != resp_len) {
207         qemu_log_mask(LOG_GUEST_ERROR,
208                       "%s: response size incorrect %zu vs %zu\n",
209                       __func__, s, resp_len);
210     }
211     virtqueue_push(cmd->vq, &cmd->elem, s);
212     virtio_notify(VIRTIO_DEVICE(g), cmd->vq);
213     cmd->finished = true;
214 }
215 
216 void virtio_gpu_ctrl_response_nodata(VirtIOGPU *g,
217                                      struct virtio_gpu_ctrl_command *cmd,
218                                      enum virtio_gpu_ctrl_type type)
219 {
220     struct virtio_gpu_ctrl_hdr resp;
221 
222     memset(&resp, 0, sizeof(resp));
223     resp.type = type;
224     virtio_gpu_ctrl_response(g, cmd, &resp, sizeof(resp));
225 }
226 
227 static void
228 virtio_gpu_fill_display_info(VirtIOGPU *g,
229                              struct virtio_gpu_resp_display_info *dpy_info)
230 {
231     int i;
232 
233     for (i = 0; i < g->conf.max_outputs; i++) {
234         if (g->enabled_output_bitmask & (1 << i)) {
235             dpy_info->pmodes[i].enabled = 1;
236             dpy_info->pmodes[i].r.width = g->req_state[i].width;
237             dpy_info->pmodes[i].r.height = g->req_state[i].height;
238         }
239     }
240 }
241 
242 void virtio_gpu_get_display_info(VirtIOGPU *g,
243                                  struct virtio_gpu_ctrl_command *cmd)
244 {
245     struct virtio_gpu_resp_display_info display_info;
246 
247     trace_virtio_gpu_cmd_get_display_info();
248     memset(&display_info, 0, sizeof(display_info));
249     display_info.hdr.type = VIRTIO_GPU_RESP_OK_DISPLAY_INFO;
250     virtio_gpu_fill_display_info(g, &display_info);
251     virtio_gpu_ctrl_response(g, cmd, &display_info.hdr,
252                              sizeof(display_info));
253 }
254 
255 static pixman_format_code_t get_pixman_format(uint32_t virtio_gpu_format)
256 {
257     switch (virtio_gpu_format) {
258 #ifdef HOST_WORDS_BIGENDIAN
259     case VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM:
260         return PIXMAN_b8g8r8x8;
261     case VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM:
262         return PIXMAN_b8g8r8a8;
263     case VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM:
264         return PIXMAN_x8r8g8b8;
265     case VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM:
266         return PIXMAN_a8r8g8b8;
267     case VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM:
268         return PIXMAN_r8g8b8x8;
269     case VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM:
270         return PIXMAN_r8g8b8a8;
271     case VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM:
272         return PIXMAN_x8b8g8r8;
273     case VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM:
274         return PIXMAN_a8b8g8r8;
275 #else
276     case VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM:
277         return PIXMAN_x8r8g8b8;
278     case VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM:
279         return PIXMAN_a8r8g8b8;
280     case VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM:
281         return PIXMAN_b8g8r8x8;
282     case VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM:
283         return PIXMAN_b8g8r8a8;
284     case VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM:
285         return PIXMAN_x8b8g8r8;
286     case VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM:
287         return PIXMAN_a8b8g8r8;
288     case VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM:
289         return PIXMAN_r8g8b8x8;
290     case VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM:
291         return PIXMAN_r8g8b8a8;
292 #endif
293     default:
294         return 0;
295     }
296 }
297 
298 static void virtio_gpu_resource_create_2d(VirtIOGPU *g,
299                                           struct virtio_gpu_ctrl_command *cmd)
300 {
301     pixman_format_code_t pformat;
302     struct virtio_gpu_simple_resource *res;
303     struct virtio_gpu_resource_create_2d c2d;
304 
305     VIRTIO_GPU_FILL_CMD(c2d);
306     trace_virtio_gpu_cmd_res_create_2d(c2d.resource_id, c2d.format,
307                                        c2d.width, c2d.height);
308 
309     if (c2d.resource_id == 0) {
310         qemu_log_mask(LOG_GUEST_ERROR, "%s: resource id 0 is not allowed\n",
311                       __func__);
312         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
313         return;
314     }
315 
316     res = virtio_gpu_find_resource(g, c2d.resource_id);
317     if (res) {
318         qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n",
319                       __func__, c2d.resource_id);
320         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
321         return;
322     }
323 
324     res = g_new0(struct virtio_gpu_simple_resource, 1);
325 
326     res->width = c2d.width;
327     res->height = c2d.height;
328     res->format = c2d.format;
329     res->resource_id = c2d.resource_id;
330 
331     pformat = get_pixman_format(c2d.format);
332     if (!pformat) {
333         qemu_log_mask(LOG_GUEST_ERROR,
334                       "%s: host couldn't handle guest format %d\n",
335                       __func__, c2d.format);
336         g_free(res);
337         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
338         return;
339     }
340     res->image = pixman_image_create_bits(pformat,
341                                           c2d.width,
342                                           c2d.height,
343                                           NULL, 0);
344 
345     if (!res->image) {
346         qemu_log_mask(LOG_GUEST_ERROR,
347                       "%s: resource creation failed %d %d %d\n",
348                       __func__, c2d.resource_id, c2d.width, c2d.height);
349         g_free(res);
350         cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
351         return;
352     }
353 
354     QTAILQ_INSERT_HEAD(&g->reslist, res, next);
355 }
356 
357 static void virtio_gpu_resource_destroy(VirtIOGPU *g,
358                                         struct virtio_gpu_simple_resource *res)
359 {
360     pixman_image_unref(res->image);
361     QTAILQ_REMOVE(&g->reslist, res, next);
362     g_free(res);
363 }
364 
365 static void virtio_gpu_resource_unref(VirtIOGPU *g,
366                                       struct virtio_gpu_ctrl_command *cmd)
367 {
368     struct virtio_gpu_simple_resource *res;
369     struct virtio_gpu_resource_unref unref;
370 
371     VIRTIO_GPU_FILL_CMD(unref);
372     trace_virtio_gpu_cmd_res_unref(unref.resource_id);
373 
374     res = virtio_gpu_find_resource(g, unref.resource_id);
375     if (!res) {
376         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
377                       __func__, unref.resource_id);
378         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
379         return;
380     }
381     virtio_gpu_resource_destroy(g, res);
382 }
383 
384 static void virtio_gpu_transfer_to_host_2d(VirtIOGPU *g,
385                                            struct virtio_gpu_ctrl_command *cmd)
386 {
387     struct virtio_gpu_simple_resource *res;
388     int h;
389     uint32_t src_offset, dst_offset, stride;
390     int bpp;
391     pixman_format_code_t format;
392     struct virtio_gpu_transfer_to_host_2d t2d;
393 
394     VIRTIO_GPU_FILL_CMD(t2d);
395     trace_virtio_gpu_cmd_res_xfer_toh_2d(t2d.resource_id);
396 
397     res = virtio_gpu_find_resource(g, t2d.resource_id);
398     if (!res || !res->iov) {
399         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
400                       __func__, t2d.resource_id);
401         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
402         return;
403     }
404 
405     if (t2d.r.x > res->width ||
406         t2d.r.y > res->height ||
407         t2d.r.width > res->width ||
408         t2d.r.height > res->height ||
409         t2d.r.x + t2d.r.width > res->width ||
410         t2d.r.y + t2d.r.height > res->height) {
411         qemu_log_mask(LOG_GUEST_ERROR, "%s: transfer bounds outside resource"
412                       " bounds for resource %d: %d %d %d %d vs %d %d\n",
413                       __func__, t2d.resource_id, t2d.r.x, t2d.r.y,
414                       t2d.r.width, t2d.r.height, res->width, res->height);
415         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
416         return;
417     }
418 
419     format = pixman_image_get_format(res->image);
420     bpp = (PIXMAN_FORMAT_BPP(format) + 7) / 8;
421     stride = pixman_image_get_stride(res->image);
422 
423     if (t2d.offset || t2d.r.x || t2d.r.y ||
424         t2d.r.width != pixman_image_get_width(res->image)) {
425         void *img_data = pixman_image_get_data(res->image);
426         for (h = 0; h < t2d.r.height; h++) {
427             src_offset = t2d.offset + stride * h;
428             dst_offset = (t2d.r.y + h) * stride + (t2d.r.x * bpp);
429 
430             iov_to_buf(res->iov, res->iov_cnt, src_offset,
431                        (uint8_t *)img_data
432                        + dst_offset, t2d.r.width * bpp);
433         }
434     } else {
435         iov_to_buf(res->iov, res->iov_cnt, 0,
436                    pixman_image_get_data(res->image),
437                    pixman_image_get_stride(res->image)
438                    * pixman_image_get_height(res->image));
439     }
440 }
441 
442 static void virtio_gpu_resource_flush(VirtIOGPU *g,
443                                       struct virtio_gpu_ctrl_command *cmd)
444 {
445     struct virtio_gpu_simple_resource *res;
446     struct virtio_gpu_resource_flush rf;
447     pixman_region16_t flush_region;
448     int i;
449 
450     VIRTIO_GPU_FILL_CMD(rf);
451     trace_virtio_gpu_cmd_res_flush(rf.resource_id,
452                                    rf.r.width, rf.r.height, rf.r.x, rf.r.y);
453 
454     res = virtio_gpu_find_resource(g, rf.resource_id);
455     if (!res) {
456         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
457                       __func__, rf.resource_id);
458         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
459         return;
460     }
461 
462     if (rf.r.x > res->width ||
463         rf.r.y > res->height ||
464         rf.r.width > res->width ||
465         rf.r.height > res->height ||
466         rf.r.x + rf.r.width > res->width ||
467         rf.r.y + rf.r.height > res->height) {
468         qemu_log_mask(LOG_GUEST_ERROR, "%s: flush bounds outside resource"
469                       " bounds for resource %d: %d %d %d %d vs %d %d\n",
470                       __func__, rf.resource_id, rf.r.x, rf.r.y,
471                       rf.r.width, rf.r.height, res->width, res->height);
472         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
473         return;
474     }
475 
476     pixman_region_init_rect(&flush_region,
477                             rf.r.x, rf.r.y, rf.r.width, rf.r.height);
478     for (i = 0; i < g->conf.max_outputs; i++) {
479         struct virtio_gpu_scanout *scanout;
480         pixman_region16_t region, finalregion;
481         pixman_box16_t *extents;
482 
483         if (!(res->scanout_bitmask & (1 << i))) {
484             continue;
485         }
486         scanout = &g->scanout[i];
487 
488         pixman_region_init(&finalregion);
489         pixman_region_init_rect(&region, scanout->x, scanout->y,
490                                 scanout->width, scanout->height);
491 
492         pixman_region_intersect(&finalregion, &flush_region, &region);
493         pixman_region_translate(&finalregion, -scanout->x, -scanout->y);
494         extents = pixman_region_extents(&finalregion);
495         /* work out the area we need to update for each console */
496         dpy_gfx_update(g->scanout[i].con,
497                        extents->x1, extents->y1,
498                        extents->x2 - extents->x1,
499                        extents->y2 - extents->y1);
500 
501         pixman_region_fini(&region);
502         pixman_region_fini(&finalregion);
503     }
504     pixman_region_fini(&flush_region);
505 }
506 
507 static void virtio_unref_resource(pixman_image_t *image, void *data)
508 {
509     pixman_image_unref(data);
510 }
511 
512 static void virtio_gpu_set_scanout(VirtIOGPU *g,
513                                    struct virtio_gpu_ctrl_command *cmd)
514 {
515     struct virtio_gpu_simple_resource *res;
516     struct virtio_gpu_scanout *scanout;
517     pixman_format_code_t format;
518     uint32_t offset;
519     int bpp;
520     struct virtio_gpu_set_scanout ss;
521 
522     VIRTIO_GPU_FILL_CMD(ss);
523     trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id,
524                                      ss.r.width, ss.r.height, ss.r.x, ss.r.y);
525 
526     if (ss.scanout_id >= g->conf.max_outputs) {
527         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",
528                       __func__, ss.scanout_id);
529         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
530         return;
531     }
532 
533     g->enable = 1;
534     if (ss.resource_id == 0) {
535         scanout = &g->scanout[ss.scanout_id];
536         if (scanout->resource_id) {
537             res = virtio_gpu_find_resource(g, scanout->resource_id);
538             if (res) {
539                 res->scanout_bitmask &= ~(1 << ss.scanout_id);
540             }
541         }
542         if (ss.scanout_id == 0) {
543             qemu_log_mask(LOG_GUEST_ERROR,
544                           "%s: illegal scanout id specified %d",
545                           __func__, ss.scanout_id);
546             cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
547             return;
548         }
549         dpy_gfx_replace_surface(g->scanout[ss.scanout_id].con, NULL);
550         scanout->ds = NULL;
551         scanout->width = 0;
552         scanout->height = 0;
553         return;
554     }
555 
556     /* create a surface for this scanout */
557     res = virtio_gpu_find_resource(g, ss.resource_id);
558     if (!res) {
559         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
560                       __func__, ss.resource_id);
561         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
562         return;
563     }
564 
565     if (ss.r.x > res->width ||
566         ss.r.y > res->height ||
567         ss.r.width > res->width ||
568         ss.r.height > res->height ||
569         ss.r.x + ss.r.width > res->width ||
570         ss.r.y + ss.r.height > res->height) {
571         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout %d bounds for"
572                       " resource %d, (%d,%d)+%d,%d vs %d %d\n",
573                       __func__, ss.scanout_id, ss.resource_id, ss.r.x, ss.r.y,
574                       ss.r.width, ss.r.height, res->width, res->height);
575         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
576         return;
577     }
578 
579     scanout = &g->scanout[ss.scanout_id];
580 
581     format = pixman_image_get_format(res->image);
582     bpp = (PIXMAN_FORMAT_BPP(format) + 7) / 8;
583     offset = (ss.r.x * bpp) + ss.r.y * pixman_image_get_stride(res->image);
584     if (!scanout->ds || surface_data(scanout->ds)
585         != ((uint8_t *)pixman_image_get_data(res->image) + offset) ||
586         scanout->width != ss.r.width ||
587         scanout->height != ss.r.height) {
588         pixman_image_t *rect;
589         void *ptr = (uint8_t *)pixman_image_get_data(res->image) + offset;
590         rect = pixman_image_create_bits(format, ss.r.width, ss.r.height, ptr,
591                                         pixman_image_get_stride(res->image));
592         pixman_image_ref(res->image);
593         pixman_image_set_destroy_function(rect, virtio_unref_resource,
594                                           res->image);
595         /* realloc the surface ptr */
596         scanout->ds = qemu_create_displaysurface_pixman(rect);
597         if (!scanout->ds) {
598             cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
599             return;
600         }
601         dpy_gfx_replace_surface(g->scanout[ss.scanout_id].con, scanout->ds);
602     }
603 
604     res->scanout_bitmask |= (1 << ss.scanout_id);
605     scanout->resource_id = ss.resource_id;
606     scanout->x = ss.r.x;
607     scanout->y = ss.r.y;
608     scanout->width = ss.r.width;
609     scanout->height = ss.r.height;
610 }
611 
612 int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab,
613                                   struct virtio_gpu_ctrl_command *cmd,
614                                   uint64_t **addr, struct iovec **iov)
615 {
616     struct virtio_gpu_mem_entry *ents;
617     size_t esize, s;
618     int i;
619 
620     if (ab->nr_entries > 16384) {
621         qemu_log_mask(LOG_GUEST_ERROR,
622                       "%s: nr_entries is too big (%d > 16384)\n",
623                       __func__, ab->nr_entries);
624         return -1;
625     }
626 
627     esize = sizeof(*ents) * ab->nr_entries;
628     ents = g_malloc(esize);
629     s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num,
630                    sizeof(*ab), ents, esize);
631     if (s != esize) {
632         qemu_log_mask(LOG_GUEST_ERROR,
633                       "%s: command data size incorrect %zu vs %zu\n",
634                       __func__, s, esize);
635         g_free(ents);
636         return -1;
637     }
638 
639     *iov = g_malloc0(sizeof(struct iovec) * ab->nr_entries);
640     if (addr) {
641         *addr = g_malloc0(sizeof(uint64_t) * ab->nr_entries);
642     }
643     for (i = 0; i < ab->nr_entries; i++) {
644         hwaddr len = ents[i].length;
645         (*iov)[i].iov_len = ents[i].length;
646         (*iov)[i].iov_base = cpu_physical_memory_map(ents[i].addr, &len, 1);
647         if (addr) {
648             (*addr)[i] = ents[i].addr;
649         }
650         if (!(*iov)[i].iov_base || len != ents[i].length) {
651             qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for"
652                           " resource %d element %d\n",
653                           __func__, ab->resource_id, i);
654             virtio_gpu_cleanup_mapping_iov(*iov, i);
655             g_free(ents);
656             *iov = NULL;
657             if (addr) {
658                 g_free(*addr);
659                 *addr = NULL;
660             }
661             return -1;
662         }
663     }
664     g_free(ents);
665     return 0;
666 }
667 
668 void virtio_gpu_cleanup_mapping_iov(struct iovec *iov, uint32_t count)
669 {
670     int i;
671 
672     for (i = 0; i < count; i++) {
673         cpu_physical_memory_unmap(iov[i].iov_base, iov[i].iov_len, 1,
674                                   iov[i].iov_len);
675     }
676     g_free(iov);
677 }
678 
679 static void virtio_gpu_cleanup_mapping(struct virtio_gpu_simple_resource *res)
680 {
681     virtio_gpu_cleanup_mapping_iov(res->iov, res->iov_cnt);
682     res->iov = NULL;
683     res->iov_cnt = 0;
684     g_free(res->addrs);
685     res->addrs = NULL;
686 }
687 
688 static void
689 virtio_gpu_resource_attach_backing(VirtIOGPU *g,
690                                    struct virtio_gpu_ctrl_command *cmd)
691 {
692     struct virtio_gpu_simple_resource *res;
693     struct virtio_gpu_resource_attach_backing ab;
694     int ret;
695 
696     VIRTIO_GPU_FILL_CMD(ab);
697     trace_virtio_gpu_cmd_res_back_attach(ab.resource_id);
698 
699     res = virtio_gpu_find_resource(g, ab.resource_id);
700     if (!res) {
701         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
702                       __func__, ab.resource_id);
703         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
704         return;
705     }
706 
707     ret = virtio_gpu_create_mapping_iov(&ab, cmd, &res->addrs, &res->iov);
708     if (ret != 0) {
709         cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
710         return;
711     }
712 
713     res->iov_cnt = ab.nr_entries;
714 }
715 
716 static void
717 virtio_gpu_resource_detach_backing(VirtIOGPU *g,
718                                    struct virtio_gpu_ctrl_command *cmd)
719 {
720     struct virtio_gpu_simple_resource *res;
721     struct virtio_gpu_resource_detach_backing detach;
722 
723     VIRTIO_GPU_FILL_CMD(detach);
724     trace_virtio_gpu_cmd_res_back_detach(detach.resource_id);
725 
726     res = virtio_gpu_find_resource(g, detach.resource_id);
727     if (!res || !res->iov) {
728         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
729                       __func__, detach.resource_id);
730         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
731         return;
732     }
733     virtio_gpu_cleanup_mapping(res);
734 }
735 
736 static void virtio_gpu_simple_process_cmd(VirtIOGPU *g,
737                                           struct virtio_gpu_ctrl_command *cmd)
738 {
739     VIRTIO_GPU_FILL_CMD(cmd->cmd_hdr);
740 
741     switch (cmd->cmd_hdr.type) {
742     case VIRTIO_GPU_CMD_GET_DISPLAY_INFO:
743         virtio_gpu_get_display_info(g, cmd);
744         break;
745     case VIRTIO_GPU_CMD_RESOURCE_CREATE_2D:
746         virtio_gpu_resource_create_2d(g, cmd);
747         break;
748     case VIRTIO_GPU_CMD_RESOURCE_UNREF:
749         virtio_gpu_resource_unref(g, cmd);
750         break;
751     case VIRTIO_GPU_CMD_RESOURCE_FLUSH:
752         virtio_gpu_resource_flush(g, cmd);
753         break;
754     case VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D:
755         virtio_gpu_transfer_to_host_2d(g, cmd);
756         break;
757     case VIRTIO_GPU_CMD_SET_SCANOUT:
758         virtio_gpu_set_scanout(g, cmd);
759         break;
760     case VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING:
761         virtio_gpu_resource_attach_backing(g, cmd);
762         break;
763     case VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING:
764         virtio_gpu_resource_detach_backing(g, cmd);
765         break;
766     default:
767         cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
768         break;
769     }
770     if (!cmd->finished) {
771         virtio_gpu_ctrl_response_nodata(g, cmd, cmd->error ? cmd->error :
772                                         VIRTIO_GPU_RESP_OK_NODATA);
773     }
774 }
775 
776 static void virtio_gpu_handle_ctrl_cb(VirtIODevice *vdev, VirtQueue *vq)
777 {
778     VirtIOGPU *g = VIRTIO_GPU(vdev);
779     qemu_bh_schedule(g->ctrl_bh);
780 }
781 
782 static void virtio_gpu_handle_cursor_cb(VirtIODevice *vdev, VirtQueue *vq)
783 {
784     VirtIOGPU *g = VIRTIO_GPU(vdev);
785     qemu_bh_schedule(g->cursor_bh);
786 }
787 
788 void virtio_gpu_process_cmdq(VirtIOGPU *g)
789 {
790     struct virtio_gpu_ctrl_command *cmd;
791 
792     while (!QTAILQ_EMPTY(&g->cmdq)) {
793         cmd = QTAILQ_FIRST(&g->cmdq);
794 
795         /* process command */
796         VIRGL(g, virtio_gpu_virgl_process_cmd, virtio_gpu_simple_process_cmd,
797               g, cmd);
798         if (cmd->waiting) {
799             break;
800         }
801         QTAILQ_REMOVE(&g->cmdq, cmd, next);
802         if (virtio_gpu_stats_enabled(g->conf)) {
803             g->stats.requests++;
804         }
805 
806         if (!cmd->finished) {
807             QTAILQ_INSERT_TAIL(&g->fenceq, cmd, next);
808             g->inflight++;
809             if (virtio_gpu_stats_enabled(g->conf)) {
810                 if (g->stats.max_inflight < g->inflight) {
811                     g->stats.max_inflight = g->inflight;
812                 }
813                 fprintf(stderr, "inflight: %3d (+)\r", g->inflight);
814             }
815         } else {
816             g_free(cmd);
817         }
818     }
819 }
820 
821 static void virtio_gpu_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
822 {
823     VirtIOGPU *g = VIRTIO_GPU(vdev);
824     struct virtio_gpu_ctrl_command *cmd;
825 
826     if (!virtio_queue_ready(vq)) {
827         return;
828     }
829 
830 #ifdef CONFIG_VIRGL
831     if (!g->renderer_inited && g->use_virgl_renderer) {
832         virtio_gpu_virgl_init(g);
833         g->renderer_inited = true;
834     }
835 #endif
836 
837     cmd = virtqueue_pop(vq, sizeof(struct virtio_gpu_ctrl_command));
838     while (cmd) {
839         cmd->vq = vq;
840         cmd->error = 0;
841         cmd->finished = false;
842         cmd->waiting = false;
843         QTAILQ_INSERT_TAIL(&g->cmdq, cmd, next);
844         cmd = virtqueue_pop(vq, sizeof(struct virtio_gpu_ctrl_command));
845     }
846 
847     virtio_gpu_process_cmdq(g);
848 
849 #ifdef CONFIG_VIRGL
850     if (g->use_virgl_renderer) {
851         virtio_gpu_virgl_fence_poll(g);
852     }
853 #endif
854 }
855 
856 static void virtio_gpu_ctrl_bh(void *opaque)
857 {
858     VirtIOGPU *g = opaque;
859     virtio_gpu_handle_ctrl(&g->parent_obj, g->ctrl_vq);
860 }
861 
862 static void virtio_gpu_handle_cursor(VirtIODevice *vdev, VirtQueue *vq)
863 {
864     VirtIOGPU *g = VIRTIO_GPU(vdev);
865     VirtQueueElement *elem;
866     size_t s;
867     struct virtio_gpu_update_cursor cursor_info;
868 
869     if (!virtio_queue_ready(vq)) {
870         return;
871     }
872     for (;;) {
873         elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
874         if (!elem) {
875             break;
876         }
877 
878         s = iov_to_buf(elem->out_sg, elem->out_num, 0,
879                        &cursor_info, sizeof(cursor_info));
880         if (s != sizeof(cursor_info)) {
881             qemu_log_mask(LOG_GUEST_ERROR,
882                           "%s: cursor size incorrect %zu vs %zu\n",
883                           __func__, s, sizeof(cursor_info));
884         } else {
885             update_cursor(g, &cursor_info);
886         }
887         virtqueue_push(vq, elem, 0);
888         virtio_notify(vdev, vq);
889         g_free(elem);
890     }
891 }
892 
893 static void virtio_gpu_cursor_bh(void *opaque)
894 {
895     VirtIOGPU *g = opaque;
896     virtio_gpu_handle_cursor(&g->parent_obj, g->cursor_vq);
897 }
898 
899 static void virtio_gpu_invalidate_display(void *opaque)
900 {
901 }
902 
903 static void virtio_gpu_update_display(void *opaque)
904 {
905 }
906 
907 static void virtio_gpu_text_update(void *opaque, console_ch_t *chardata)
908 {
909 }
910 
911 static int virtio_gpu_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info)
912 {
913     VirtIOGPU *g = opaque;
914 
915     if (idx >= g->conf.max_outputs) {
916         return -1;
917     }
918 
919     g->req_state[idx].x = info->xoff;
920     g->req_state[idx].y = info->yoff;
921     g->req_state[idx].width = info->width;
922     g->req_state[idx].height = info->height;
923 
924     if (info->width && info->height) {
925         g->enabled_output_bitmask |= (1 << idx);
926     } else {
927         g->enabled_output_bitmask &= ~(1 << idx);
928     }
929 
930     /* send event to guest */
931     virtio_gpu_notify_event(g, VIRTIO_GPU_EVENT_DISPLAY);
932     return 0;
933 }
934 
935 static void virtio_gpu_gl_block(void *opaque, bool block)
936 {
937     VirtIOGPU *g = opaque;
938 
939     if (block) {
940         g->renderer_blocked++;
941     } else {
942         g->renderer_blocked--;
943     }
944     assert(g->renderer_blocked >= 0);
945 
946     if (g->renderer_blocked == 0) {
947         virtio_gpu_process_cmdq(g);
948     }
949 }
950 
951 const GraphicHwOps virtio_gpu_ops = {
952     .invalidate = virtio_gpu_invalidate_display,
953     .gfx_update = virtio_gpu_update_display,
954     .text_update = virtio_gpu_text_update,
955     .ui_info = virtio_gpu_ui_info,
956     .gl_block = virtio_gpu_gl_block,
957 };
958 
959 static const VMStateDescription vmstate_virtio_gpu_scanout = {
960     .name = "virtio-gpu-one-scanout",
961     .version_id = 1,
962     .fields = (VMStateField[]) {
963         VMSTATE_UINT32(resource_id, struct virtio_gpu_scanout),
964         VMSTATE_UINT32(width, struct virtio_gpu_scanout),
965         VMSTATE_UINT32(height, struct virtio_gpu_scanout),
966         VMSTATE_INT32(x, struct virtio_gpu_scanout),
967         VMSTATE_INT32(y, struct virtio_gpu_scanout),
968         VMSTATE_UINT32(cursor.resource_id, struct virtio_gpu_scanout),
969         VMSTATE_UINT32(cursor.hot_x, struct virtio_gpu_scanout),
970         VMSTATE_UINT32(cursor.hot_y, struct virtio_gpu_scanout),
971         VMSTATE_UINT32(cursor.pos.x, struct virtio_gpu_scanout),
972         VMSTATE_UINT32(cursor.pos.y, struct virtio_gpu_scanout),
973         VMSTATE_END_OF_LIST()
974     },
975 };
976 
977 static const VMStateDescription vmstate_virtio_gpu_scanouts = {
978     .name = "virtio-gpu-scanouts",
979     .version_id = 1,
980     .fields = (VMStateField[]) {
981         VMSTATE_INT32(enable, struct VirtIOGPU),
982         VMSTATE_UINT32_EQUAL(conf.max_outputs, struct VirtIOGPU),
983         VMSTATE_STRUCT_VARRAY_UINT32(scanout, struct VirtIOGPU,
984                                      conf.max_outputs, 1,
985                                      vmstate_virtio_gpu_scanout,
986                                      struct virtio_gpu_scanout),
987         VMSTATE_END_OF_LIST()
988     },
989 };
990 
991 static void virtio_gpu_save(QEMUFile *f, void *opaque, size_t size)
992 {
993     VirtIOGPU *g = opaque;
994     struct virtio_gpu_simple_resource *res;
995     int i;
996 
997     /* in 2d mode we should never find unprocessed commands here */
998     assert(QTAILQ_EMPTY(&g->cmdq));
999 
1000     QTAILQ_FOREACH(res, &g->reslist, next) {
1001         qemu_put_be32(f, res->resource_id);
1002         qemu_put_be32(f, res->width);
1003         qemu_put_be32(f, res->height);
1004         qemu_put_be32(f, res->format);
1005         qemu_put_be32(f, res->iov_cnt);
1006         for (i = 0; i < res->iov_cnt; i++) {
1007             qemu_put_be64(f, res->addrs[i]);
1008             qemu_put_be32(f, res->iov[i].iov_len);
1009         }
1010         qemu_put_buffer(f, (void *)pixman_image_get_data(res->image),
1011                         pixman_image_get_stride(res->image) * res->height);
1012     }
1013     qemu_put_be32(f, 0); /* end of list */
1014 
1015     vmstate_save_state(f, &vmstate_virtio_gpu_scanouts, g, NULL);
1016 }
1017 
1018 static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size)
1019 {
1020     VirtIOGPU *g = opaque;
1021     struct virtio_gpu_simple_resource *res;
1022     struct virtio_gpu_scanout *scanout;
1023     uint32_t resource_id, pformat;
1024     int i;
1025 
1026     resource_id = qemu_get_be32(f);
1027     while (resource_id != 0) {
1028         res = g_new0(struct virtio_gpu_simple_resource, 1);
1029         res->resource_id = resource_id;
1030         res->width = qemu_get_be32(f);
1031         res->height = qemu_get_be32(f);
1032         res->format = qemu_get_be32(f);
1033         res->iov_cnt = qemu_get_be32(f);
1034 
1035         /* allocate */
1036         pformat = get_pixman_format(res->format);
1037         if (!pformat) {
1038             return -EINVAL;
1039         }
1040         res->image = pixman_image_create_bits(pformat,
1041                                               res->width, res->height,
1042                                               NULL, 0);
1043         if (!res->image) {
1044             return -EINVAL;
1045         }
1046 
1047         res->addrs = g_new(uint64_t, res->iov_cnt);
1048         res->iov = g_new(struct iovec, res->iov_cnt);
1049 
1050         /* read data */
1051         for (i = 0; i < res->iov_cnt; i++) {
1052             res->addrs[i] = qemu_get_be64(f);
1053             res->iov[i].iov_len = qemu_get_be32(f);
1054         }
1055         qemu_get_buffer(f, (void *)pixman_image_get_data(res->image),
1056                         pixman_image_get_stride(res->image) * res->height);
1057 
1058         /* restore mapping */
1059         for (i = 0; i < res->iov_cnt; i++) {
1060             hwaddr len = res->iov[i].iov_len;
1061             res->iov[i].iov_base =
1062                 cpu_physical_memory_map(res->addrs[i], &len, 1);
1063             if (!res->iov[i].iov_base || len != res->iov[i].iov_len) {
1064                 return -EINVAL;
1065             }
1066         }
1067 
1068         QTAILQ_INSERT_HEAD(&g->reslist, res, next);
1069 
1070         resource_id = qemu_get_be32(f);
1071     }
1072 
1073     /* load & apply scanout state */
1074     vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1);
1075     for (i = 0; i < g->conf.max_outputs; i++) {
1076         scanout = &g->scanout[i];
1077         if (!scanout->resource_id) {
1078             continue;
1079         }
1080         res = virtio_gpu_find_resource(g, scanout->resource_id);
1081         if (!res) {
1082             return -EINVAL;
1083         }
1084         scanout->ds = qemu_create_displaysurface_pixman(res->image);
1085         if (!scanout->ds) {
1086             return -EINVAL;
1087         }
1088 
1089         dpy_gfx_replace_surface(scanout->con, scanout->ds);
1090         dpy_gfx_update(scanout->con, 0, 0, scanout->width, scanout->height);
1091         update_cursor(g, &scanout->cursor);
1092         res->scanout_bitmask |= (1 << i);
1093     }
1094 
1095     return 0;
1096 }
1097 
1098 static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
1099 {
1100     VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
1101     VirtIOGPU *g = VIRTIO_GPU(qdev);
1102     bool have_virgl;
1103     int i;
1104 
1105     if (g->conf.max_outputs > VIRTIO_GPU_MAX_SCANOUTS) {
1106         error_setg(errp, "invalid max_outputs > %d", VIRTIO_GPU_MAX_SCANOUTS);
1107         return;
1108     }
1109 
1110     g->config_size = sizeof(struct virtio_gpu_config);
1111     g->virtio_config.num_scanouts = g->conf.max_outputs;
1112     virtio_init(VIRTIO_DEVICE(g), "virtio-gpu", VIRTIO_ID_GPU,
1113                 g->config_size);
1114 
1115     g->req_state[0].width = 1024;
1116     g->req_state[0].height = 768;
1117 
1118     g->use_virgl_renderer = false;
1119 #if !defined(CONFIG_VIRGL) || defined(HOST_WORDS_BIGENDIAN)
1120     have_virgl = false;
1121 #else
1122     have_virgl = display_opengl;
1123 #endif
1124     if (!have_virgl) {
1125         g->conf.flags &= ~(1 << VIRTIO_GPU_FLAG_VIRGL_ENABLED);
1126     }
1127 
1128     if (virtio_gpu_virgl_enabled(g->conf)) {
1129         /* use larger control queue in 3d mode */
1130         g->ctrl_vq   = virtio_add_queue(vdev, 256, virtio_gpu_handle_ctrl_cb);
1131         g->cursor_vq = virtio_add_queue(vdev, 16, virtio_gpu_handle_cursor_cb);
1132         g->virtio_config.num_capsets = 1;
1133     } else {
1134         g->ctrl_vq   = virtio_add_queue(vdev, 64, virtio_gpu_handle_ctrl_cb);
1135         g->cursor_vq = virtio_add_queue(vdev, 16, virtio_gpu_handle_cursor_cb);
1136     }
1137 
1138     g->ctrl_bh = qemu_bh_new(virtio_gpu_ctrl_bh, g);
1139     g->cursor_bh = qemu_bh_new(virtio_gpu_cursor_bh, g);
1140     QTAILQ_INIT(&g->reslist);
1141     QTAILQ_INIT(&g->cmdq);
1142     QTAILQ_INIT(&g->fenceq);
1143 
1144     g->enabled_output_bitmask = 1;
1145     g->qdev = qdev;
1146 
1147     for (i = 0; i < g->conf.max_outputs; i++) {
1148         g->scanout[i].con =
1149             graphic_console_init(DEVICE(g), i, &virtio_gpu_ops, g);
1150         if (i > 0) {
1151             dpy_gfx_replace_surface(g->scanout[i].con, NULL);
1152         }
1153     }
1154 
1155     if (virtio_gpu_virgl_enabled(g->conf)) {
1156         error_setg(&g->migration_blocker, "virgl is not yet migratable");
1157         migrate_add_blocker(g->migration_blocker);
1158     }
1159 }
1160 
1161 static void virtio_gpu_device_unrealize(DeviceState *qdev, Error **errp)
1162 {
1163     VirtIOGPU *g = VIRTIO_GPU(qdev);
1164     if (g->migration_blocker) {
1165         migrate_del_blocker(g->migration_blocker);
1166         error_free(g->migration_blocker);
1167     }
1168 }
1169 
1170 static void virtio_gpu_instance_init(Object *obj)
1171 {
1172 }
1173 
1174 static void virtio_gpu_reset(VirtIODevice *vdev)
1175 {
1176     VirtIOGPU *g = VIRTIO_GPU(vdev);
1177     struct virtio_gpu_simple_resource *res, *tmp;
1178     int i;
1179 
1180     g->enable = 0;
1181 
1182     QTAILQ_FOREACH_SAFE(res, &g->reslist, next, tmp) {
1183         virtio_gpu_resource_destroy(g, res);
1184     }
1185     for (i = 0; i < g->conf.max_outputs; i++) {
1186 #if 0
1187         g->req_state[i].x = 0;
1188         g->req_state[i].y = 0;
1189         if (i == 0) {
1190             g->req_state[0].width = 1024;
1191             g->req_state[0].height = 768;
1192         } else {
1193             g->req_state[i].width = 0;
1194             g->req_state[i].height = 0;
1195         }
1196 #endif
1197         g->scanout[i].resource_id = 0;
1198         g->scanout[i].width = 0;
1199         g->scanout[i].height = 0;
1200         g->scanout[i].x = 0;
1201         g->scanout[i].y = 0;
1202         g->scanout[i].ds = NULL;
1203     }
1204     g->enabled_output_bitmask = 1;
1205 
1206 #ifdef CONFIG_VIRGL
1207     if (g->use_virgl_renderer) {
1208         virtio_gpu_virgl_reset(g);
1209         g->use_virgl_renderer = 0;
1210     }
1211 #endif
1212 }
1213 
1214 /*
1215  * For historical reasons virtio_gpu does not adhere to virtio migration
1216  * scheme as described in doc/virtio-migration.txt, in a sense that no
1217  * save/load callback are provided to the core. Instead the device data
1218  * is saved/loaded after the core data.
1219  *
1220  * Because of this we need a special vmsd.
1221  */
1222 static const VMStateDescription vmstate_virtio_gpu = {
1223     .name = "virtio-gpu",
1224     .minimum_version_id = VIRTIO_GPU_VM_VERSION,
1225     .version_id = VIRTIO_GPU_VM_VERSION,
1226     .fields = (VMStateField[]) {
1227         VMSTATE_VIRTIO_DEVICE /* core */,
1228         {
1229             .name = "virtio-gpu",
1230             .info = &(const VMStateInfo) {
1231                         .name = "virtio-gpu",
1232                         .get = virtio_gpu_load,
1233                         .put = virtio_gpu_save,
1234             },
1235             .flags = VMS_SINGLE,
1236         } /* device */,
1237         VMSTATE_END_OF_LIST()
1238     },
1239 };
1240 
1241 static Property virtio_gpu_properties[] = {
1242     DEFINE_PROP_UINT32("max_outputs", VirtIOGPU, conf.max_outputs, 1),
1243 #ifdef CONFIG_VIRGL
1244     DEFINE_PROP_BIT("virgl", VirtIOGPU, conf.flags,
1245                     VIRTIO_GPU_FLAG_VIRGL_ENABLED, true),
1246     DEFINE_PROP_BIT("stats", VirtIOGPU, conf.flags,
1247                     VIRTIO_GPU_FLAG_STATS_ENABLED, false),
1248 #endif
1249     DEFINE_PROP_END_OF_LIST(),
1250 };
1251 
1252 static void virtio_gpu_class_init(ObjectClass *klass, void *data)
1253 {
1254     DeviceClass *dc = DEVICE_CLASS(klass);
1255     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
1256 
1257     vdc->realize = virtio_gpu_device_realize;
1258     vdc->unrealize = virtio_gpu_device_unrealize;
1259     vdc->get_config = virtio_gpu_get_config;
1260     vdc->set_config = virtio_gpu_set_config;
1261     vdc->get_features = virtio_gpu_get_features;
1262     vdc->set_features = virtio_gpu_set_features;
1263 
1264     vdc->reset = virtio_gpu_reset;
1265 
1266     dc->props = virtio_gpu_properties;
1267     dc->vmsd = &vmstate_virtio_gpu;
1268 }
1269 
1270 static const TypeInfo virtio_gpu_info = {
1271     .name = TYPE_VIRTIO_GPU,
1272     .parent = TYPE_VIRTIO_DEVICE,
1273     .instance_size = sizeof(VirtIOGPU),
1274     .instance_init = virtio_gpu_instance_init,
1275     .class_init = virtio_gpu_class_init,
1276 };
1277 
1278 static void virtio_register_types(void)
1279 {
1280     type_register_static(&virtio_gpu_info);
1281 }
1282 
1283 type_init(virtio_register_types)
1284 
1285 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_ctrl_hdr)                != 24);
1286 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_update_cursor)           != 56);
1287 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_unref)          != 32);
1288 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_create_2d)      != 40);
1289 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_set_scanout)             != 48);
1290 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_flush)          != 48);
1291 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_transfer_to_host_2d)     != 56);
1292 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_mem_entry)               != 16);
1293 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_attach_backing) != 32);
1294 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_detach_backing) != 32);
1295 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resp_display_info)       != 408);
1296 
1297 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_transfer_host_3d)        != 72);
1298 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_create_3d)      != 72);
1299 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_ctx_create)              != 96);
1300 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_ctx_destroy)             != 24);
1301 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_ctx_resource)            != 32);
1302 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_cmd_submit)              != 32);
1303 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_get_capset_info)         != 32);
1304 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resp_capset_info)        != 40);
1305 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_get_capset)              != 32);
1306 QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resp_capset)             != 24);
1307