1d5970055SMichael S. Tsirkin #ifndef VHOST_H 2d5970055SMichael S. Tsirkin #define VHOST_H 3d5970055SMichael S. Tsirkin 424d1eb33SNikolay Nikolaev #include "hw/virtio/vhost-backend.h" 50d09e41aSPaolo Bonzini #include "hw/virtio/virtio.h" 6022c62cbSPaolo Bonzini #include "exec/memory.h" 7d5970055SMichael S. Tsirkin 8d5970055SMichael S. Tsirkin /* Generic structures common for any vhost based device. */ 95ad204bfSXie Yongji 105ad204bfSXie Yongji struct vhost_inflight { 115ad204bfSXie Yongji int fd; 125ad204bfSXie Yongji void *addr; 135ad204bfSXie Yongji uint64_t size; 145ad204bfSXie Yongji uint64_t offset; 155ad204bfSXie Yongji uint16_t queue_size; 165ad204bfSXie Yongji }; 175ad204bfSXie Yongji 18d5970055SMichael S. Tsirkin struct vhost_virtqueue { 19d5970055SMichael S. Tsirkin int kick; 20d5970055SMichael S. Tsirkin int call; 21d5970055SMichael S. Tsirkin void *desc; 22d5970055SMichael S. Tsirkin void *avail; 23d5970055SMichael S. Tsirkin void *used; 24d5970055SMichael S. Tsirkin int num; 25f1f9e6c5SGreg Kurz unsigned long long desc_phys; 26f1f9e6c5SGreg Kurz unsigned desc_size; 27f1f9e6c5SGreg Kurz unsigned long long avail_phys; 28f1f9e6c5SGreg Kurz unsigned avail_size; 29d5970055SMichael S. Tsirkin unsigned long long used_phys; 30d5970055SMichael S. Tsirkin unsigned used_size; 31f56a1247SMichael S. Tsirkin EventNotifier masked_notifier; 32c471ad0eSJason Wang struct vhost_dev *dev; 33d5970055SMichael S. Tsirkin }; 34d5970055SMichael S. Tsirkin 35d5970055SMichael S. Tsirkin typedef unsigned long vhost_log_chunk_t; 36d5970055SMichael S. Tsirkin #define VHOST_LOG_PAGE 0x1000 37d5970055SMichael S. Tsirkin #define VHOST_LOG_BITS (8 * sizeof(vhost_log_chunk_t)) 38d5970055SMichael S. Tsirkin #define VHOST_LOG_CHUNK (VHOST_LOG_PAGE * VHOST_LOG_BITS) 392e6d46d7SNikolay Nikolaev #define VHOST_INVALID_FEATURE_BIT (0xff) 40d5970055SMichael S. Tsirkin 41309750faSJason Wang struct vhost_log { 42309750faSJason Wang unsigned long long size; 43309750faSJason Wang int refcnt; 4415324404SMarc-André Lureau int fd; 4515324404SMarc-André Lureau vhost_log_chunk_t *log; 46309750faSJason Wang }; 47309750faSJason Wang 48375f74f4SJason Wang struct vhost_dev; 49375f74f4SJason Wang struct vhost_iommu { 50375f74f4SJason Wang struct vhost_dev *hdev; 51375f74f4SJason Wang MemoryRegion *mr; 52375f74f4SJason Wang hwaddr iommu_offset; 53375f74f4SJason Wang IOMMUNotifier n; 54375f74f4SJason Wang QLIST_ENTRY(vhost_iommu) iommu_next; 55375f74f4SJason Wang }; 56375f74f4SJason Wang 574c3e257bSChangpeng Liu typedef struct VhostDevConfigOps { 584c3e257bSChangpeng Liu /* Vhost device config space changed callback 594c3e257bSChangpeng Liu */ 604c3e257bSChangpeng Liu int (*vhost_dev_config_notifier)(struct vhost_dev *dev); 614c3e257bSChangpeng Liu } VhostDevConfigOps; 624c3e257bSChangpeng Liu 63d5970055SMichael S. Tsirkin struct vhost_memory; 64*27351992SAlex Bennée 65*27351992SAlex Bennée /** 66*27351992SAlex Bennée * struct vhost_dev - common vhost_dev structure 67*27351992SAlex Bennée * @vhost_ops: backend specific ops 68*27351992SAlex Bennée * @config_ops: ops for config changes (see @vhost_dev_set_config_notifier) 69*27351992SAlex Bennée */ 70d5970055SMichael S. Tsirkin struct vhost_dev { 71c471ad0eSJason Wang VirtIODevice *vdev; 7204097f7cSAvi Kivity MemoryListener memory_listener; 73375f74f4SJason Wang MemoryListener iommu_listener; 74d5970055SMichael S. Tsirkin struct vhost_memory *mem; 752817b260SAvi Kivity int n_mem_sections; 762817b260SAvi Kivity MemoryRegionSection *mem_sections; 77c44317efSDr. David Alan Gilbert int n_tmp_sections; 78c44317efSDr. David Alan Gilbert MemoryRegionSection *tmp_sections; 79d5970055SMichael S. Tsirkin struct vhost_virtqueue *vqs; 805fc13603SJason Wang unsigned int nvqs; 819be6e69fSGreg Kurz /* the first virtqueue which would be used by this vhost dev */ 82a9f98bb5SJason Wang int vq_index; 83245cf2c2SEugenio Pérez /* one past the last vq index for the virtio device (not vhost) */ 84245cf2c2SEugenio Pérez int vq_index_end; 85c90bd505SKevin Wolf /* if non-zero, minimum required value for max_queues */ 86c90bd505SKevin Wolf int num_queues; 8721e70425SMarc-André Lureau uint64_t features; 8821e70425SMarc-André Lureau uint64_t acked_features; 8921e70425SMarc-André Lureau uint64_t backend_features; 9021e70425SMarc-André Lureau uint64_t protocol_features; 9121e70425SMarc-André Lureau uint64_t max_queues; 92b37556edSJason Wang uint64_t backend_cap; 93d5970055SMichael S. Tsirkin bool started; 94d5970055SMichael S. Tsirkin bool log_enabled; 9521e70425SMarc-André Lureau uint64_t log_size; 967145872eSMichael S. Tsirkin Error *migration_blocker; 9724d1eb33SNikolay Nikolaev const VhostOps *vhost_ops; 981a1bfac9SNikolay Nikolaev void *opaque; 99309750faSJason Wang struct vhost_log *log; 1002ce68e4cSIgor Mammedov QLIST_ENTRY(vhost_dev) entry; 101375f74f4SJason Wang QLIST_HEAD(, vhost_iommu) iommu_list; 102c471ad0eSJason Wang IOMMUNotifier n; 1034c3e257bSChangpeng Liu const VhostDevConfigOps *config_ops; 104d5970055SMichael S. Tsirkin }; 105d5970055SMichael S. Tsirkin 1069b1d929aSTiberiu Georgescu extern const VhostOps kernel_ops; 1079b1d929aSTiberiu Georgescu extern const VhostOps user_ops; 1089b1d929aSTiberiu Georgescu extern const VhostOps vdpa_ops; 1099b1d929aSTiberiu Georgescu 110108a6481SCindy Lu struct vhost_net { 111108a6481SCindy Lu struct vhost_dev dev; 112108a6481SCindy Lu struct vhost_virtqueue vqs[2]; 113108a6481SCindy Lu int backend; 114108a6481SCindy Lu NetClientState *nc; 115108a6481SCindy Lu }; 116108a6481SCindy Lu 117*27351992SAlex Bennée /** 118*27351992SAlex Bennée * vhost_dev_init() - initialise the vhost interface 119*27351992SAlex Bennée * @hdev: the common vhost_dev structure 120*27351992SAlex Bennée * @opaque: opaque ptr passed to backend (vhost/vhost-user/vdpa) 121*27351992SAlex Bennée * @backend_type: type of backend 122*27351992SAlex Bennée * @busyloop_timeout: timeout for polling virtqueue 123*27351992SAlex Bennée * @errp: error handle 124*27351992SAlex Bennée * 125*27351992SAlex Bennée * The initialisation of the vhost device will trigger the 126*27351992SAlex Bennée * initialisation of the backend and potentially capability 127*27351992SAlex Bennée * negotiation of backend interface. Configuration of the VirtIO 128*27351992SAlex Bennée * itself won't happen until the interface is started. 129*27351992SAlex Bennée * 130*27351992SAlex Bennée * Return: 0 on success, non-zero on error while setting errp. 131*27351992SAlex Bennée */ 13281647a65SNikolay Nikolaev int vhost_dev_init(struct vhost_dev *hdev, void *opaque, 13369e87b32SJason Wang VhostBackendType backend_type, 134a6945f22SKevin Wolf uint32_t busyloop_timeout, Error **errp); 135*27351992SAlex Bennée 136*27351992SAlex Bennée /** 137*27351992SAlex Bennée * vhost_dev_cleanup() - tear down and cleanup vhost interface 138*27351992SAlex Bennée * @hdev: the common vhost_dev structure 139*27351992SAlex Bennée */ 140d5970055SMichael S. Tsirkin void vhost_dev_cleanup(struct vhost_dev *hdev); 141*27351992SAlex Bennée 142*27351992SAlex Bennée /** 143*27351992SAlex Bennée * vhost_dev_enable_notifiers() - enable event notifiers 144*27351992SAlex Bennée * @hdev: common vhost_dev structure 145*27351992SAlex Bennée * @vdev: the VirtIODevice structure 146*27351992SAlex Bennée * 147*27351992SAlex Bennée * Enable notifications directly to the vhost device rather than being 148*27351992SAlex Bennée * triggered by QEMU itself. Notifications should be enabled before 149*27351992SAlex Bennée * the vhost device is started via @vhost_dev_start. 150*27351992SAlex Bennée * 151*27351992SAlex Bennée * Return: 0 on success, < 0 on error. 152*27351992SAlex Bennée */ 153b0b3db79SMichael S. Tsirkin int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); 154*27351992SAlex Bennée 155*27351992SAlex Bennée /** 156*27351992SAlex Bennée * vhost_dev_disable_notifiers - disable event notifications 157*27351992SAlex Bennée * @hdev: common vhost_dev structure 158*27351992SAlex Bennée * @vdev: the VirtIODevice structure 159*27351992SAlex Bennée * 160*27351992SAlex Bennée * Disable direct notifications to vhost device. 161*27351992SAlex Bennée */ 162b0b3db79SMichael S. Tsirkin void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); 163d5970055SMichael S. Tsirkin 164*27351992SAlex Bennée /** 165*27351992SAlex Bennée * vhost_dev_start() - start the vhost device 166*27351992SAlex Bennée * @hdev: common vhost_dev structure 167*27351992SAlex Bennée * @vdev: the VirtIODevice structure 168*27351992SAlex Bennée * 169*27351992SAlex Bennée * Starts the vhost device. From this point VirtIO feature negotiation 170*27351992SAlex Bennée * can start and the device can start processing VirtIO transactions. 171*27351992SAlex Bennée * 172*27351992SAlex Bennée * Return: 0 on success, < 0 on error. 173*27351992SAlex Bennée */ 174*27351992SAlex Bennée int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev); 175*27351992SAlex Bennée 176*27351992SAlex Bennée /** 177*27351992SAlex Bennée * vhost_dev_stop() - stop the vhost device 178*27351992SAlex Bennée * @hdev: common vhost_dev structure 179*27351992SAlex Bennée * @vdev: the VirtIODevice structure 180*27351992SAlex Bennée * 181*27351992SAlex Bennée * Stop the vhost device. After the device is stopped the notifiers 182*27351992SAlex Bennée * can be disabled (@vhost_dev_disable_notifiers) and the device can 183*27351992SAlex Bennée * be torn down (@vhost_dev_cleanup). 184*27351992SAlex Bennée */ 185*27351992SAlex Bennée void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev); 186*27351992SAlex Bennée 187*27351992SAlex Bennée /** 188*27351992SAlex Bennée * DOC: vhost device configuration handling 189*27351992SAlex Bennée * 190*27351992SAlex Bennée * The VirtIO device configuration space is used for rarely changing 191*27351992SAlex Bennée * or initialisation time parameters. The configuration can be updated 192*27351992SAlex Bennée * by either the guest driver or the device itself. If the device can 193*27351992SAlex Bennée * change the configuration over time the vhost handler should 194*27351992SAlex Bennée * register a @VhostDevConfigOps structure with 195*27351992SAlex Bennée * @vhost_dev_set_config_notifier so the guest can be notified. Some 196*27351992SAlex Bennée * devices register a handler anyway and will signal an error if an 197*27351992SAlex Bennée * unexpected config change happens. 198*27351992SAlex Bennée */ 199*27351992SAlex Bennée 200*27351992SAlex Bennée /** 201*27351992SAlex Bennée * vhost_dev_get_config() - fetch device configuration 202*27351992SAlex Bennée * @hdev: common vhost_dev_structure 203*27351992SAlex Bennée * @config: pointer to device appropriate config structure 204*27351992SAlex Bennée * @config_len: size of device appropriate config structure 205*27351992SAlex Bennée * 206*27351992SAlex Bennée * Return: 0 on success, < 0 on error while setting errp 207*27351992SAlex Bennée */ 208*27351992SAlex Bennée int vhost_dev_get_config(struct vhost_dev *hdev, uint8_t *config, 209*27351992SAlex Bennée uint32_t config_len, Error **errp); 210*27351992SAlex Bennée 211*27351992SAlex Bennée /** 212*27351992SAlex Bennée * vhost_dev_set_config() - set device configuration 213*27351992SAlex Bennée * @hdev: common vhost_dev_structure 214*27351992SAlex Bennée * @data: pointer to data to set 215*27351992SAlex Bennée * @offset: offset into configuration space 216*27351992SAlex Bennée * @size: length of set 217*27351992SAlex Bennée * @flags: @VhostSetConfigType flags 218*27351992SAlex Bennée * 219*27351992SAlex Bennée * By use of @offset/@size a subset of the configuration space can be 220*27351992SAlex Bennée * written to. The @flags are used to indicate if it is a normal 221*27351992SAlex Bennée * transaction or related to migration. 222*27351992SAlex Bennée * 223*27351992SAlex Bennée * Return: 0 on success, non-zero on error 224*27351992SAlex Bennée */ 225*27351992SAlex Bennée int vhost_dev_set_config(struct vhost_dev *dev, const uint8_t *data, 226*27351992SAlex Bennée uint32_t offset, uint32_t size, uint32_t flags); 227*27351992SAlex Bennée 228*27351992SAlex Bennée /** 229*27351992SAlex Bennée * vhost_dev_set_config_notifier() - register VhostDevConfigOps 230*27351992SAlex Bennée * @hdev: common vhost_dev_structure 231*27351992SAlex Bennée * @ops: notifier ops 232*27351992SAlex Bennée * 233*27351992SAlex Bennée * If the device is expected to change configuration a notifier can be 234*27351992SAlex Bennée * setup to handle the case. 235*27351992SAlex Bennée */ 236*27351992SAlex Bennée void vhost_dev_set_config_notifier(struct vhost_dev *dev, 237*27351992SAlex Bennée const VhostDevConfigOps *ops); 238*27351992SAlex Bennée 239*27351992SAlex Bennée 240f56a1247SMichael S. Tsirkin /* Test and clear masked event pending status. 241f56a1247SMichael S. Tsirkin * Should be called after unmask to avoid losing events. 242f56a1247SMichael S. Tsirkin */ 243f56a1247SMichael S. Tsirkin bool vhost_virtqueue_pending(struct vhost_dev *hdev, int n); 244f56a1247SMichael S. Tsirkin 245f56a1247SMichael S. Tsirkin /* Mask/unmask events from this vq. 246f56a1247SMichael S. Tsirkin */ 247f56a1247SMichael S. Tsirkin void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n, 248f56a1247SMichael S. Tsirkin bool mask); 2499a2ba823SCornelia Huck uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits, 2509a2ba823SCornelia Huck uint64_t features); 2512e6d46d7SNikolay Nikolaev void vhost_ack_features(struct vhost_dev *hdev, const int *feature_bits, 2529a2ba823SCornelia Huck uint64_t features); 2532ce68e4cSIgor Mammedov bool vhost_has_free_slot(void); 254950d94baSMarc-André Lureau 255950d94baSMarc-André Lureau int vhost_net_set_backend(struct vhost_dev *hdev, 256950d94baSMarc-André Lureau struct vhost_vring_file *file); 257950d94baSMarc-André Lureau 258fc58bd0dSMaxime Coquelin int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write); 2595ad204bfSXie Yongji 2605ad204bfSXie Yongji void vhost_dev_reset_inflight(struct vhost_inflight *inflight); 2615ad204bfSXie Yongji void vhost_dev_free_inflight(struct vhost_inflight *inflight); 2625ad204bfSXie Yongji void vhost_dev_save_inflight(struct vhost_inflight *inflight, QEMUFile *f); 2635ad204bfSXie Yongji int vhost_dev_load_inflight(struct vhost_inflight *inflight, QEMUFile *f); 2641b0063b3SJin Yu int vhost_dev_prepare_inflight(struct vhost_dev *hdev, VirtIODevice *vdev); 2655ad204bfSXie Yongji int vhost_dev_set_inflight(struct vhost_dev *dev, 2665ad204bfSXie Yongji struct vhost_inflight *inflight); 2675ad204bfSXie Yongji int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size, 2685ad204bfSXie Yongji struct vhost_inflight *inflight); 269d5970055SMichael S. Tsirkin #endif 270