qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

virtio-gpu.c (47840B)


      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/units.h"
     16 #include "qemu/iov.h"
     17 #include "ui/console.h"
     18 #include "trace.h"
     19 #include "sysemu/dma.h"
     20 #include "sysemu/sysemu.h"
     21 #include "hw/virtio/virtio.h"
     22 #include "migration/qemu-file-types.h"
     23 #include "hw/virtio/virtio-gpu.h"
     24 #include "hw/virtio/virtio-gpu-bswap.h"
     25 #include "hw/virtio/virtio-gpu-pixman.h"
     26 #include "hw/virtio/virtio-bus.h"
     27 #include "hw/display/edid.h"
     28 #include "hw/qdev-properties.h"
     29 #include "qemu/log.h"
     30 #include "qemu/module.h"
     31 #include "qapi/error.h"
     32 #include "qemu/error-report.h"
     33 
     34 #define VIRTIO_GPU_VM_VERSION 1
     35 
     36 static struct virtio_gpu_simple_resource*
     37 virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id);
     38 static struct virtio_gpu_simple_resource *
     39 virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id,
     40                                bool require_backing,
     41                                const char *caller, uint32_t *error);
     42 
     43 static void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
     44                                        struct virtio_gpu_simple_resource *res);
     45 
     46 void virtio_gpu_update_cursor_data(VirtIOGPU *g,
     47                                    struct virtio_gpu_scanout *s,
     48                                    uint32_t resource_id)
     49 {
     50     struct virtio_gpu_simple_resource *res;
     51     uint32_t pixels;
     52     void *data;
     53 
     54     res = virtio_gpu_find_check_resource(g, resource_id, false,
     55                                          __func__, NULL);
     56     if (!res) {
     57         return;
     58     }
     59 
     60     if (res->blob_size) {
     61         if (res->blob_size < (s->current_cursor->width *
     62                               s->current_cursor->height * 4)) {
     63             return;
     64         }
     65         data = res->blob;
     66     } else {
     67         if (pixman_image_get_width(res->image)  != s->current_cursor->width ||
     68             pixman_image_get_height(res->image) != s->current_cursor->height) {
     69             return;
     70         }
     71         data = pixman_image_get_data(res->image);
     72     }
     73 
     74     pixels = s->current_cursor->width * s->current_cursor->height;
     75     memcpy(s->current_cursor->data, data,
     76            pixels * sizeof(uint32_t));
     77 }
     78 
     79 static void update_cursor(VirtIOGPU *g, struct virtio_gpu_update_cursor *cursor)
     80 {
     81     struct virtio_gpu_scanout *s;
     82     VirtIOGPUClass *vgc = VIRTIO_GPU_GET_CLASS(g);
     83     bool move = cursor->hdr.type == VIRTIO_GPU_CMD_MOVE_CURSOR;
     84 
     85     if (cursor->pos.scanout_id >= g->parent_obj.conf.max_outputs) {
     86         return;
     87     }
     88     s = &g->parent_obj.scanout[cursor->pos.scanout_id];
     89 
     90     trace_virtio_gpu_update_cursor(cursor->pos.scanout_id,
     91                                    cursor->pos.x,
     92                                    cursor->pos.y,
     93                                    move ? "move" : "update",
     94                                    cursor->resource_id);
     95 
     96     if (!move) {
     97         if (!s->current_cursor) {
     98             s->current_cursor = cursor_alloc(64, 64);
     99         }
    100 
    101         s->current_cursor->hot_x = cursor->hot_x;
    102         s->current_cursor->hot_y = cursor->hot_y;
    103 
    104         if (cursor->resource_id > 0) {
    105             vgc->update_cursor_data(g, s, cursor->resource_id);
    106         }
    107         dpy_cursor_define(s->con, s->current_cursor);
    108 
    109         s->cursor = *cursor;
    110     } else {
    111         s->cursor.pos.x = cursor->pos.x;
    112         s->cursor.pos.y = cursor->pos.y;
    113     }
    114     dpy_mouse_set(s->con, cursor->pos.x, cursor->pos.y,
    115                   cursor->resource_id ? 1 : 0);
    116 }
    117 
    118 static struct virtio_gpu_simple_resource *
    119 virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id)
    120 {
    121     struct virtio_gpu_simple_resource *res;
    122 
    123     QTAILQ_FOREACH(res, &g->reslist, next) {
    124         if (res->resource_id == resource_id) {
    125             return res;
    126         }
    127     }
    128     return NULL;
    129 }
    130 
    131 static struct virtio_gpu_simple_resource *
    132 virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id,
    133                                bool require_backing,
    134                                const char *caller, uint32_t *error)
    135 {
    136     struct virtio_gpu_simple_resource *res;
    137 
    138     res = virtio_gpu_find_resource(g, resource_id);
    139     if (!res) {
    140         qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid resource specified %d\n",
    141                       caller, resource_id);
    142         if (error) {
    143             *error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
    144         }
    145         return NULL;
    146     }
    147 
    148     if (require_backing) {
    149         if (!res->iov || (!res->image && !res->blob)) {
    150             qemu_log_mask(LOG_GUEST_ERROR, "%s: no backing storage %d\n",
    151                           caller, resource_id);
    152             if (error) {
    153                 *error = VIRTIO_GPU_RESP_ERR_UNSPEC;
    154             }
    155             return NULL;
    156         }
    157     }
    158 
    159     return res;
    160 }
    161 
    162 void virtio_gpu_ctrl_response(VirtIOGPU *g,
    163                               struct virtio_gpu_ctrl_command *cmd,
    164                               struct virtio_gpu_ctrl_hdr *resp,
    165                               size_t resp_len)
    166 {
    167     size_t s;
    168 
    169     if (cmd->cmd_hdr.flags & VIRTIO_GPU_FLAG_FENCE) {
    170         resp->flags |= VIRTIO_GPU_FLAG_FENCE;
    171         resp->fence_id = cmd->cmd_hdr.fence_id;
    172         resp->ctx_id = cmd->cmd_hdr.ctx_id;
    173     }
    174     virtio_gpu_ctrl_hdr_bswap(resp);
    175     s = iov_from_buf(cmd->elem.in_sg, cmd->elem.in_num, 0, resp, resp_len);
    176     if (s != resp_len) {
    177         qemu_log_mask(LOG_GUEST_ERROR,
    178                       "%s: response size incorrect %zu vs %zu\n",
    179                       __func__, s, resp_len);
    180     }
    181     virtqueue_push(cmd->vq, &cmd->elem, s);
    182     virtio_notify(VIRTIO_DEVICE(g), cmd->vq);
    183     cmd->finished = true;
    184 }
    185 
    186 void virtio_gpu_ctrl_response_nodata(VirtIOGPU *g,
    187                                      struct virtio_gpu_ctrl_command *cmd,
    188                                      enum virtio_gpu_ctrl_type type)
    189 {
    190     struct virtio_gpu_ctrl_hdr resp;
    191 
    192     memset(&resp, 0, sizeof(resp));
    193     resp.type = type;
    194     virtio_gpu_ctrl_response(g, cmd, &resp, sizeof(resp));
    195 }
    196 
    197 void virtio_gpu_get_display_info(VirtIOGPU *g,
    198                                  struct virtio_gpu_ctrl_command *cmd)
    199 {
    200     struct virtio_gpu_resp_display_info display_info;
    201 
    202     trace_virtio_gpu_cmd_get_display_info();
    203     memset(&display_info, 0, sizeof(display_info));
    204     display_info.hdr.type = VIRTIO_GPU_RESP_OK_DISPLAY_INFO;
    205     virtio_gpu_base_fill_display_info(VIRTIO_GPU_BASE(g), &display_info);
    206     virtio_gpu_ctrl_response(g, cmd, &display_info.hdr,
    207                              sizeof(display_info));
    208 }
    209 
    210 static void
    211 virtio_gpu_generate_edid(VirtIOGPU *g, int scanout,
    212                          struct virtio_gpu_resp_edid *edid)
    213 {
    214     VirtIOGPUBase *b = VIRTIO_GPU_BASE(g);
    215     qemu_edid_info info = {
    216         .width_mm = b->req_state[scanout].width_mm,
    217         .height_mm = b->req_state[scanout].height_mm,
    218         .prefx = b->req_state[scanout].width,
    219         .prefy = b->req_state[scanout].height,
    220         .refresh_rate = b->req_state[scanout].refresh_rate,
    221     };
    222 
    223     edid->size = cpu_to_le32(sizeof(edid->edid));
    224     qemu_edid_generate(edid->edid, sizeof(edid->edid), &info);
    225 }
    226 
    227 void virtio_gpu_get_edid(VirtIOGPU *g,
    228                          struct virtio_gpu_ctrl_command *cmd)
    229 {
    230     struct virtio_gpu_resp_edid edid;
    231     struct virtio_gpu_cmd_get_edid get_edid;
    232     VirtIOGPUBase *b = VIRTIO_GPU_BASE(g);
    233 
    234     VIRTIO_GPU_FILL_CMD(get_edid);
    235     virtio_gpu_bswap_32(&get_edid, sizeof(get_edid));
    236 
    237     if (get_edid.scanout >= b->conf.max_outputs) {
    238         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
    239         return;
    240     }
    241 
    242     trace_virtio_gpu_cmd_get_edid(get_edid.scanout);
    243     memset(&edid, 0, sizeof(edid));
    244     edid.hdr.type = VIRTIO_GPU_RESP_OK_EDID;
    245     virtio_gpu_generate_edid(g, get_edid.scanout, &edid);
    246     virtio_gpu_ctrl_response(g, cmd, &edid.hdr, sizeof(edid));
    247 }
    248 
    249 static uint32_t calc_image_hostmem(pixman_format_code_t pformat,
    250                                    uint32_t width, uint32_t height)
    251 {
    252     /* Copied from pixman/pixman-bits-image.c, skip integer overflow check.
    253      * pixman_image_create_bits will fail in case it overflow.
    254      */
    255 
    256     int bpp = PIXMAN_FORMAT_BPP(pformat);
    257     int stride = ((width * bpp + 0x1f) >> 5) * sizeof(uint32_t);
    258     return height * stride;
    259 }
    260 
    261 static void virtio_gpu_resource_create_2d(VirtIOGPU *g,
    262                                           struct virtio_gpu_ctrl_command *cmd)
    263 {
    264     pixman_format_code_t pformat;
    265     struct virtio_gpu_simple_resource *res;
    266     struct virtio_gpu_resource_create_2d c2d;
    267 
    268     VIRTIO_GPU_FILL_CMD(c2d);
    269     virtio_gpu_bswap_32(&c2d, sizeof(c2d));
    270     trace_virtio_gpu_cmd_res_create_2d(c2d.resource_id, c2d.format,
    271                                        c2d.width, c2d.height);
    272 
    273     if (c2d.resource_id == 0) {
    274         qemu_log_mask(LOG_GUEST_ERROR, "%s: resource id 0 is not allowed\n",
    275                       __func__);
    276         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
    277         return;
    278     }
    279 
    280     res = virtio_gpu_find_resource(g, c2d.resource_id);
    281     if (res) {
    282         qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n",
    283                       __func__, c2d.resource_id);
    284         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
    285         return;
    286     }
    287 
    288     res = g_new0(struct virtio_gpu_simple_resource, 1);
    289 
    290     res->width = c2d.width;
    291     res->height = c2d.height;
    292     res->format = c2d.format;
    293     res->resource_id = c2d.resource_id;
    294 
    295     pformat = virtio_gpu_get_pixman_format(c2d.format);
    296     if (!pformat) {
    297         qemu_log_mask(LOG_GUEST_ERROR,
    298                       "%s: host couldn't handle guest format %d\n",
    299                       __func__, c2d.format);
    300         g_free(res);
    301         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
    302         return;
    303     }
    304 
    305     res->hostmem = calc_image_hostmem(pformat, c2d.width, c2d.height);
    306     if (res->hostmem + g->hostmem < g->conf_max_hostmem) {
    307         res->image = pixman_image_create_bits(pformat,
    308                                               c2d.width,
    309                                               c2d.height,
    310                                               NULL, 0);
    311     }
    312 
    313     if (!res->image) {
    314         qemu_log_mask(LOG_GUEST_ERROR,
    315                       "%s: resource creation failed %d %d %d\n",
    316                       __func__, c2d.resource_id, c2d.width, c2d.height);
    317         g_free(res);
    318         cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
    319         return;
    320     }
    321 
    322     QTAILQ_INSERT_HEAD(&g->reslist, res, next);
    323     g->hostmem += res->hostmem;
    324 }
    325 
    326 static void virtio_gpu_resource_create_blob(VirtIOGPU *g,
    327                                             struct virtio_gpu_ctrl_command *cmd)
    328 {
    329     struct virtio_gpu_simple_resource *res;
    330     struct virtio_gpu_resource_create_blob cblob;
    331     int ret;
    332 
    333     VIRTIO_GPU_FILL_CMD(cblob);
    334     virtio_gpu_create_blob_bswap(&cblob);
    335     trace_virtio_gpu_cmd_res_create_blob(cblob.resource_id, cblob.size);
    336 
    337     if (cblob.resource_id == 0) {
    338         qemu_log_mask(LOG_GUEST_ERROR, "%s: resource id 0 is not allowed\n",
    339                       __func__);
    340         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
    341         return;
    342     }
    343 
    344     if (cblob.blob_mem != VIRTIO_GPU_BLOB_MEM_GUEST &&
    345         cblob.blob_flags != VIRTIO_GPU_BLOB_FLAG_USE_SHAREABLE) {
    346         qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid memory type\n",
    347                       __func__);
    348         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
    349         return;
    350     }
    351 
    352     if (virtio_gpu_find_resource(g, cblob.resource_id)) {
    353         qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n",
    354                       __func__, cblob.resource_id);
    355         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
    356         return;
    357     }
    358 
    359     res = g_new0(struct virtio_gpu_simple_resource, 1);
    360     res->resource_id = cblob.resource_id;
    361     res->blob_size = cblob.size;
    362 
    363     ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob),
    364                                         cmd, &res->addrs, &res->iov,
    365                                         &res->iov_cnt);
    366     if (ret != 0) {
    367         cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
    368         g_free(res);
    369         return;
    370     }
    371 
    372     virtio_gpu_init_udmabuf(res);
    373     QTAILQ_INSERT_HEAD(&g->reslist, res, next);
    374 }
    375 
    376 static void virtio_gpu_disable_scanout(VirtIOGPU *g, int scanout_id)
    377 {
    378     struct virtio_gpu_scanout *scanout = &g->parent_obj.scanout[scanout_id];
    379     struct virtio_gpu_simple_resource *res;
    380 
    381     if (scanout->resource_id == 0) {
    382         return;
    383     }
    384 
    385     res = virtio_gpu_find_resource(g, scanout->resource_id);
    386     if (res) {
    387         res->scanout_bitmask &= ~(1 << scanout_id);
    388     }
    389 
    390     dpy_gfx_replace_surface(scanout->con, NULL);
    391     scanout->resource_id = 0;
    392     scanout->ds = NULL;
    393     scanout->width = 0;
    394     scanout->height = 0;
    395 }
    396 
    397 static void virtio_gpu_resource_destroy(VirtIOGPU *g,
    398                                         struct virtio_gpu_simple_resource *res)
    399 {
    400     int i;
    401 
    402     if (res->scanout_bitmask) {
    403         for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
    404             if (res->scanout_bitmask & (1 << i)) {
    405                 virtio_gpu_disable_scanout(g, i);
    406             }
    407         }
    408     }
    409 
    410     qemu_pixman_image_unref(res->image);
    411     virtio_gpu_cleanup_mapping(g, res);
    412     QTAILQ_REMOVE(&g->reslist, res, next);
    413     g->hostmem -= res->hostmem;
    414     g_free(res);
    415 }
    416 
    417 static void virtio_gpu_resource_unref(VirtIOGPU *g,
    418                                       struct virtio_gpu_ctrl_command *cmd)
    419 {
    420     struct virtio_gpu_simple_resource *res;
    421     struct virtio_gpu_resource_unref unref;
    422 
    423     VIRTIO_GPU_FILL_CMD(unref);
    424     virtio_gpu_bswap_32(&unref, sizeof(unref));
    425     trace_virtio_gpu_cmd_res_unref(unref.resource_id);
    426 
    427     res = virtio_gpu_find_resource(g, unref.resource_id);
    428     if (!res) {
    429         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
    430                       __func__, unref.resource_id);
    431         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
    432         return;
    433     }
    434     virtio_gpu_resource_destroy(g, res);
    435 }
    436 
    437 static void virtio_gpu_transfer_to_host_2d(VirtIOGPU *g,
    438                                            struct virtio_gpu_ctrl_command *cmd)
    439 {
    440     struct virtio_gpu_simple_resource *res;
    441     int h;
    442     uint32_t src_offset, dst_offset, stride;
    443     int bpp;
    444     pixman_format_code_t format;
    445     struct virtio_gpu_transfer_to_host_2d t2d;
    446 
    447     VIRTIO_GPU_FILL_CMD(t2d);
    448     virtio_gpu_t2d_bswap(&t2d);
    449     trace_virtio_gpu_cmd_res_xfer_toh_2d(t2d.resource_id);
    450 
    451     res = virtio_gpu_find_check_resource(g, t2d.resource_id, true,
    452                                          __func__, &cmd->error);
    453     if (!res || res->blob) {
    454         return;
    455     }
    456 
    457     if (t2d.r.x > res->width ||
    458         t2d.r.y > res->height ||
    459         t2d.r.width > res->width ||
    460         t2d.r.height > res->height ||
    461         t2d.r.x + t2d.r.width > res->width ||
    462         t2d.r.y + t2d.r.height > res->height) {
    463         qemu_log_mask(LOG_GUEST_ERROR, "%s: transfer bounds outside resource"
    464                       " bounds for resource %d: %d %d %d %d vs %d %d\n",
    465                       __func__, t2d.resource_id, t2d.r.x, t2d.r.y,
    466                       t2d.r.width, t2d.r.height, res->width, res->height);
    467         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
    468         return;
    469     }
    470 
    471     format = pixman_image_get_format(res->image);
    472     bpp = DIV_ROUND_UP(PIXMAN_FORMAT_BPP(format), 8);
    473     stride = pixman_image_get_stride(res->image);
    474 
    475     if (t2d.offset || t2d.r.x || t2d.r.y ||
    476         t2d.r.width != pixman_image_get_width(res->image)) {
    477         void *img_data = pixman_image_get_data(res->image);
    478         for (h = 0; h < t2d.r.height; h++) {
    479             src_offset = t2d.offset + stride * h;
    480             dst_offset = (t2d.r.y + h) * stride + (t2d.r.x * bpp);
    481 
    482             iov_to_buf(res->iov, res->iov_cnt, src_offset,
    483                        (uint8_t *)img_data
    484                        + dst_offset, t2d.r.width * bpp);
    485         }
    486     } else {
    487         iov_to_buf(res->iov, res->iov_cnt, 0,
    488                    pixman_image_get_data(res->image),
    489                    pixman_image_get_stride(res->image)
    490                    * pixman_image_get_height(res->image));
    491     }
    492 }
    493 
    494 static void virtio_gpu_resource_flush(VirtIOGPU *g,
    495                                       struct virtio_gpu_ctrl_command *cmd)
    496 {
    497     struct virtio_gpu_simple_resource *res;
    498     struct virtio_gpu_resource_flush rf;
    499     struct virtio_gpu_scanout *scanout;
    500     pixman_region16_t flush_region;
    501     int i;
    502 
    503     VIRTIO_GPU_FILL_CMD(rf);
    504     virtio_gpu_bswap_32(&rf, sizeof(rf));
    505     trace_virtio_gpu_cmd_res_flush(rf.resource_id,
    506                                    rf.r.width, rf.r.height, rf.r.x, rf.r.y);
    507 
    508     res = virtio_gpu_find_check_resource(g, rf.resource_id, false,
    509                                          __func__, &cmd->error);
    510     if (!res) {
    511         return;
    512     }
    513 
    514     if (res->blob) {
    515         for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
    516             scanout = &g->parent_obj.scanout[i];
    517             if (scanout->resource_id == res->resource_id &&
    518                 rf.r.x < scanout->x + scanout->width &&
    519                 rf.r.x + rf.r.width >= scanout->x &&
    520                 rf.r.y < scanout->y + scanout->height &&
    521                 rf.r.y + rf.r.height >= scanout->y &&
    522                 console_has_gl(scanout->con)) {
    523                 dpy_gl_update(scanout->con, 0, 0, scanout->width,
    524                               scanout->height);
    525             }
    526         }
    527         return;
    528     }
    529 
    530     if (!res->blob &&
    531         (rf.r.x > res->width ||
    532         rf.r.y > res->height ||
    533         rf.r.width > res->width ||
    534         rf.r.height > res->height ||
    535         rf.r.x + rf.r.width > res->width ||
    536         rf.r.y + rf.r.height > res->height)) {
    537         qemu_log_mask(LOG_GUEST_ERROR, "%s: flush bounds outside resource"
    538                       " bounds for resource %d: %d %d %d %d vs %d %d\n",
    539                       __func__, rf.resource_id, rf.r.x, rf.r.y,
    540                       rf.r.width, rf.r.height, res->width, res->height);
    541         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
    542         return;
    543     }
    544 
    545     pixman_region_init_rect(&flush_region,
    546                             rf.r.x, rf.r.y, rf.r.width, rf.r.height);
    547     for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
    548         pixman_region16_t region, finalregion;
    549         pixman_box16_t *extents;
    550 
    551         if (!(res->scanout_bitmask & (1 << i))) {
    552             continue;
    553         }
    554         scanout = &g->parent_obj.scanout[i];
    555 
    556         pixman_region_init(&finalregion);
    557         pixman_region_init_rect(&region, scanout->x, scanout->y,
    558                                 scanout->width, scanout->height);
    559 
    560         pixman_region_intersect(&finalregion, &flush_region, &region);
    561         pixman_region_translate(&finalregion, -scanout->x, -scanout->y);
    562         extents = pixman_region_extents(&finalregion);
    563         /* work out the area we need to update for each console */
    564         dpy_gfx_update(g->parent_obj.scanout[i].con,
    565                        extents->x1, extents->y1,
    566                        extents->x2 - extents->x1,
    567                        extents->y2 - extents->y1);
    568 
    569         pixman_region_fini(&region);
    570         pixman_region_fini(&finalregion);
    571     }
    572     pixman_region_fini(&flush_region);
    573 }
    574 
    575 static void virtio_unref_resource(pixman_image_t *image, void *data)
    576 {
    577     pixman_image_unref(data);
    578 }
    579 
    580 static void virtio_gpu_update_scanout(VirtIOGPU *g,
    581                                       uint32_t scanout_id,
    582                                       struct virtio_gpu_simple_resource *res,
    583                                       struct virtio_gpu_rect *r)
    584 {
    585     struct virtio_gpu_simple_resource *ores;
    586     struct virtio_gpu_scanout *scanout;
    587 
    588     scanout = &g->parent_obj.scanout[scanout_id];
    589     ores = virtio_gpu_find_resource(g, scanout->resource_id);
    590     if (ores) {
    591         ores->scanout_bitmask &= ~(1 << scanout_id);
    592     }
    593 
    594     res->scanout_bitmask |= (1 << scanout_id);
    595     scanout->resource_id = res->resource_id;
    596     scanout->x = r->x;
    597     scanout->y = r->y;
    598     scanout->width = r->width;
    599     scanout->height = r->height;
    600 }
    601 
    602 static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
    603                                       uint32_t scanout_id,
    604                                       struct virtio_gpu_framebuffer *fb,
    605                                       struct virtio_gpu_simple_resource *res,
    606                                       struct virtio_gpu_rect *r,
    607                                       uint32_t *error)
    608 {
    609     struct virtio_gpu_scanout *scanout;
    610     uint8_t *data;
    611 
    612     scanout = &g->parent_obj.scanout[scanout_id];
    613 
    614     if (r->x > fb->width ||
    615         r->y > fb->height ||
    616         r->width < 16 ||
    617         r->height < 16 ||
    618         r->width > fb->width ||
    619         r->height > fb->height ||
    620         r->x + r->width > fb->width ||
    621         r->y + r->height > fb->height) {
    622         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout %d bounds for"
    623                       " resource %d, rect (%d,%d)+%d,%d, fb %d %d\n",
    624                       __func__, scanout_id, res->resource_id,
    625                       r->x, r->y, r->width, r->height,
    626                       fb->width, fb->height);
    627         *error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
    628         return;
    629     }
    630 
    631     g->parent_obj.enable = 1;
    632 
    633     if (res->blob) {
    634         if (console_has_gl(scanout->con)) {
    635             if (!virtio_gpu_update_dmabuf(g, scanout_id, res, fb, r)) {
    636                 virtio_gpu_update_scanout(g, scanout_id, res, r);
    637                 return;
    638             }
    639         }
    640 
    641         data = res->blob;
    642     } else {
    643         data = (uint8_t *)pixman_image_get_data(res->image);
    644     }
    645 
    646     /* create a surface for this scanout */
    647     if ((res->blob && !console_has_gl(scanout->con)) ||
    648         !scanout->ds ||
    649         surface_data(scanout->ds) != data + fb->offset ||
    650         scanout->width != r->width ||
    651         scanout->height != r->height) {
    652         pixman_image_t *rect;
    653         void *ptr = data + fb->offset;
    654         rect = pixman_image_create_bits(fb->format, r->width, r->height,
    655                                         ptr, fb->stride);
    656 
    657         if (res->image) {
    658             pixman_image_ref(res->image);
    659             pixman_image_set_destroy_function(rect, virtio_unref_resource,
    660                                               res->image);
    661         }
    662 
    663         /* realloc the surface ptr */
    664         scanout->ds = qemu_create_displaysurface_pixman(rect);
    665         if (!scanout->ds) {
    666             *error = VIRTIO_GPU_RESP_ERR_UNSPEC;
    667             return;
    668         }
    669 
    670         pixman_image_unref(rect);
    671         dpy_gfx_replace_surface(g->parent_obj.scanout[scanout_id].con,
    672                                 scanout->ds);
    673     }
    674 
    675     virtio_gpu_update_scanout(g, scanout_id, res, r);
    676 }
    677 
    678 static void virtio_gpu_set_scanout(VirtIOGPU *g,
    679                                    struct virtio_gpu_ctrl_command *cmd)
    680 {
    681     struct virtio_gpu_simple_resource *res;
    682     struct virtio_gpu_framebuffer fb = { 0 };
    683     struct virtio_gpu_set_scanout ss;
    684 
    685     VIRTIO_GPU_FILL_CMD(ss);
    686     virtio_gpu_bswap_32(&ss, sizeof(ss));
    687     trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id,
    688                                      ss.r.width, ss.r.height, ss.r.x, ss.r.y);
    689 
    690     if (ss.scanout_id >= g->parent_obj.conf.max_outputs) {
    691         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",
    692                       __func__, ss.scanout_id);
    693         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
    694         return;
    695     }
    696 
    697     if (ss.resource_id == 0) {
    698         virtio_gpu_disable_scanout(g, ss.scanout_id);
    699         return;
    700     }
    701 
    702     res = virtio_gpu_find_check_resource(g, ss.resource_id, true,
    703                                          __func__, &cmd->error);
    704     if (!res) {
    705         return;
    706     }
    707 
    708     fb.format = pixman_image_get_format(res->image);
    709     fb.bytes_pp = DIV_ROUND_UP(PIXMAN_FORMAT_BPP(fb.format), 8);
    710     fb.width  = pixman_image_get_width(res->image);
    711     fb.height = pixman_image_get_height(res->image);
    712     fb.stride = pixman_image_get_stride(res->image);
    713     fb.offset = ss.r.x * fb.bytes_pp + ss.r.y * fb.stride;
    714 
    715     virtio_gpu_do_set_scanout(g, ss.scanout_id,
    716                               &fb, res, &ss.r, &cmd->error);
    717 }
    718 
    719 static void virtio_gpu_set_scanout_blob(VirtIOGPU *g,
    720                                         struct virtio_gpu_ctrl_command *cmd)
    721 {
    722     struct virtio_gpu_simple_resource *res;
    723     struct virtio_gpu_framebuffer fb = { 0 };
    724     struct virtio_gpu_set_scanout_blob ss;
    725     uint64_t fbend;
    726 
    727     VIRTIO_GPU_FILL_CMD(ss);
    728     virtio_gpu_scanout_blob_bswap(&ss);
    729     trace_virtio_gpu_cmd_set_scanout_blob(ss.scanout_id, ss.resource_id,
    730                                           ss.r.width, ss.r.height, ss.r.x,
    731                                           ss.r.y);
    732 
    733     if (ss.scanout_id >= g->parent_obj.conf.max_outputs) {
    734         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",
    735                       __func__, ss.scanout_id);
    736         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
    737         return;
    738     }
    739 
    740     if (ss.resource_id == 0) {
    741         virtio_gpu_disable_scanout(g, ss.scanout_id);
    742         return;
    743     }
    744 
    745     res = virtio_gpu_find_check_resource(g, ss.resource_id, true,
    746                                          __func__, &cmd->error);
    747     if (!res) {
    748         return;
    749     }
    750 
    751     fb.format = virtio_gpu_get_pixman_format(ss.format);
    752     if (!fb.format) {
    753         qemu_log_mask(LOG_GUEST_ERROR,
    754                       "%s: host couldn't handle guest format %d\n",
    755                       __func__, ss.format);
    756         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
    757         return;
    758     }
    759 
    760     fb.bytes_pp = DIV_ROUND_UP(PIXMAN_FORMAT_BPP(fb.format), 8);
    761     fb.width = ss.width;
    762     fb.height = ss.height;
    763     fb.stride = ss.strides[0];
    764     fb.offset = ss.offsets[0] + ss.r.x * fb.bytes_pp + ss.r.y * fb.stride;
    765 
    766     fbend = fb.offset;
    767     fbend += fb.stride * (ss.r.height - 1);
    768     fbend += fb.bytes_pp * ss.r.width;
    769     if (fbend > res->blob_size) {
    770         qemu_log_mask(LOG_GUEST_ERROR,
    771                       "%s: fb end out of range\n",
    772                       __func__);
    773         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
    774         return;
    775     }
    776 
    777     virtio_gpu_do_set_scanout(g, ss.scanout_id,
    778                               &fb, res, &ss.r, &cmd->error);
    779 }
    780 
    781 int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
    782                                   uint32_t nr_entries, uint32_t offset,
    783                                   struct virtio_gpu_ctrl_command *cmd,
    784                                   uint64_t **addr, struct iovec **iov,
    785                                   uint32_t *niov)
    786 {
    787     struct virtio_gpu_mem_entry *ents;
    788     size_t esize, s;
    789     int e, v;
    790 
    791     if (nr_entries > 16384) {
    792         qemu_log_mask(LOG_GUEST_ERROR,
    793                       "%s: nr_entries is too big (%d > 16384)\n",
    794                       __func__, nr_entries);
    795         return -1;
    796     }
    797 
    798     esize = sizeof(*ents) * nr_entries;
    799     ents = g_malloc(esize);
    800     s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num,
    801                    offset, ents, esize);
    802     if (s != esize) {
    803         qemu_log_mask(LOG_GUEST_ERROR,
    804                       "%s: command data size incorrect %zu vs %zu\n",
    805                       __func__, s, esize);
    806         g_free(ents);
    807         return -1;
    808     }
    809 
    810     *iov = NULL;
    811     if (addr) {
    812         *addr = NULL;
    813     }
    814     for (e = 0, v = 0; e < nr_entries; e++) {
    815         uint64_t a = le64_to_cpu(ents[e].addr);
    816         uint32_t l = le32_to_cpu(ents[e].length);
    817         hwaddr len;
    818         void *map;
    819 
    820         do {
    821             len = l;
    822             map = dma_memory_map(VIRTIO_DEVICE(g)->dma_as, a, &len,
    823                                  DMA_DIRECTION_TO_DEVICE,
    824                                  MEMTXATTRS_UNSPECIFIED);
    825             if (!map) {
    826                 qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for"
    827                               " element %d\n", __func__, e);
    828                 virtio_gpu_cleanup_mapping_iov(g, *iov, v);
    829                 g_free(ents);
    830                 *iov = NULL;
    831                 if (addr) {
    832                     g_free(*addr);
    833                     *addr = NULL;
    834                 }
    835                 return -1;
    836             }
    837 
    838             if (!(v % 16)) {
    839                 *iov = g_renew(struct iovec, *iov, v + 16);
    840                 if (addr) {
    841                     *addr = g_renew(uint64_t, *addr, v + 16);
    842                 }
    843             }
    844             (*iov)[v].iov_base = map;
    845             (*iov)[v].iov_len = len;
    846             if (addr) {
    847                 (*addr)[v] = a;
    848             }
    849 
    850             a += len;
    851             l -= len;
    852             v += 1;
    853         } while (l > 0);
    854     }
    855     *niov = v;
    856 
    857     g_free(ents);
    858     return 0;
    859 }
    860 
    861 void virtio_gpu_cleanup_mapping_iov(VirtIOGPU *g,
    862                                     struct iovec *iov, uint32_t count)
    863 {
    864     int i;
    865 
    866     for (i = 0; i < count; i++) {
    867         dma_memory_unmap(VIRTIO_DEVICE(g)->dma_as,
    868                          iov[i].iov_base, iov[i].iov_len,
    869                          DMA_DIRECTION_TO_DEVICE,
    870                          iov[i].iov_len);
    871     }
    872     g_free(iov);
    873 }
    874 
    875 static void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
    876                                        struct virtio_gpu_simple_resource *res)
    877 {
    878     virtio_gpu_cleanup_mapping_iov(g, res->iov, res->iov_cnt);
    879     res->iov = NULL;
    880     res->iov_cnt = 0;
    881     g_free(res->addrs);
    882     res->addrs = NULL;
    883 
    884     if (res->blob) {
    885         virtio_gpu_fini_udmabuf(res);
    886     }
    887 }
    888 
    889 static void
    890 virtio_gpu_resource_attach_backing(VirtIOGPU *g,
    891                                    struct virtio_gpu_ctrl_command *cmd)
    892 {
    893     struct virtio_gpu_simple_resource *res;
    894     struct virtio_gpu_resource_attach_backing ab;
    895     int ret;
    896 
    897     VIRTIO_GPU_FILL_CMD(ab);
    898     virtio_gpu_bswap_32(&ab, sizeof(ab));
    899     trace_virtio_gpu_cmd_res_back_attach(ab.resource_id);
    900 
    901     res = virtio_gpu_find_resource(g, ab.resource_id);
    902     if (!res) {
    903         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
    904                       __func__, ab.resource_id);
    905         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
    906         return;
    907     }
    908 
    909     if (res->iov) {
    910         cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
    911         return;
    912     }
    913 
    914     ret = virtio_gpu_create_mapping_iov(g, ab.nr_entries, sizeof(ab), cmd,
    915                                         &res->addrs, &res->iov, &res->iov_cnt);
    916     if (ret != 0) {
    917         cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
    918         return;
    919     }
    920 }
    921 
    922 static void
    923 virtio_gpu_resource_detach_backing(VirtIOGPU *g,
    924                                    struct virtio_gpu_ctrl_command *cmd)
    925 {
    926     struct virtio_gpu_simple_resource *res;
    927     struct virtio_gpu_resource_detach_backing detach;
    928 
    929     VIRTIO_GPU_FILL_CMD(detach);
    930     virtio_gpu_bswap_32(&detach, sizeof(detach));
    931     trace_virtio_gpu_cmd_res_back_detach(detach.resource_id);
    932 
    933     res = virtio_gpu_find_check_resource(g, detach.resource_id, true,
    934                                          __func__, &cmd->error);
    935     if (!res) {
    936         return;
    937     }
    938     virtio_gpu_cleanup_mapping(g, res);
    939 }
    940 
    941 void virtio_gpu_simple_process_cmd(VirtIOGPU *g,
    942                                    struct virtio_gpu_ctrl_command *cmd)
    943 {
    944     VIRTIO_GPU_FILL_CMD(cmd->cmd_hdr);
    945     virtio_gpu_ctrl_hdr_bswap(&cmd->cmd_hdr);
    946 
    947     switch (cmd->cmd_hdr.type) {
    948     case VIRTIO_GPU_CMD_GET_DISPLAY_INFO:
    949         virtio_gpu_get_display_info(g, cmd);
    950         break;
    951     case VIRTIO_GPU_CMD_GET_EDID:
    952         virtio_gpu_get_edid(g, cmd);
    953         break;
    954     case VIRTIO_GPU_CMD_RESOURCE_CREATE_2D:
    955         virtio_gpu_resource_create_2d(g, cmd);
    956         break;
    957     case VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB:
    958         if (!virtio_gpu_blob_enabled(g->parent_obj.conf)) {
    959             cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
    960             break;
    961         }
    962         virtio_gpu_resource_create_blob(g, cmd);
    963         break;
    964     case VIRTIO_GPU_CMD_RESOURCE_UNREF:
    965         virtio_gpu_resource_unref(g, cmd);
    966         break;
    967     case VIRTIO_GPU_CMD_RESOURCE_FLUSH:
    968         virtio_gpu_resource_flush(g, cmd);
    969         break;
    970     case VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D:
    971         virtio_gpu_transfer_to_host_2d(g, cmd);
    972         break;
    973     case VIRTIO_GPU_CMD_SET_SCANOUT:
    974         virtio_gpu_set_scanout(g, cmd);
    975         break;
    976     case VIRTIO_GPU_CMD_SET_SCANOUT_BLOB:
    977         if (!virtio_gpu_blob_enabled(g->parent_obj.conf)) {
    978             cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
    979             break;
    980         }
    981         virtio_gpu_set_scanout_blob(g, cmd);
    982         break;
    983     case VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING:
    984         virtio_gpu_resource_attach_backing(g, cmd);
    985         break;
    986     case VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING:
    987         virtio_gpu_resource_detach_backing(g, cmd);
    988         break;
    989     default:
    990         cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
    991         break;
    992     }
    993     if (!cmd->finished) {
    994         if (!g->parent_obj.renderer_blocked) {
    995             virtio_gpu_ctrl_response_nodata(g, cmd, cmd->error ? cmd->error :
    996                                             VIRTIO_GPU_RESP_OK_NODATA);
    997         }
    998     }
    999 }
   1000 
   1001 static void virtio_gpu_handle_ctrl_cb(VirtIODevice *vdev, VirtQueue *vq)
   1002 {
   1003     VirtIOGPU *g = VIRTIO_GPU(vdev);
   1004     qemu_bh_schedule(g->ctrl_bh);
   1005 }
   1006 
   1007 static void virtio_gpu_handle_cursor_cb(VirtIODevice *vdev, VirtQueue *vq)
   1008 {
   1009     VirtIOGPU *g = VIRTIO_GPU(vdev);
   1010     qemu_bh_schedule(g->cursor_bh);
   1011 }
   1012 
   1013 void virtio_gpu_process_cmdq(VirtIOGPU *g)
   1014 {
   1015     struct virtio_gpu_ctrl_command *cmd;
   1016     VirtIOGPUClass *vgc = VIRTIO_GPU_GET_CLASS(g);
   1017 
   1018     if (g->processing_cmdq) {
   1019         return;
   1020     }
   1021     g->processing_cmdq = true;
   1022     while (!QTAILQ_EMPTY(&g->cmdq)) {
   1023         cmd = QTAILQ_FIRST(&g->cmdq);
   1024 
   1025         if (g->parent_obj.renderer_blocked) {
   1026             break;
   1027         }
   1028 
   1029         /* process command */
   1030         vgc->process_cmd(g, cmd);
   1031 
   1032         QTAILQ_REMOVE(&g->cmdq, cmd, next);
   1033         if (virtio_gpu_stats_enabled(g->parent_obj.conf)) {
   1034             g->stats.requests++;
   1035         }
   1036 
   1037         if (!cmd->finished) {
   1038             QTAILQ_INSERT_TAIL(&g->fenceq, cmd, next);
   1039             g->inflight++;
   1040             if (virtio_gpu_stats_enabled(g->parent_obj.conf)) {
   1041                 if (g->stats.max_inflight < g->inflight) {
   1042                     g->stats.max_inflight = g->inflight;
   1043                 }
   1044                 fprintf(stderr, "inflight: %3d (+)\r", g->inflight);
   1045             }
   1046         } else {
   1047             g_free(cmd);
   1048         }
   1049     }
   1050     g->processing_cmdq = false;
   1051 }
   1052 
   1053 static void virtio_gpu_process_fenceq(VirtIOGPU *g)
   1054 {
   1055     struct virtio_gpu_ctrl_command *cmd, *tmp;
   1056 
   1057     QTAILQ_FOREACH_SAFE(cmd, &g->fenceq, next, tmp) {
   1058         trace_virtio_gpu_fence_resp(cmd->cmd_hdr.fence_id);
   1059         virtio_gpu_ctrl_response_nodata(g, cmd, VIRTIO_GPU_RESP_OK_NODATA);
   1060         QTAILQ_REMOVE(&g->fenceq, cmd, next);
   1061         g_free(cmd);
   1062         g->inflight--;
   1063         if (virtio_gpu_stats_enabled(g->parent_obj.conf)) {
   1064             fprintf(stderr, "inflight: %3d (-)\r", g->inflight);
   1065         }
   1066     }
   1067 }
   1068 
   1069 static void virtio_gpu_handle_gl_flushed(VirtIOGPUBase *b)
   1070 {
   1071     VirtIOGPU *g = container_of(b, VirtIOGPU, parent_obj);
   1072 
   1073     virtio_gpu_process_fenceq(g);
   1074     virtio_gpu_process_cmdq(g);
   1075 }
   1076 
   1077 static void virtio_gpu_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
   1078 {
   1079     VirtIOGPU *g = VIRTIO_GPU(vdev);
   1080     struct virtio_gpu_ctrl_command *cmd;
   1081 
   1082     if (!virtio_queue_ready(vq)) {
   1083         return;
   1084     }
   1085 
   1086     cmd = virtqueue_pop(vq, sizeof(struct virtio_gpu_ctrl_command));
   1087     while (cmd) {
   1088         cmd->vq = vq;
   1089         cmd->error = 0;
   1090         cmd->finished = false;
   1091         QTAILQ_INSERT_TAIL(&g->cmdq, cmd, next);
   1092         cmd = virtqueue_pop(vq, sizeof(struct virtio_gpu_ctrl_command));
   1093     }
   1094 
   1095     virtio_gpu_process_cmdq(g);
   1096 }
   1097 
   1098 static void virtio_gpu_ctrl_bh(void *opaque)
   1099 {
   1100     VirtIOGPU *g = opaque;
   1101     VirtIOGPUClass *vgc = VIRTIO_GPU_GET_CLASS(g);
   1102 
   1103     vgc->handle_ctrl(&g->parent_obj.parent_obj, g->ctrl_vq);
   1104 }
   1105 
   1106 static void virtio_gpu_handle_cursor(VirtIODevice *vdev, VirtQueue *vq)
   1107 {
   1108     VirtIOGPU *g = VIRTIO_GPU(vdev);
   1109     VirtQueueElement *elem;
   1110     size_t s;
   1111     struct virtio_gpu_update_cursor cursor_info;
   1112 
   1113     if (!virtio_queue_ready(vq)) {
   1114         return;
   1115     }
   1116     for (;;) {
   1117         elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
   1118         if (!elem) {
   1119             break;
   1120         }
   1121 
   1122         s = iov_to_buf(elem->out_sg, elem->out_num, 0,
   1123                        &cursor_info, sizeof(cursor_info));
   1124         if (s != sizeof(cursor_info)) {
   1125             qemu_log_mask(LOG_GUEST_ERROR,
   1126                           "%s: cursor size incorrect %zu vs %zu\n",
   1127                           __func__, s, sizeof(cursor_info));
   1128         } else {
   1129             virtio_gpu_bswap_32(&cursor_info, sizeof(cursor_info));
   1130             update_cursor(g, &cursor_info);
   1131         }
   1132         virtqueue_push(vq, elem, 0);
   1133         virtio_notify(vdev, vq);
   1134         g_free(elem);
   1135     }
   1136 }
   1137 
   1138 static void virtio_gpu_cursor_bh(void *opaque)
   1139 {
   1140     VirtIOGPU *g = opaque;
   1141     virtio_gpu_handle_cursor(&g->parent_obj.parent_obj, g->cursor_vq);
   1142 }
   1143 
   1144 static const VMStateDescription vmstate_virtio_gpu_scanout = {
   1145     .name = "virtio-gpu-one-scanout",
   1146     .version_id = 1,
   1147     .fields = (VMStateField[]) {
   1148         VMSTATE_UINT32(resource_id, struct virtio_gpu_scanout),
   1149         VMSTATE_UINT32(width, struct virtio_gpu_scanout),
   1150         VMSTATE_UINT32(height, struct virtio_gpu_scanout),
   1151         VMSTATE_INT32(x, struct virtio_gpu_scanout),
   1152         VMSTATE_INT32(y, struct virtio_gpu_scanout),
   1153         VMSTATE_UINT32(cursor.resource_id, struct virtio_gpu_scanout),
   1154         VMSTATE_UINT32(cursor.hot_x, struct virtio_gpu_scanout),
   1155         VMSTATE_UINT32(cursor.hot_y, struct virtio_gpu_scanout),
   1156         VMSTATE_UINT32(cursor.pos.x, struct virtio_gpu_scanout),
   1157         VMSTATE_UINT32(cursor.pos.y, struct virtio_gpu_scanout),
   1158         VMSTATE_END_OF_LIST()
   1159     },
   1160 };
   1161 
   1162 static const VMStateDescription vmstate_virtio_gpu_scanouts = {
   1163     .name = "virtio-gpu-scanouts",
   1164     .version_id = 1,
   1165     .fields = (VMStateField[]) {
   1166         VMSTATE_INT32(parent_obj.enable, struct VirtIOGPU),
   1167         VMSTATE_UINT32_EQUAL(parent_obj.conf.max_outputs,
   1168                              struct VirtIOGPU, NULL),
   1169         VMSTATE_STRUCT_VARRAY_UINT32(parent_obj.scanout, struct VirtIOGPU,
   1170                                      parent_obj.conf.max_outputs, 1,
   1171                                      vmstate_virtio_gpu_scanout,
   1172                                      struct virtio_gpu_scanout),
   1173         VMSTATE_END_OF_LIST()
   1174     },
   1175 };
   1176 
   1177 static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
   1178                            const VMStateField *field, JSONWriter *vmdesc)
   1179 {
   1180     VirtIOGPU *g = opaque;
   1181     struct virtio_gpu_simple_resource *res;
   1182     int i;
   1183 
   1184     /* in 2d mode we should never find unprocessed commands here */
   1185     assert(QTAILQ_EMPTY(&g->cmdq));
   1186 
   1187     QTAILQ_FOREACH(res, &g->reslist, next) {
   1188         qemu_put_be32(f, res->resource_id);
   1189         qemu_put_be32(f, res->width);
   1190         qemu_put_be32(f, res->height);
   1191         qemu_put_be32(f, res->format);
   1192         qemu_put_be32(f, res->iov_cnt);
   1193         for (i = 0; i < res->iov_cnt; i++) {
   1194             qemu_put_be64(f, res->addrs[i]);
   1195             qemu_put_be32(f, res->iov[i].iov_len);
   1196         }
   1197         qemu_put_buffer(f, (void *)pixman_image_get_data(res->image),
   1198                         pixman_image_get_stride(res->image) * res->height);
   1199     }
   1200     qemu_put_be32(f, 0); /* end of list */
   1201 
   1202     return vmstate_save_state(f, &vmstate_virtio_gpu_scanouts, g, NULL);
   1203 }
   1204 
   1205 static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
   1206                            const VMStateField *field)
   1207 {
   1208     VirtIOGPU *g = opaque;
   1209     struct virtio_gpu_simple_resource *res;
   1210     struct virtio_gpu_scanout *scanout;
   1211     uint32_t resource_id, pformat;
   1212     int i;
   1213 
   1214     g->hostmem = 0;
   1215 
   1216     resource_id = qemu_get_be32(f);
   1217     while (resource_id != 0) {
   1218         res = virtio_gpu_find_resource(g, resource_id);
   1219         if (res) {
   1220             return -EINVAL;
   1221         }
   1222 
   1223         res = g_new0(struct virtio_gpu_simple_resource, 1);
   1224         res->resource_id = resource_id;
   1225         res->width = qemu_get_be32(f);
   1226         res->height = qemu_get_be32(f);
   1227         res->format = qemu_get_be32(f);
   1228         res->iov_cnt = qemu_get_be32(f);
   1229 
   1230         /* allocate */
   1231         pformat = virtio_gpu_get_pixman_format(res->format);
   1232         if (!pformat) {
   1233             g_free(res);
   1234             return -EINVAL;
   1235         }
   1236         res->image = pixman_image_create_bits(pformat,
   1237                                               res->width, res->height,
   1238                                               NULL, 0);
   1239         if (!res->image) {
   1240             g_free(res);
   1241             return -EINVAL;
   1242         }
   1243 
   1244         res->hostmem = calc_image_hostmem(pformat, res->width, res->height);
   1245 
   1246         res->addrs = g_new(uint64_t, res->iov_cnt);
   1247         res->iov = g_new(struct iovec, res->iov_cnt);
   1248 
   1249         /* read data */
   1250         for (i = 0; i < res->iov_cnt; i++) {
   1251             res->addrs[i] = qemu_get_be64(f);
   1252             res->iov[i].iov_len = qemu_get_be32(f);
   1253         }
   1254         qemu_get_buffer(f, (void *)pixman_image_get_data(res->image),
   1255                         pixman_image_get_stride(res->image) * res->height);
   1256 
   1257         /* restore mapping */
   1258         for (i = 0; i < res->iov_cnt; i++) {
   1259             hwaddr len = res->iov[i].iov_len;
   1260             res->iov[i].iov_base =
   1261                 dma_memory_map(VIRTIO_DEVICE(g)->dma_as, res->addrs[i], &len,
   1262                                DMA_DIRECTION_TO_DEVICE,
   1263                                MEMTXATTRS_UNSPECIFIED);
   1264 
   1265             if (!res->iov[i].iov_base || len != res->iov[i].iov_len) {
   1266                 /* Clean up the half-a-mapping we just created... */
   1267                 if (res->iov[i].iov_base) {
   1268                     dma_memory_unmap(VIRTIO_DEVICE(g)->dma_as,
   1269                                      res->iov[i].iov_base,
   1270                                      len,
   1271                                      DMA_DIRECTION_TO_DEVICE,
   1272                                      0);
   1273                 }
   1274                 /* ...and the mappings for previous loop iterations */
   1275                 res->iov_cnt = i;
   1276                 virtio_gpu_cleanup_mapping(g, res);
   1277                 pixman_image_unref(res->image);
   1278                 g_free(res);
   1279                 return -EINVAL;
   1280             }
   1281         }
   1282 
   1283         QTAILQ_INSERT_HEAD(&g->reslist, res, next);
   1284         g->hostmem += res->hostmem;
   1285 
   1286         resource_id = qemu_get_be32(f);
   1287     }
   1288 
   1289     /* load & apply scanout state */
   1290     vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1);
   1291     for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
   1292         scanout = &g->parent_obj.scanout[i];
   1293         if (!scanout->resource_id) {
   1294             continue;
   1295         }
   1296         res = virtio_gpu_find_resource(g, scanout->resource_id);
   1297         if (!res) {
   1298             return -EINVAL;
   1299         }
   1300         scanout->ds = qemu_create_displaysurface_pixman(res->image);
   1301         if (!scanout->ds) {
   1302             return -EINVAL;
   1303         }
   1304 
   1305         dpy_gfx_replace_surface(scanout->con, scanout->ds);
   1306         dpy_gfx_update_full(scanout->con);
   1307         if (scanout->cursor.resource_id) {
   1308             update_cursor(g, &scanout->cursor);
   1309         }
   1310         res->scanout_bitmask |= (1 << i);
   1311     }
   1312 
   1313     return 0;
   1314 }
   1315 
   1316 void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
   1317 {
   1318     VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
   1319     VirtIOGPU *g = VIRTIO_GPU(qdev);
   1320 
   1321     if (virtio_gpu_blob_enabled(g->parent_obj.conf)) {
   1322         if (!virtio_gpu_have_udmabuf()) {
   1323             error_setg(errp, "cannot enable blob resources without udmabuf");
   1324             return;
   1325         }
   1326 
   1327         if (virtio_gpu_virgl_enabled(g->parent_obj.conf)) {
   1328             error_setg(errp, "blobs and virgl are not compatible (yet)");
   1329             return;
   1330         }
   1331     }
   1332 
   1333     if (!virtio_gpu_base_device_realize(qdev,
   1334                                         virtio_gpu_handle_ctrl_cb,
   1335                                         virtio_gpu_handle_cursor_cb,
   1336                                         errp)) {
   1337         return;
   1338     }
   1339 
   1340     g->ctrl_vq = virtio_get_queue(vdev, 0);
   1341     g->cursor_vq = virtio_get_queue(vdev, 1);
   1342     g->ctrl_bh = qemu_bh_new(virtio_gpu_ctrl_bh, g);
   1343     g->cursor_bh = qemu_bh_new(virtio_gpu_cursor_bh, g);
   1344     QTAILQ_INIT(&g->reslist);
   1345     QTAILQ_INIT(&g->cmdq);
   1346     QTAILQ_INIT(&g->fenceq);
   1347 }
   1348 
   1349 void virtio_gpu_reset(VirtIODevice *vdev)
   1350 {
   1351     VirtIOGPU *g = VIRTIO_GPU(vdev);
   1352     struct virtio_gpu_simple_resource *res, *tmp;
   1353     struct virtio_gpu_ctrl_command *cmd;
   1354 
   1355     QTAILQ_FOREACH_SAFE(res, &g->reslist, next, tmp) {
   1356         virtio_gpu_resource_destroy(g, res);
   1357     }
   1358 
   1359     while (!QTAILQ_EMPTY(&g->cmdq)) {
   1360         cmd = QTAILQ_FIRST(&g->cmdq);
   1361         QTAILQ_REMOVE(&g->cmdq, cmd, next);
   1362         g_free(cmd);
   1363     }
   1364 
   1365     while (!QTAILQ_EMPTY(&g->fenceq)) {
   1366         cmd = QTAILQ_FIRST(&g->fenceq);
   1367         QTAILQ_REMOVE(&g->fenceq, cmd, next);
   1368         g->inflight--;
   1369         g_free(cmd);
   1370     }
   1371 
   1372     virtio_gpu_base_reset(VIRTIO_GPU_BASE(vdev));
   1373 }
   1374 
   1375 static void
   1376 virtio_gpu_get_config(VirtIODevice *vdev, uint8_t *config)
   1377 {
   1378     VirtIOGPUBase *g = VIRTIO_GPU_BASE(vdev);
   1379 
   1380     memcpy(config, &g->virtio_config, sizeof(g->virtio_config));
   1381 }
   1382 
   1383 static void
   1384 virtio_gpu_set_config(VirtIODevice *vdev, const uint8_t *config)
   1385 {
   1386     VirtIOGPUBase *g = VIRTIO_GPU_BASE(vdev);
   1387     const struct virtio_gpu_config *vgconfig =
   1388         (const struct virtio_gpu_config *)config;
   1389 
   1390     if (vgconfig->events_clear) {
   1391         g->virtio_config.events_read &= ~vgconfig->events_clear;
   1392     }
   1393 }
   1394 
   1395 /*
   1396  * For historical reasons virtio_gpu does not adhere to virtio migration
   1397  * scheme as described in doc/virtio-migration.txt, in a sense that no
   1398  * save/load callback are provided to the core. Instead the device data
   1399  * is saved/loaded after the core data.
   1400  *
   1401  * Because of this we need a special vmsd.
   1402  */
   1403 static const VMStateDescription vmstate_virtio_gpu = {
   1404     .name = "virtio-gpu",
   1405     .minimum_version_id = VIRTIO_GPU_VM_VERSION,
   1406     .version_id = VIRTIO_GPU_VM_VERSION,
   1407     .fields = (VMStateField[]) {
   1408         VMSTATE_VIRTIO_DEVICE /* core */,
   1409         {
   1410             .name = "virtio-gpu",
   1411             .info = &(const VMStateInfo) {
   1412                         .name = "virtio-gpu",
   1413                         .get = virtio_gpu_load,
   1414                         .put = virtio_gpu_save,
   1415             },
   1416             .flags = VMS_SINGLE,
   1417         } /* device */,
   1418         VMSTATE_END_OF_LIST()
   1419     },
   1420 };
   1421 
   1422 static Property virtio_gpu_properties[] = {
   1423     VIRTIO_GPU_BASE_PROPERTIES(VirtIOGPU, parent_obj.conf),
   1424     DEFINE_PROP_SIZE("max_hostmem", VirtIOGPU, conf_max_hostmem,
   1425                      256 * MiB),
   1426     DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags,
   1427                     VIRTIO_GPU_FLAG_BLOB_ENABLED, false),
   1428     DEFINE_PROP_END_OF_LIST(),
   1429 };
   1430 
   1431 static void virtio_gpu_class_init(ObjectClass *klass, void *data)
   1432 {
   1433     DeviceClass *dc = DEVICE_CLASS(klass);
   1434     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
   1435     VirtIOGPUClass *vgc = VIRTIO_GPU_CLASS(klass);
   1436     VirtIOGPUBaseClass *vgbc = &vgc->parent;
   1437 
   1438     vgc->handle_ctrl = virtio_gpu_handle_ctrl;
   1439     vgc->process_cmd = virtio_gpu_simple_process_cmd;
   1440     vgc->update_cursor_data = virtio_gpu_update_cursor_data;
   1441     vgbc->gl_flushed = virtio_gpu_handle_gl_flushed;
   1442 
   1443     vdc->realize = virtio_gpu_device_realize;
   1444     vdc->reset = virtio_gpu_reset;
   1445     vdc->get_config = virtio_gpu_get_config;
   1446     vdc->set_config = virtio_gpu_set_config;
   1447 
   1448     dc->vmsd = &vmstate_virtio_gpu;
   1449     device_class_set_props(dc, virtio_gpu_properties);
   1450 }
   1451 
   1452 static const TypeInfo virtio_gpu_info = {
   1453     .name = TYPE_VIRTIO_GPU,
   1454     .parent = TYPE_VIRTIO_GPU_BASE,
   1455     .instance_size = sizeof(VirtIOGPU),
   1456     .class_size = sizeof(VirtIOGPUClass),
   1457     .class_init = virtio_gpu_class_init,
   1458 };
   1459 module_obj(TYPE_VIRTIO_GPU);
   1460 module_kconfig(VIRTIO_GPU);
   1461 
   1462 static void virtio_register_types(void)
   1463 {
   1464     type_register_static(&virtio_gpu_info);
   1465 }
   1466 
   1467 type_init(virtio_register_types)