Messages in this thread |  | | Subject | Re: [PATCH v7 05/15] iommu: Use bitmap to calculate page size in iommu_pgsize() | From | Lu Baolu <> | Date | Thu, 17 Jun 2021 15:16:05 +0800 |
| |
On 6/16/21 9:38 PM, Georgi Djakov wrote: > From: Will Deacon <will@kernel.org> > > Avoid the potential for shifting values by amounts greater than the > width of their type by using a bitmap to compute page size in > iommu_pgsize(). > > Signed-off-by: Will Deacon <will@kernel.org> > Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org> > Signed-off-by: Georgi Djakov <quic_c_gdjako@quicinc.com> > --- > drivers/iommu/iommu.c | 31 ++++++++++++------------------- > 1 file changed, 12 insertions(+), 19 deletions(-) > > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c > index 5419c4b9f27a..80e471ada358 100644 > --- a/drivers/iommu/iommu.c > +++ b/drivers/iommu/iommu.c > @@ -8,6 +8,7 @@ > > #include <linux/device.h> > #include <linux/kernel.h> > +#include <linux/bits.h> > #include <linux/bug.h> > #include <linux/types.h> > #include <linux/init.h> > @@ -2378,30 +2379,22 @@ static size_t iommu_pgsize(struct iommu_domain *domain, > unsigned long addr_merge, size_t size) > { > unsigned int pgsize_idx; > + unsigned long pgsizes; > size_t pgsize; > > - /* Max page size that still fits into 'size' */ > - pgsize_idx = __fls(size); > + /* Page sizes supported by the hardware and small enough for @size */ > + pgsizes = domain->pgsize_bitmap & GENMASK(__fls(size), 0); > > - /* need to consider alignment requirements ? */ > - if (likely(addr_merge)) { > - /* Max page size allowed by address */ > - unsigned int align_pgsize_idx = __ffs(addr_merge); > - pgsize_idx = min(pgsize_idx, align_pgsize_idx); > - } > - > - /* build a mask of acceptable page sizes */ > - pgsize = (1UL << (pgsize_idx + 1)) - 1; > - > - /* throw away page sizes not supported by the hardware */ > - pgsize &= domain->pgsize_bitmap; > + /* Constrain the page sizes further based on the maximum alignment */ > + if (likely(addr_merge)) > + pgsizes &= GENMASK(__ffs(addr_merge), 0); > > - /* make sure we're still sane */ > - BUG_ON(!pgsize); > + /* Make sure we have at least one suitable page size */ > + BUG_ON(!pgsizes); > > - /* pick the biggest page */ > - pgsize_idx = __fls(pgsize); > - pgsize = 1UL << pgsize_idx; > + /* Pick the biggest page size remaining */ > + pgsize_idx = __fls(pgsizes); > + pgsize = BIT(pgsize_idx); > > return pgsize; > } >
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Best regards, baolu
|  |