2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/*
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * Virtio Support
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * Copyright IBM, Corp. 2007
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * Authors:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *  Anthony Liguori   <aliguori@us.ibm.com>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * This work is licensed under the terms of the GNU GPL, version 2.  See
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * the COPYING file in the top-level directory.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-06-29 13:47:03 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#ifndef QEMU_VIRTIO_H
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define QEMU_VIRTIO_H
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2013-02-04 15:40:22 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include "hw/hw.h"
							 | 
						
					
						
							
								
									
										
										
										
											2012-10-24 08:43:34 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include "net/net.h"
							 | 
						
					
						
							
								
									
										
										
										
											2013-02-04 15:40:22 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include "hw/qdev.h"
							 | 
						
					
						
							
								
									
										
										
										
											2012-12-17 18:20:04 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include "sysemu/sysemu.h"
							 | 
						
					
						
							
								
									
										
										
										
											2012-12-17 18:20:00 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include "qemu/event_notifier.h"
							 | 
						
					
						
							
								
									
										
										
										
											2015-02-16 22:35:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include "standard-headers/linux/virtio_config.h"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include "standard-headers/linux/virtio_ring.h"
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-04-05 17:40:08 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								/* A guest should never accept this.  It implies negotiation is broken. */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define VIRTIO_F_BAD_FEATURE		30
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2015-07-22 13:09:25 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define VIRTIO_LEGACY_FEATURES ((0x1ULL << VIRTIO_F_BAD_FEATURE) | \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                (0x1ULL << VIRTIO_F_NOTIFY_ON_EMPTY) | \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                (0x1ULL << VIRTIO_F_ANY_LAYOUT))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								struct VirtQueue;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static inline hwaddr vring_align(hwaddr addr,
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:58:45 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                                             unsigned long align)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-24 16:19:43 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    return QEMU_ALIGN_UP(addr, align);
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:58:45 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								typedef struct VirtQueue VirtQueue;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define VIRTQUEUE_MAX_SIZE 1024
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								typedef struct VirtQueueElement
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    unsigned int index;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    unsigned int out_num;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    unsigned int in_num;
							 | 
						
					
						
							
								
									
										
										
										
											2016-01-31 11:29:00 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    hwaddr *in_addr;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    hwaddr *out_addr;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    struct iovec *in_sg;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    struct iovec *out_sg;
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								} VirtQueueElement;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2015-05-29 14:15:32 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define VIRTIO_QUEUE_MAX 1024
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-06-21 19:50:13 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define VIRTIO_NO_VECTOR 0xffff
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2013-01-15 00:08:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define TYPE_VIRTIO_DEVICE "virtio-device"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define VIRTIO_DEVICE_GET_CLASS(obj) \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        OBJECT_GET_CLASS(VirtioDeviceClass, obj, TYPE_VIRTIO_DEVICE)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define VIRTIO_DEVICE_CLASS(klass) \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        OBJECT_CLASS_CHECK(VirtioDeviceClass, klass, TYPE_VIRTIO_DEVICE)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define VIRTIO_DEVICE(obj) \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        OBJECT_CHECK(VirtIODevice, (obj), TYPE_VIRTIO_DEVICE)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2014-06-24 19:38:54 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								enum virtio_device_endian {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    VIRTIO_DEVICE_ENDIAN_UNKNOWN,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    VIRTIO_DEVICE_ENDIAN_LITTLE,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    VIRTIO_DEVICE_ENDIAN_BIG,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								struct VirtIODevice
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2013-01-15 00:08:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    DeviceState parent_obj;
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    const char *name;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    uint8_t status;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    uint8_t isr;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    uint16_t queue_sel;
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-01 10:45:40 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    uint64_t guest_features;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    uint64_t host_features;
							 | 
						
					
						
							
								
									
										
										
										
											2017-05-23 14:31:19 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    uint64_t backend_features;
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    size_t config_len;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    void *config;
							 | 
						
					
						
							
								
									
										
										
										
											2009-06-21 19:50:13 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    uint16_t config_vector;
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-04 12:34:23 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    uint32_t generation;
							 | 
						
					
						
							
								
									
										
										
										
											2009-06-21 19:50:13 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    int nvectors;
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    VirtQueue *vq;
							 | 
						
					
						
							
								
									
										
										
										
											2017-01-27 16:40:17 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    MemoryListener listener;
							 | 
						
					
						
							
								
									
										
										
										
											2009-05-18 14:51:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    uint16_t device_id;
							 | 
						
					
						
							
								
									
										
										
										
											2011-01-10 14:28:40 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    bool vm_running;
							 | 
						
					
						
							
								
									
										
										
										
											2016-09-21 16:52:19 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    bool broken; /* device in invalid state, needs reset */
							 | 
						
					
						
							
								
									
										
										
										
											2011-01-10 14:28:40 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    VMChangeStateEntry *vmstate;
							 | 
						
					
						
							
								
									
										
										
										
											2013-04-30 16:08:48 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    char *bus_name;
							 | 
						
					
						
							
								
									
										
										
										
											2014-06-24 19:38:54 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    uint8_t device_endian;
							 | 
						
					
						
							
								
									
										
										
										
											2016-02-18 16:12:23 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    bool use_guest_notifier_mask;
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-30 18:09:10 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    AddressSpace *dma_as;
							 | 
						
					
						
							
								
									
										
										
										
											2015-04-27 21:01:20 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    QLIST_HEAD(, VirtQueue) *vector_queues;
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2013-01-15 00:08:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								typedef struct VirtioDeviceClass {
							 | 
						
					
						
							
								
									
										
										
										
											2013-07-30 04:05:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    /*< private >*/
							 | 
						
					
						
							
								
									
										
										
										
											2013-01-15 00:08:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    DeviceClass parent;
							 | 
						
					
						
							
								
									
										
										
										
											2013-07-30 04:05:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    /*< public >*/
							 | 
						
					
						
							
								
									
										
										
										
											2013-07-30 00:50:27 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    /* This is what a VirtioDevice must implement */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    DeviceRealize realize;
							 | 
						
					
						
							
								
									
										
										
										
											2013-07-30 03:50:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    DeviceUnrealize unrealize;
							 | 
						
					
						
							
								
									
										
										
										
											2015-07-27 17:49:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    uint64_t (*get_features)(VirtIODevice *vdev,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                             uint64_t requested_features,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                             Error **errp);
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-01 10:45:40 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    uint64_t (*bad_features)(VirtIODevice *vdev);
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-03 14:47:19 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    void (*set_features)(VirtIODevice *vdev, uint64_t val);
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-04 12:34:15 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    int (*validate_features)(VirtIODevice *vdev);
							 | 
						
					
						
							
								
									
										
										
										
											2013-01-15 00:08:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    void (*get_config)(VirtIODevice *vdev, uint8_t *config);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    void (*reset)(VirtIODevice *vdev);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    void (*set_status)(VirtIODevice *vdev, uint8_t val);
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-04 12:04:23 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    /* For transitional devices, this is a bitmap of features
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								     * that are only exposed on the legacy interface but not
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								     * the modern one.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								     */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    uint64_t legacy_features;
							 | 
						
					
						
							
								
									
										
										
										
											2013-04-11 16:29:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    /* Test and clear event pending status.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								     * Should be called after unmask to avoid losing events.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								     * If backend does not support masking,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								     * must check in frontend instead.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								     */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    bool (*guest_notifier_pending)(VirtIODevice *vdev, int n);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    /* Mask/unmask events from this vq. Any events reported
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								     * while masked will become pending.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								     * If backend does not support masking,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								     * must mask in frontend instead.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								     */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    void (*guest_notifier_mask)(VirtIODevice *vdev, int n, bool mask);
							 | 
						
					
						
							
								
									
										
										
										
											2016-10-21 22:48:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    int (*start_ioeventfd)(VirtIODevice *vdev);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    void (*stop_ioeventfd)(VirtIODevice *vdev);
							 | 
						
					
						
							
								
									
										
										
										
											2016-10-27 18:36:36 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    /* Saving and loading of a device; trying to deprecate save/load
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								     * use vmsd for new devices.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								     */
							 | 
						
					
						
							
								
									
										
										
										
											2014-06-24 19:15:31 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    void (*save)(VirtIODevice *vdev, QEMUFile *f);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    int (*load)(VirtIODevice *vdev, QEMUFile *f, int version_id);
							 | 
						
					
						
							
								
									
										
										
										
											2016-10-27 18:36:36 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    const VMStateDescription *vmsd;
							 | 
						
					
						
							
								
									
										
										
										
											2013-01-15 00:08:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								} VirtioDeviceClass;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2014-09-30 14:10:38 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_instance_init_common(Object *proxy_obj, void *data,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                 size_t vdev_size, const char *vdev_name);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2013-01-15 00:08:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_init(VirtIODevice *vdev, const char *name,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                         uint16_t device_id, size_t config_size);
							 | 
						
					
						
							
								
									
										
										
										
											2013-04-24 10:21:22 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_cleanup(VirtIODevice *vdev);
							 | 
						
					
						
							
								
									
										
										
										
											2013-01-15 00:08:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-09-21 16:52:19 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_error(VirtIODevice *vdev, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2013-04-30 16:08:48 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								/* Set the child bus name. */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtio_device_set_child_bus_name(VirtIODevice *vdev, char *bus_name);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-13 13:09:43 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								typedef void (*VirtIOHandleOutput)(VirtIODevice *, VirtQueue *);
							 | 
						
					
						
							
								
									
										
										
										
											2017-02-09 16:40:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								typedef bool (*VirtIOHandleAIOOutput)(VirtIODevice *, VirtQueue *);
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-13 13:09:43 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-13 13:09:43 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                            VirtIOHandleOutput handle_output);
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2013-01-30 19:12:36 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_del_queue(VirtIODevice *vdev, int n);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    unsigned int len);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtqueue_flush(VirtQueue *vq, unsigned int count);
							 | 
						
					
						
							
								
									
										
										
										
											2016-09-19 14:28:03 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtqueue_detach_element(VirtQueue *vq, const VirtQueueElement *elem,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                              unsigned int len);
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-03 09:55:49 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtqueue_unpop(VirtQueue *vq, const VirtQueueElement *elem,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                     unsigned int len);
							 | 
						
					
						
							
								
									
										
										
										
											2016-09-07 17:20:48 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								bool virtqueue_rewind(VirtQueue *vq, unsigned int num);
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    unsigned int len, unsigned int idx);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-30 18:09:10 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtqueue_map(VirtIODevice *vdev, VirtQueueElement *elem);
							 | 
						
					
						
							
								
									
										
										
										
											2016-02-04 16:26:51 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void *virtqueue_pop(VirtQueue *vq, size_t sz);
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-13 10:12:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								unsigned int virtqueue_drop_all(VirtQueue *vq);
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-30 18:09:10 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void *qemu_get_virtqueue_element(VirtIODevice *vdev, QEMUFile *f, size_t sz);
							 | 
						
					
						
							
								
									
										
										
										
											2016-01-31 11:28:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void qemu_put_virtqueue_element(QEMUFile *f, VirtQueueElement *elem);
							 | 
						
					
						
							
								
									
										
										
										
											2012-09-25 00:05:15 +05:30
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                          unsigned int out_bytes);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
							 | 
						
					
						
							
								
									
										
										
										
											2012-11-30 00:02:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                               unsigned int *out_bytes,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                               unsigned max_in_bytes, unsigned max_out_bytes);
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												virtio: set ISR on dataplane notifications
Dataplane has been omitting forever the step of setting ISR when
an interrupt is raised.  This caused little breakage, because the
specification actually says that ISR may not be updated in MSI mode.
Some versions of the Windows drivers however didn't clear MSI mode
correctly, and proceeded using polling mode (using ISR, not the used
ring index!) for crashdump and hibernation.  If it were just crashdump
and hibernation it would not be a big deal, but recent releases of
Windows do not really shut down, but rather log out and hibernate to
make the next startup faster.  Hence, this manifested as a more serious
hang during shutdown with e.g. Windows 8.1 and virtio-win 1.8.0 RPMs.
Newer versions fixed this, while older versions do not use MSI at all.
The failure has always been there for virtio dataplane, but it became
visible after commits 9ffe337 ("virtio-blk: always use dataplane path
if ioeventfd is active", 2016-10-30) and ad07cd6 ("virtio-scsi: always
use dataplane path if ioeventfd is active", 2016-10-30) made virtio-blk
and virtio-scsi always use the dataplane code under KVM.  The good news
therefore is that it was not a bug in the patches---they were doing
exactly what they were meant for, i.e. shake out remaining dataplane bugs.
The fix is not hard, so it's worth arranging for the broken drivers.
The virtio_should_notify+event_notifier_set pair that is common to
virtio-blk and virtio-scsi dataplane is replaced with a new public
function virtio_notify_irqfd that also sets ISR.  The irqfd emulation
code now need not set ISR anymore, so virtio_irq is removed.
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Tested-by: Farhan Ali <alifm@linux.vnet.ibm.com>
Tested-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
											
										 
										
											2016-11-18 16:07:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_notify_irqfd(VirtIODevice *vdev, VirtQueue *vq);
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-09-25 12:29:17 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								int virtio_save(VirtIODevice *vdev, QEMUFile *f);
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-14 18:22:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-10-06 14:55:39 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								extern const VMStateInfo virtio_vmstate_info;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define VMSTATE_VIRTIO_DEVICE \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    {                                         \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        .name = "virtio",                     \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        .info = &virtio_vmstate_info,         \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        .flags = VMS_SINGLE,                  \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2014-06-24 19:15:31 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id);
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtio_notify_config(VirtIODevice *vdev);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtio_queue_set_notification(VirtQueue *vq, int enable);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								int virtio_queue_ready(VirtQueue *vq);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								int virtio_queue_empty(VirtQueue *vq);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-05-18 14:51:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								/* Host binding interface.  */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								uint32_t virtio_config_readw(VirtIODevice *vdev, uint32_t addr);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								uint32_t virtio_config_readl(VirtIODevice *vdev, uint32_t addr);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtio_config_writeb(VirtIODevice *vdev, uint32_t addr, uint32_t data);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtio_config_writew(VirtIODevice *vdev, uint32_t addr, uint32_t data);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data);
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-04 12:34:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								uint32_t virtio_config_modern_readb(VirtIODevice *vdev, uint32_t addr);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								uint32_t virtio_config_modern_readw(VirtIODevice *vdev, uint32_t addr);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								uint32_t virtio_config_modern_readl(VirtIODevice *vdev, uint32_t addr);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtio_config_modern_writeb(VirtIODevice *vdev,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                 uint32_t addr, uint32_t data);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtio_config_modern_writew(VirtIODevice *vdev,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                 uint32_t addr, uint32_t data);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtio_config_modern_writel(VirtIODevice *vdev,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                 uint32_t addr, uint32_t data);
							 | 
						
					
						
							
								
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_queue_set_addr(VirtIODevice *vdev, int n, hwaddr addr);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n);
							 | 
						
					
						
							
								
									
										
										
										
											2013-07-16 13:25:07 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_queue_set_num(VirtIODevice *vdev, int n, int num);
							 | 
						
					
						
							
								
									
										
										
										
											2009-05-18 14:51:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								int virtio_queue_get_num(VirtIODevice *vdev, int n);
							 | 
						
					
						
							
								
									
										
										
										
											2017-01-12 23:26:22 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								int virtio_queue_get_max_num(VirtIODevice *vdev, int n);
							 | 
						
					
						
							
								
									
										
										
										
											2015-05-29 14:15:26 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								int virtio_get_num_queues(VirtIODevice *vdev);
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-04 12:34:12 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_queue_set_rings(VirtIODevice *vdev, int n, hwaddr desc,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            hwaddr avail, hwaddr used);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtio_queue_update_rings(VirtIODevice *vdev, int n);
							 | 
						
					
						
							
								
									
										
										
										
											2013-07-16 13:25:08 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
							 | 
						
					
						
							
								
									
										
										
										
											2009-05-18 14:51:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_queue_notify(VirtIODevice *vdev, int n);
							 | 
						
					
						
							
								
									
										
										
										
											2009-06-21 19:50:13 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-04 12:34:15 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								int virtio_set_status(VirtIODevice *vdev, uint8_t val);
							 | 
						
					
						
							
								
									
										
										
										
											2009-05-18 14:51:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_reset(void *opaque);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtio_update_irq(VirtIODevice *vdev);
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-03 14:47:19 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								int virtio_set_features(VirtIODevice *vdev, uint64_t val);
							 | 
						
					
						
							
								
									
										
										
										
											2009-05-18 14:51:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/* Base devices.  */
							 | 
						
					
						
							
								
									
										
										
										
											2012-05-16 12:54:05 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								typedef struct VirtIOBlkConf VirtIOBlkConf;
							 | 
						
					
						
							
								
									
										
										
										
											2010-09-02 09:00:50 -06:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								struct virtio_net_conf;
							 | 
						
					
						
							
								
									
										
										
										
											2011-02-03 11:22:32 +05:30
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								typedef struct virtio_serial_conf virtio_serial_conf;
							 | 
						
					
						
							
								
									
										
										
										
											2014-03-14 14:39:20 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								typedef struct virtio_input_conf virtio_input_conf;
							 | 
						
					
						
							
								
									
										
										
										
											2011-02-11 08:40:59 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								typedef struct VirtIOSCSIConf VirtIOSCSIConf;
							 | 
						
					
						
							
								
									
										
										
										
											2012-06-20 12:29:32 +05:30
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								typedef struct VirtIORNGConf VirtIORNGConf;
							 | 
						
					
						
							
								
									
										
										
										
											2009-10-21 15:25:35 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-10 13:52:53 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-01 10:45:40 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    DEFINE_PROP_BIT64("indirect_desc", _state, _field,    \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                      VIRTIO_RING_F_INDIRECT_DESC, true), \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    DEFINE_PROP_BIT64("event_idx", _state, _field,        \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                      VIRTIO_RING_F_EVENT_IDX, true),     \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    DEFINE_PROP_BIT64("notify_on_empty", _state, _field,  \
							 | 
						
					
						
							
								
									
										
										
										
											2015-07-22 12:32:25 +03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                      VIRTIO_F_NOTIFY_ON_EMPTY, true), \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    DEFINE_PROP_BIT64("any_layout", _state, _field, \
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-30 18:09:10 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                      VIRTIO_F_ANY_LAYOUT, true), \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    DEFINE_PROP_BIT64("iommu_platform", _state, _field, \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                      VIRTIO_F_IOMMU_PLATFORM, false)
							 | 
						
					
						
							
								
									
										
										
										
											2010-01-10 13:52:53 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								hwaddr virtio_queue_get_used_addr(VirtIODevice *vdev, int n);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								hwaddr virtio_queue_get_desc_size(VirtIODevice *vdev, int n);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								hwaddr virtio_queue_get_avail_size(VirtIODevice *vdev, int n);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								hwaddr virtio_queue_get_used_size(VirtIODevice *vdev, int n);
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-17 13:08:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								uint16_t virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx);
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-16 19:48:34 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_queue_restore_last_avail_idx(VirtIODevice *vdev, int n);
							 | 
						
					
						
							
								
									
										
										
										
											2013-08-12 11:08:09 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_queue_invalidate_signalled_used(VirtIODevice *vdev, int n);
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-13 10:12:05 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_queue_update_used_idx(VirtIODevice *vdev, int n);
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-17 13:08:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								VirtQueue *virtio_get_queue(VirtIODevice *vdev, int n);
							 | 
						
					
						
							
								
									
										
										
										
											2013-01-30 19:12:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								uint16_t virtio_get_queue_index(VirtQueue *vq);
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-17 13:08:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq);
							 | 
						
					
						
							
								
									
										
										
										
											2012-07-05 17:16:30 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                                bool with_irqfd);
							 | 
						
					
						
							
								
									
										
										
										
											2016-10-21 22:48:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								int virtio_device_start_ioeventfd(VirtIODevice *vdev);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtio_device_stop_ioeventfd(VirtIODevice *vdev);
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-18 16:07:00 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								int virtio_device_grab_ioeventfd(VirtIODevice *vdev);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void virtio_device_release_ioeventfd(VirtIODevice *vdev);
							 | 
						
					
						
							
								
									
										
										
										
											2016-10-21 22:48:08 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev);
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-17 13:08:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq);
							 | 
						
					
						
							
								
									
										
										
										
											2016-10-21 22:48:15 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_queue_host_notifier_read(EventNotifier *n);
							 | 
						
					
						
							
								
									
										
										
										
											2016-02-14 18:17:06 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
							 | 
						
					
						
							
								
									
										
										
										
											2017-02-09 16:40:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                                                VirtIOHandleAIOOutput handle_output);
							 | 
						
					
						
							
								
									
										
										
										
											2015-04-23 14:21:46 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								VirtQueue *virtio_vector_next_queue(VirtQueue *vq);
							 | 
						
					
						
							
								
									
										
										
										
											2014-06-24 19:26:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-01 10:45:40 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static inline void virtio_add_feature(uint64_t *features, unsigned int fbit)
							 | 
						
					
						
							
								
									
										
										
										
											2014-12-11 14:25:05 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-01 10:45:40 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    assert(fbit < 64);
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-03 14:47:19 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    *features |= (1ULL << fbit);
							 | 
						
					
						
							
								
									
										
										
										
											2014-12-11 14:25:05 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-01 10:45:40 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static inline void virtio_clear_feature(uint64_t *features, unsigned int fbit)
							 | 
						
					
						
							
								
									
										
										
										
											2014-12-11 14:25:05 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-01 10:45:40 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    assert(fbit < 64);
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-03 14:47:19 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    *features &= ~(1ULL << fbit);
							 | 
						
					
						
							
								
									
										
										
										
											2014-12-11 14:25:05 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2015-08-17 11:48:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static inline bool virtio_has_feature(uint64_t features, unsigned int fbit)
							 | 
						
					
						
							
								
									
										
										
										
											2014-12-11 14:25:06 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-01 10:45:40 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    assert(fbit < 64);
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-03 14:47:19 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    return !!(features & (1ULL << fbit));
							 | 
						
					
						
							
								
									
										
										
										
											2014-12-11 14:25:06 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2015-08-17 11:48:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static inline bool virtio_vdev_has_feature(VirtIODevice *vdev,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                           unsigned int fbit)
							 | 
						
					
						
							
								
									
										
										
										
											2014-12-11 14:25:06 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2015-08-17 11:48:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    return virtio_has_feature(vdev->guest_features, fbit);
							 | 
						
					
						
							
								
									
										
										
										
											2014-12-11 14:25:06 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2015-08-05 17:50:07 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static inline bool virtio_host_has_feature(VirtIODevice *vdev,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                           unsigned int fbit)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2015-08-17 11:48:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    return virtio_has_feature(vdev->host_features, fbit);
							 | 
						
					
						
							
								
									
										
										
										
											2015-08-05 17:50:07 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2014-06-24 19:38:54 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static inline bool virtio_is_big_endian(VirtIODevice *vdev)
							 | 
						
					
						
							
								
									
										
										
										
											2014-06-24 19:26:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2015-08-17 11:48:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if (!virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-04 12:34:11 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    /* Devices conforming to VIRTIO 1.0 or later are always LE. */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return false;
							 | 
						
					
						
							
								
									
										
										
										
											2014-06-24 19:26:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-04 19:38:57 +00:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#endif
							 |