Skip to content

Commit a9f10ba

Browse files
nicolincjgunthorpe
authored andcommitted
iommufd: Allow an input data_type via iommu_hw_info
The iommu_hw_info can output via the out_data_type field the vendor data type from a driver, but this only allows driver to report one data type. Now, with SMMUv3 having a Tegra241 CMDQV implementation, it has two sets of types and data structs to report. One way to support that is to use the same type field bidirectionally. Reuse the same field by adding an "in_data_type", allowing user space to request for a specific type and to get the corresponding data. For backward compatibility, since the ioctl handler has never checked an input value, add an IOMMU_HW_INFO_FLAG_INPUT_TYPE to switch between the old output-only field and the new bidirectional field. Link: https://patch.msgid.link/r/887378a7167e1786d9d13cde0c36263ed61823d7.1752126748.git.nicolinc@nvidia.com Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Pranjal Shrivastava <praan@google.com> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
1 parent 62622a8 commit a9f10ba

2 files changed

Lines changed: 25 additions & 4 deletions

File tree

drivers/iommu/iommufd/device.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,6 +1499,7 @@ EXPORT_SYMBOL_NS_GPL(iommufd_access_rw, "IOMMUFD");
14991499

15001500
int iommufd_get_hw_info(struct iommufd_ucmd *ucmd)
15011501
{
1502+
const u32 SUPPORTED_FLAGS = IOMMU_HW_INFO_FLAG_INPUT_TYPE;
15021503
struct iommu_hw_info *cmd = ucmd->cmd;
15031504
void __user *user_ptr = u64_to_user_ptr(cmd->data_uptr);
15041505
const struct iommu_ops *ops;
@@ -1508,12 +1509,14 @@ int iommufd_get_hw_info(struct iommufd_ucmd *ucmd)
15081509
void *data;
15091510
int rc;
15101511

1511-
if (cmd->flags || cmd->__reserved[0] || cmd->__reserved[1] ||
1512-
cmd->__reserved[2])
1512+
if (cmd->flags & ~SUPPORTED_FLAGS)
1513+
return -EOPNOTSUPP;
1514+
if (cmd->__reserved[0] || cmd->__reserved[1] || cmd->__reserved[2])
15131515
return -EOPNOTSUPP;
15141516

15151517
/* Clear the type field since drivers don't support a random input */
1516-
cmd->out_data_type = IOMMU_HW_INFO_TYPE_DEFAULT;
1518+
if (!(cmd->flags & IOMMU_HW_INFO_FLAG_INPUT_TYPE))
1519+
cmd->in_data_type = IOMMU_HW_INFO_TYPE_DEFAULT;
15171520

15181521
idev = iommufd_get_device(ucmd, cmd->dev_id);
15191522
if (IS_ERR(idev))

include/uapi/linux/iommufd.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,15 @@ enum iommufd_hw_capabilities {
628628
IOMMU_HW_CAP_PCI_PASID_PRIV = 1 << 2,
629629
};
630630

631+
/**
632+
* enum iommufd_hw_info_flags - Flags for iommu_hw_info
633+
* @IOMMU_HW_INFO_FLAG_INPUT_TYPE: If set, @in_data_type carries an input type
634+
* for user space to request for a specific info
635+
*/
636+
enum iommufd_hw_info_flags {
637+
IOMMU_HW_INFO_FLAG_INPUT_TYPE = 1 << 0,
638+
};
639+
631640
/**
632641
* struct iommu_hw_info - ioctl(IOMMU_GET_HW_INFO)
633642
* @size: sizeof(struct iommu_hw_info)
@@ -637,6 +646,12 @@ enum iommufd_hw_capabilities {
637646
* data that kernel supports
638647
* @data_uptr: User pointer to a user-space buffer used by the kernel to fill
639648
* the iommu type specific hardware information data
649+
* @in_data_type: This shares the same field with @out_data_type, making it be
650+
* a bidirectional field. When IOMMU_HW_INFO_FLAG_INPUT_TYPE is
651+
* set, an input type carried via this @in_data_type field will
652+
* be valid, requesting for the info data to the given type. If
653+
* IOMMU_HW_INFO_FLAG_INPUT_TYPE is unset, any input value will
654+
* be seen as IOMMU_HW_INFO_TYPE_DEFAULT
640655
* @out_data_type: Output the iommu hardware info type as defined in the enum
641656
* iommu_hw_info_type.
642657
* @out_capabilities: Output the generic iommu capability info type as defined
@@ -666,7 +681,10 @@ struct iommu_hw_info {
666681
__u32 dev_id;
667682
__u32 data_len;
668683
__aligned_u64 data_uptr;
669-
__u32 out_data_type;
684+
union {
685+
__u32 in_data_type;
686+
__u32 out_data_type;
687+
};
670688
__u8 out_max_pasid_log2;
671689
__u8 __reserved[3];
672690
__aligned_u64 out_capabilities;

0 commit comments

Comments
 (0)