If I'm not doing something wrong, here is what happens on my i386 box:
$ uname -m
i686
$ cat 64-bit-page-align.c
#include <stdio.h>
#include <asm/page.h>
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
#define PAGE_ALIGN64(addr) (((((addr)+PAGE_SIZE-1))>>PAGE_SHIFT)<<PAGE_SHIFT)
#define SIZE ((1ULL << 32) - 1)
int main(int argc, char **argv)
{
unsigned long long good, bad;
good = (unsigned long long)PAGE_ALIGN64(SIZE);
bad = (unsigned long long)PAGE_ALIGN(SIZE);
fprintf(stdout, "good = %llu, bad = %llu\n", good, bad);
return 0;
}
$ gcc -O2 -o 64-bit-page-align 64-bit-page-align.c
$ ./64-bit-page-align
good = 4294967296, bad = 0
^^^^^^^
On a x86_64, instead, both PAGE_ALIGN()s work as expected:
$ uname -m
x86_64
$ gcc -O2 -o 64-bit-page-align 64-bit-page-align.c
$ ./64-bit-page-align
good = 4294967296, bad = 4294967296
At least we could add something like:
#ifdef CONFIG_32BIT
#define PAGE_ALIGN64(addr) (((((addr)+PAGE_SIZE-1))>>PAGE_SHIFT)<<PAGE_SHIFT)
#else
#define PAGE_ALIGN64(addr) PAGE_ALIGN(addr)
#endif
But IMHO the single PAGE_ALIGN64() implementation is more clear.
-Andrea
--