Import QEMU upstream snapshot d2e570c
Upstream: https://gitlab.com/qemu-project/qemu.git Upstream-Commit: d2e570cc0f97b936902a5b1b86b73c0f5998b475
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Virtio vhost-user GPU Device
|
||||
*
|
||||
* Copyright Red Hat, Inc. 2013-2018
|
||||
*
|
||||
* Authors:
|
||||
* Dave Airlie <[email protected]>
|
||||
* Gerd Hoffmann <[email protected]>
|
||||
* Marc-André Lureau <[email protected]>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef VUGPU_H
|
||||
#define VUGPU_H
|
||||
|
||||
|
||||
#include "libvhost-user-glib.h"
|
||||
#include "standard-headers/linux/virtio_gpu.h"
|
||||
|
||||
#include "qemu/queue.h"
|
||||
#include "qemu/iov.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "qemu/units.h"
|
||||
#include "vugbm.h"
|
||||
|
||||
typedef enum VhostUserGpuRequest {
|
||||
VHOST_USER_GPU_NONE = 0,
|
||||
VHOST_USER_GPU_GET_PROTOCOL_FEATURES,
|
||||
VHOST_USER_GPU_SET_PROTOCOL_FEATURES,
|
||||
VHOST_USER_GPU_GET_DISPLAY_INFO,
|
||||
VHOST_USER_GPU_CURSOR_POS,
|
||||
VHOST_USER_GPU_CURSOR_POS_HIDE,
|
||||
VHOST_USER_GPU_CURSOR_UPDATE,
|
||||
VHOST_USER_GPU_SCANOUT,
|
||||
VHOST_USER_GPU_UPDATE,
|
||||
VHOST_USER_GPU_DMABUF_SCANOUT,
|
||||
VHOST_USER_GPU_DMABUF_UPDATE,
|
||||
VHOST_USER_GPU_GET_EDID,
|
||||
VHOST_USER_GPU_DMABUF_SCANOUT2,
|
||||
} VhostUserGpuRequest;
|
||||
|
||||
typedef struct VhostUserGpuDisplayInfoReply {
|
||||
struct virtio_gpu_resp_display_info info;
|
||||
} VhostUserGpuDisplayInfoReply;
|
||||
|
||||
typedef struct VhostUserGpuCursorPos {
|
||||
uint32_t scanout_id;
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
} QEMU_PACKED VhostUserGpuCursorPos;
|
||||
|
||||
typedef struct VhostUserGpuCursorUpdate {
|
||||
VhostUserGpuCursorPos pos;
|
||||
uint32_t hot_x;
|
||||
uint32_t hot_y;
|
||||
uint32_t data[64 * 64];
|
||||
} QEMU_PACKED VhostUserGpuCursorUpdate;
|
||||
|
||||
typedef struct VhostUserGpuScanout {
|
||||
uint32_t scanout_id;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
} QEMU_PACKED VhostUserGpuScanout;
|
||||
|
||||
typedef struct VhostUserGpuUpdate {
|
||||
uint32_t scanout_id;
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint8_t data[];
|
||||
} QEMU_PACKED VhostUserGpuUpdate;
|
||||
|
||||
typedef struct VhostUserGpuDMABUFScanout {
|
||||
uint32_t scanout_id;
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t fd_width;
|
||||
uint32_t fd_height;
|
||||
uint32_t fd_stride;
|
||||
uint32_t fd_flags;
|
||||
int fd_drm_fourcc;
|
||||
} QEMU_PACKED VhostUserGpuDMABUFScanout;
|
||||
|
||||
typedef struct VhostUserGpuDMABUFScanout2 {
|
||||
struct VhostUserGpuDMABUFScanout dmabuf_scanout;
|
||||
uint64_t modifier;
|
||||
} QEMU_PACKED VhostUserGpuDMABUFScanout2;
|
||||
|
||||
typedef struct VhostUserGpuEdidRequest {
|
||||
uint32_t scanout_id;
|
||||
} QEMU_PACKED VhostUserGpuEdidRequest;
|
||||
|
||||
typedef struct VhostUserGpuMsg {
|
||||
uint32_t request; /* VhostUserGpuRequest */
|
||||
uint32_t flags;
|
||||
uint32_t size; /* the following payload size */
|
||||
union {
|
||||
VhostUserGpuCursorPos cursor_pos;
|
||||
VhostUserGpuCursorUpdate cursor_update;
|
||||
VhostUserGpuScanout scanout;
|
||||
VhostUserGpuUpdate update;
|
||||
VhostUserGpuDMABUFScanout dmabuf_scanout;
|
||||
VhostUserGpuDMABUFScanout2 dmabuf_scanout2;
|
||||
VhostUserGpuEdidRequest edid_req;
|
||||
struct virtio_gpu_resp_edid resp_edid;
|
||||
struct virtio_gpu_resp_display_info display_info;
|
||||
uint64_t u64;
|
||||
} payload;
|
||||
} QEMU_PACKED VhostUserGpuMsg;
|
||||
|
||||
static VhostUserGpuMsg m __attribute__ ((unused));
|
||||
#define VHOST_USER_GPU_HDR_SIZE \
|
||||
(sizeof(m.request) + sizeof(m.flags) + sizeof(m.size))
|
||||
|
||||
#define VHOST_USER_GPU_MSG_FLAG_REPLY 0x4
|
||||
|
||||
#define VHOST_USER_GPU_PROTOCOL_F_EDID 0
|
||||
#define VHOST_USER_GPU_PROTOCOL_F_DMABUF2 1
|
||||
|
||||
struct virtio_gpu_scanout {
|
||||
uint32_t width, height;
|
||||
int x, y;
|
||||
int invalidate;
|
||||
uint32_t resource_id;
|
||||
};
|
||||
|
||||
typedef struct VuGpu {
|
||||
VugDev dev;
|
||||
struct virtio_gpu_config virtio_config;
|
||||
struct vugbm_device gdev;
|
||||
int sock_fd;
|
||||
int drm_rnode_fd;
|
||||
GSource *renderer_source;
|
||||
guint wait_in;
|
||||
|
||||
bool virgl;
|
||||
bool virgl_inited;
|
||||
bool edid_inited;
|
||||
bool use_modifiers;
|
||||
uint32_t inflight;
|
||||
|
||||
struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS];
|
||||
QTAILQ_HEAD(, virtio_gpu_simple_resource) reslist;
|
||||
QTAILQ_HEAD(, virtio_gpu_ctrl_command) fenceq;
|
||||
} VuGpu;
|
||||
|
||||
enum {
|
||||
VG_CMD_STATE_NEW,
|
||||
VG_CMD_STATE_PENDING,
|
||||
VG_CMD_STATE_FINISHED,
|
||||
};
|
||||
|
||||
struct virtio_gpu_ctrl_command {
|
||||
VuVirtqElement elem;
|
||||
VuVirtq *vq;
|
||||
struct virtio_gpu_ctrl_hdr cmd_hdr;
|
||||
uint32_t error;
|
||||
int state;
|
||||
QTAILQ_ENTRY(virtio_gpu_ctrl_command) next;
|
||||
};
|
||||
|
||||
/*
|
||||
* With 4 KiB pages and QEMU's VIRTQUEUE_MAX_SIZE (1024) mapped-iov
|
||||
* limit, the largest inline command is ~4 MiB. Cap submit_3d
|
||||
* allocations to this value to prevent a malicious guest from
|
||||
* triggering an OOM abort via an inflated cs.size field.
|
||||
*/
|
||||
#define VIRTIO_GPU_MAX_CMD_SUBMIT_SIZE (4 * MiB)
|
||||
|
||||
#define VUGPU_FILL_CMD(out) do { \
|
||||
size_t vugpufillcmd_s_ = \
|
||||
iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0, \
|
||||
&out, sizeof(out)); \
|
||||
if (vugpufillcmd_s_ != sizeof(out)) { \
|
||||
g_critical("%s: command size incorrect %zu vs %zu", \
|
||||
__func__, vugpufillcmd_s_, sizeof(out)); \
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
void vg_ctrl_response(VuGpu *g,
|
||||
struct virtio_gpu_ctrl_command *cmd,
|
||||
struct virtio_gpu_ctrl_hdr *resp,
|
||||
size_t resp_len);
|
||||
|
||||
void vg_ctrl_response_nodata(VuGpu *g,
|
||||
struct virtio_gpu_ctrl_command *cmd,
|
||||
enum virtio_gpu_ctrl_type type);
|
||||
|
||||
int vg_create_mapping_iov(VuGpu *g,
|
||||
struct virtio_gpu_resource_attach_backing *ab,
|
||||
struct virtio_gpu_ctrl_command *cmd,
|
||||
struct iovec **iov);
|
||||
void vg_cleanup_mapping_iov(VuGpu *g, struct iovec *iov, uint32_t count);
|
||||
void vg_get_display_info(VuGpu *vg, struct virtio_gpu_ctrl_command *cmd);
|
||||
void vg_get_edid(VuGpu *vg, struct virtio_gpu_ctrl_command *cmd);
|
||||
|
||||
void vg_wait_ok(VuGpu *g);
|
||||
|
||||
void vg_send_msg(VuGpu *g, const VhostUserGpuMsg *msg, int fd);
|
||||
|
||||
bool vg_recv_msg(VuGpu *g, uint32_t expect_req, uint32_t expect_size,
|
||||
gpointer payload);
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user