powerpc/iommu: Avoid undefined right shift in iommu_range_alloc()
authorMichael Ellerman <mpe@ellerman.id.au>
Tue, 8 Aug 2017 07:06:32 +0000 (17:06 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 15 Aug 2017 10:30:58 +0000 (20:30 +1000)
In iommu_range_alloc() we generate a mask by right shifting ~0,
however if the specified alignment is 0 then we right shift by 64,
which is undefined. UBSAN tells us so:

  UBSAN: Undefined behaviour in ../arch/powerpc/kernel/iommu.c:193:35
  shift exponent 64 is too large for 64-bit type 'long unsigned int'

We can avoid it by instead generating the mask with:

  align_mask = (1ull << align_order) - 1;

That will also generate an undefined shift if align_order is 64 or
greater, but that shouldn't be a problem for a while.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/kernel/iommu.c

index 0e49a4560cff11bf728a786462e2f342c6e749f7..e0af6cd7ba4f7cef79dcd0e643230188ebf42ee2 100644 (file)
@@ -190,7 +190,7 @@ static unsigned long iommu_range_alloc(struct device *dev,
        unsigned int pool_nr;
        struct iommu_pool *pool;
 
-       align_mask = 0xffffffffffffffffl >> (64 - align_order);
+       align_mask = (1ull << align_order) - 1;
 
        /* This allocator was derived from x86_64's bit string search */