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