The original ALIGN macro calculated a mask as ~(alignment - 1), andwhen alignment is just an int, this creates an int mask. If alignmentis also unsigned, then this mask will not be sign extended whenpromoted to a long, which leads to the code above chopping off the tophalf of addr when long is 64 bits.

However, the changed ALIGN macro, which computes the mask as~(alignment - 1UL) actually breaks code like the following when longis 32 bits:

u64 addr; int alignment; addr = ALIGN(addr, alignment);

The reason this breaks is pretty much the same as the original bugthat the change was supposed to fix: ~(alignment - 1UL) creates a maskthat is an unsigned long, which is unsigned and therefore not signextended when promoted to u64 (if long is 32 bits).

I think the right fix is to use 1L instead of 1UL, to avoid thepossibility of turning the mask unsigned by accident. This will stillfix the original problem, without breaking code that uses ALIGN() thesecond way.

This second construct is actually used in the amso1100 driver, so thatdriver does not work on 32-bit architectures right now. Unfortunatelyalmost everyone using it runs 64-bit kernels, so this regression wasnot noticed until now.

Signed-off-by: Roland Dreier <rolandd@cisco.com>

---If it's too late to merge this for 2.6.19, I can work around this inthe amso1100 driver by doing ALIGN(addr, (u64) alignment) instead.Let me know if I should send that patch.

However I think this should go in for 2.6.20 at least, since I seeonly danger with no benefit from having the constant 1 be unsigned.