History

Merge tag 'for-linus-iommufd' of git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd

Pull iommufd updates from Jason Gunthorpe: "Two significant new items: - Allow reporting IOMMU HW events to userspace when the events are clearly linked to a device. This is linked to the VIOMMU object and is intended to be used by a VMM to forward HW events to the virtual machine as part of emulating a vIOMMU. ARM SMMUv3 is the first driver to use this mechanism. Like the existing fault events the data is delivered through a simple FD returning event records on read(). - PASID support in VFIO. The "Process Address Space ID" is a PCI feature that allows the device to tag all PCI DMA operations with an ID. The IOMMU will then use the ID to select a unique translation for those DMAs. This is part of Intel's vIOMMU support as VT-D HW requires the hypervisor to manage each PASID entry. The support is generic so any VFIO user could attach any translation to a PASID, and the support should work on ARM SMMUv3 as well. AMD requires additional driver work. Some minor updates, along with fixes: - Prevent using nested parents with fault's, no driver support today - Put a single "cookie_type" value in the iommu_domain to indicate what owns the various opaque owner fields" * tag 'for-linus-iommufd' of git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd: (49 commits) iommufd: Test attach before detaching pasid iommufd: Fix iommu_vevent_header tables markup iommu: Convert unreachable() to BUG() iommufd: Balance veventq->num_events inc/dec iommufd: Initialize the flags of vevent in iommufd_viommu_report_event() iommufd/selftest: Add coverage for reporting max_pasid_log2 via IOMMU_HW_INFO iommufd: Extend IOMMU_GET_HW_INFO to report PASID capability vfio: VFIO_DEVICE_[AT|DE]TACH_IOMMUFD_PT support pasid vfio-iommufd: Support pasid [at|de]tach for physical VFIO devices ida: Add ida_find_first_range() iommufd/selftest: Add coverage for iommufd pasid attach/detach iommufd/selftest: Add test ops to test pasid attach/detach iommufd/selftest: Add a helper to get test device iommufd/selftest: Add set_dev_pasid in mock iommu iommufd: Allow allocating PASID-compatible domain iommu/vt-d: Add IOMMU_HWPT_ALLOC_PASID support iommufd: Enforce PASID-compatible domain for RID iommufd: Support pasid attach/replace iommufd: Enforce PASID-compatible domain in PASID path iommufd/device: Add pasid_attach array to track per-PASID attach ...

Linus Torvalds committed 1 year ago

Commit 48552152 parents 792b830 7be11d339 files · +3147 −829Browse files

Showing the changes to include/uapi (2 of 39 files). Show all

Unified · Split

2 files
  1. include/uapi/linux/iommufd.h +128 −1
  2. include/uapi/linux/vfio.h +19 −10
include/uapi/linux/iommufd.h+128−1
@@ -55,6 +55,7 @@ enum { · 54 unmodified lines
5555 IOMMUFD_CMD_VIOMMU_ALLOC = 0x90,
5656 IOMMUFD_CMD_VDEVICE_ALLOC = 0x91,
5757 IOMMUFD_CMD_IOAS_CHANGE_PROCESS = 0x92,
58+ IOMMUFD_CMD_VEVENTQ_ALLOC = 0x93,
5859 };
5960
6061 /**
@@ -392,6 +393,9 @@ struct iommu_vfio_ioas { · 331 unmodified lines
392393 * Any domain attached to the non-PASID part of the
393394 * device must also be flagged, otherwise attaching a
394395 * PASID will blocked.
396+ * For the user that wants to attach PASID, ioas is
397+ * not recommended for both the non-PASID part
398+ * and PASID part of the device.
395399 * If IOMMU does not support PASID it will return
396400 * error (-EOPNOTSUPP).
397401 */
@@ -608,9 +612,17 @@ enum iommu_hw_info_type { · 210 unmodified lines
608612 * IOMMU_HWPT_GET_DIRTY_BITMAP
609613 * IOMMU_HWPT_SET_DIRTY_TRACKING
610614 *
615+ * @IOMMU_HW_CAP_PCI_PASID_EXEC: Execute Permission Supported, user ignores it
616+ * when the struct
617+ * iommu_hw_info::out_max_pasid_log2 is zero.
618+ * @IOMMU_HW_CAP_PCI_PASID_PRIV: Privileged Mode Supported, user ignores it
619+ * when the struct
620+ * iommu_hw_info::out_max_pasid_log2 is zero.
611621 */
612622 enum iommufd_hw_capabilities {
613623 IOMMU_HW_CAP_DIRTY_TRACKING = 1 << 0,
624+ IOMMU_HW_CAP_PCI_PASID_EXEC = 1 << 1,
625+ IOMMU_HW_CAP_PCI_PASID_PRIV = 1 << 2,
614626 };
615627
616628 /**
@@ -626,6 +638,9 @@ enum iommufd_hw_capabilities { · 9 unmodified lines
626638 * iommu_hw_info_type.
627639 * @out_capabilities: Output the generic iommu capability info type as defined
628640 * in the enum iommu_hw_capabilities.
641+ * @out_max_pasid_log2: Output the width of PASIDs. 0 means no PASID support.
642+ * PCI devices turn to out_capabilities to check if the
643+ * specific capabilities is supported or not.
629644 * @__reserved: Must be 0
630645 *
631646 * Query an iommu type specific hardware information data from an iommu behind
@@ -649,7 +664,8 @@ struct iommu_hw_info { · 17 unmodified lines
649664 __u32 data_len;
650665 __aligned_u64 data_uptr;
651666 __u32 out_data_type;
652− __u32 __reserved;
667+ __u8 out_max_pasid_log2;
668+ __u8 __reserved[3];
653669 __aligned_u64 out_capabilities;
654670 };
655671 #define IOMMU_GET_HW_INFO _IO(IOMMUFD_TYPE, IOMMUFD_CMD_GET_HW_INFO)
@@ -1014,4 +1030,115 @@ struct iommu_ioas_change_process { · 358 unmodified lines
10141030 #define IOMMU_IOAS_CHANGE_PROCESS \
10151031 _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_CHANGE_PROCESS)
10161032
1033+/**
1034+ * enum iommu_veventq_flag - flag for struct iommufd_vevent_header
1035+ * @IOMMU_VEVENTQ_FLAG_LOST_EVENTS: vEVENTQ has lost vEVENTs
1036+ */
1037+enum iommu_veventq_flag {
1038+ IOMMU_VEVENTQ_FLAG_LOST_EVENTS = (1U << 0),
1039+};
1040+
1041+/**
1042+ * struct iommufd_vevent_header - Virtual Event Header for a vEVENTQ Status
1043+ * @flags: Combination of enum iommu_veventq_flag
1044+ * @sequence: The sequence index of a vEVENT in the vEVENTQ, with a range of
1045+ * [0, INT_MAX] where the following index of INT_MAX is 0
1046+ *
1047+ * Each iommufd_vevent_header reports a sequence index of the following vEVENT:
1048+ *
1049+ * +----------------------+-------+----------------------+-------+---+-------+
1050+ * | header0 {sequence=0} | data0 | header1 {sequence=1} | data1 |...| dataN |
1051+ * +----------------------+-------+----------------------+-------+---+-------+
1052+ *
1053+ * And this sequence index is expected to be monotonic to the sequence index of
1054+ * the previous vEVENT. If two adjacent sequence indexes has a delta larger than
1055+ * 1, it means that delta - 1 number of vEVENTs has lost, e.g. two lost vEVENTs:
1056+ *
1057+ * +-----+----------------------+-------+----------------------+-------+-----+
1058+ * | ... | header3 {sequence=3} | data3 | header6 {sequence=6} | data6 | ... |
1059+ * +-----+----------------------+-------+----------------------+-------+-----+
1060+ *
1061+ * If a vEVENT lost at the tail of the vEVENTQ and there is no following vEVENT
1062+ * providing the next sequence index, an IOMMU_VEVENTQ_FLAG_LOST_EVENTS header
1063+ * would be added to the tail, and no data would follow this header:
1064+ *
1065+ * +--+----------------------+-------+-----------------------------------------+
1066+ * |..| header3 {sequence=3} | data3 | header4 {flags=LOST_EVENTS, sequence=4} |
1067+ * +--+----------------------+-------+-----------------------------------------+
1068+ */
1069+struct iommufd_vevent_header {
1070+ __u32 flags;
1071+ __u32 sequence;
1072+};
1073+
1074+/**
1075+ * enum iommu_veventq_type - Virtual Event Queue Type
1076+ * @IOMMU_VEVENTQ_TYPE_DEFAULT: Reserved for future use
1077+ * @IOMMU_VEVENTQ_TYPE_ARM_SMMUV3: ARM SMMUv3 Virtual Event Queue
1078+ */
1079+enum iommu_veventq_type {
1080+ IOMMU_VEVENTQ_TYPE_DEFAULT = 0,
1081+ IOMMU_VEVENTQ_TYPE_ARM_SMMUV3 = 1,
1082+};
1083+
1084+/**
1085+ * struct iommu_vevent_arm_smmuv3 - ARM SMMUv3 Virtual Event
1086+ * (IOMMU_VEVENTQ_TYPE_ARM_SMMUV3)
1087+ * @evt: 256-bit ARM SMMUv3 Event record, little-endian.
1088+ * Reported event records: (Refer to "7.3 Event records" in SMMUv3 HW Spec)
1089+ * - 0x04 C_BAD_STE
1090+ * - 0x06 F_STREAM_DISABLED
1091+ * - 0x08 C_BAD_SUBSTREAMID
1092+ * - 0x0a C_BAD_CD
1093+ * - 0x10 F_TRANSLATION
1094+ * - 0x11 F_ADDR_SIZE
1095+ * - 0x12 F_ACCESS
1096+ * - 0x13 F_PERMISSION
1097+ *
1098+ * StreamID field reports a virtual device ID. To receive a virtual event for a
1099+ * device, a vDEVICE must be allocated via IOMMU_VDEVICE_ALLOC.
1100+ */
1101+struct iommu_vevent_arm_smmuv3 {
1102+ __aligned_le64 evt[4];
1103+};
1104+
1105+/**
1106+ * struct iommu_veventq_alloc - ioctl(IOMMU_VEVENTQ_ALLOC)
1107+ * @size: sizeof(struct iommu_veventq_alloc)
1108+ * @flags: Must be 0
1109+ * @viommu_id: virtual IOMMU ID to associate the vEVENTQ with
1110+ * @type: Type of the vEVENTQ. Must be defined in enum iommu_veventq_type
1111+ * @veventq_depth: Maximum number of events in the vEVENTQ
1112+ * @out_veventq_id: The ID of the new vEVENTQ
1113+ * @out_veventq_fd: The fd of the new vEVENTQ. User space must close the
1114+ * successfully returned fd after using it
1115+ * @__reserved: Must be 0
1116+ *
1117+ * Explicitly allocate a virtual event queue interface for a vIOMMU. A vIOMMU
1118+ * can have multiple FDs for different types, but is confined to one per @type.
1119+ * User space should open the @out_veventq_fd to read vEVENTs out of a vEVENTQ,
1120+ * if there are vEVENTs available. A vEVENTQ will lose events due to overflow,
1121+ * if the number of the vEVENTs hits @veventq_depth.
1122+ *
1123+ * Each vEVENT in a vEVENTQ encloses a struct iommufd_vevent_header followed by
1124+ * a type-specific data structure, in a normal case:
1125+ *
1126+ * +-+---------+-------+---------+-------+-----+---------+-------+-+
1127+ * | | header0 | data0 | header1 | data1 | ... | headerN | dataN | |
1128+ * +-+---------+-------+---------+-------+-----+---------+-------+-+
1129+ *
1130+ * unless a tailing IOMMU_VEVENTQ_FLAG_LOST_EVENTS header is logged (refer to
1131+ * struct iommufd_vevent_header).
1132+ */
1133+struct iommu_veventq_alloc {
1134+ __u32 size;
1135+ __u32 flags;
1136+ __u32 viommu_id;
1137+ __u32 type;
1138+ __u32 veventq_depth;
1139+ __u32 out_veventq_id;
1140+ __u32 out_veventq_fd;
1141+ __u32 __reserved;
1142+};
1143+#define IOMMU_VEVENTQ_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VEVENTQ_ALLOC)
10171144 #endif
include/uapi/linux/vfio.h+19−10
@@ -932,29 +932,34 @@ struct vfio_device_bind_iommufd { · 931 unmodified lines
932932 * VFIO_DEVICE_ATTACH_IOMMUFD_PT - _IOW(VFIO_TYPE, VFIO_BASE + 19,
933933 * struct vfio_device_attach_iommufd_pt)
934934 * @argsz: User filled size of this data.
935− * @flags: Must be 0.
935+ * @flags: Flags for attach.
936936 * @pt_id: Input the target id which can represent an ioas or a hwpt
937937 * allocated via iommufd subsystem.
938938 * Output the input ioas id or the attached hwpt id which could
939939 * be the specified hwpt itself or a hwpt automatically created
940940 * for the specified ioas by kernel during the attachment.
941+ * @pasid: The pasid to be attached, only meaningful when
942+ * VFIO_DEVICE_ATTACH_PASID is set in @flags
941943 *
942944 * Associate the device with an address space within the bound iommufd.
943945 * Undo by VFIO_DEVICE_DETACH_IOMMUFD_PT or device fd close. This is only
944946 * allowed on cdev fds.
945947 *
946− * If a vfio device is currently attached to a valid hw_pagetable, without doing
947− * a VFIO_DEVICE_DETACH_IOMMUFD_PT, a second VFIO_DEVICE_ATTACH_IOMMUFD_PT ioctl
948− * passing in another hw_pagetable (hwpt) id is allowed. This action, also known
949− * as a hw_pagetable replacement, will replace the device's currently attached
950− * hw_pagetable with a new hw_pagetable corresponding to the given pt_id.
948+ * If a vfio device or a pasid of this device is currently attached to a valid
949+ * hw_pagetable (hwpt), without doing a VFIO_DEVICE_DETACH_IOMMUFD_PT, a second
950+ * VFIO_DEVICE_ATTACH_IOMMUFD_PT ioctl passing in another hwpt id is allowed.
951+ * This action, also known as a hw_pagetable replacement, will replace the
952+ * currently attached hwpt of the device or the pasid of this device with a new
953+ * hwpt corresponding to the given pt_id.
951954 *
952955 * Return: 0 on success, -errno on failure.
953956 */
954957 struct vfio_device_attach_iommufd_pt {
955958 __u32 argsz;
956959 __u32 flags;
960+#define VFIO_DEVICE_ATTACH_PASID (1 << 0)
957961 __u32 pt_id;
962+ __u32 pasid;
958963 };
959964
960965 #define VFIO_DEVICE_ATTACH_IOMMUFD_PT _IO(VFIO_TYPE, VFIO_BASE + 19)
@@ -963,17 +968,21 @@ struct vfio_device_attach_iommufd_pt { · 2 unmodified lines
963968 * VFIO_DEVICE_DETACH_IOMMUFD_PT - _IOW(VFIO_TYPE, VFIO_BASE + 20,
964969 * struct vfio_device_detach_iommufd_pt)
965970 * @argsz: User filled size of this data.
966− * @flags: Must be 0.
971+ * @flags: Flags for detach.
972+ * @pasid: The pasid to be detached, only meaningful when
973+ * VFIO_DEVICE_DETACH_PASID is set in @flags
967974 *
968− * Remove the association of the device and its current associated address
969− * space. After it, the device should be in a blocking DMA state. This is only
970− * allowed on cdev fds.
975+ * Remove the association of the device or a pasid of the device and its current
976+ * associated address space. After it, the device or the pasid should be in a
977+ * blocking DMA state. This is only allowed on cdev fds.
971978 *
972979 * Return: 0 on success, -errno on failure.
973980 */
974981 struct vfio_device_detach_iommufd_pt {
975982 __u32 argsz;
976983 __u32 flags;
984+#define VFIO_DEVICE_DETACH_PASID (1 << 0)
985+ __u32 pasid;
977986 };
978987
979988 #define VFIO_DEVICE_DETACH_IOMMUFD_PT _IO(VFIO_TYPE, VFIO_BASE + 20)