111b8b9d5SCédric Le Goater /* 211b8b9d5SCédric Le Goater * VFIO Device interface 311b8b9d5SCédric Le Goater * 411b8b9d5SCédric Le Goater * Copyright Red Hat, Inc. 2012 511b8b9d5SCédric Le Goater * 611b8b9d5SCédric Le Goater * Authors: 711b8b9d5SCédric Le Goater * Alex Williamson <alex.williamson@redhat.com> 811b8b9d5SCédric Le Goater * 911b8b9d5SCédric Le Goater * This work is licensed under the terms of the GNU GPL, version 2. See 1011b8b9d5SCédric Le Goater * the COPYING file in the top-level directory. 1111b8b9d5SCédric Le Goater * 1211b8b9d5SCédric Le Goater * Based on qemu-kvm device-assignment: 1311b8b9d5SCédric Le Goater * Adapted for KVM by Qumranet. 1411b8b9d5SCédric Le Goater * Copyright (c) 2007, Neocleus, Alex Novik (alex@neocleus.com) 1511b8b9d5SCédric Le Goater * Copyright (c) 2007, Neocleus, Guy Zana (guy@neocleus.com) 1611b8b9d5SCédric Le Goater * Copyright (C) 2008, Qumranet, Amit Shah (amit.shah@qumranet.com) 1711b8b9d5SCédric Le Goater * Copyright (C) 2008, Red Hat, Amit Shah (amit.shah@redhat.com) 1811b8b9d5SCédric Le Goater * Copyright (C) 2008, IBM, Muli Ben-Yehuda (muli@il.ibm.com) 1911b8b9d5SCédric Le Goater */ 2011b8b9d5SCédric Le Goater 2111b8b9d5SCédric Le Goater #ifndef HW_VFIO_VFIO_COMMON_H 2211b8b9d5SCédric Le Goater #define HW_VFIO_VFIO_COMMON_H 2311b8b9d5SCédric Le Goater 2411b8b9d5SCédric Le Goater #include "system/memory.h" 2511b8b9d5SCédric Le Goater #include "qemu/queue.h" 2611b8b9d5SCédric Le Goater #ifdef CONFIG_LINUX 2711b8b9d5SCédric Le Goater #include <linux/vfio.h> 2811b8b9d5SCédric Le Goater #endif 2911b8b9d5SCédric Le Goater #include "system/system.h" 3011b8b9d5SCédric Le Goater #include "hw/vfio/vfio-container-base.h" 31dac0dd68SSteve Sistare #include "hw/vfio/vfio-cpr.h" 3211b8b9d5SCédric Le Goater #include "system/host_iommu_device.h" 3311b8b9d5SCédric Le Goater #include "system/iommufd.h" 3411b8b9d5SCédric Le Goater 3511b8b9d5SCédric Le Goater #define VFIO_MSG_PREFIX "vfio %s: " 3611b8b9d5SCédric Le Goater 3711b8b9d5SCédric Le Goater enum { 3811b8b9d5SCédric Le Goater VFIO_DEVICE_TYPE_PCI = 0, 3911b8b9d5SCédric Le Goater VFIO_DEVICE_TYPE_PLATFORM = 1, 4011b8b9d5SCédric Le Goater VFIO_DEVICE_TYPE_CCW = 2, 4111b8b9d5SCédric Le Goater VFIO_DEVICE_TYPE_AP = 3, 4211b8b9d5SCédric Le Goater }; 4311b8b9d5SCédric Le Goater 4411b8b9d5SCédric Le Goater typedef struct VFIODeviceOps VFIODeviceOps; 4538bf025dSJohn Levon typedef struct VFIODeviceIOOps VFIODeviceIOOps; 4611b8b9d5SCédric Le Goater typedef struct VFIOMigration VFIOMigration; 4711b8b9d5SCédric Le Goater 4811b8b9d5SCédric Le Goater typedef struct IOMMUFDBackend IOMMUFDBackend; 4911b8b9d5SCédric Le Goater typedef struct VFIOIOASHwpt VFIOIOASHwpt; 50438d863fSJohn Levon typedef struct VFIOUserProxy VFIOUserProxy; 5111b8b9d5SCédric Le Goater 5211b8b9d5SCédric Le Goater typedef struct VFIODevice { 5311b8b9d5SCédric Le Goater QLIST_ENTRY(VFIODevice) next; 5411b8b9d5SCédric Le Goater QLIST_ENTRY(VFIODevice) container_next; 5511b8b9d5SCédric Le Goater QLIST_ENTRY(VFIODevice) global_next; 5611b8b9d5SCédric Le Goater struct VFIOGroup *group; 5711b8b9d5SCédric Le Goater VFIOContainerBase *bcontainer; 5811b8b9d5SCédric Le Goater char *sysfsdev; 5911b8b9d5SCédric Le Goater char *name; 6011b8b9d5SCédric Le Goater DeviceState *dev; 6111b8b9d5SCédric Le Goater int fd; 6211b8b9d5SCédric Le Goater int type; 6311b8b9d5SCédric Le Goater bool mdev; 6411b8b9d5SCédric Le Goater bool reset_works; 6511b8b9d5SCédric Le Goater bool needs_reset; 6611b8b9d5SCédric Le Goater bool no_mmap; 6711b8b9d5SCédric Le Goater bool ram_block_discard_allowed; 6811b8b9d5SCédric Le Goater OnOffAuto enable_migration; 6911b8b9d5SCédric Le Goater OnOffAuto migration_multifd_transfer; 706380b0a0SMaciej S. Szmigiero OnOffAuto migration_load_config_after_iter; 71*300dcf58SMaciej S. Szmigiero uint64_t migration_max_queued_buffers_size; 7211b8b9d5SCédric Le Goater bool migration_events; 7359adfc6fSJohn Levon bool use_region_fds; 7411b8b9d5SCédric Le Goater VFIODeviceOps *ops; 7538bf025dSJohn Levon VFIODeviceIOOps *io_ops; 7611b8b9d5SCédric Le Goater unsigned int num_irqs; 7711b8b9d5SCédric Le Goater unsigned int num_regions; 7811b8b9d5SCédric Le Goater unsigned int flags; 7911b8b9d5SCédric Le Goater VFIOMigration *migration; 8011b8b9d5SCédric Le Goater Error *migration_blocker; 8111b8b9d5SCédric Le Goater OnOffAuto pre_copy_dirty_page_tracking; 8211b8b9d5SCédric Le Goater OnOffAuto device_dirty_page_tracking; 8311b8b9d5SCédric Le Goater bool dirty_pages_supported; 8411b8b9d5SCédric Le Goater bool dirty_tracking; /* Protected by BQL */ 8511b8b9d5SCédric Le Goater bool iommu_dirty_tracking; 8611b8b9d5SCédric Le Goater HostIOMMUDevice *hiod; 8711b8b9d5SCédric Le Goater int devid; 8811b8b9d5SCédric Le Goater IOMMUFDBackend *iommufd; 8911b8b9d5SCédric Le Goater VFIOIOASHwpt *hwpt; 9011b8b9d5SCédric Le Goater QLIST_ENTRY(VFIODevice) hwpt_next; 9195cdb024SJohn Levon struct vfio_region_info **reginfo; 9259adfc6fSJohn Levon int *region_fds; 93dac0dd68SSteve Sistare VFIODeviceCPR cpr; 94438d863fSJohn Levon VFIOUserProxy *proxy; 9511b8b9d5SCédric Le Goater } VFIODevice; 9611b8b9d5SCédric Le Goater 9711b8b9d5SCédric Le Goater struct VFIODeviceOps { 9811b8b9d5SCédric Le Goater void (*vfio_compute_needs_reset)(VFIODevice *vdev); 9911b8b9d5SCédric Le Goater int (*vfio_hot_reset_multi)(VFIODevice *vdev); 10011b8b9d5SCédric Le Goater void (*vfio_eoi)(VFIODevice *vdev); 10111b8b9d5SCédric Le Goater Object *(*vfio_get_object)(VFIODevice *vdev); 10211b8b9d5SCédric Le Goater 10311b8b9d5SCédric Le Goater /** 10411b8b9d5SCédric Le Goater * @vfio_save_config 10511b8b9d5SCédric Le Goater * 10611b8b9d5SCédric Le Goater * Save device config state 10711b8b9d5SCédric Le Goater * 10811b8b9d5SCédric Le Goater * @vdev: #VFIODevice for which to save the config 10911b8b9d5SCédric Le Goater * @f: #QEMUFile where to send the data 11011b8b9d5SCédric Le Goater * @errp: pointer to Error*, to store an error if it happens. 11111b8b9d5SCédric Le Goater * 11211b8b9d5SCédric Le Goater * Returns zero to indicate success and negative for error 11311b8b9d5SCédric Le Goater */ 11411b8b9d5SCédric Le Goater int (*vfio_save_config)(VFIODevice *vdev, QEMUFile *f, Error **errp); 11511b8b9d5SCédric Le Goater 11611b8b9d5SCédric Le Goater /** 11711b8b9d5SCédric Le Goater * @vfio_load_config 11811b8b9d5SCédric Le Goater * 11911b8b9d5SCédric Le Goater * Load device config state 12011b8b9d5SCédric Le Goater * 12111b8b9d5SCédric Le Goater * @vdev: #VFIODevice for which to load the config 12211b8b9d5SCédric Le Goater * @f: #QEMUFile where to get the data 12311b8b9d5SCédric Le Goater * 12411b8b9d5SCédric Le Goater * Returns zero to indicate success and negative for error 12511b8b9d5SCédric Le Goater */ 12611b8b9d5SCédric Le Goater int (*vfio_load_config)(VFIODevice *vdev, QEMUFile *f); 12711b8b9d5SCédric Le Goater }; 12811b8b9d5SCédric Le Goater 1295363a1a1SJohn Levon /* 1305363a1a1SJohn Levon * Given a return value of either a short number of bytes read or -errno, 1315363a1a1SJohn Levon * construct a meaningful error message. 1325363a1a1SJohn Levon */ 1335363a1a1SJohn Levon #define strreaderror(ret) \ 1345363a1a1SJohn Levon (ret < 0 ? strerror(-ret) : "short read") 1355363a1a1SJohn Levon 1365363a1a1SJohn Levon /* 1375363a1a1SJohn Levon * Given a return value of either a short number of bytes written or -errno, 1385363a1a1SJohn Levon * construct a meaningful error message. 1395363a1a1SJohn Levon */ 1405363a1a1SJohn Levon #define strwriteerror(ret) \ 1415363a1a1SJohn Levon (ret < 0 ? strerror(-ret) : "short write") 1425363a1a1SJohn Levon 143e218ccf0SCédric Le Goater void vfio_device_irq_disable(VFIODevice *vbasedev, int index); 144e218ccf0SCédric Le Goater void vfio_device_irq_unmask(VFIODevice *vbasedev, int index); 145e218ccf0SCédric Le Goater void vfio_device_irq_mask(VFIODevice *vbasedev, int index); 146e218ccf0SCédric Le Goater bool vfio_device_irq_set_signaling(VFIODevice *vbasedev, int index, int subindex, 14711b8b9d5SCédric Le Goater int action, int fd, Error **errp); 14811b8b9d5SCédric Le Goater 149e218ccf0SCédric Le Goater void vfio_device_reset_handler(void *opaque); 15011b8b9d5SCédric Le Goater bool vfio_device_is_mdev(VFIODevice *vbasedev); 1510805f829SZhenzhong Duan bool vfio_device_hiod_create_and_realize(VFIODevice *vbasedev, 1520805f829SZhenzhong Duan const char *typename, Error **errp); 153e218ccf0SCédric Le Goater bool vfio_device_attach(char *name, VFIODevice *vbasedev, 15411b8b9d5SCédric Le Goater AddressSpace *as, Error **errp); 155ef73671fSJohn Levon bool vfio_device_attach_by_iommu_type(const char *iommu_type, char *name, 156ef73671fSJohn Levon VFIODevice *vbasedev, AddressSpace *as, 157ef73671fSJohn Levon Error **errp); 158e218ccf0SCédric Le Goater void vfio_device_detach(VFIODevice *vbasedev); 15911b8b9d5SCédric Le Goater VFIODevice *vfio_get_vfio_device(Object *obj); 16011b8b9d5SCédric Le Goater 16111b8b9d5SCédric Le Goater typedef QLIST_HEAD(VFIODeviceList, VFIODevice) VFIODeviceList; 16211b8b9d5SCédric Le Goater extern VFIODeviceList vfio_device_list; 16311b8b9d5SCédric Le Goater 16411b8b9d5SCédric Le Goater #ifdef CONFIG_LINUX 16538bf025dSJohn Levon /* 16638bf025dSJohn Levon * How devices communicate with the server. The default option is through 16738bf025dSJohn Levon * ioctl() to the kernel VFIO driver, but vfio-user can use a socket to a remote 16838bf025dSJohn Levon * process. 16938bf025dSJohn Levon */ 17038bf025dSJohn Levon struct VFIODeviceIOOps { 17138bf025dSJohn Levon /** 17238bf025dSJohn Levon * @device_feature 17338bf025dSJohn Levon * 17438bf025dSJohn Levon * Fill in feature info for the given device. 175079e7216SJohn Levon * 176079e7216SJohn Levon * @vdev: #VFIODevice to use 177079e7216SJohn Levon * @feat: feature information to fill in 178079e7216SJohn Levon * 179079e7216SJohn Levon * Returns 0 on success or -errno. 18038bf025dSJohn Levon */ 181079e7216SJohn Levon int (*device_feature)(VFIODevice *vdev, struct vfio_device_feature *feat); 18238bf025dSJohn Levon 18338bf025dSJohn Levon /** 18438bf025dSJohn Levon * @get_region_info 18538bf025dSJohn Levon * 186079e7216SJohn Levon * Get the information for a given region on the device. 187079e7216SJohn Levon * 188079e7216SJohn Levon * @vdev: #VFIODevice to use 189079e7216SJohn Levon * @info: set @info->index to the region index to look up; the rest of the 190079e7216SJohn Levon * struct will be filled in on success 191079e7216SJohn Levon * @fd: pointer to the fd for the region; will be -1 if not found 192079e7216SJohn Levon * 193079e7216SJohn Levon * Returns 0 on success or -errno. 19438bf025dSJohn Levon */ 19538bf025dSJohn Levon int (*get_region_info)(VFIODevice *vdev, 19659adfc6fSJohn Levon struct vfio_region_info *info, int *fd); 19738bf025dSJohn Levon 19838bf025dSJohn Levon /** 19938bf025dSJohn Levon * @get_irq_info 20038bf025dSJohn Levon * 201079e7216SJohn Levon * @vdev: #VFIODevice to use 202079e7216SJohn Levon * @irq: set @irq->index to the IRQ index to look up; the rest of the struct 203079e7216SJohn Levon * will be filled in on success 204079e7216SJohn Levon * 205079e7216SJohn Levon * Returns 0 on success or -errno. 20638bf025dSJohn Levon */ 20738bf025dSJohn Levon int (*get_irq_info)(VFIODevice *vdev, struct vfio_irq_info *irq); 20838bf025dSJohn Levon 20938bf025dSJohn Levon /** 21038bf025dSJohn Levon * @set_irqs 21138bf025dSJohn Levon * 212079e7216SJohn Levon * Configure IRQs. 213079e7216SJohn Levon * 214079e7216SJohn Levon * @vdev: #VFIODevice to use 215079e7216SJohn Levon * @irqs: IRQ configuration as defined by VFIO docs. 216079e7216SJohn Levon * 217079e7216SJohn Levon * Returns 0 on success or -errno. 21838bf025dSJohn Levon */ 21938bf025dSJohn Levon int (*set_irqs)(VFIODevice *vdev, struct vfio_irq_set *irqs); 220776066acSJohn Levon 221776066acSJohn Levon /** 222776066acSJohn Levon * @region_read 223776066acSJohn Levon * 224079e7216SJohn Levon * Read part of a region. 225079e7216SJohn Levon * 226079e7216SJohn Levon * @vdev: #VFIODevice to use 227079e7216SJohn Levon * @nr: region index 228079e7216SJohn Levon * @off: offset within the region 229079e7216SJohn Levon * @size: size in bytes to read 230079e7216SJohn Levon * @data: buffer to read into 231079e7216SJohn Levon * 232079e7216SJohn Levon * Returns number of bytes read on success or -errno. 233776066acSJohn Levon */ 234776066acSJohn Levon int (*region_read)(VFIODevice *vdev, uint8_t nr, off_t off, uint32_t size, 235776066acSJohn Levon void *data); 236776066acSJohn Levon 237776066acSJohn Levon /** 238776066acSJohn Levon * @region_write 239776066acSJohn Levon * 240079e7216SJohn Levon * Write part of a region. 241079e7216SJohn Levon * 242079e7216SJohn Levon * @vdev: #VFIODevice to use 243079e7216SJohn Levon * @nr: region index 244079e7216SJohn Levon * @off: offset within the region 245079e7216SJohn Levon * @size: size in bytes to write 246079e7216SJohn Levon * @data: buffer to write from 2478d60d069SJohn Levon * @post: true if this is a posted write 248079e7216SJohn Levon * 249079e7216SJohn Levon * Returns number of bytes write on success or -errno. 250776066acSJohn Levon */ 251776066acSJohn Levon int (*region_write)(VFIODevice *vdev, uint8_t nr, off_t off, uint32_t size, 252a574b061SJohn Levon void *data, bool post); 25338bf025dSJohn Levon }; 25438bf025dSJohn Levon 255a901682fSJohn Levon void vfio_device_prepare(VFIODevice *vbasedev, VFIOContainerBase *bcontainer, 256a901682fSJohn Levon struct vfio_device_info *info); 257a901682fSJohn Levon 258d60fb709SJohn Levon void vfio_device_unprepare(VFIODevice *vbasedev); 259d60fb709SJohn Levon 260e218ccf0SCédric Le Goater int vfio_device_get_region_info(VFIODevice *vbasedev, int index, 26111b8b9d5SCédric Le Goater struct vfio_region_info **info); 262e218ccf0SCédric Le Goater int vfio_device_get_region_info_type(VFIODevice *vbasedev, uint32_t type, 26311b8b9d5SCédric Le Goater uint32_t subtype, struct vfio_region_info **info); 264b1f521deSJohn Levon 265b1f521deSJohn Levon /** 266b1f521deSJohn Levon * Return the fd for mapping this region. This is either the device's fd (for 267b1f521deSJohn Levon * e.g. kernel vfio), or a per-region fd (for vfio-user). 268b1f521deSJohn Levon * 269b1f521deSJohn Levon * @vbasedev: #VFIODevice to use 270b1f521deSJohn Levon * @index: region index 271b1f521deSJohn Levon * 272b1f521deSJohn Levon * Returns the fd. 273b1f521deSJohn Levon */ 274b1f521deSJohn Levon int vfio_device_get_region_fd(VFIODevice *vbasedev, int index); 275b1f521deSJohn Levon 276e218ccf0SCédric Le Goater bool vfio_device_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type); 2775321e623SJohn Levon 2785321e623SJohn Levon int vfio_device_get_irq_info(VFIODevice *vbasedev, int index, 2795321e623SJohn Levon struct vfio_irq_info *info); 28011b8b9d5SCédric Le Goater #endif 28111b8b9d5SCédric Le Goater 28211b8b9d5SCédric Le Goater /* Returns 0 on success, or a negative errno. */ 28311b8b9d5SCédric Le Goater bool vfio_device_get_name(VFIODevice *vbasedev, Error **errp); 284184053f0SSteve Sistare void vfio_device_free_name(VFIODevice *vbasedev); 28511b8b9d5SCédric Le Goater void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp); 28611b8b9d5SCédric Le Goater void vfio_device_init(VFIODevice *vbasedev, int type, VFIODeviceOps *ops, 28711b8b9d5SCédric Le Goater DeviceState *dev, bool ram_discard); 28811b8b9d5SCédric Le Goater int vfio_device_get_aw_bits(VFIODevice *vdev); 2897ed09191SSteve Sistare 2907ed09191SSteve Sistare void vfio_kvm_device_close(void); 29111b8b9d5SCédric Le Goater #endif /* HW_VFIO_VFIO_COMMON_H */ 292