1e2c7d025SEric Auger /* 211b8b9d5SCédric Le Goater * VFIO Device interface 3e2c7d025SEric Auger * 4e2c7d025SEric Auger * Copyright Red Hat, Inc. 2012 5e2c7d025SEric Auger * 6e2c7d025SEric Auger * Authors: 7e2c7d025SEric Auger * Alex Williamson <alex.williamson@redhat.com> 8e2c7d025SEric Auger * 9e2c7d025SEric Auger * This work is licensed under the terms of the GNU GPL, version 2. See 10e2c7d025SEric Auger * the COPYING file in the top-level directory. 11e2c7d025SEric Auger * 12e2c7d025SEric Auger * Based on qemu-kvm device-assignment: 13e2c7d025SEric Auger * Adapted for KVM by Qumranet. 14e2c7d025SEric Auger * Copyright (c) 2007, Neocleus, Alex Novik (alex@neocleus.com) 15e2c7d025SEric Auger * Copyright (c) 2007, Neocleus, Guy Zana (guy@neocleus.com) 16e2c7d025SEric Auger * Copyright (C) 2008, Qumranet, Amit Shah (amit.shah@qumranet.com) 17e2c7d025SEric Auger * Copyright (C) 2008, Red Hat, Amit Shah (amit.shah@redhat.com) 18e2c7d025SEric Auger * Copyright (C) 2008, IBM, Muli Ben-Yehuda (muli@il.ibm.com) 19e2c7d025SEric Auger */ 20175de524SMarkus Armbruster 21e2c7d025SEric Auger #ifndef HW_VFIO_VFIO_COMMON_H 22e2c7d025SEric Auger #define HW_VFIO_VFIO_COMMON_H 23e2c7d025SEric Auger 248be545baSRichard Henderson #include "system/memory.h" 25e2c7d025SEric Auger #include "qemu/queue.h" 2646900226SAlex Williamson #ifdef CONFIG_LINUX 2746900226SAlex Williamson #include <linux/vfio.h> 2846900226SAlex Williamson #endif 2932cad1ffSPhilippe Mathieu-Daudé #include "system/system.h" 30f61dddd7SZhenzhong Duan #include "hw/vfio/vfio-container-base.h" 3132cad1ffSPhilippe Mathieu-Daudé #include "system/host_iommu_device.h" 3232cad1ffSPhilippe Mathieu-Daudé #include "system/iommufd.h" 33e2c7d025SEric Auger 34e1eb292aSMarkus Armbruster #define VFIO_MSG_PREFIX "vfio %s: " 35426ec904SEric Auger 36e2c7d025SEric Auger enum { 37e2c7d025SEric Auger VFIO_DEVICE_TYPE_PCI = 0, 380ea2730bSEric Auger VFIO_DEVICE_TYPE_PLATFORM = 1, 391dcac3e1SXiao Feng Ren VFIO_DEVICE_TYPE_CCW = 2, 402fe2942cSTony Krowiak VFIO_DEVICE_TYPE_AP = 3, 41e2c7d025SEric Auger }; 42504d297eSCédric Le Goater 43e2c7d025SEric Auger typedef struct VFIODeviceOps VFIODeviceOps; 4438bf025dSJohn Levon typedef struct VFIODeviceIOOps VFIODeviceIOOps; 45b553d2c4SCédric Le Goater typedef struct VFIOMigration VFIOMigration; 46e2c7d025SEric Auger 47d4a8f286SCédric Le Goater typedef struct IOMMUFDBackend IOMMUFDBackend; 48d4a8f286SCédric Le Goater typedef struct VFIOIOASHwpt VFIOIOASHwpt; 49d4a8f286SCédric Le Goater 50e2c7d025SEric Auger typedef struct VFIODevice { 51e2c7d025SEric Auger QLIST_ENTRY(VFIODevice) next; 527103ef7eSZhenzhong Duan QLIST_ENTRY(VFIODevice) container_next; 533d779abaSZhenzhong Duan QLIST_ENTRY(VFIODevice) global_next; 54e2c7d025SEric Auger struct VFIOGroup *group; 553e6015d1SZhenzhong Duan VFIOContainerBase *bcontainer; 567df9381bSAlex Williamson char *sysfsdev; 57e2c7d025SEric Auger char *name; 587da624e2SAlex Williamson DeviceState *dev; 59e2c7d025SEric Auger int fd; 60e2c7d025SEric Auger int type; 6113e522f6SJoao Martins bool mdev; 62e2c7d025SEric Auger bool reset_works; 63e2c7d025SEric Auger bool needs_reset; 645e15d79bSAlex Williamson bool no_mmap; 65aff92b82SDavid Hildenbrand bool ram_block_discard_allowed; 668bbcb64aSAvihai Horon OnOffAuto enable_migration; 67623af41dSMaciej S. Szmigiero OnOffAuto migration_multifd_transfer; 685e1f8905SAvihai Horon bool migration_events; 69e2c7d025SEric Auger VFIODeviceOps *ops; 7038bf025dSJohn Levon VFIODeviceIOOps *io_ops; 71e2c7d025SEric Auger unsigned int num_irqs; 72e2c7d025SEric Auger unsigned int num_regions; 73e2c7d025SEric Auger unsigned int flags; 74a9e271ecSKirti Wankhede VFIOMigration *migration; 75a9e271ecSKirti Wankhede Error *migration_blocker; 76bb0990d1SKirti Wankhede OnOffAuto pre_copy_dirty_page_tracking; 7730b91677SJoao Martins OnOffAuto device_dirty_page_tracking; 785255bbf4SJoao Martins bool dirty_pages_supported; 790ae05e08SAvihai Horon bool dirty_tracking; /* Protected by BQL */ 80dddfd8d6SJoao Martins bool iommu_dirty_tracking; 81a7fd91b8SZhenzhong Duan HostIOMMUDevice *hiod; 825ee3dc7aSYi Liu int devid; 835ee3dc7aSYi Liu IOMMUFDBackend *iommufd; 845b1e96e6SJoao Martins VFIOIOASHwpt *hwpt; 855b1e96e6SJoao Martins QLIST_ENTRY(VFIODevice) hwpt_next; 8695cdb024SJohn Levon struct vfio_region_info **reginfo; 87e2c7d025SEric Auger } VFIODevice; 88e2c7d025SEric Auger 89e2c7d025SEric Auger struct VFIODeviceOps { 90e2c7d025SEric Auger void (*vfio_compute_needs_reset)(VFIODevice *vdev); 91e2c7d025SEric Auger int (*vfio_hot_reset_multi)(VFIODevice *vdev); 92e2c7d025SEric Auger void (*vfio_eoi)(VFIODevice *vdev); 93e93b733bSKirti Wankhede Object *(*vfio_get_object)(VFIODevice *vdev); 943783f814SCédric Le Goater 953783f814SCédric Le Goater /** 963783f814SCédric Le Goater * @vfio_save_config 973783f814SCédric Le Goater * 983783f814SCédric Le Goater * Save device config state 993783f814SCédric Le Goater * 1003783f814SCédric Le Goater * @vdev: #VFIODevice for which to save the config 1013783f814SCédric Le Goater * @f: #QEMUFile where to send the data 1023783f814SCédric Le Goater * @errp: pointer to Error*, to store an error if it happens. 1033783f814SCédric Le Goater * 1043783f814SCédric Le Goater * Returns zero to indicate success and negative for error 1053783f814SCédric Le Goater */ 1063783f814SCédric Le Goater int (*vfio_save_config)(VFIODevice *vdev, QEMUFile *f, Error **errp); 1073783f814SCédric Le Goater 1083783f814SCédric Le Goater /** 1093783f814SCédric Le Goater * @vfio_load_config 1103783f814SCédric Le Goater * 1113783f814SCédric Le Goater * Load device config state 1123783f814SCédric Le Goater * 1133783f814SCédric Le Goater * @vdev: #VFIODevice for which to load the config 1143783f814SCédric Le Goater * @f: #QEMUFile where to get the data 1153783f814SCédric Le Goater * 1163783f814SCédric Le Goater * Returns zero to indicate success and negative for error 1173783f814SCédric Le Goater */ 118c5e2fb3cSKirti Wankhede int (*vfio_load_config)(VFIODevice *vdev, QEMUFile *f); 119e2c7d025SEric Auger }; 120e2c7d025SEric Auger 1215363a1a1SJohn Levon /* 1225363a1a1SJohn Levon * Given a return value of either a short number of bytes read or -errno, 1235363a1a1SJohn Levon * construct a meaningful error message. 1245363a1a1SJohn Levon */ 1255363a1a1SJohn Levon #define strreaderror(ret) \ 1265363a1a1SJohn Levon (ret < 0 ? strerror(-ret) : "short read") 1275363a1a1SJohn Levon 1285363a1a1SJohn Levon /* 1295363a1a1SJohn Levon * Given a return value of either a short number of bytes written or -errno, 1305363a1a1SJohn Levon * construct a meaningful error message. 1315363a1a1SJohn Levon */ 1325363a1a1SJohn Levon #define strwriteerror(ret) \ 1335363a1a1SJohn Levon (ret < 0 ? strerror(-ret) : "short write") 1345363a1a1SJohn Levon 135e218ccf0SCédric Le Goater void vfio_device_irq_disable(VFIODevice *vbasedev, int index); 136e218ccf0SCédric Le Goater void vfio_device_irq_unmask(VFIODevice *vbasedev, int index); 137e218ccf0SCédric Le Goater void vfio_device_irq_mask(VFIODevice *vbasedev, int index); 138e218ccf0SCédric Le Goater bool vfio_device_irq_set_signaling(VFIODevice *vbasedev, int index, int subindex, 139201a7331SEric Auger int action, int fd, Error **errp); 140499e53ccSCédric Le Goater 141e218ccf0SCédric Le Goater void vfio_device_reset_handler(void *opaque); 14213e522f6SJoao Martins bool vfio_device_is_mdev(VFIODevice *vbasedev); 1430805f829SZhenzhong Duan bool vfio_device_hiod_create_and_realize(VFIODevice *vbasedev, 1440805f829SZhenzhong Duan const char *typename, Error **errp); 145e218ccf0SCédric Le Goater bool vfio_device_attach(char *name, VFIODevice *vbasedev, 1465456b186SEric Auger AddressSpace *as, Error **errp); 147ef73671fSJohn Levon bool vfio_device_attach_by_iommu_type(const char *iommu_type, char *name, 148ef73671fSJohn Levon VFIODevice *vbasedev, AddressSpace *as, 149ef73671fSJohn Levon Error **errp); 150e218ccf0SCédric Le Goater void vfio_device_detach(VFIODevice *vbasedev); 15180936cf7SCédric Le Goater VFIODevice *vfio_get_vfio_device(Object *obj); 152e2c7d025SEric Auger 1533d779abaSZhenzhong Duan typedef QLIST_HEAD(VFIODeviceList, VFIODevice) VFIODeviceList; 1547e63b311SYi Liu extern VFIODeviceList vfio_device_list; 155e2c7d025SEric Auger 15646900226SAlex Williamson #ifdef CONFIG_LINUX 15738bf025dSJohn Levon /* 15838bf025dSJohn Levon * How devices communicate with the server. The default option is through 15938bf025dSJohn Levon * ioctl() to the kernel VFIO driver, but vfio-user can use a socket to a remote 16038bf025dSJohn Levon * process. 16138bf025dSJohn Levon */ 16238bf025dSJohn Levon struct VFIODeviceIOOps { 16338bf025dSJohn Levon /** 16438bf025dSJohn Levon * @device_feature 16538bf025dSJohn Levon * 16638bf025dSJohn Levon * Fill in feature info for the given device. 16738bf025dSJohn Levon */ 16838bf025dSJohn Levon int (*device_feature)(VFIODevice *vdev, struct vfio_device_feature *); 16938bf025dSJohn Levon 17038bf025dSJohn Levon /** 17138bf025dSJohn Levon * @get_region_info 17238bf025dSJohn Levon * 17338bf025dSJohn Levon * Fill in @info with information on the region given by @info->index. 17438bf025dSJohn Levon */ 17538bf025dSJohn Levon int (*get_region_info)(VFIODevice *vdev, 17638bf025dSJohn Levon struct vfio_region_info *info); 17738bf025dSJohn Levon 17838bf025dSJohn Levon /** 17938bf025dSJohn Levon * @get_irq_info 18038bf025dSJohn Levon * 18138bf025dSJohn Levon * Fill in @irq with information on the IRQ given by @info->index. 18238bf025dSJohn Levon */ 18338bf025dSJohn Levon int (*get_irq_info)(VFIODevice *vdev, struct vfio_irq_info *irq); 18438bf025dSJohn Levon 18538bf025dSJohn Levon /** 18638bf025dSJohn Levon * @set_irqs 18738bf025dSJohn Levon * 18838bf025dSJohn Levon * Configure IRQs as defined by @irqs. 18938bf025dSJohn Levon */ 19038bf025dSJohn Levon int (*set_irqs)(VFIODevice *vdev, struct vfio_irq_set *irqs); 191*776066acSJohn Levon 192*776066acSJohn Levon /** 193*776066acSJohn Levon * @region_read 194*776066acSJohn Levon * 195*776066acSJohn Levon * Read @size bytes from the region @nr at offset @off into the buffer 196*776066acSJohn Levon * @data. 197*776066acSJohn Levon */ 198*776066acSJohn Levon int (*region_read)(VFIODevice *vdev, uint8_t nr, off_t off, uint32_t size, 199*776066acSJohn Levon void *data); 200*776066acSJohn Levon 201*776066acSJohn Levon /** 202*776066acSJohn Levon * @region_write 203*776066acSJohn Levon * 204*776066acSJohn Levon * Write @size bytes to the region @nr at offset @off from the buffer 205*776066acSJohn Levon * @data. 206*776066acSJohn Levon */ 207*776066acSJohn Levon int (*region_write)(VFIODevice *vdev, uint8_t nr, off_t off, uint32_t size, 208*776066acSJohn Levon void *data); 20938bf025dSJohn Levon }; 21038bf025dSJohn Levon 211a901682fSJohn Levon void vfio_device_prepare(VFIODevice *vbasedev, VFIOContainerBase *bcontainer, 212a901682fSJohn Levon struct vfio_device_info *info); 213a901682fSJohn Levon 214d60fb709SJohn Levon void vfio_device_unprepare(VFIODevice *vbasedev); 215d60fb709SJohn Levon 216e218ccf0SCédric Le Goater int vfio_device_get_region_info(VFIODevice *vbasedev, int index, 21746900226SAlex Williamson struct vfio_region_info **info); 218e218ccf0SCédric Le Goater int vfio_device_get_region_info_type(VFIODevice *vbasedev, uint32_t type, 219e61a424fSAlex Williamson uint32_t subtype, struct vfio_region_info **info); 220e218ccf0SCédric Le Goater bool vfio_device_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type); 2215321e623SJohn Levon 2225321e623SJohn Levon int vfio_device_get_irq_info(VFIODevice *vbasedev, int index, 2235321e623SJohn Levon struct vfio_irq_info *info); 22446900226SAlex Williamson #endif 225318f67ceSAlexey Kardashevskiy 226da3e04b2SZhenzhong Duan /* Returns 0 on success, or a negative errno. */ 227c6c6cf91SZhenzhong Duan bool vfio_device_get_name(VFIODevice *vbasedev, Error **errp); 228da3e04b2SZhenzhong Duan void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp); 2296106a329SZhenzhong Duan void vfio_device_init(VFIODevice *vbasedev, int type, VFIODeviceOps *ops, 2306106a329SZhenzhong Duan DeviceState *dev, bool ram_discard); 231d441e05eSZhenzhong Duan int vfio_device_get_aw_bits(VFIODevice *vdev); 232175de524SMarkus Armbruster #endif /* HW_VFIO_VFIO_COMMON_H */ 233