[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <ZQyuIQbyVk9p8C8o@Asurada-Nvidia>
Date: Thu, 21 Sep 2023 13:58:19 -0700
From: Nicolin Chen <nicolinc@...dia.com>
To: Baolu Lu <baolu.lu@...ux.intel.com>
CC: Yi Liu <yi.l.liu@...el.com>, <joro@...tes.org>,
<alex.williamson@...hat.com>, <jgg@...dia.com>,
<kevin.tian@...el.com>, <robin.murphy@....com>,
<cohuck@...hat.com>, <eric.auger@...hat.com>,
<kvm@...r.kernel.org>, <mjrosato@...ux.ibm.com>,
<chao.p.peng@...ux.intel.com>, <yi.y.sun@...ux.intel.com>,
<peterx@...hat.com>, <jasowang@...hat.com>,
<shameerali.kolothum.thodi@...wei.com>, <lulu@...hat.com>,
<suravee.suthikulpanit@....com>, <iommu@...ts.linux.dev>,
<linux-kernel@...r.kernel.org>, <linux-kselftest@...r.kernel.org>,
<zhenzhong.duan@...el.com>, <joao.m.martins@...cle.com>
Subject: Re: [PATCH v4 01/17] iommu: Add hwpt_type with user_data for
domain_alloc_user op
On Thu, Sep 21, 2023 at 08:10:58PM +0800, Baolu Lu wrote:
> On 2023/9/21 15:51, Yi Liu wrote:
> > +/**
> > + * iommu_copy_user_data - Copy iommu driver specific user space data
> > + * @dst_data: Pointer to an iommu driver specific user data that is defined in
> > + * include/uapi/linux/iommufd.h
> > + * @src_data: Pointer to a struct iommu_user_data for user space data info
> > + * @data_len: Length of current user data structure, i.e. sizeof(struct _dst)
> > + * @min_len: Initial length of user data structure for backward compatibility.
> > + * This should be offsetofend using the last member in the user data
> > + * struct that was initially added to include/uapi/linux/iommufd.h
> > + */
> > +static inline int iommu_copy_user_data(void *dst_data,
> > + const struct iommu_user_data *src_data,
> > + size_t data_len, size_t min_len)
> > +{
> > + if (WARN_ON(!dst_data || !src_data))
> > + return -EINVAL;
> > + if (src_data->len < min_len || data_len < src_data->len)
> > + return -EINVAL;
> > + return copy_struct_from_user(dst_data, data_len,
> > + src_data->uptr, src_data->len);
> > +}
>
> I am not sure that I understand the purpose of "min_len" correctly. It
> seems like it would always be equal to data_len?
>
> Or, it means the minimal data length that the iommu driver requires?
Hmm, I thought I had made it quite clear with the kdoc that it's
the "initial" length (min_len) v.s. "current" length (data_len),
i.e. min_len was set when the structure was introduced and would
never change while data_len can grow if the structure introduces
a new member. E.g. after this series struct iommu_hwpt_alloc has
a min_len fixed to offsetofend(..., __reserved) but its data_len
is actually increased to offsetofend(..., data_uptr).
Perhaps we could put all min_len defines in uAPI header, like:
include/uapi/linux/gfs2_ondisk.h:442:#define LH_V1_SIZE (offsetofend(struct gfs2_log_header, lh_hash))
In this way, drivers won't need to deal with that nor have risks
of breaking ABI by changing a min_len.
Also, if we go a bit further to ease the drivers, we could do:
========================================================================================
diff --git a/drivers/iommu/iommufd/iommufd_test.h b/drivers/iommu/iommufd/iommufd_test.h
index 65a363f5e81e..13234e67409c 100644
--- a/drivers/iommu/iommufd/iommufd_test.h
+++ b/drivers/iommu/iommufd/iommufd_test.h
@@ -147,6 +147,9 @@ struct iommu_hwpt_selftest {
__u32 iotlb;
};
+#define iommu_hwpt_selftest_min_len \
+ (offsetofend(struct iommu_hwpt_selftest, iotlb))
+
/**
* struct iommu_hwpt_invalidate_selftest
*
diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index 117776d236dc..2cc3a8a3355b 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -263,8 +263,8 @@ mock_domain_alloc_user(struct device *dev, u32 flags,
}
if (user_data) {
- int rc = iommu_copy_user_data(&data, user_data,
- data_len, min_len);
+ int rc = iommu_copy_user_data2(iommu_hwpt_selftest, &data,
+ user_data);
if (rc)
return ERR_PTR(rc);
user_cfg = &data;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index fb2febe7b8d8..db82803b026f 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -282,6 +282,10 @@ static inline int iommu_copy_user_data(void *dst_data,
src_data->uptr, src_data->len);
}
+#define iommu_copy_user_data2(dst_struct, dst, src) \
+ iommu_copy_user_data(dst, src, sizeof(struct dst_struct), \
+ dst_struct##_min_len)
+
/**
* iommu_copy_user_data_from_array - Copy iommu driver specific user space data
* from an iommu_user_data_array input
========================================================================================
Surely, the end product of the test code above can do:
iommu_copy_user_data = > __iommu_copy_user_data
iommu_copy_user_data2 = > iommu_copy_user_data
Thanks
Nicolin
Powered by blists - more mailing lists