cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

virtio-gpu.h (8951B)


      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.
     11 * See the COPYING file in the top-level directory.
     12 */
     13
     14#ifndef HW_VIRTIO_GPU_H
     15#define HW_VIRTIO_GPU_H
     16
     17#include "qemu/queue.h"
     18#include "ui/qemu-pixman.h"
     19#include "ui/console.h"
     20#include "hw/virtio/virtio.h"
     21#include "qemu/log.h"
     22#include "sysemu/vhost-user-backend.h"
     23
     24#include "standard-headers/linux/virtio_gpu.h"
     25#include "qom/object.h"
     26
     27#define TYPE_VIRTIO_GPU_BASE "virtio-gpu-base"
     28OBJECT_DECLARE_TYPE(VirtIOGPUBase, VirtIOGPUBaseClass,
     29                    VIRTIO_GPU_BASE)
     30
     31#define TYPE_VIRTIO_GPU "virtio-gpu-device"
     32OBJECT_DECLARE_TYPE(VirtIOGPU, VirtIOGPUClass, VIRTIO_GPU)
     33
     34#define TYPE_VIRTIO_GPU_GL "virtio-gpu-gl-device"
     35OBJECT_DECLARE_SIMPLE_TYPE(VirtIOGPUGL, VIRTIO_GPU_GL)
     36
     37#define TYPE_VHOST_USER_GPU "vhost-user-gpu"
     38OBJECT_DECLARE_SIMPLE_TYPE(VhostUserGPU, VHOST_USER_GPU)
     39
     40#define VIRTIO_ID_GPU 16
     41
     42struct virtio_gpu_simple_resource {
     43    uint32_t resource_id;
     44    uint32_t width;
     45    uint32_t height;
     46    uint32_t format;
     47    uint64_t *addrs;
     48    struct iovec *iov;
     49    unsigned int iov_cnt;
     50    uint32_t scanout_bitmask;
     51    pixman_image_t *image;
     52    uint64_t hostmem;
     53
     54    uint64_t blob_size;
     55    void *blob;
     56    int dmabuf_fd;
     57    uint8_t *remapped;
     58
     59    QTAILQ_ENTRY(virtio_gpu_simple_resource) next;
     60};
     61
     62struct virtio_gpu_framebuffer {
     63    pixman_format_code_t format;
     64    uint32_t bytes_pp;
     65    uint32_t width, height;
     66    uint32_t stride;
     67    uint32_t offset;
     68};
     69
     70struct virtio_gpu_scanout {
     71    QemuConsole *con;
     72    DisplaySurface *ds;
     73    uint32_t width, height;
     74    int x, y;
     75    int invalidate;
     76    uint32_t resource_id;
     77    struct virtio_gpu_update_cursor cursor;
     78    QEMUCursor *current_cursor;
     79};
     80
     81struct virtio_gpu_requested_state {
     82    uint16_t width_mm, height_mm;
     83    uint32_t width, height;
     84    int x, y;
     85};
     86
     87enum virtio_gpu_base_conf_flags {
     88    VIRTIO_GPU_FLAG_VIRGL_ENABLED = 1,
     89    VIRTIO_GPU_FLAG_STATS_ENABLED,
     90    VIRTIO_GPU_FLAG_EDID_ENABLED,
     91    VIRTIO_GPU_FLAG_DMABUF_ENABLED,
     92    VIRTIO_GPU_FLAG_BLOB_ENABLED,
     93};
     94
     95#define virtio_gpu_virgl_enabled(_cfg) \
     96    (_cfg.flags & (1 << VIRTIO_GPU_FLAG_VIRGL_ENABLED))
     97#define virtio_gpu_stats_enabled(_cfg) \
     98    (_cfg.flags & (1 << VIRTIO_GPU_FLAG_STATS_ENABLED))
     99#define virtio_gpu_edid_enabled(_cfg) \
    100    (_cfg.flags & (1 << VIRTIO_GPU_FLAG_EDID_ENABLED))
    101#define virtio_gpu_dmabuf_enabled(_cfg) \
    102    (_cfg.flags & (1 << VIRTIO_GPU_FLAG_DMABUF_ENABLED))
    103#define virtio_gpu_blob_enabled(_cfg) \
    104    (_cfg.flags & (1 << VIRTIO_GPU_FLAG_BLOB_ENABLED))
    105
    106struct virtio_gpu_base_conf {
    107    uint32_t max_outputs;
    108    uint32_t flags;
    109    uint32_t xres;
    110    uint32_t yres;
    111};
    112
    113struct virtio_gpu_ctrl_command {
    114    VirtQueueElement elem;
    115    VirtQueue *vq;
    116    struct virtio_gpu_ctrl_hdr cmd_hdr;
    117    uint32_t error;
    118    bool finished;
    119    QTAILQ_ENTRY(virtio_gpu_ctrl_command) next;
    120};
    121
    122struct VirtIOGPUBase {
    123    VirtIODevice parent_obj;
    124
    125    Error *migration_blocker;
    126
    127    struct virtio_gpu_base_conf conf;
    128    struct virtio_gpu_config virtio_config;
    129    const GraphicHwOps *hw_ops;
    130
    131    int renderer_blocked;
    132    int enable;
    133
    134    struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS];
    135
    136    int enabled_output_bitmask;
    137    struct virtio_gpu_requested_state req_state[VIRTIO_GPU_MAX_SCANOUTS];
    138};
    139
    140struct VirtIOGPUBaseClass {
    141    VirtioDeviceClass parent;
    142
    143    void (*gl_flushed)(VirtIOGPUBase *g);
    144};
    145
    146#define VIRTIO_GPU_BASE_PROPERTIES(_state, _conf)                       \
    147    DEFINE_PROP_UINT32("max_outputs", _state, _conf.max_outputs, 1),    \
    148    DEFINE_PROP_BIT("edid", _state, _conf.flags, \
    149                    VIRTIO_GPU_FLAG_EDID_ENABLED, true), \
    150    DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1024), \
    151    DEFINE_PROP_UINT32("yres", _state, _conf.yres, 768)
    152
    153typedef struct VGPUDMABuf {
    154    QemuDmaBuf buf;
    155    uint32_t scanout_id;
    156    QTAILQ_ENTRY(VGPUDMABuf) next;
    157} VGPUDMABuf;
    158
    159struct VirtIOGPU {
    160    VirtIOGPUBase parent_obj;
    161
    162    uint64_t conf_max_hostmem;
    163
    164    VirtQueue *ctrl_vq;
    165    VirtQueue *cursor_vq;
    166
    167    QEMUBH *ctrl_bh;
    168    QEMUBH *cursor_bh;
    169
    170    QTAILQ_HEAD(, virtio_gpu_simple_resource) reslist;
    171    QTAILQ_HEAD(, virtio_gpu_ctrl_command) cmdq;
    172    QTAILQ_HEAD(, virtio_gpu_ctrl_command) fenceq;
    173
    174    uint64_t hostmem;
    175
    176    bool processing_cmdq;
    177    QEMUTimer *fence_poll;
    178    QEMUTimer *print_stats;
    179
    180    uint32_t inflight;
    181    struct {
    182        uint32_t max_inflight;
    183        uint32_t requests;
    184        uint32_t req_3d;
    185        uint32_t bytes_3d;
    186    } stats;
    187
    188    struct {
    189        QTAILQ_HEAD(, VGPUDMABuf) bufs;
    190        VGPUDMABuf *primary;
    191    } dmabuf;
    192};
    193
    194struct VirtIOGPUClass {
    195    VirtIOGPUBaseClass parent;
    196
    197    void (*handle_ctrl)(VirtIODevice *vdev, VirtQueue *vq);
    198    void (*process_cmd)(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd);
    199    void (*update_cursor_data)(VirtIOGPU *g,
    200                               struct virtio_gpu_scanout *s,
    201                               uint32_t resource_id);
    202};
    203
    204struct VirtIOGPUGL {
    205    struct VirtIOGPU parent_obj;
    206
    207    bool renderer_inited;
    208    bool renderer_reset;
    209};
    210
    211struct VhostUserGPU {
    212    VirtIOGPUBase parent_obj;
    213
    214    VhostUserBackend *vhost;
    215    int vhost_gpu_fd; /* closed by the chardev */
    216    CharBackend vhost_chr;
    217    QemuDmaBuf dmabuf[VIRTIO_GPU_MAX_SCANOUTS];
    218    bool backend_blocked;
    219};
    220
    221#define VIRTIO_GPU_FILL_CMD(out) do {                                   \
    222        size_t s;                                                       \
    223        s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0,          \
    224                       &out, sizeof(out));                              \
    225        if (s != sizeof(out)) {                                         \
    226            qemu_log_mask(LOG_GUEST_ERROR,                              \
    227                          "%s: command size incorrect %zu vs %zu\n",    \
    228                          __func__, s, sizeof(out));                    \
    229            return;                                                     \
    230        }                                                               \
    231    } while (0)
    232
    233/* virtio-gpu-base.c */
    234bool virtio_gpu_base_device_realize(DeviceState *qdev,
    235                                    VirtIOHandleOutput ctrl_cb,
    236                                    VirtIOHandleOutput cursor_cb,
    237                                    Error **errp);
    238void virtio_gpu_base_reset(VirtIOGPUBase *g);
    239void virtio_gpu_base_fill_display_info(VirtIOGPUBase *g,
    240                        struct virtio_gpu_resp_display_info *dpy_info);
    241
    242/* virtio-gpu.c */
    243void virtio_gpu_ctrl_response(VirtIOGPU *g,
    244                              struct virtio_gpu_ctrl_command *cmd,
    245                              struct virtio_gpu_ctrl_hdr *resp,
    246                              size_t resp_len);
    247void virtio_gpu_ctrl_response_nodata(VirtIOGPU *g,
    248                                     struct virtio_gpu_ctrl_command *cmd,
    249                                     enum virtio_gpu_ctrl_type type);
    250void virtio_gpu_get_display_info(VirtIOGPU *g,
    251                                 struct virtio_gpu_ctrl_command *cmd);
    252void virtio_gpu_get_edid(VirtIOGPU *g,
    253                         struct virtio_gpu_ctrl_command *cmd);
    254int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
    255                                  uint32_t nr_entries, uint32_t offset,
    256                                  struct virtio_gpu_ctrl_command *cmd,
    257                                  uint64_t **addr, struct iovec **iov,
    258                                  uint32_t *niov);
    259void virtio_gpu_cleanup_mapping_iov(VirtIOGPU *g,
    260                                    struct iovec *iov, uint32_t count);
    261void virtio_gpu_process_cmdq(VirtIOGPU *g);
    262void virtio_gpu_device_realize(DeviceState *qdev, Error **errp);
    263void virtio_gpu_reset(VirtIODevice *vdev);
    264void virtio_gpu_simple_process_cmd(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd);
    265void virtio_gpu_update_cursor_data(VirtIOGPU *g,
    266                                   struct virtio_gpu_scanout *s,
    267                                   uint32_t resource_id);
    268
    269/* virtio-gpu-udmabuf.c */
    270bool virtio_gpu_have_udmabuf(void);
    271void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res);
    272void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res);
    273int virtio_gpu_update_dmabuf(VirtIOGPU *g,
    274                             uint32_t scanout_id,
    275                             struct virtio_gpu_simple_resource *res,
    276                             struct virtio_gpu_framebuffer *fb);
    277
    278/* virtio-gpu-3d.c */
    279void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
    280                                  struct virtio_gpu_ctrl_command *cmd);
    281void virtio_gpu_virgl_fence_poll(VirtIOGPU *g);
    282void virtio_gpu_virgl_reset_scanout(VirtIOGPU *g);
    283void virtio_gpu_virgl_reset(VirtIOGPU *g);
    284int virtio_gpu_virgl_init(VirtIOGPU *g);
    285int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g);
    286
    287#endif