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