ARM: PL08x: ensure pl08x_pre_boundary() works for any value of addr
authorRussell King - ARM Linux <linux@arm.linux.org.uk>
Mon, 3 Jan 2011 22:42:14 +0000 (22:42 +0000)
committerDan Williams <dan.j.williams@intel.com>
Wed, 5 Jan 2011 03:16:13 +0000 (19:16 -0800)
commitb61be8d728abad7fd98e62e98f22325f8f254b51
treea4c5d5aa7e942122fc24d45d6ab977de5032be99
parent0059005f2cbf4847551b9ad9915ffffe23aef0b9
ARM: PL08x: ensure pl08x_pre_boundary() works for any value of addr

pl08x_pre_boundary() was unsafe with addresses towards the top of
memory space:

boundary = ((addr >> PL08X_BOUNDARY_SHIFT) + 1)
<< PL08X_BOUNDARY_SHIFT;

This can overflow a 32-bit number, producing zero.  When it does:

if (boundary < addr + len)
return boundary - addr;
else
return len;

results in (boundary - addr) returning either a large positive value.
Also if addr + len overflows, this calculation also fails.

We can fix this trivially as the only thing we're actually interested
in is the value of the least significant PL08X_BOUNDARY_SHIFT bits:

boundary_len = PL08X_BOUNDARY_SIZE -
(addr & (PL08X_BOUNDARY_SIZE - 1));

gives us the number of bytes before 'addr' becomes a multiple of
PL08X_BOUNDARY_SIZE.  We can then just take the min() of the two
calculated lengths.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
drivers/dma/amba-pl08x.c