xref: /qemu/include/hw/hyperv/vmbus.h (revision db1015e92e04835c9eb50c29625fe566d1202dbd)
10d71f708SJon Doron /*
20d71f708SJon Doron  * QEMU Hyper-V VMBus
30d71f708SJon Doron  *
40d71f708SJon Doron  * Copyright (c) 2017-2018 Virtuozzo International GmbH.
50d71f708SJon Doron  *
60d71f708SJon Doron  * This work is licensed under the terms of the GNU GPL, version 2 or later.
70d71f708SJon Doron  * See the COPYING file in the top-level directory.
80d71f708SJon Doron  */
90d71f708SJon Doron 
100d71f708SJon Doron #ifndef HW_HYPERV_VMBUS_H
110d71f708SJon Doron #define HW_HYPERV_VMBUS_H
120d71f708SJon Doron 
130d71f708SJon Doron #include "sysemu/sysemu.h"
140d71f708SJon Doron #include "sysemu/dma.h"
150d71f708SJon Doron #include "hw/qdev-core.h"
160d71f708SJon Doron #include "migration/vmstate.h"
170d71f708SJon Doron #include "hw/hyperv/vmbus-proto.h"
180d71f708SJon Doron #include "qemu/uuid.h"
19*db1015e9SEduardo Habkost #include "qom/object.h"
200d71f708SJon Doron 
210d71f708SJon Doron #define TYPE_VMBUS_DEVICE "vmbus-dev"
220d71f708SJon Doron 
23*db1015e9SEduardo Habkost typedef struct VMBusDevice VMBusDevice;
24*db1015e9SEduardo Habkost typedef struct VMBusDeviceClass VMBusDeviceClass;
250d71f708SJon Doron #define VMBUS_DEVICE(obj) \
260d71f708SJon Doron     OBJECT_CHECK(VMBusDevice, (obj), TYPE_VMBUS_DEVICE)
270d71f708SJon Doron #define VMBUS_DEVICE_CLASS(klass) \
280d71f708SJon Doron     OBJECT_CLASS_CHECK(VMBusDeviceClass, (klass), TYPE_VMBUS_DEVICE)
290d71f708SJon Doron #define VMBUS_DEVICE_GET_CLASS(obj) \
300d71f708SJon Doron     OBJECT_GET_CLASS(VMBusDeviceClass, (obj), TYPE_VMBUS_DEVICE)
310d71f708SJon Doron 
32240b6cd7SEduardo Habkost #define TYPE_VMBUS "vmbus"
33240b6cd7SEduardo Habkost typedef struct VMBus VMBus;
34240b6cd7SEduardo Habkost #define VMBUS(obj) OBJECT_CHECK(VMBus, (obj), TYPE_VMBUS)
35240b6cd7SEduardo Habkost 
360d71f708SJon Doron /*
370d71f708SJon Doron  * Object wrapping a GPADL -- GPA Descriptor List -- an array of guest physical
380d71f708SJon Doron  * pages, to be used for various buffers shared between the host and the guest.
390d71f708SJon Doron  */
400d71f708SJon Doron typedef struct VMBusGpadl VMBusGpadl;
410d71f708SJon Doron /*
420d71f708SJon Doron  * VMBus channel -- a pair of ring buffers for either direction, placed within
430d71f708SJon Doron  * one GPADL, and the associated notification means.
440d71f708SJon Doron  */
450d71f708SJon Doron typedef struct VMBusChannel VMBusChannel;
460d71f708SJon Doron /*
470d71f708SJon Doron  * Base class for VMBus devices.  Includes one or more channels.  Identified by
480d71f708SJon Doron  * class GUID and instance GUID.
490d71f708SJon Doron  */
500d71f708SJon Doron 
510d71f708SJon Doron typedef void(*VMBusChannelNotifyCb)(struct VMBusChannel *chan);
520d71f708SJon Doron 
53*db1015e9SEduardo Habkost struct VMBusDeviceClass {
540d71f708SJon Doron     DeviceClass parent;
550d71f708SJon Doron 
560d71f708SJon Doron     QemuUUID classid;
570d71f708SJon Doron     QemuUUID instanceid;     /* Fixed UUID for singleton devices */
580d71f708SJon Doron     uint16_t channel_flags;
590d71f708SJon Doron     uint16_t mmio_size_mb;
600d71f708SJon Doron 
610d71f708SJon Doron     /* Extentions to standard device callbacks */
620d71f708SJon Doron     void (*vmdev_realize)(VMBusDevice *vdev, Error **errp);
630d71f708SJon Doron     void (*vmdev_unrealize)(VMBusDevice *vdev);
640d71f708SJon Doron     void (*vmdev_reset)(VMBusDevice *vdev);
650d71f708SJon Doron     /*
660d71f708SJon Doron      * Calculate the number of channels based on the device properties.  Called
670d71f708SJon Doron      * at realize time.
680d71f708SJon Doron      **/
690d71f708SJon Doron     uint16_t (*num_channels)(VMBusDevice *vdev);
700d71f708SJon Doron     /*
710d71f708SJon Doron      * Device-specific actions to complete the otherwise successful process of
720d71f708SJon Doron      * opening a channel.
730d71f708SJon Doron      * Return 0 on success, -errno on failure.
740d71f708SJon Doron      */
750d71f708SJon Doron     int (*open_channel)(VMBusChannel *chan);
760d71f708SJon Doron     /*
770d71f708SJon Doron      * Device-specific actions to perform before closing a channel.
780d71f708SJon Doron      */
790d71f708SJon Doron     void (*close_channel)(VMBusChannel *chan);
800d71f708SJon Doron     /*
810d71f708SJon Doron      * Main device worker; invoked in response to notifications from either
820d71f708SJon Doron      * side, when there's work to do with the data in the channel ring buffers.
830d71f708SJon Doron      */
840d71f708SJon Doron     VMBusChannelNotifyCb chan_notify_cb;
85*db1015e9SEduardo Habkost };
860d71f708SJon Doron 
870d71f708SJon Doron struct VMBusDevice {
880d71f708SJon Doron     DeviceState parent;
890d71f708SJon Doron     QemuUUID instanceid;
900d71f708SJon Doron     uint16_t num_channels;
910d71f708SJon Doron     VMBusChannel *channels;
920d71f708SJon Doron     AddressSpace *dma_as;
930d71f708SJon Doron };
940d71f708SJon Doron 
950d71f708SJon Doron extern const VMStateDescription vmstate_vmbus_dev;
960d71f708SJon Doron 
970d71f708SJon Doron /*
980d71f708SJon Doron  * A unit of work parsed out of a message in the receive (i.e. guest->host)
990d71f708SJon Doron  * ring buffer of a channel.  It's supposed to be subclassed (through
1000d71f708SJon Doron  * embedding) by the specific devices.
1010d71f708SJon Doron  */
1020d71f708SJon Doron typedef struct VMBusChanReq {
1030d71f708SJon Doron     VMBusChannel *chan;
1040d71f708SJon Doron     uint16_t pkt_type;
1050d71f708SJon Doron     uint32_t msglen;
1060d71f708SJon Doron     void *msg;
1070d71f708SJon Doron     uint64_t transaction_id;
1080d71f708SJon Doron     bool need_comp;
1090d71f708SJon Doron     QEMUSGList sgl;
1100d71f708SJon Doron } VMBusChanReq;
1110d71f708SJon Doron 
1120d71f708SJon Doron VMBusDevice *vmbus_channel_device(VMBusChannel *chan);
1130d71f708SJon Doron VMBusChannel *vmbus_device_channel(VMBusDevice *dev, uint32_t chan_idx);
1140d71f708SJon Doron uint32_t vmbus_channel_idx(VMBusChannel *chan);
1150d71f708SJon Doron bool vmbus_channel_is_open(VMBusChannel *chan);
1160d71f708SJon Doron 
1170d71f708SJon Doron /*
1180d71f708SJon Doron  * Notify (on guest's behalf) the host side of the channel that there's data in
1190d71f708SJon Doron  * the ringbuffer to process.
1200d71f708SJon Doron  */
1210d71f708SJon Doron void vmbus_channel_notify_host(VMBusChannel *chan);
1220d71f708SJon Doron 
1230d71f708SJon Doron /*
1240d71f708SJon Doron  * Reserve space for a packet in the send (i.e. host->guest) ringbuffer.  If
1250d71f708SJon Doron  * there isn't enough room, indicate that to the guest, to be notified when it
1260d71f708SJon Doron  * becomes available.
1270d71f708SJon Doron  * Return 0 on success, negative errno on failure.
1280d71f708SJon Doron  * The ringbuffer indices are NOT updated, the requested space indicator may.
1290d71f708SJon Doron  */
1300d71f708SJon Doron int vmbus_channel_reserve(VMBusChannel *chan,
1310d71f708SJon Doron                           uint32_t desclen, uint32_t msglen);
1320d71f708SJon Doron 
1330d71f708SJon Doron /*
1340d71f708SJon Doron  * Send a packet to the guest.  The space for the packet MUST be reserved
1350d71f708SJon Doron  * first.
1360d71f708SJon Doron  * Return total number of bytes placed in the send ringbuffer on success,
1370d71f708SJon Doron  * negative errno on failure.
1380d71f708SJon Doron  * The ringbuffer indices are updated on success, and the guest is signaled if
1390d71f708SJon Doron  * needed.
1400d71f708SJon Doron  */
1410d71f708SJon Doron ssize_t vmbus_channel_send(VMBusChannel *chan, uint16_t pkt_type,
1420d71f708SJon Doron                            void *desc, uint32_t desclen,
1430d71f708SJon Doron                            void *msg, uint32_t msglen,
1440d71f708SJon Doron                            bool need_comp, uint64_t transaction_id);
1450d71f708SJon Doron 
1460d71f708SJon Doron /*
1470d71f708SJon Doron  * Prepare to fetch a batch of packets from the receive ring buffer.
1480d71f708SJon Doron  * Return 0 on success, negative errno on failure.
1490d71f708SJon Doron  */
1500d71f708SJon Doron int vmbus_channel_recv_start(VMBusChannel *chan);
1510d71f708SJon Doron 
1520d71f708SJon Doron /*
1530d71f708SJon Doron  * Shortcut for a common case of sending a simple completion packet with no
1540d71f708SJon Doron  * auxiliary descriptors.
1550d71f708SJon Doron  */
1560d71f708SJon Doron ssize_t vmbus_channel_send_completion(VMBusChanReq *req,
1570d71f708SJon Doron                                       void *msg, uint32_t msglen);
1580d71f708SJon Doron 
1590d71f708SJon Doron /*
1600d71f708SJon Doron  * Peek at the receive (i.e. guest->host) ring buffer and extract a unit of
1610d71f708SJon Doron  * work (a device-specific subclass of VMBusChanReq) from a packet if there's
1620d71f708SJon Doron  * one.
1630d71f708SJon Doron  * Return an allocated buffer, containing the request of @size with filled
1640d71f708SJon Doron  * VMBusChanReq at the beginning, followed by the message payload, or NULL on
1650d71f708SJon Doron  * failure.
1660d71f708SJon Doron  * The ringbuffer indices are NOT updated, nor is the private copy of the read
1670d71f708SJon Doron  * index.
1680d71f708SJon Doron  */
1690d71f708SJon Doron void *vmbus_channel_recv_peek(VMBusChannel *chan, uint32_t size);
1700d71f708SJon Doron 
1710d71f708SJon Doron /*
1720d71f708SJon Doron  * Update the private copy of the read index once the preceding peek is deemed
1730d71f708SJon Doron  * successful.
1740d71f708SJon Doron  * The ringbuffer indices are NOT updated.
1750d71f708SJon Doron  */
1760d71f708SJon Doron void vmbus_channel_recv_pop(VMBusChannel *chan);
1770d71f708SJon Doron 
1780d71f708SJon Doron /*
1790d71f708SJon Doron  * Propagate the private copy of the read index into the receive ring buffer,
1800d71f708SJon Doron  * and thus complete the reception of a series of packets.  Notify guest if
1810d71f708SJon Doron  * needed.
1820d71f708SJon Doron  * Return the number of bytes popped off the receive ring buffer by the
1830d71f708SJon Doron  * preceding recv_peek/recv_pop calls on success, negative errno on failure.
1840d71f708SJon Doron  */
1850d71f708SJon Doron ssize_t vmbus_channel_recv_done(VMBusChannel *chan);
1860d71f708SJon Doron 
1870d71f708SJon Doron /*
1880d71f708SJon Doron  * Free the request allocated by vmbus_channel_recv_peek, together with its
1890d71f708SJon Doron  * fields.
1900d71f708SJon Doron  */
1910d71f708SJon Doron void vmbus_free_req(void *req);
1920d71f708SJon Doron 
1930d71f708SJon Doron /*
1940d71f708SJon Doron  * Find and reference a GPADL by @gpadl_id.
1950d71f708SJon Doron  * If not found return NULL.
1960d71f708SJon Doron  */
1970d71f708SJon Doron VMBusGpadl *vmbus_get_gpadl(VMBusChannel *chan, uint32_t gpadl_id);
1980d71f708SJon Doron 
1990d71f708SJon Doron /*
2000d71f708SJon Doron  * Unreference @gpadl.  If the reference count drops to zero, free it.
2010d71f708SJon Doron  * @gpadl may be NULL, in which case nothing is done.
2020d71f708SJon Doron  */
2030d71f708SJon Doron void vmbus_put_gpadl(VMBusGpadl *gpadl);
2040d71f708SJon Doron 
2050d71f708SJon Doron /*
2060d71f708SJon Doron  * Calculate total length in bytes of @gpadl.
2070d71f708SJon Doron  * @gpadl must be valid.
2080d71f708SJon Doron  */
2090d71f708SJon Doron uint32_t vmbus_gpadl_len(VMBusGpadl *gpadl);
2100d71f708SJon Doron 
2110d71f708SJon Doron /*
2120d71f708SJon Doron  * Copy data from @iov to @gpadl at offset @off.
2130d71f708SJon Doron  * Return the number of bytes copied, or a negative status on failure.
2140d71f708SJon Doron  */
2150d71f708SJon Doron ssize_t vmbus_iov_to_gpadl(VMBusChannel *chan, VMBusGpadl *gpadl, uint32_t off,
2160d71f708SJon Doron                            const struct iovec *iov, size_t iov_cnt);
2170d71f708SJon Doron 
2180d71f708SJon Doron /*
2190d71f708SJon Doron  * Map SGList contained in the request @req, at offset @off and no more than
2200d71f708SJon Doron  * @len bytes, for io in direction @dir, and populate @iov with the mapped
2210d71f708SJon Doron  * iovecs.
2220d71f708SJon Doron  * Return the number of iovecs mapped, or negative status on failure.
2230d71f708SJon Doron  */
2240d71f708SJon Doron int vmbus_map_sgl(VMBusChanReq *req, DMADirection dir, struct iovec *iov,
2250d71f708SJon Doron                   unsigned iov_cnt, size_t len, size_t off);
2260d71f708SJon Doron 
2270d71f708SJon Doron /*
2280d71f708SJon Doron  * Unmap *iov mapped with vmbus_map_sgl, marking the number of bytes @accessed.
2290d71f708SJon Doron  */
2300d71f708SJon Doron void vmbus_unmap_sgl(VMBusChanReq *req, DMADirection dir, struct iovec *iov,
2310d71f708SJon Doron                      unsigned iov_cnt, size_t accessed);
2320d71f708SJon Doron 
2334dd8a706SJon Doron void vmbus_save_req(QEMUFile *f, VMBusChanReq *req);
2344dd8a706SJon Doron void *vmbus_load_req(QEMUFile *f, VMBusDevice *dev, uint32_t size);
2354dd8a706SJon Doron 
2360d71f708SJon Doron #endif
237