hw/display/next-fb: Fix comment typo
[qemu/ar7.git] / hw / virtio / vhost-shadow-virtqueue.h
blobd04c34a58961534cda45077cec2be3af9a8ccf6f
1 /*
2 * vhost shadow virtqueue
4 * SPDX-FileCopyrightText: Red Hat, Inc. 2021
5 * SPDX-FileContributor: Author: Eugenio PĂ©rez <eperezma@redhat.com>
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
10 #ifndef VHOST_SHADOW_VIRTQUEUE_H
11 #define VHOST_SHADOW_VIRTQUEUE_H
13 #include "qemu/event_notifier.h"
14 #include "hw/virtio/virtio.h"
15 #include "standard-headers/linux/vhost_types.h"
16 #include "hw/virtio/vhost-iova-tree.h"
18 typedef struct SVQDescState {
19 VirtQueueElement *elem;
22 * Number of descriptors exposed to the device. May or may not match
23 * guest's
25 unsigned int ndescs;
26 } SVQDescState;
28 typedef struct VhostShadowVirtqueue VhostShadowVirtqueue;
30 /**
31 * Callback to handle an avail buffer.
33 * @svq: Shadow virtqueue
34 * @elem: Element placed in the queue by the guest
35 * @vq_callback_opaque: Opaque
37 * Returns 0 if the vq is running as expected.
39 * Note that ownership of elem is transferred to the callback.
41 typedef int (*VirtQueueAvailCallback)(VhostShadowVirtqueue *svq,
42 VirtQueueElement *elem,
43 void *vq_callback_opaque);
45 typedef struct VhostShadowVirtqueueOps {
46 VirtQueueAvailCallback avail_handler;
47 } VhostShadowVirtqueueOps;
49 /* Shadow virtqueue to relay notifications */
50 typedef struct VhostShadowVirtqueue {
51 /* Shadow vring */
52 struct vring vring;
54 /* Shadow kick notifier, sent to vhost */
55 EventNotifier hdev_kick;
56 /* Shadow call notifier, sent to vhost */
57 EventNotifier hdev_call;
60 * Borrowed virtqueue's guest to host notifier. To borrow it in this event
61 * notifier allows to recover the VhostShadowVirtqueue from the event loop
62 * easily. If we use the VirtQueue's one, we don't have an easy way to
63 * retrieve VhostShadowVirtqueue.
65 * So shadow virtqueue must not clean it, or we would lose VirtQueue one.
67 EventNotifier svq_kick;
69 /* Guest's call notifier, where the SVQ calls guest. */
70 EventNotifier svq_call;
72 /* Virtio queue shadowing */
73 VirtQueue *vq;
75 /* Virtio device */
76 VirtIODevice *vdev;
78 /* IOVA mapping */
79 VhostIOVATree *iova_tree;
81 /* SVQ vring descriptors state */
82 SVQDescState *desc_state;
84 /* Next VirtQueue element that guest made available */
85 VirtQueueElement *next_guest_avail_elem;
88 * Backup next field for each descriptor so we can recover securely, not
89 * needing to trust the device access.
91 uint16_t *desc_next;
93 /* Caller callbacks */
94 const VhostShadowVirtqueueOps *ops;
96 /* Caller callbacks opaque */
97 void *ops_opaque;
99 /* Next head to expose to the device */
100 uint16_t shadow_avail_idx;
102 /* Next free descriptor */
103 uint16_t free_head;
105 /* Last seen used idx */
106 uint16_t shadow_used_idx;
108 /* Next head to consume from the device */
109 uint16_t last_used_idx;
110 } VhostShadowVirtqueue;
112 bool vhost_svq_valid_features(uint64_t features, Error **errp);
114 void vhost_svq_push_elem(VhostShadowVirtqueue *svq,
115 const VirtQueueElement *elem, uint32_t len);
116 int vhost_svq_add(VhostShadowVirtqueue *svq, const struct iovec *out_sg,
117 size_t out_num, const struct iovec *in_sg, size_t in_num,
118 VirtQueueElement *elem);
119 size_t vhost_svq_poll(VhostShadowVirtqueue *svq);
121 void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd);
122 void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd);
123 void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq,
124 struct vhost_vring_addr *addr);
125 size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *svq);
126 size_t vhost_svq_device_area_size(const VhostShadowVirtqueue *svq);
128 void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev,
129 VirtQueue *vq);
130 void vhost_svq_stop(VhostShadowVirtqueue *svq);
132 VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree,
133 const VhostShadowVirtqueueOps *ops,
134 void *ops_opaque);
136 void vhost_svq_free(gpointer vq);
137 G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostShadowVirtqueue, vhost_svq_free);
139 #endif