| 1 | /* |
| 2 | * Host IOMMU device abstract declaration |
| 3 | * |
| 4 | * Copyright (C) 2024 Intel Corporation. |
| 5 | * |
| 6 | * Authors: Zhenzhong Duan <zhenzhong.duan@intel.com> |
| 7 | * |
| 8 | * This work is licensed under the terms of the GNU GPL, version 2. See |
| 9 | * the COPYING file in the top-level directory. |
| 10 | */ |
| 11 | |
| 12 | #ifndef HOST_IOMMU_DEVICE_H |
| 13 | #define HOST_IOMMU_DEVICE_H |
| 14 | |
| 15 | #include "qom/object.h" |
| 16 | #include "qapi/error.h" |
| 17 | #ifdef CONFIG_LINUX |
| 18 | #include "linux/iommufd.h" |
| 19 | |
| 20 | typedef union VendorCaps { |
| 21 | struct iommu_hw_info_vtd vtd; |
| 22 | struct iommu_hw_info_arm_smmuv3 smmuv3; |
| 23 | } VendorCaps; |
| 24 | |
| 25 | /** |
| 26 | * struct HostIOMMUDeviceCaps - Define host IOMMU device capabilities. |
| 27 | * |
| 28 | * @type: host platform IOMMU type. |
| 29 | * |
| 30 | * @hw_caps: host platform IOMMU capabilities (e.g. on IOMMUFD this represents |
| 31 | * the @out_capabilities value returned from IOMMU_GET_HW_INFO ioctl) |
| 32 | * |
| 33 | * @max_pasid_log2: width of PASIDs supported by host IOMMU device |
| 34 | * |
| 35 | * @vendor_caps: host platform IOMMU vendor specific capabilities (e.g. on |
| 36 | * IOMMUFD this represents a user-space buffer filled by kernel |
| 37 | * with host IOMMU @type specific hardware information data) |
| 38 | */ |
| 39 | typedef struct HostIOMMUDeviceCaps { |
| 40 | uint32_t type; |
| 41 | uint64_t hw_caps; |
| 42 | uint8_t max_pasid_log2; |
| 43 | VendorCaps vendor_caps; |
| 44 | } HostIOMMUDeviceCaps; |
| 45 | #endif |
| 46 | |
| 47 | #define TYPE_HOST_IOMMU_DEVICE "host-iommu-device" |
| 48 | OBJECT_DECLARE_TYPE(HostIOMMUDevice, HostIOMMUDeviceClass, HOST_IOMMU_DEVICE) |
| 49 | |
| 50 | struct HostIOMMUDevice { |
| 51 | Object parent_obj; |
| 52 | |
| 53 | char *name; |
| 54 | void *agent; /* pointer to agent device, ie. VFIO or VDPA device */ |
| 55 | PCIBus *aliased_bus; |
| 56 | int aliased_devfn; |
| 57 | #ifdef CONFIG_LINUX |
| 58 | HostIOMMUDeviceCaps caps; |
| 59 | #endif |
| 60 | }; |
| 61 | |
| 62 | typedef struct PasidInfo { |
| 63 | bool exec_perm; |
| 64 | bool priv_mod; |
| 65 | uint8_t max_pasid_log2; |
| 66 | } PasidInfo; |
| 67 | |
| 68 | /** |
| 69 | * struct HostIOMMUDeviceClass - The base class for all host IOMMU devices. |
| 70 | * |
| 71 | * Different types of host devices (e.g., VFIO or VDPA device) or devices |
| 72 | * with different backend (e.g., VFIO legacy container or IOMMUFD backend) |
| 73 | * will have different implementations of the HostIOMMUDeviceClass. |
| 74 | */ |
| 75 | struct HostIOMMUDeviceClass { |
| 76 | ObjectClass parent_class; |
| 77 | |
| 78 | /** |
| 79 | * @realize: initialize host IOMMU device instance further. |
| 80 | * |
| 81 | * Mandatory callback. |
| 82 | * |
| 83 | * @hiod: pointer to a host IOMMU device instance. |
| 84 | * |
| 85 | * @opaque: pointer to agent device of this host IOMMU device, |
| 86 | * e.g., VFIO base device or VDPA device. |
| 87 | * |
| 88 | * @errp: pass an Error out when realize fails. |
| 89 | * |
| 90 | * Returns: true on success, false on failure. |
| 91 | */ |
| 92 | bool (*realize)(HostIOMMUDevice *hiod, void *opaque, Error **errp); |
| 93 | /** |
| 94 | * @get_cap: check if a host IOMMU device capability is supported. |
| 95 | * |
| 96 | * Optional callback, if not implemented, hint not supporting query |
| 97 | * of @cap. |
| 98 | * |
| 99 | * @hiod: pointer to a host IOMMU device instance. |
| 100 | * |
| 101 | * @cap: capability to check. |
| 102 | * |
| 103 | * @errp: pass an Error out when fails to query capability. |
| 104 | * |
| 105 | * Returns: <0 on failure, 0 if a @cap is unsupported, or else |
| 106 | * 1 or some positive value for some special @cap, |
| 107 | * i.e., HOST_IOMMU_DEVICE_CAP_AW_BITS. |
| 108 | */ |
| 109 | int (*get_cap)(HostIOMMUDevice *hiod, int cap, Error **errp); |
| 110 | /** |
| 111 | * @get_iova_ranges: Return the list of usable iova_ranges along with |
| 112 | * @hiod Host IOMMU device |
| 113 | * |
| 114 | * @hiod: handle to the host IOMMU device |
| 115 | */ |
| 116 | GList* (*get_iova_ranges)(HostIOMMUDevice *hiod); |
| 117 | /** |
| 118 | * |
| 119 | * @get_page_size_mask: Return the page size mask supported along this |
| 120 | * @hiod Host IOMMU device |
| 121 | * |
| 122 | * @hiod: handle to the host IOMMU device |
| 123 | */ |
| 124 | uint64_t (*get_page_size_mask)(HostIOMMUDevice *hiod); |
| 125 | /** |
| 126 | * @get_pasid_info: Return the PASID information associated with the |
| 127 | * @hiod Host IOMMU device. |
| 128 | * |
| 129 | * @hiod: handle to the host IOMMU device |
| 130 | * |
| 131 | * @pasid_info: If success, returns the PASID related information. |
| 132 | * |
| 133 | * Returns: true on success, false on failure. |
| 134 | */ |
| 135 | bool (*get_pasid_info)(HostIOMMUDevice *hiod, PasidInfo *pasid_info); |
| 136 | /** |
| 137 | * @support_ats: Returns true if ATS can be used by the device, |
| 138 | * false if the host IOMMU reports it is unavailable. |
| 139 | * |
| 140 | * @hiod: handle to the host IOMMU device |
| 141 | * |
| 142 | * Returns: true if ATS is supported, false otherwise |
| 143 | */ |
| 144 | bool (*support_ats)(HostIOMMUDevice *hiod); |
| 145 | }; |
| 146 | |
| 147 | /* |
| 148 | * Host IOMMU device capability list. |
| 149 | */ |
| 150 | #define HOST_IOMMU_DEVICE_CAP_IOMMU_TYPE 0 |
| 151 | #define HOST_IOMMU_DEVICE_CAP_AW_BITS 1 |
| 152 | |
| 153 | #define HOST_IOMMU_DEVICE_CAP_AW_BITS_MAX 64 |
| 154 | #endif |