Introduce a new IOMMUFD_OBJ_VEVENTQ object for vIOMMU Event Queue that provides user space (VMM) another FD to read the vIOMMU Events. Allow a vIOMMU object to allocate vEVENTQs, with a condition that each vIOMMU can only have one single vEVENTQ per type. Add iommufd_veventq_alloc() with iommufd_veventq_ops for the new ioctl.
Showing the changes to include/uapi/linux (1 of 6 files). Show all
Unified · Split
| @@ -55,6 +55,7 @@ enum { · 54 unmodified lines | |||
| 55 | IOMMUFD_CMD_VIOMMU_ALLOC = 0x90, | 55 | IOMMUFD_CMD_VIOMMU_ALLOC = 0x90, |
| 56 | IOMMUFD_CMD_VDEVICE_ALLOC = 0x91, | 56 | IOMMUFD_CMD_VDEVICE_ALLOC = 0x91, |
| 57 | IOMMUFD_CMD_IOAS_CHANGE_PROCESS = 0x92, | 57 | IOMMUFD_CMD_IOAS_CHANGE_PROCESS = 0x92, |
| 58 | IOMMUFD_CMD_VEVENTQ_ALLOC = 0x93, | ||
| 58 | }; | 59 | }; |
| 59 | 60 | ||
| 60 | /** | 61 | /** |
| @@ -1014,4 +1015,85 @@ struct iommu_ioas_change_process { · 953 unmodified lines | |||
| 1014 | #define IOMMU_IOAS_CHANGE_PROCESS \ | 1015 | #define IOMMU_IOAS_CHANGE_PROCESS \ |
| 1015 | _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_CHANGE_PROCESS) | 1016 | _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_CHANGE_PROCESS) |
| 1016 | 1017 | ||
| 1018 | /** | ||
| 1019 | * enum iommu_veventq_flag - flag for struct iommufd_vevent_header | ||
| 1020 | * @IOMMU_VEVENTQ_FLAG_LOST_EVENTS: vEVENTQ has lost vEVENTs | ||
| 1021 | */ | ||
| 1022 | enum iommu_veventq_flag { | ||
| 1023 | IOMMU_VEVENTQ_FLAG_LOST_EVENTS = (1U << 0), | ||
| 1024 | }; | ||
| 1025 | |||
| 1026 | /** | ||
| 1027 | * struct iommufd_vevent_header - Virtual Event Header for a vEVENTQ Status | ||
| 1028 | * @flags: Combination of enum iommu_veventq_flag | ||
| 1029 | * @sequence: The sequence index of a vEVENT in the vEVENTQ, with a range of | ||
| 1030 | * [0, INT_MAX] where the following index of INT_MAX is 0 | ||
| 1031 | * | ||
| 1032 | * Each iommufd_vevent_header reports a sequence index of the following vEVENT: | ||
| 1033 | * ------------------------------------------------------------------------- | ||
| 1034 | * | header0 {sequence=0} | data0 | header1 {sequence=1} | data1 |...| dataN | | ||
| 1035 | * ------------------------------------------------------------------------- | ||
| 1036 | * And this sequence index is expected to be monotonic to the sequence index of | ||
| 1037 | * the previous vEVENT. If two adjacent sequence indexes has a delta larger than | ||
| 1038 | * 1, it means that delta - 1 number of vEVENTs has lost, e.g. two lost vEVENTs: | ||
| 1039 | * ------------------------------------------------------------------------- | ||
| 1040 | * | ... | header3 {sequence=3} | data3 | header6 {sequence=6} | data6 | ... | | ||
| 1041 | * ------------------------------------------------------------------------- | ||
| 1042 | * If a vEVENT lost at the tail of the vEVENTQ and there is no following vEVENT | ||
| 1043 | * providing the next sequence index, an IOMMU_VEVENTQ_FLAG_LOST_EVENTS header | ||
| 1044 | * would be added to the tail, and no data would follow this header: | ||
| 1045 | * --------------------------------------------------------------------------- | ||
| 1046 | * |..| header3 {sequence=3} | data3 | header4 {flags=LOST_EVENTS, sequence=4} | | ||
| 1047 | * --------------------------------------------------------------------------- | ||
| 1048 | */ | ||
| 1049 | struct iommufd_vevent_header { | ||
| 1050 | __u32 flags; | ||
| 1051 | __u32 sequence; | ||
| 1052 | }; | ||
| 1053 | |||
| 1054 | /** | ||
| 1055 | * enum iommu_veventq_type - Virtual Event Queue Type | ||
| 1056 | * @IOMMU_VEVENTQ_TYPE_DEFAULT: Reserved for future use | ||
| 1057 | */ | ||
| 1058 | enum iommu_veventq_type { | ||
| 1059 | IOMMU_VEVENTQ_TYPE_DEFAULT = 0, | ||
| 1060 | }; | ||
| 1061 | |||
| 1062 | /** | ||
| 1063 | * struct iommu_veventq_alloc - ioctl(IOMMU_VEVENTQ_ALLOC) | ||
| 1064 | * @size: sizeof(struct iommu_veventq_alloc) | ||
| 1065 | * @flags: Must be 0 | ||
| 1066 | * @viommu_id: virtual IOMMU ID to associate the vEVENTQ with | ||
| 1067 | * @type: Type of the vEVENTQ. Must be defined in enum iommu_veventq_type | ||
| 1068 | * @veventq_depth: Maximum number of events in the vEVENTQ | ||
| 1069 | * @out_veventq_id: The ID of the new vEVENTQ | ||
| 1070 | * @out_veventq_fd: The fd of the new vEVENTQ. User space must close the | ||
| 1071 | * successfully returned fd after using it | ||
| 1072 | * @__reserved: Must be 0 | ||
| 1073 | * | ||
| 1074 | * Explicitly allocate a virtual event queue interface for a vIOMMU. A vIOMMU | ||
| 1075 | * can have multiple FDs for different types, but is confined to one per @type. | ||
| 1076 | * User space should open the @out_veventq_fd to read vEVENTs out of a vEVENTQ, | ||
| 1077 | * if there are vEVENTs available. A vEVENTQ will lose events due to overflow, | ||
| 1078 | * if the number of the vEVENTs hits @veventq_depth. | ||
| 1079 | * | ||
| 1080 | * Each vEVENT in a vEVENTQ encloses a struct iommufd_vevent_header followed by | ||
| 1081 | * a type-specific data structure, in a normal case: | ||
| 1082 | * ------------------------------------------------------------- | ||
| 1083 | * || header0 | data0 | header1 | data1 | ... | headerN | dataN || | ||
| 1084 | * ------------------------------------------------------------- | ||
| 1085 | * unless a tailing IOMMU_VEVENTQ_FLAG_LOST_EVENTS header is logged (refer to | ||
| 1086 | * struct iommufd_vevent_header). | ||
| 1087 | */ | ||
| 1088 | struct iommu_veventq_alloc { | ||
| 1089 | __u32 size; | ||
| 1090 | __u32 flags; | ||
| 1091 | __u32 viommu_id; | ||
| 1092 | __u32 type; | ||
| 1093 | __u32 veventq_depth; | ||
| 1094 | __u32 out_veventq_id; | ||
| 1095 | __u32 out_veventq_fd; | ||
| 1096 | __u32 __reserved; | ||
| 1097 | }; | ||
| 1098 | #define IOMMU_VEVENTQ_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VEVENTQ_ALLOC) | ||
| 1017 | #endif | 1099 | #endif |