From: Sven Peter <sven@svenpeter.dev> To: iommu@lists.linux-foundation.org Cc: Sven Peter <sven@svenpeter.dev>, Joerg Roedel <joro@8bytes.org>, Will Deacon <will@kernel.org>, Robin Murphy <robin.murphy@arm.com>, Arnd Bergmann <arnd@kernel.org>, Mohamed Mediouni <mohamed.mediouni@caramail.com>, Alexander Graf <graf@amazon.com>, Hector Martin <marcan@marcan.st>, linux-kernel@vger.kernel.org Subject: [RFC PATCH 1/3] iommu: Move IOMMU pagesize check to attach_device Date: Fri, 6 Aug 2021 17:55:21 +0200 [thread overview] Message-ID: <20210806155523.50429-2-sven@svenpeter.dev> (raw) In-Reply-To: <20210806155523.50429-1-sven@svenpeter.dev> The iova allocator is capable of handling any granularity which is a power of two. Remove the much stronger condition that the granularity must be smaller or equal to the CPU page size from a BUG_ON there. Instead, check this condition during __iommu_attach_device and fail gracefully. Signed-off-by: Sven Peter <sven@svenpeter.dev> --- drivers/iommu/iommu.c | 34 +++++++++++++++++++++++++++++++--- drivers/iommu/iova.c | 7 ++++--- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 1de503ddb343..5854a4ef5681 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -78,6 +78,8 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus, unsigned type); static int __iommu_attach_device(struct iommu_domain *domain, struct device *dev); +static void __iommu_detach_device(struct iommu_domain *domain, + struct device *dev); static int __iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group); static void __iommu_detach_group(struct iommu_domain *domain, @@ -1964,6 +1966,18 @@ void iommu_domain_free(struct iommu_domain *domain) } EXPORT_SYMBOL_GPL(iommu_domain_free); +static int iommu_check_page_size(struct iommu_domain *domain) +{ + if (!(domain->type & __IOMMU_DOMAIN_PAGING)) + return 0; + + if ((1 << __ffs(domain->pgsize_bitmap)) > PAGE_SIZE) { + pr_warn("IOMMU page size cannot represent CPU pages.\n"); + return -EFAULT; + } + + return 0; +} static int __iommu_attach_device(struct iommu_domain *domain, struct device *dev) { @@ -1973,9 +1987,23 @@ static int __iommu_attach_device(struct iommu_domain *domain, return -ENODEV; ret = domain->ops->attach_dev(domain, dev); - if (!ret) - trace_attach_device_to_domain(dev); - return ret; + if (ret) + return ret; + + /* + * Check that CPU pages can be represented by the IOVA granularity. + * This has to be done after ops->attach_dev since many IOMMU drivers + * only limit domain->pgsize_bitmap after having attached the first + * device. + */ + ret = iommu_check_page_size(domain); + if (ret) { + __iommu_detach_device(domain, dev); + return ret; + } + + trace_attach_device_to_domain(dev); + return 0; } int iommu_attach_device(struct iommu_domain *domain, struct device *dev) diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index b6cf5f16123b..e0f8adde0f1b 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -50,10 +50,11 @@ init_iova_domain(struct iova_domain *iovad, unsigned long granule, { /* * IOVA granularity will normally be equal to the smallest - * supported IOMMU page size; both *must* be capable of - * representing individual CPU pages exactly. + * supported IOMMU page size; while both usually are capable of + * representing individual CPU pages exactly the IOVA allocator + * supports any granularities that are an exact power of two. */ - BUG_ON((granule > PAGE_SIZE) || !is_power_of_2(granule)); + BUG_ON(!is_power_of_2(granule)); spin_lock_init(&iovad->iova_rbtree_lock); iovad->rbroot = RB_ROOT; -- 2.25.1
WARNING: multiple messages have this Message-ID (diff)
From: Sven Peter via iommu <iommu@lists.linux-foundation.org> To: iommu@lists.linux-foundation.org Cc: Arnd Bergmann <arnd@kernel.org>, Will Deacon <will@kernel.org>, Hector Martin <marcan@marcan.st>, linux-kernel@vger.kernel.org, Alexander Graf <graf@amazon.com>, Mohamed Mediouni <mohamed.mediouni@caramail.com>, Robin Murphy <robin.murphy@arm.com> Subject: [RFC PATCH 1/3] iommu: Move IOMMU pagesize check to attach_device Date: Fri, 6 Aug 2021 17:55:21 +0200 [thread overview] Message-ID: <20210806155523.50429-2-sven@svenpeter.dev> (raw) In-Reply-To: <20210806155523.50429-1-sven@svenpeter.dev> The iova allocator is capable of handling any granularity which is a power of two. Remove the much stronger condition that the granularity must be smaller or equal to the CPU page size from a BUG_ON there. Instead, check this condition during __iommu_attach_device and fail gracefully. Signed-off-by: Sven Peter <sven@svenpeter.dev> --- drivers/iommu/iommu.c | 34 +++++++++++++++++++++++++++++++--- drivers/iommu/iova.c | 7 ++++--- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 1de503ddb343..5854a4ef5681 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -78,6 +78,8 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus, unsigned type); static int __iommu_attach_device(struct iommu_domain *domain, struct device *dev); +static void __iommu_detach_device(struct iommu_domain *domain, + struct device *dev); static int __iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group); static void __iommu_detach_group(struct iommu_domain *domain, @@ -1964,6 +1966,18 @@ void iommu_domain_free(struct iommu_domain *domain) } EXPORT_SYMBOL_GPL(iommu_domain_free); +static int iommu_check_page_size(struct iommu_domain *domain) +{ + if (!(domain->type & __IOMMU_DOMAIN_PAGING)) + return 0; + + if ((1 << __ffs(domain->pgsize_bitmap)) > PAGE_SIZE) { + pr_warn("IOMMU page size cannot represent CPU pages.\n"); + return -EFAULT; + } + + return 0; +} static int __iommu_attach_device(struct iommu_domain *domain, struct device *dev) { @@ -1973,9 +1987,23 @@ static int __iommu_attach_device(struct iommu_domain *domain, return -ENODEV; ret = domain->ops->attach_dev(domain, dev); - if (!ret) - trace_attach_device_to_domain(dev); - return ret; + if (ret) + return ret; + + /* + * Check that CPU pages can be represented by the IOVA granularity. + * This has to be done after ops->attach_dev since many IOMMU drivers + * only limit domain->pgsize_bitmap after having attached the first + * device. + */ + ret = iommu_check_page_size(domain); + if (ret) { + __iommu_detach_device(domain, dev); + return ret; + } + + trace_attach_device_to_domain(dev); + return 0; } int iommu_attach_device(struct iommu_domain *domain, struct device *dev) diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index b6cf5f16123b..e0f8adde0f1b 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -50,10 +50,11 @@ init_iova_domain(struct iova_domain *iovad, unsigned long granule, { /* * IOVA granularity will normally be equal to the smallest - * supported IOMMU page size; both *must* be capable of - * representing individual CPU pages exactly. + * supported IOMMU page size; while both usually are capable of + * representing individual CPU pages exactly the IOVA allocator + * supports any granularities that are an exact power of two. */ - BUG_ON((granule > PAGE_SIZE) || !is_power_of_2(granule)); + BUG_ON(!is_power_of_2(granule)); spin_lock_init(&iovad->iova_rbtree_lock); iovad->rbroot = RB_ROOT; -- 2.25.1 _______________________________________________ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
next prev parent reply other threads:[~2021-08-06 15:56 UTC|newest] Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-08-06 15:55 [RFC PATCH 0/3] iommu/dma-iommu: Support IOMMU page size larger than the CPU page size Sven Peter 2021-08-06 15:55 ` Sven Peter via iommu 2021-08-06 15:55 ` Sven Peter [this message] 2021-08-06 15:55 ` [RFC PATCH 1/3] iommu: Move IOMMU pagesize check to attach_device Sven Peter via iommu 2021-08-06 15:55 ` [RFC PATCH 2/3] iommu/dma-iommu: Support iovad->granule > PAGE_SIZE Sven Peter 2021-08-06 15:55 ` Sven Peter via iommu 2021-08-06 18:04 ` Robin Murphy 2021-08-06 18:04 ` Robin Murphy 2021-08-07 8:41 ` Sven Peter 2021-08-07 8:41 ` Sven Peter via iommu 2021-08-09 18:37 ` Robin Murphy 2021-08-09 18:37 ` Robin Murphy 2021-08-09 19:57 ` Sven Peter 2021-08-09 19:57 ` Sven Peter via iommu 2021-08-07 11:47 ` Sven Peter 2021-08-07 11:47 ` Sven Peter via iommu 2021-08-09 17:41 ` Robin Murphy 2021-08-09 17:41 ` Robin Murphy 2021-08-09 20:45 ` Sven Peter 2021-08-09 20:45 ` Sven Peter via iommu 2021-08-10 9:51 ` Robin Murphy 2021-08-10 9:51 ` Robin Murphy 2021-08-11 20:18 ` Sven Peter 2021-08-11 20:18 ` Sven Peter via iommu 2021-08-12 12:43 ` Robin Murphy 2021-08-12 12:43 ` Robin Murphy 2021-08-06 15:55 ` [RFC PATCH 3/3] iommu: Introduce __IOMMU_DOMAIN_LARGE_PAGES Sven Peter 2021-08-06 15:55 ` Sven Peter via iommu
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=20210806155523.50429-2-sven@svenpeter.dev \ --to=sven@svenpeter.dev \ --cc=arnd@kernel.org \ --cc=graf@amazon.com \ --cc=iommu@lists.linux-foundation.org \ --cc=joro@8bytes.org \ --cc=linux-kernel@vger.kernel.org \ --cc=marcan@marcan.st \ --cc=mohamed.mediouni@caramail.com \ --cc=robin.murphy@arm.com \ --cc=will@kernel.org \ /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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.