1*0d71f708SJon Doron /* 2*0d71f708SJon Doron * QEMU Hyper-V VMBus 3*0d71f708SJon Doron * 4*0d71f708SJon Doron * Copyright (c) 2017-2018 Virtuozzo International GmbH. 5*0d71f708SJon Doron * 6*0d71f708SJon Doron * This work is licensed under the terms of the GNU GPL, version 2 or later. 7*0d71f708SJon Doron * See the COPYING file in the top-level directory. 8*0d71f708SJon Doron */ 9*0d71f708SJon Doron 10*0d71f708SJon Doron #ifndef HW_HYPERV_VMBUS_H 11*0d71f708SJon Doron #define HW_HYPERV_VMBUS_H 12*0d71f708SJon Doron 13*0d71f708SJon Doron #include "sysemu/sysemu.h" 14*0d71f708SJon Doron #include "sysemu/dma.h" 15*0d71f708SJon Doron #include "hw/qdev-core.h" 16*0d71f708SJon Doron #include "migration/vmstate.h" 17*0d71f708SJon Doron #include "hw/hyperv/vmbus-proto.h" 18*0d71f708SJon Doron #include "qemu/uuid.h" 19*0d71f708SJon Doron 20*0d71f708SJon Doron #define TYPE_VMBUS_DEVICE "vmbus-dev" 21*0d71f708SJon Doron 22*0d71f708SJon Doron #define VMBUS_DEVICE(obj) \ 23*0d71f708SJon Doron OBJECT_CHECK(VMBusDevice, (obj), TYPE_VMBUS_DEVICE) 24*0d71f708SJon Doron #define VMBUS_DEVICE_CLASS(klass) \ 25*0d71f708SJon Doron OBJECT_CLASS_CHECK(VMBusDeviceClass, (klass), TYPE_VMBUS_DEVICE) 26*0d71f708SJon Doron #define VMBUS_DEVICE_GET_CLASS(obj) \ 27*0d71f708SJon Doron OBJECT_GET_CLASS(VMBusDeviceClass, (obj), TYPE_VMBUS_DEVICE) 28*0d71f708SJon Doron 29*0d71f708SJon Doron /* 30*0d71f708SJon Doron * Object wrapping a GPADL -- GPA Descriptor List -- an array of guest physical 31*0d71f708SJon Doron * pages, to be used for various buffers shared between the host and the guest. 32*0d71f708SJon Doron */ 33*0d71f708SJon Doron typedef struct VMBusGpadl VMBusGpadl; 34*0d71f708SJon Doron /* 35*0d71f708SJon Doron * VMBus channel -- a pair of ring buffers for either direction, placed within 36*0d71f708SJon Doron * one GPADL, and the associated notification means. 37*0d71f708SJon Doron */ 38*0d71f708SJon Doron typedef struct VMBusChannel VMBusChannel; 39*0d71f708SJon Doron /* 40*0d71f708SJon Doron * Base class for VMBus devices. Includes one or more channels. Identified by 41*0d71f708SJon Doron * class GUID and instance GUID. 42*0d71f708SJon Doron */ 43*0d71f708SJon Doron typedef struct VMBusDevice VMBusDevice; 44*0d71f708SJon Doron 45*0d71f708SJon Doron typedef void(*VMBusChannelNotifyCb)(struct VMBusChannel *chan); 46*0d71f708SJon Doron 47*0d71f708SJon Doron typedef struct VMBusDeviceClass { 48*0d71f708SJon Doron DeviceClass parent; 49*0d71f708SJon Doron 50*0d71f708SJon Doron QemuUUID classid; 51*0d71f708SJon Doron QemuUUID instanceid; /* Fixed UUID for singleton devices */ 52*0d71f708SJon Doron uint16_t channel_flags; 53*0d71f708SJon Doron uint16_t mmio_size_mb; 54*0d71f708SJon Doron 55*0d71f708SJon Doron /* Extentions to standard device callbacks */ 56*0d71f708SJon Doron void (*vmdev_realize)(VMBusDevice *vdev, Error **errp); 57*0d71f708SJon Doron void (*vmdev_unrealize)(VMBusDevice *vdev); 58*0d71f708SJon Doron void (*vmdev_reset)(VMBusDevice *vdev); 59*0d71f708SJon Doron /* 60*0d71f708SJon Doron * Calculate the number of channels based on the device properties. Called 61*0d71f708SJon Doron * at realize time. 62*0d71f708SJon Doron **/ 63*0d71f708SJon Doron uint16_t (*num_channels)(VMBusDevice *vdev); 64*0d71f708SJon Doron /* 65*0d71f708SJon Doron * Device-specific actions to complete the otherwise successful process of 66*0d71f708SJon Doron * opening a channel. 67*0d71f708SJon Doron * Return 0 on success, -errno on failure. 68*0d71f708SJon Doron */ 69*0d71f708SJon Doron int (*open_channel)(VMBusChannel *chan); 70*0d71f708SJon Doron /* 71*0d71f708SJon Doron * Device-specific actions to perform before closing a channel. 72*0d71f708SJon Doron */ 73*0d71f708SJon Doron void (*close_channel)(VMBusChannel *chan); 74*0d71f708SJon Doron /* 75*0d71f708SJon Doron * Main device worker; invoked in response to notifications from either 76*0d71f708SJon Doron * side, when there's work to do with the data in the channel ring buffers. 77*0d71f708SJon Doron */ 78*0d71f708SJon Doron VMBusChannelNotifyCb chan_notify_cb; 79*0d71f708SJon Doron } VMBusDeviceClass; 80*0d71f708SJon Doron 81*0d71f708SJon Doron struct VMBusDevice { 82*0d71f708SJon Doron DeviceState parent; 83*0d71f708SJon Doron QemuUUID instanceid; 84*0d71f708SJon Doron uint16_t num_channels; 85*0d71f708SJon Doron VMBusChannel *channels; 86*0d71f708SJon Doron AddressSpace *dma_as; 87*0d71f708SJon Doron }; 88*0d71f708SJon Doron 89*0d71f708SJon Doron extern const VMStateDescription vmstate_vmbus_dev; 90*0d71f708SJon Doron 91*0d71f708SJon Doron /* 92*0d71f708SJon Doron * A unit of work parsed out of a message in the receive (i.e. guest->host) 93*0d71f708SJon Doron * ring buffer of a channel. It's supposed to be subclassed (through 94*0d71f708SJon Doron * embedding) by the specific devices. 95*0d71f708SJon Doron */ 96*0d71f708SJon Doron typedef struct VMBusChanReq { 97*0d71f708SJon Doron VMBusChannel *chan; 98*0d71f708SJon Doron uint16_t pkt_type; 99*0d71f708SJon Doron uint32_t msglen; 100*0d71f708SJon Doron void *msg; 101*0d71f708SJon Doron uint64_t transaction_id; 102*0d71f708SJon Doron bool need_comp; 103*0d71f708SJon Doron QEMUSGList sgl; 104*0d71f708SJon Doron } VMBusChanReq; 105*0d71f708SJon Doron 106*0d71f708SJon Doron VMBusDevice *vmbus_channel_device(VMBusChannel *chan); 107*0d71f708SJon Doron VMBusChannel *vmbus_device_channel(VMBusDevice *dev, uint32_t chan_idx); 108*0d71f708SJon Doron uint32_t vmbus_channel_idx(VMBusChannel *chan); 109*0d71f708SJon Doron bool vmbus_channel_is_open(VMBusChannel *chan); 110*0d71f708SJon Doron 111*0d71f708SJon Doron /* 112*0d71f708SJon Doron * Notify (on guest's behalf) the host side of the channel that there's data in 113*0d71f708SJon Doron * the ringbuffer to process. 114*0d71f708SJon Doron */ 115*0d71f708SJon Doron void vmbus_channel_notify_host(VMBusChannel *chan); 116*0d71f708SJon Doron 117*0d71f708SJon Doron /* 118*0d71f708SJon Doron * Reserve space for a packet in the send (i.e. host->guest) ringbuffer. If 119*0d71f708SJon Doron * there isn't enough room, indicate that to the guest, to be notified when it 120*0d71f708SJon Doron * becomes available. 121*0d71f708SJon Doron * Return 0 on success, negative errno on failure. 122*0d71f708SJon Doron * The ringbuffer indices are NOT updated, the requested space indicator may. 123*0d71f708SJon Doron */ 124*0d71f708SJon Doron int vmbus_channel_reserve(VMBusChannel *chan, 125*0d71f708SJon Doron uint32_t desclen, uint32_t msglen); 126*0d71f708SJon Doron 127*0d71f708SJon Doron /* 128*0d71f708SJon Doron * Send a packet to the guest. The space for the packet MUST be reserved 129*0d71f708SJon Doron * first. 130*0d71f708SJon Doron * Return total number of bytes placed in the send ringbuffer on success, 131*0d71f708SJon Doron * negative errno on failure. 132*0d71f708SJon Doron * The ringbuffer indices are updated on success, and the guest is signaled if 133*0d71f708SJon Doron * needed. 134*0d71f708SJon Doron */ 135*0d71f708SJon Doron ssize_t vmbus_channel_send(VMBusChannel *chan, uint16_t pkt_type, 136*0d71f708SJon Doron void *desc, uint32_t desclen, 137*0d71f708SJon Doron void *msg, uint32_t msglen, 138*0d71f708SJon Doron bool need_comp, uint64_t transaction_id); 139*0d71f708SJon Doron 140*0d71f708SJon Doron /* 141*0d71f708SJon Doron * Prepare to fetch a batch of packets from the receive ring buffer. 142*0d71f708SJon Doron * Return 0 on success, negative errno on failure. 143*0d71f708SJon Doron */ 144*0d71f708SJon Doron int vmbus_channel_recv_start(VMBusChannel *chan); 145*0d71f708SJon Doron 146*0d71f708SJon Doron /* 147*0d71f708SJon Doron * Shortcut for a common case of sending a simple completion packet with no 148*0d71f708SJon Doron * auxiliary descriptors. 149*0d71f708SJon Doron */ 150*0d71f708SJon Doron ssize_t vmbus_channel_send_completion(VMBusChanReq *req, 151*0d71f708SJon Doron void *msg, uint32_t msglen); 152*0d71f708SJon Doron 153*0d71f708SJon Doron /* 154*0d71f708SJon Doron * Peek at the receive (i.e. guest->host) ring buffer and extract a unit of 155*0d71f708SJon Doron * work (a device-specific subclass of VMBusChanReq) from a packet if there's 156*0d71f708SJon Doron * one. 157*0d71f708SJon Doron * Return an allocated buffer, containing the request of @size with filled 158*0d71f708SJon Doron * VMBusChanReq at the beginning, followed by the message payload, or NULL on 159*0d71f708SJon Doron * failure. 160*0d71f708SJon Doron * The ringbuffer indices are NOT updated, nor is the private copy of the read 161*0d71f708SJon Doron * index. 162*0d71f708SJon Doron */ 163*0d71f708SJon Doron void *vmbus_channel_recv_peek(VMBusChannel *chan, uint32_t size); 164*0d71f708SJon Doron 165*0d71f708SJon Doron /* 166*0d71f708SJon Doron * Update the private copy of the read index once the preceding peek is deemed 167*0d71f708SJon Doron * successful. 168*0d71f708SJon Doron * The ringbuffer indices are NOT updated. 169*0d71f708SJon Doron */ 170*0d71f708SJon Doron void vmbus_channel_recv_pop(VMBusChannel *chan); 171*0d71f708SJon Doron 172*0d71f708SJon Doron /* 173*0d71f708SJon Doron * Propagate the private copy of the read index into the receive ring buffer, 174*0d71f708SJon Doron * and thus complete the reception of a series of packets. Notify guest if 175*0d71f708SJon Doron * needed. 176*0d71f708SJon Doron * Return the number of bytes popped off the receive ring buffer by the 177*0d71f708SJon Doron * preceding recv_peek/recv_pop calls on success, negative errno on failure. 178*0d71f708SJon Doron */ 179*0d71f708SJon Doron ssize_t vmbus_channel_recv_done(VMBusChannel *chan); 180*0d71f708SJon Doron 181*0d71f708SJon Doron /* 182*0d71f708SJon Doron * Free the request allocated by vmbus_channel_recv_peek, together with its 183*0d71f708SJon Doron * fields. 184*0d71f708SJon Doron */ 185*0d71f708SJon Doron void vmbus_free_req(void *req); 186*0d71f708SJon Doron 187*0d71f708SJon Doron /* 188*0d71f708SJon Doron * Find and reference a GPADL by @gpadl_id. 189*0d71f708SJon Doron * If not found return NULL. 190*0d71f708SJon Doron */ 191*0d71f708SJon Doron VMBusGpadl *vmbus_get_gpadl(VMBusChannel *chan, uint32_t gpadl_id); 192*0d71f708SJon Doron 193*0d71f708SJon Doron /* 194*0d71f708SJon Doron * Unreference @gpadl. If the reference count drops to zero, free it. 195*0d71f708SJon Doron * @gpadl may be NULL, in which case nothing is done. 196*0d71f708SJon Doron */ 197*0d71f708SJon Doron void vmbus_put_gpadl(VMBusGpadl *gpadl); 198*0d71f708SJon Doron 199*0d71f708SJon Doron /* 200*0d71f708SJon Doron * Calculate total length in bytes of @gpadl. 201*0d71f708SJon Doron * @gpadl must be valid. 202*0d71f708SJon Doron */ 203*0d71f708SJon Doron uint32_t vmbus_gpadl_len(VMBusGpadl *gpadl); 204*0d71f708SJon Doron 205*0d71f708SJon Doron /* 206*0d71f708SJon Doron * Copy data from @iov to @gpadl at offset @off. 207*0d71f708SJon Doron * Return the number of bytes copied, or a negative status on failure. 208*0d71f708SJon Doron */ 209*0d71f708SJon Doron ssize_t vmbus_iov_to_gpadl(VMBusChannel *chan, VMBusGpadl *gpadl, uint32_t off, 210*0d71f708SJon Doron const struct iovec *iov, size_t iov_cnt); 211*0d71f708SJon Doron 212*0d71f708SJon Doron /* 213*0d71f708SJon Doron * Map SGList contained in the request @req, at offset @off and no more than 214*0d71f708SJon Doron * @len bytes, for io in direction @dir, and populate @iov with the mapped 215*0d71f708SJon Doron * iovecs. 216*0d71f708SJon Doron * Return the number of iovecs mapped, or negative status on failure. 217*0d71f708SJon Doron */ 218*0d71f708SJon Doron int vmbus_map_sgl(VMBusChanReq *req, DMADirection dir, struct iovec *iov, 219*0d71f708SJon Doron unsigned iov_cnt, size_t len, size_t off); 220*0d71f708SJon Doron 221*0d71f708SJon Doron /* 222*0d71f708SJon Doron * Unmap *iov mapped with vmbus_map_sgl, marking the number of bytes @accessed. 223*0d71f708SJon Doron */ 224*0d71f708SJon Doron void vmbus_unmap_sgl(VMBusChanReq *req, DMADirection dir, struct iovec *iov, 225*0d71f708SJon Doron unsigned iov_cnt, size_t accessed); 226*0d71f708SJon Doron 227*0d71f708SJon Doron #endif 228