From: Jacob Pan <jacob.jun.pan@linux.intel.com> To: iommu@lists.linux-foundation.org, LKML <linux-kernel@vger.kernel.org>, Joerg Roedel <joro@8bytes.org>, Alex Williamson <alex.williamson@redhat.com> Cc: "Tian, Kevin" <kevin.tian@intel.com>, Raj Ashok <ashok.raj@intel.com>, Jonathan Corbet <corbet@lwn.net>, Jean-Philippe Brucker <jean-philippe@linaro.com>, Christoph Hellwig <hch@infradead.org>, David Woodhouse <dwmw2@infradead.org> Subject: [PATCH v3 5/5] iommu/uapi: Support both kernel and user unbind guest PASID Date: Tue, 23 Jun 2020 10:03:57 -0700 [thread overview] Message-ID: <1592931837-58223-6-git-send-email-jacob.jun.pan@linux.intel.com> (raw) In-Reply-To: <1592931837-58223-1-git-send-email-jacob.jun.pan@linux.intel.com> Guest SVA unbind data can come from either kernel and user space, if a user pointer is passed in, IOMMU driver must copy from data from user. If the unbind data is assembled in kernel, data can be trusted and directly used. This patch creates a wrapper for unbind gpasid such that user pointer can be parsed and sanitized before calling into the kernel unbind function. Common user data copy code also consolidated. Signed-off-by: Liu Yi L <yi.l.liu@intel.com> Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com> --- drivers/iommu/iommu.c | 70 ++++++++++++++++++++++++++++++++++++++------------- include/linux/iommu.h | 13 ++++++++-- 2 files changed, 64 insertions(+), 19 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 4a025c429b41..595527e4c6b7 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2010,19 +2010,15 @@ int iommu_cache_invalidate(struct iommu_domain *domain, struct device *dev, } EXPORT_SYMBOL_GPL(iommu_cache_invalidate); -int iommu_sva_bind_gpasid(struct iommu_domain *domain, struct device *dev, - void __user *udata) -{ - struct iommu_gpasid_bind_data data; +static int iommu_sva_prepare_bind_data(void __user *udata, bool bind, + struct iommu_gpasid_bind_data *data) +{ unsigned long minsz, maxsz; - if (unlikely(!domain->ops->sva_bind_gpasid)) - return -ENODEV; - /* Current kernel data size is the max to be copied from user */ maxsz = sizeof(struct iommu_gpasid_bind_data); - memset((void *)&data, 0, maxsz); + memset((void *)data, 0, maxsz); /* * No new spaces can be added before the variable sized union, the @@ -2031,11 +2027,11 @@ int iommu_sva_bind_gpasid(struct iommu_domain *domain, struct device *dev, minsz = offsetof(struct iommu_gpasid_bind_data, vendor); /* Copy minsz from user to get flags and argsz */ - if (copy_from_user(&data, udata, minsz)) + if (copy_from_user(data, udata, minsz)) return -EFAULT; /* Fields before variable size union is mandatory */ - if (data.argsz < minsz) + if (data->argsz < minsz) return -EINVAL; /* * User might be using a newer UAPI header, we shall let IOMMU vendor @@ -2043,26 +2039,66 @@ int iommu_sva_bind_gpasid(struct iommu_domain *domain, struct device *dev, * can be vendor specific, larger argsz could be the result of extension * for one vendor but it should not affect another vendor. */ - if (data.argsz > maxsz) - data.argsz = maxsz; + if (data->argsz > maxsz) + data->argsz = maxsz; + + /* + * For unbind, we don't need any extra data, host PASID is included in + * the minsz and that is all we need. + */ + if (!bind) + return 0; /* Copy the remaining user data _after_ minsz */ - if (copy_from_user((void *)&data + minsz, udata + minsz, - data.argsz - minsz)) + if (copy_from_user((void *)data + minsz, udata + minsz, + data->argsz - minsz)) return -EFAULT; + return 0; +} + +int iommu_sva_bind_gpasid(struct iommu_domain *domain, struct device *dev, + void __user *udata) +{ + + struct iommu_gpasid_bind_data data; + int ret; + + if (unlikely(!domain->ops->sva_bind_gpasid)) + return -ENODEV; + + ret = iommu_sva_prepare_bind_data(udata, true, &data); + if (ret) + return ret; return domain->ops->sva_bind_gpasid(domain, dev, &data); } EXPORT_SYMBOL_GPL(iommu_sva_bind_gpasid); -int iommu_sva_unbind_gpasid(struct iommu_domain *domain, struct device *dev, - ioasid_t pasid) +int __iommu_sva_unbind_gpasid(struct iommu_domain *domain, struct device *dev, + struct iommu_gpasid_bind_data *data) { if (unlikely(!domain->ops->sva_unbind_gpasid)) return -ENODEV; - return domain->ops->sva_unbind_gpasid(dev, pasid); + return domain->ops->sva_unbind_gpasid(dev, data->hpasid); +} +EXPORT_SYMBOL_GPL(__iommu_sva_unbind_gpasid); + +int iommu_sva_unbind_gpasid(struct iommu_domain *domain, struct device *dev, + void __user *udata) +{ + struct iommu_gpasid_bind_data data; + int ret; + + if (unlikely(!domain->ops->sva_bind_gpasid)) + return -ENODEV; + + ret = iommu_sva_prepare_bind_data(udata, false, &data); + if (ret) + return ret; + + return __iommu_sva_unbind_gpasid(domain, dev, &data); } EXPORT_SYMBOL_GPL(iommu_sva_unbind_gpasid); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index a688fea42ae5..2567c33dc4e8 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -437,7 +437,9 @@ extern int iommu_cache_invalidate(struct iommu_domain *domain, extern int iommu_sva_bind_gpasid(struct iommu_domain *domain, struct device *dev, void __user *udata); extern int iommu_sva_unbind_gpasid(struct iommu_domain *domain, - struct device *dev, ioasid_t pasid); + struct device *dev, void __user *udata); +extern int __iommu_sva_unbind_gpasid(struct iommu_domain *domain, + struct device *dev, struct iommu_gpasid_bind_data *data); extern struct iommu_domain *iommu_get_domain_for_dev(struct device *dev); extern struct iommu_domain *iommu_get_dma_domain(struct device *dev); extern int iommu_map(struct iommu_domain *domain, unsigned long iova, @@ -1069,7 +1071,14 @@ static inline int iommu_sva_bind_gpasid(struct iommu_domain *domain, } static inline int iommu_sva_unbind_gpasid(struct iommu_domain *domain, - struct device *dev, int pasid) + struct device *dev, void __user *udata) +{ + return -ENODEV; +} + +static inline int __iommu_sva_unbind_gpasid(struct iommu_domain *domain, + struct device *dev, + struct iommu_gpasid_bind_data *data) { return -ENODEV; } -- 2.7.4 _______________________________________________ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
next prev parent reply other threads:[~2020-06-23 16:57 UTC|newest] Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-06-23 17:03 [PATCH v3 0/5] IOMMU user API enhancement Jacob Pan 2020-06-23 17:03 ` [PATCH v3 1/5] docs: IOMMU user API Jacob Pan 2020-06-26 22:19 ` Alex Williamson 2020-06-29 23:05 ` Jacob Pan 2020-06-30 2:52 ` Tian, Kevin 2020-06-30 17:39 ` Jacob Pan 2020-07-07 21:40 ` Alex Williamson 2020-07-08 15:21 ` Jacob Pan 2020-06-23 17:03 ` [PATCH v3 2/5] iommu/uapi: Add argsz for user filled data Jacob Pan 2020-06-23 17:03 ` [PATCH v3 3/5] iommu/uapi: Use named union for user data Jacob Pan 2020-06-24 6:29 ` Lu Baolu 2020-06-24 15:48 ` Jacob Pan 2020-06-23 17:03 ` [PATCH v3 4/5] iommu/uapi: Handle data and argsz filled by users Jacob Pan 2020-06-24 6:54 ` Lu Baolu 2020-06-24 17:07 ` Jacob Pan 2020-06-25 7:07 ` Lu Baolu 2020-06-23 17:03 ` Jacob Pan [this message] 2020-06-24 7:55 ` [PATCH v3 5/5] iommu/uapi: Support both kernel and user unbind guest PASID Lu Baolu 2020-06-25 12:59 ` Lu Baolu
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1592931837-58223-6-git-send-email-jacob.jun.pan@linux.intel.com \ --to=jacob.jun.pan@linux.intel.com \ --cc=alex.williamson@redhat.com \ --cc=ashok.raj@intel.com \ --cc=corbet@lwn.net \ --cc=dwmw2@infradead.org \ --cc=hch@infradead.org \ --cc=iommu@lists.linux-foundation.org \ --cc=jean-philippe@linaro.com \ --cc=joro@8bytes.org \ --cc=kevin.tian@intel.com \ --cc=linux-kernel@vger.kernel.org \ --subject='Re: [PATCH v3 5/5] iommu/uapi: Support both kernel and user unbind guest PASID' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).