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