blob: c8f72850bc05f4c6ea7b51aae4b572b04882725f [file] [log] [blame]
aliguori967f97f2008-12-04 19:38:57 +00001/*
2 * Virtio Support
3 *
4 * Copyright IBM, Corp. 2007
5 *
6 * Authors:
7 * Anthony Liguori <aliguori@us.ibm.com>
8 *
9 * This work is licensed under the terms of the GNU GPL, version 2. See
10 * the COPYING file in the top-level directory.
11 *
12 */
13
Markus Armbruster2a6a4072016-06-29 13:47:03 +020014#ifndef QEMU_VIRTIO_H
15#define QEMU_VIRTIO_H
aliguori967f97f2008-12-04 19:38:57 +000016
Markus Armbrusterd4842052019-08-12 07:23:46 +020017#include "exec/memory.h"
Markus Armbrustera27bd6c2019-08-12 07:23:51 +020018#include "hw/qdev-core.h"
Paolo Bonzini1422e322012-10-24 08:43:34 +020019#include "net/net.h"
Markus Armbrusterd6454272019-08-12 07:23:45 +020020#include "migration/vmstate.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010021#include "qemu/event_notifier.h"
Michael S. Tsirkine9600c62015-02-16 22:35:46 +010022#include "standard-headers/linux/virtio_config.h"
23#include "standard-headers/linux/virtio_ring.h"
Eduardo Habkostdb1015e2020-09-03 16:43:22 -040024#include "qom/object.h"
aliguori967f97f2008-12-04 19:38:57 +000025
Alex Bennéeea5d6ea2022-08-02 10:49:53 +010026/*
27 * A guest should never accept this. It implies negotiation is broken
28 * between the driver frontend and the device. This bit is re-used for
29 * vhost-user to advertise VHOST_USER_F_PROTOCOL_FEATURES between QEMU
30 * and a vhost-user backend.
31 */
Yeqi Fu48805df2023-03-15 11:26:49 +080032#define VIRTIO_F_BAD_FEATURE 30
aliguori967f97f2008-12-04 19:38:57 +000033
Michael S. Tsirkin5f456072015-07-22 13:09:25 +030034#define VIRTIO_LEGACY_FEATURES ((0x1ULL << VIRTIO_F_BAD_FEATURE) | \
35 (0x1ULL << VIRTIO_F_NOTIFY_ON_EMPTY) | \
36 (0x1ULL << VIRTIO_F_ANY_LAYOUT))
37
aliguori967f97f2008-12-04 19:38:57 +000038struct VirtQueue;
39
Avi Kivitya8170e52012-10-23 12:30:10 +020040static inline hwaddr vring_align(hwaddr addr,
aliguorif46f15b2008-12-04 19:58:45 +000041 unsigned long align)
42{
Andrew Baumannb8adbc62017-03-24 16:19:43 -070043 return QEMU_ALIGN_UP(addr, align);
aliguorif46f15b2008-12-04 19:58:45 +000044}
45
Stefano Garzarellaba550852019-02-21 11:33:08 +010046typedef struct VirtIOFeature {
47 uint64_t flags;
48 size_t end;
49} VirtIOFeature;
50
Daniil Tatianind74c30c2022-09-06 10:31:07 +030051typedef struct VirtIOConfigSizeParams {
52 size_t min_size;
53 size_t max_size;
54 const VirtIOFeature *feature_sizes;
55} VirtIOConfigSizeParams;
56
57size_t virtio_get_config_size(const VirtIOConfigSizeParams *params,
58 uint64_t host_features);
Stefano Garzarellaba550852019-02-21 11:33:08 +010059
aliguori967f97f2008-12-04 19:38:57 +000060typedef struct VirtQueue VirtQueue;
aliguori967f97f2008-12-04 19:38:57 +000061
62#define VIRTQUEUE_MAX_SIZE 1024
63
64typedef struct VirtQueueElement
65{
66 unsigned int index;
Jason Wang86044b22019-10-25 10:35:24 +020067 unsigned int len;
68 unsigned int ndescs;
aliguori967f97f2008-12-04 19:38:57 +000069 unsigned int out_num;
70 unsigned int in_num;
Paolo Bonzini37246502016-01-31 11:29:00 +010071 hwaddr *in_addr;
72 hwaddr *out_addr;
73 struct iovec *in_sg;
74 struct iovec *out_sg;
aliguori967f97f2008-12-04 19:38:57 +000075} VirtQueueElement;
76
Jason Wangb829c2a2015-05-29 14:15:32 +080077#define VIRTIO_QUEUE_MAX 1024
aliguori967f97f2008-12-04 19:38:57 +000078
Michael S. Tsirkin7055e682009-06-21 19:50:13 +030079#define VIRTIO_NO_VECTOR 0xffff
80
Cindy Lu544f0272022-12-22 15:04:42 +080081/* special index value used internally for config irqs */
82#define VIRTIO_CONFIG_IRQ_IDX -1
83
KONRAD Frederic8e05db92013-01-15 00:08:02 +010084#define TYPE_VIRTIO_DEVICE "virtio-device"
Eduardo Habkosta489d192020-09-16 14:25:18 -040085OBJECT_DECLARE_TYPE(VirtIODevice, VirtioDeviceClass, VIRTIO_DEVICE)
KONRAD Frederic8e05db92013-01-15 00:08:02 +010086
Laurent Vivierf3034ad2022-08-11 08:24:41 -040087typedef struct {
88 int virtio_bit;
89 const char *feature_desc;
90} qmp_virtio_feature_map_t;
91
Greg Kurz616a6552014-06-24 19:38:54 +020092enum virtio_device_endian {
93 VIRTIO_DEVICE_ENDIAN_UNKNOWN,
94 VIRTIO_DEVICE_ENDIAN_LITTLE,
95 VIRTIO_DEVICE_ENDIAN_BIG,
96};
97
Alex Bennée9600c982022-11-23 15:21:33 +000098/**
99 * struct VirtIODevice - common VirtIO structure
100 * @name: name of the device
101 * @status: VirtIO Device Status field
102 *
103 */
aliguori967f97f2008-12-04 19:38:57 +0000104struct VirtIODevice
105{
KONRAD Frederic8e05db92013-01-15 00:08:02 +0100106 DeviceState parent_obj;
aliguori967f97f2008-12-04 19:38:57 +0000107 const char *name;
aliguori967f97f2008-12-04 19:38:57 +0000108 uint8_t status;
109 uint8_t isr;
110 uint16_t queue_sel;
Alex Bennée9600c982022-11-23 15:21:33 +0000111 /**
112 * These fields represent a set of VirtIO features at various
113 * levels of the stack. @host_features indicates the complete
114 * feature set the VirtIO device can offer to the driver.
115 * @guest_features indicates which features the VirtIO driver has
116 * selected by writing to the feature register. Finally
117 * @backend_features represents everything supported by the
118 * backend (e.g. vhost) and could potentially be a subset of the
119 * total feature set offered by QEMU.
120 */
Gerd Hoffmann019a3ed2015-06-01 10:45:40 +0200121 uint64_t host_features;
Alex Bennée9600c982022-11-23 15:21:33 +0000122 uint64_t guest_features;
Maxime Coquelin75ebec12017-05-23 14:31:19 +0200123 uint64_t backend_features;
Alex Bennée9600c982022-11-23 15:21:33 +0000124
aliguori967f97f2008-12-04 19:38:57 +0000125 size_t config_len;
126 void *config;
Michael S. Tsirkin7055e682009-06-21 19:50:13 +0300127 uint16_t config_vector;
Michael S. Tsirkinb8f05902015-06-04 12:34:23 +0200128 uint32_t generation;
Michael S. Tsirkin7055e682009-06-21 19:50:13 +0300129 int nvectors;
aliguori967f97f2008-12-04 19:38:57 +0000130 VirtQueue *vq;
Paolo Bonzinic611c762017-01-27 16:40:17 +0100131 MemoryListener listener;
Paul Brook53c25ce2009-05-18 14:51:59 +0100132 uint16_t device_id;
Alex Bennée9f6bcfd2022-08-02 10:49:58 +0100133 /* @vm_running: current VM running state via virtio_vmstate_change() */
Michael S. Tsirkin85cf2a82011-01-10 14:28:40 +0200134 bool vm_running;
Stefan Hajnoczif5ed3662016-09-21 16:52:19 +0100135 bool broken; /* device in invalid state, needs reset */
Michael Roth9d7bd082019-11-19 18:50:03 -0600136 bool use_disabled_flag; /* allow use of 'disable' flag when needed */
137 bool disabled; /* device in temporarily disabled state */
Alex Bennée4987e5b2022-11-30 11:24:39 +0000138 /**
139 * @use_started: true if the @started flag should be used to check the
140 * current state of the VirtIO device. Otherwise status bits
141 * should be checked for a current status of the device.
142 * @use_started is only set via QMP and defaults to true for all
143 * modern machines (since 4.1).
144 */
Xie Yongjie57f2c32019-06-26 10:31:26 +0800145 bool use_started;
Xie Yongjibadaf792019-03-20 19:26:40 +0800146 bool started;
Xie Yongji7abccd02019-06-26 10:31:27 +0800147 bool start_on_kick; /* when virtio 1.0 feature has not been negotiated */
Stefano Garzarellad55f5182020-09-21 14:25:03 +0200148 bool disable_legacy_check;
Jonah Palmerc2554882022-04-01 09:23:19 -0400149 bool vhost_started;
Michael S. Tsirkin85cf2a82011-01-10 14:28:40 +0200150 VMChangeStateEntry *vmstate;
KONRAD Frederic1034e9c2013-04-30 16:08:48 +0200151 char *bus_name;
Greg Kurz616a6552014-06-24 19:38:54 +0200152 uint8_t device_endian;
Alex Bennée661dee72023-07-10 16:35:08 +0100153 /**
154 * @user_guest_notifier_mask: gate usage of ->guest_notifier_mask() callback.
155 * This is used to suppress the masking of guest updates for
156 * vhost-user devices which are asynchronous by design.
157 */
Victor Kaplansky56696552016-02-18 16:12:23 +0200158 bool use_guest_notifier_mask;
Jason Wang8607f5c2016-12-30 18:09:10 +0800159 AddressSpace *dma_as;
Michael S. Tsirkin850d0072015-04-27 21:01:20 +0200160 QLIST_HEAD(, VirtQueue) *vector_queues;
Laurent Viviera5ebce32022-08-11 08:24:39 -0400161 QTAILQ_ENTRY(VirtIODevice) next;
Alex Bennée661dee72023-07-10 16:35:08 +0100162 /**
163 * @config_notifier: the event notifier that handles config events
164 */
Cindy Lu7d847d02022-12-22 15:04:47 +0800165 EventNotifier config_notifier;
Viktor Prutyanov206e91d2023-05-12 16:51:20 +0300166 bool device_iotlb_enabled;
aliguori967f97f2008-12-04 19:38:57 +0000167};
168
Eduardo Habkostdb1015e2020-09-03 16:43:22 -0400169struct VirtioDeviceClass {
Andreas Färber0ba94b62013-07-30 04:05:02 +0200170 /*< private >*/
KONRAD Frederic8e05db92013-01-15 00:08:02 +0100171 DeviceClass parent;
Andreas Färber0ba94b62013-07-30 04:05:02 +0200172 /*< public >*/
Andreas Färber1d244b42013-07-30 00:50:27 +0200173
174 /* This is what a VirtioDevice must implement */
Andreas Färber1d244b42013-07-30 00:50:27 +0200175 DeviceRealize realize;
Andreas Färber306ec6c2013-07-30 03:50:44 +0200176 DeviceUnrealize unrealize;
Jason Wang9d5b7312015-07-27 17:49:19 +0800177 uint64_t (*get_features)(VirtIODevice *vdev,
178 uint64_t requested_features,
179 Error **errp);
Gerd Hoffmann019a3ed2015-06-01 10:45:40 +0200180 uint64_t (*bad_features)(VirtIODevice *vdev);
Gerd Hoffmannd5aaa1b2015-06-03 14:47:19 +0200181 void (*set_features)(VirtIODevice *vdev, uint64_t val);
Cornelia Huck0b352fd2015-06-04 12:34:15 +0200182 int (*validate_features)(VirtIODevice *vdev);
KONRAD Frederic8e05db92013-01-15 00:08:02 +0100183 void (*get_config)(VirtIODevice *vdev, uint8_t *config);
184 void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
185 void (*reset)(VirtIODevice *vdev);
186 void (*set_status)(VirtIODevice *vdev, uint8_t val);
Xuan Zhuof47af0a2022-11-10 17:57:39 +0800187 /* Device must validate queue_index. */
Xuan Zhuob3a8d6f2022-10-17 17:25:45 +0800188 void (*queue_reset)(VirtIODevice *vdev, uint32_t queue_index);
Xuan Zhuof47af0a2022-11-10 17:57:39 +0800189 /* Device must validate queue_index. */
Kangjie Xu3c37f8b2022-10-17 17:25:46 +0800190 void (*queue_enable)(VirtIODevice *vdev, uint32_t queue_index);
Michael S. Tsirkin9b706db2016-11-04 12:04:23 +0200191 /* For transitional devices, this is a bitmap of features
192 * that are only exposed on the legacy interface but not
193 * the modern one.
194 */
195 uint64_t legacy_features;
KONRAD Frederic6a87acf2013-04-11 16:29:56 +0200196 /* Test and clear event pending status.
197 * Should be called after unmask to avoid losing events.
198 * If backend does not support masking,
199 * must check in frontend instead.
200 */
201 bool (*guest_notifier_pending)(VirtIODevice *vdev, int n);
202 /* Mask/unmask events from this vq. Any events reported
203 * while masked will become pending.
204 * If backend does not support masking,
205 * must mask in frontend instead.
206 */
207 void (*guest_notifier_mask)(VirtIODevice *vdev, int n, bool mask);
Paolo Bonziniff4c07d2016-10-21 22:48:07 +0200208 int (*start_ioeventfd)(VirtIODevice *vdev);
209 void (*stop_ioeventfd)(VirtIODevice *vdev);
Dr. David Alan Gilbertea43e252016-10-27 18:36:36 +0100210 /* Saving and loading of a device; trying to deprecate save/load
211 * use vmsd for new devices.
212 */
Greg Kurz1b5fc0d2014-06-24 19:15:31 +0200213 void (*save)(VirtIODevice *vdev, QEMUFile *f);
214 int (*load)(VirtIODevice *vdev, QEMUFile *f, int version_id);
Michael S. Tsirkin1dd71382019-10-11 15:58:03 +0200215 /* Post load hook in vmsd is called early while device is processed, and
216 * when VirtIODevice isn't fully initialized. Devices should use this instead,
217 * unless they specifically want to verify the migration stream as it's
218 * processed, e.g. for bounds checking.
219 */
220 int (*post_load)(VirtIODevice *vdev);
Dr. David Alan Gilbertea43e252016-10-27 18:36:36 +0100221 const VMStateDescription *vmsd;
Jens Freimann9711cd02019-10-29 12:49:04 +0100222 bool (*primary_unplug_pending)(void *opaque);
Jonah Palmerc2554882022-04-01 09:23:19 -0400223 struct vhost_dev *(*get_vhost)(VirtIODevice *vdev);
Viktor Prutyanov206e91d2023-05-12 16:51:20 +0300224 void (*toggle_device_iotlb)(VirtIODevice *vdev);
Eduardo Habkostdb1015e2020-09-03 16:43:22 -0400225};
KONRAD Frederic8e05db92013-01-15 00:08:02 +0100226
Gongleic8075ca2014-09-30 14:10:38 +0800227void virtio_instance_init_common(Object *proxy_obj, void *data,
228 size_t vdev_size, const char *vdev_name);
229
Alex Bennée3b6256c2023-07-10 16:35:07 +0100230/**
231 * virtio_init() - initialise the common VirtIODevice structure
232 * @vdev: pointer to VirtIODevice
233 * @device_id: the VirtIO device ID (see virtio_ids.h)
234 * @config_size: size of the config space
235 */
Jonah Palmer3857cd52022-04-01 09:23:18 -0400236void virtio_init(VirtIODevice *vdev, uint16_t device_id, size_t config_size);
237
KONRAD Frederic6a1a8cc2013-04-24 10:21:22 +0200238void virtio_cleanup(VirtIODevice *vdev);
KONRAD Frederic8e05db92013-01-15 00:08:02 +0100239
Marc-André Lureau9edc6312022-02-20 20:39:25 +0400240void virtio_error(VirtIODevice *vdev, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
Stefan Hajnoczif5ed3662016-09-21 16:52:19 +0100241
KONRAD Frederic1034e9c2013-04-30 16:08:48 +0200242/* Set the child bus name. */
243void virtio_device_set_child_bus_name(VirtIODevice *vdev, char *bus_name);
244
Fam Zhengbf1780b2016-07-13 13:09:43 +0800245typedef void (*VirtIOHandleOutput)(VirtIODevice *, VirtQueue *);
246
aliguori967f97f2008-12-04 19:38:57 +0000247VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
Fam Zhengbf1780b2016-07-13 13:09:43 +0800248 VirtIOHandleOutput handle_output);
aliguori967f97f2008-12-04 19:38:57 +0000249
Jason Wangf23fd812013-01-30 19:12:36 +0800250void virtio_del_queue(VirtIODevice *vdev, int n);
251
Michael S. Tsirkin722f8c52019-12-09 11:46:13 -0500252void virtio_delete_queue(VirtQueue *vq);
253
aliguori967f97f2008-12-04 19:38:57 +0000254void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
255 unsigned int len);
256void virtqueue_flush(VirtQueue *vq, unsigned int count);
Stefan Hajnoczi2640d2a2016-09-19 14:28:03 +0100257void virtqueue_detach_element(VirtQueue *vq, const VirtQueueElement *elem,
258 unsigned int len);
Ladi Prosek27e57ef2016-11-03 09:55:49 +0100259void virtqueue_unpop(VirtQueue *vq, const VirtQueueElement *elem,
260 unsigned int len);
Stefan Hajnoczi297a75e2016-09-07 17:20:48 +0200261bool virtqueue_rewind(VirtQueue *vq, unsigned int num);
aliguori967f97f2008-12-04 19:38:57 +0000262void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
263 unsigned int len, unsigned int idx);
264
Jason Wang8607f5c2016-12-30 18:09:10 +0800265void virtqueue_map(VirtIODevice *vdev, VirtQueueElement *elem);
Paolo Bonzini51b19eb2016-02-04 16:26:51 +0200266void *virtqueue_pop(VirtQueue *vq, size_t sz);
Yuri Benditovich54e17702016-12-13 10:12:07 +0200267unsigned int virtqueue_drop_all(VirtQueue *vq);
Jason Wang8607f5c2016-12-30 18:09:10 +0800268void *qemu_get_virtqueue_element(VirtIODevice *vdev, QEMUFile *f, size_t sz);
Jason Wang86044b22019-10-25 10:35:24 +0200269void qemu_put_virtqueue_element(VirtIODevice *vdev, QEMUFile *f,
270 VirtQueueElement *elem);
Amit Shah0d8d7692012-09-25 00:05:15 +0530271int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes,
272 unsigned int out_bytes);
273void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
Michael S. Tsirkine1f7b482012-11-30 00:02:56 +0200274 unsigned int *out_bytes,
275 unsigned max_in_bytes, unsigned max_out_bytes);
aliguori967f97f2008-12-04 19:38:57 +0000276
Paolo Bonzini83d768b2016-11-18 16:07:02 +0100277void virtio_notify_irqfd(VirtIODevice *vdev, VirtQueue *vq);
aliguori967f97f2008-12-04 19:38:57 +0000278void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
279
Dr. David Alan Gilbert2f168d02017-09-25 12:29:17 +0100280int virtio_save(VirtIODevice *vdev, QEMUFile *f);
Dr. David Alan Gilbert59431242016-07-14 18:22:45 +0100281
Halil Pasic1a665852016-10-06 14:55:39 +0200282extern const VMStateInfo virtio_vmstate_info;
283
Halil Pasic1a665852016-10-06 14:55:39 +0200284#define VMSTATE_VIRTIO_DEVICE \
285 { \
286 .name = "virtio", \
287 .info = &virtio_vmstate_info, \
288 .flags = VMS_SINGLE, \
289 }
290
Greg Kurz1b5fc0d2014-06-24 19:15:31 +0200291int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id);
aliguori967f97f2008-12-04 19:38:57 +0000292
Alex Bennéea0cc7672023-07-10 16:35:06 +0100293/**
294 * virtio_notify_config() - signal a change to device config
295 * @vdev: the virtio device
296 *
297 * Assuming the virtio device is up (VIRTIO_CONFIG_S_DRIVER_OK) this
298 * will trigger a guest interrupt and update the config version.
299 */
aliguori967f97f2008-12-04 19:38:57 +0000300void virtio_notify_config(VirtIODevice *vdev);
301
Stefan Hajnoczid0435bc2019-12-09 21:09:57 +0000302bool virtio_queue_get_notification(VirtQueue *vq);
aliguori967f97f2008-12-04 19:38:57 +0000303void virtio_queue_set_notification(VirtQueue *vq, int enable);
304
305int virtio_queue_ready(VirtQueue *vq);
306
307int virtio_queue_empty(VirtQueue *vq);
308
Paul Brook53c25ce2009-05-18 14:51:59 +0100309/* Host binding interface. */
310
Paul Brook53c25ce2009-05-18 14:51:59 +0100311uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr);
312uint32_t virtio_config_readw(VirtIODevice *vdev, uint32_t addr);
313uint32_t virtio_config_readl(VirtIODevice *vdev, uint32_t addr);
314void virtio_config_writeb(VirtIODevice *vdev, uint32_t addr, uint32_t data);
315void virtio_config_writew(VirtIODevice *vdev, uint32_t addr, uint32_t data);
316void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data);
Michael S. Tsirkinadfb7432015-06-04 12:34:24 +0200317uint32_t virtio_config_modern_readb(VirtIODevice *vdev, uint32_t addr);
318uint32_t virtio_config_modern_readw(VirtIODevice *vdev, uint32_t addr);
319uint32_t virtio_config_modern_readl(VirtIODevice *vdev, uint32_t addr);
320void virtio_config_modern_writeb(VirtIODevice *vdev,
321 uint32_t addr, uint32_t data);
322void virtio_config_modern_writew(VirtIODevice *vdev,
323 uint32_t addr, uint32_t data);
324void virtio_config_modern_writel(VirtIODevice *vdev,
325 uint32_t addr, uint32_t data);
Avi Kivitya8170e52012-10-23 12:30:10 +0200326void virtio_queue_set_addr(VirtIODevice *vdev, int n, hwaddr addr);
327hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n);
Peter Maydelle63c0ba2013-07-16 13:25:07 +0100328void virtio_queue_set_num(VirtIODevice *vdev, int n, int num);
Paul Brook53c25ce2009-05-18 14:51:59 +0100329int virtio_queue_get_num(VirtIODevice *vdev, int n);
Michael S. Tsirkin8c797e72017-01-12 23:26:22 +0200330int virtio_queue_get_max_num(VirtIODevice *vdev, int n);
Jason Wang8ad176a2015-05-29 14:15:26 +0800331int virtio_get_num_queues(VirtIODevice *vdev);
Cornelia Huckab223c92015-06-04 12:34:12 +0200332void virtio_queue_set_rings(VirtIODevice *vdev, int n, hwaddr desc,
333 hwaddr avail, hwaddr used);
334void virtio_queue_update_rings(VirtIODevice *vdev, int n);
Carlos Lópezf0d634e2023-03-17 01:27:51 +0100335void virtio_init_region_cache(VirtIODevice *vdev, int n);
Peter Maydell6ce69d12013-07-16 13:25:08 +0100336void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
Paul Brook53c25ce2009-05-18 14:51:59 +0100337void virtio_queue_notify(VirtIODevice *vdev, int n);
Michael S. Tsirkin7055e682009-06-21 19:50:13 +0300338uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
339void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
Tiwei Bie6f80e612018-04-12 23:12:30 +0800340int virtio_queue_set_host_notifier_mr(VirtIODevice *vdev, int n,
341 MemoryRegion *mr, bool assign);
Cornelia Huck0b352fd2015-06-04 12:34:15 +0200342int virtio_set_status(VirtIODevice *vdev, uint8_t val);
Paul Brook53c25ce2009-05-18 14:51:59 +0100343void virtio_reset(void *opaque);
Xuan Zhuob3a8d6f2022-10-17 17:25:45 +0800344void virtio_queue_reset(VirtIODevice *vdev, uint32_t queue_index);
Kangjie Xu3c37f8b2022-10-17 17:25:46 +0800345void virtio_queue_enable(VirtIODevice *vdev, uint32_t queue_index);
Paul Brook53c25ce2009-05-18 14:51:59 +0100346void virtio_update_irq(VirtIODevice *vdev);
Gerd Hoffmannd5aaa1b2015-06-03 14:47:19 +0200347int virtio_set_features(VirtIODevice *vdev, uint64_t val);
Paul Brook53c25ce2009-05-18 14:51:59 +0100348
Paul Brook53c25ce2009-05-18 14:51:59 +0100349/* Base devices. */
Paolo Bonzini12c56742012-05-16 12:54:05 +0200350typedef struct VirtIOBlkConf VirtIOBlkConf;
Alex Williamsonf0c07c72010-09-02 09:00:50 -0600351struct virtio_net_conf;
Amit Shah6b331ef2011-02-03 11:22:32 +0530352typedef struct virtio_serial_conf virtio_serial_conf;
Gerd Hoffmannf73ddba2014-03-14 14:39:20 +0100353typedef struct virtio_input_conf virtio_input_conf;
Stefan Hajnoczi973abc72011-02-11 08:40:59 +0000354typedef struct VirtIOSCSIConf VirtIOSCSIConf;
Amit Shah16c915b2012-06-20 12:29:32 +0530355typedef struct VirtIORNGConf VirtIORNGConf;
Gerd Hoffmann97b15622009-10-21 15:25:35 +0200356
Michael S. Tsirkin81725392010-01-10 13:52:53 +0200357#define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \
Gerd Hoffmann019a3ed2015-06-01 10:45:40 +0200358 DEFINE_PROP_BIT64("indirect_desc", _state, _field, \
359 VIRTIO_RING_F_INDIRECT_DESC, true), \
360 DEFINE_PROP_BIT64("event_idx", _state, _field, \
361 VIRTIO_RING_F_EVENT_IDX, true), \
362 DEFINE_PROP_BIT64("notify_on_empty", _state, _field, \
Michael S. Tsirkin09999a52015-07-22 12:32:25 +0300363 VIRTIO_F_NOTIFY_ON_EMPTY, true), \
364 DEFINE_PROP_BIT64("any_layout", _state, _field, \
Jason Wang8607f5c2016-12-30 18:09:10 +0800365 VIRTIO_F_ANY_LAYOUT, true), \
366 DEFINE_PROP_BIT64("iommu_platform", _state, _field, \
Jason Wang74b3e462019-10-25 10:35:27 +0200367 VIRTIO_F_IOMMU_PLATFORM, false), \
368 DEFINE_PROP_BIT64("packed", _state, _field, \
Kangjie Xu69e1c142022-10-17 17:25:47 +0800369 VIRTIO_F_RING_PACKED, false), \
370 DEFINE_PROP_BIT64("queue_reset", _state, _field, \
371 VIRTIO_F_RING_RESET, true)
Michael S. Tsirkin81725392010-01-10 13:52:53 +0200372
Avi Kivitya8170e52012-10-23 12:30:10 +0200373hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n);
Laurent Vivier0c9753e2020-07-27 17:33:19 +0200374bool virtio_queue_enabled_legacy(VirtIODevice *vdev, int n);
Jason Wang23bfaf72019-03-25 11:40:36 +0800375bool virtio_queue_enabled(VirtIODevice *vdev, int n);
Avi Kivitya8170e52012-10-23 12:30:10 +0200376hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n);
377hwaddr virtio_queue_get_used_addr(VirtIODevice *vdev, int n);
Avi Kivitya8170e52012-10-23 12:30:10 +0200378hwaddr virtio_queue_get_desc_size(VirtIODevice *vdev, int n);
379hwaddr virtio_queue_get_avail_size(VirtIODevice *vdev, int n);
380hwaddr virtio_queue_get_used_size(VirtIODevice *vdev, int n);
Jason Wang86044b22019-10-25 10:35:24 +0200381unsigned int virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n);
382void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n,
383 unsigned int idx);
Maxime Coquelin2d4ba6c2017-11-16 19:48:34 +0100384void virtio_queue_restore_last_avail_idx(VirtIODevice *vdev, int n);
Stefan Hajnoczi6793dfd2013-08-12 11:08:09 +0200385void virtio_queue_invalidate_signalled_used(VirtIODevice *vdev, int n);
Yuri Benditovich312d3b32016-12-13 10:12:05 +0200386void virtio_queue_update_used_idx(VirtIODevice *vdev, int n);
Michael S. Tsirkin1cbdabe2010-03-17 13:08:02 +0200387VirtQueue *virtio_get_queue(VirtIODevice *vdev, int n);
Jason Wange78a2b42013-01-30 19:12:37 +0800388uint16_t virtio_get_queue_index(VirtQueue *vq);
Michael S. Tsirkin1cbdabe2010-03-17 13:08:02 +0200389EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq);
Paolo Bonzini15b2bd12012-07-05 17:16:30 +0200390void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
391 bool with_irqfd);
Paolo Bonziniff4c07d2016-10-21 22:48:07 +0200392int virtio_device_start_ioeventfd(VirtIODevice *vdev);
Paolo Bonzini310837d2016-11-18 16:07:00 +0100393int virtio_device_grab_ioeventfd(VirtIODevice *vdev);
394void virtio_device_release_ioeventfd(VirtIODevice *vdev);
Paolo Bonzini8e93cef2016-10-21 22:48:08 +0200395bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev);
Michael S. Tsirkin1cbdabe2010-03-17 13:08:02 +0200396EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq);
Stefan Hajnoczifcccb272019-11-05 15:09:46 +0100397void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled);
Paolo Bonzinifa283a42016-10-21 22:48:15 +0200398void virtio_queue_host_notifier_read(EventNotifier *n);
Stefan Hajnoczidb608fb2021-12-07 13:23:36 +0000399void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx);
Stefan Hajnoczi38738f72022-04-27 15:35:37 +0100400void virtio_queue_aio_attach_host_notifier_no_poll(VirtQueue *vq, AioContext *ctx);
Stefan Hajnoczidb608fb2021-12-07 13:23:36 +0000401void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx);
Jason Wange0d686b2015-04-23 14:21:46 +0800402VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector);
403VirtQueue *virtio_vector_next_queue(VirtQueue *vq);
Cindy Lu7d847d02022-12-22 15:04:47 +0800404EventNotifier *virtio_config_get_guest_notifier(VirtIODevice *vdev);
405void virtio_config_set_guest_notifier_fd_handler(VirtIODevice *vdev,
406 bool assign, bool with_irqfd);
Greg Kurz98ed8ec2014-06-24 19:26:29 +0200407
Gerd Hoffmann019a3ed2015-06-01 10:45:40 +0200408static inline void virtio_add_feature(uint64_t *features, unsigned int fbit)
Cornelia Huck0cd09c32014-12-11 14:25:05 +0100409{
Gerd Hoffmann019a3ed2015-06-01 10:45:40 +0200410 assert(fbit < 64);
Gerd Hoffmannd5aaa1b2015-06-03 14:47:19 +0200411 *features |= (1ULL << fbit);
Cornelia Huck0cd09c32014-12-11 14:25:05 +0100412}
413
Gerd Hoffmann019a3ed2015-06-01 10:45:40 +0200414static inline void virtio_clear_feature(uint64_t *features, unsigned int fbit)
Cornelia Huck0cd09c32014-12-11 14:25:05 +0100415{
Gerd Hoffmann019a3ed2015-06-01 10:45:40 +0200416 assert(fbit < 64);
Gerd Hoffmannd5aaa1b2015-06-03 14:47:19 +0200417 *features &= ~(1ULL << fbit);
Cornelia Huck0cd09c32014-12-11 14:25:05 +0100418}
419
Cornelia Huck95129d62015-08-17 11:48:29 +0200420static inline bool virtio_has_feature(uint64_t features, unsigned int fbit)
Cornelia Huckef546f12014-12-11 14:25:06 +0100421{
Gerd Hoffmann019a3ed2015-06-01 10:45:40 +0200422 assert(fbit < 64);
Gerd Hoffmannd5aaa1b2015-06-03 14:47:19 +0200423 return !!(features & (1ULL << fbit));
Cornelia Huckef546f12014-12-11 14:25:06 +0100424}
425
Hawkins Jiawei0a478102023-06-02 19:52:13 +0800426static inline bool virtio_vdev_has_feature(const VirtIODevice *vdev,
Cornelia Huck95129d62015-08-17 11:48:29 +0200427 unsigned int fbit)
Cornelia Huckef546f12014-12-11 14:25:06 +0100428{
Cornelia Huck95129d62015-08-17 11:48:29 +0200429 return virtio_has_feature(vdev->guest_features, fbit);
Cornelia Huckef546f12014-12-11 14:25:06 +0100430}
431
Jason Wang74aae7b2015-08-05 17:50:07 +0800432static inline bool virtio_host_has_feature(VirtIODevice *vdev,
433 unsigned int fbit)
434{
Cornelia Huck95129d62015-08-17 11:48:29 +0200435 return virtio_has_feature(vdev->host_features, fbit);
Jason Wang74aae7b2015-08-05 17:50:07 +0800436}
437
Greg Kurz616a6552014-06-24 19:38:54 +0200438static inline bool virtio_is_big_endian(VirtIODevice *vdev)
Greg Kurz98ed8ec2014-06-24 19:26:29 +0200439{
Cornelia Huck95129d62015-08-17 11:48:29 +0200440 if (!virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
Cornelia Huck3c185592015-06-04 12:34:11 +0200441 assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
442 return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
443 }
444 /* Devices conforming to VIRTIO 1.0 or later are always LE. */
445 return false;
Greg Kurz98ed8ec2014-06-24 19:26:29 +0200446}
Xie Yongjie57f2c32019-06-26 10:31:26 +0800447
Alex Bennée4987e5b2022-11-30 11:24:39 +0000448/**
449 * virtio_device_started() - check if device started
450 * @vdev - the VirtIO device
451 * @status - the devices status bits
452 *
453 * Check if the device is started. For most modern machines this is
454 * tracked via the @vdev->started field (to support migration),
455 * otherwise we check for the final negotiated status bit that
456 * indicates everything is ready.
457 */
Xie Yongjie57f2c32019-06-26 10:31:26 +0800458static inline bool virtio_device_started(VirtIODevice *vdev, uint8_t status)
459{
460 if (vdev->use_started) {
461 return vdev->started;
462 }
463
Alex Bennée259d69c2022-11-07 12:14:07 +0000464 return status & VIRTIO_CONFIG_S_DRIVER_OK;
465}
466
467/**
468 * virtio_device_should_start() - check if device startable
469 * @vdev - the VirtIO device
470 * @status - the devices status bits
471 *
472 * This is similar to virtio_device_started() but also encapsulates a
473 * check on the VM status which would prevent a device starting
474 * anyway.
475 */
476static inline bool virtio_device_should_start(VirtIODevice *vdev, uint8_t status)
477{
Alex Bennée9f6bcfd2022-08-02 10:49:58 +0100478 if (!vdev->vm_running) {
479 return false;
480 }
481
Alex Bennée4987e5b2022-11-30 11:24:39 +0000482 return virtio_device_started(vdev, status);
Xie Yongjie57f2c32019-06-26 10:31:26 +0800483}
484
485static inline void virtio_set_started(VirtIODevice *vdev, bool started)
486{
487 if (started) {
488 vdev->start_on_kick = false;
489 }
490
491 if (vdev->use_started) {
492 vdev->started = started;
493 }
494}
Michael Roth9d7bd082019-11-19 18:50:03 -0600495
496static inline void virtio_set_disabled(VirtIODevice *vdev, bool disable)
497{
498 if (vdev->use_disabled_flag) {
499 vdev->disabled = disable;
500 }
501}
502
503static inline bool virtio_device_disabled(VirtIODevice *vdev)
504{
505 return unlikely(vdev->disabled || vdev->broken);
506}
507
Cornelia Huck7c78bdd2020-07-07 12:54:45 +0200508bool virtio_legacy_allowed(VirtIODevice *vdev);
Stefano Garzarellad55f5182020-09-21 14:25:03 +0200509bool virtio_legacy_check_disabled(VirtIODevice *vdev);
Cornelia Huck7c78bdd2020-07-07 12:54:45 +0200510
aliguori967f97f2008-12-04 19:38:57 +0000511#endif