I had a problem on some ppc embedded system where
there was a flash rom located at 0xffe00000-0xffffffff.
I wrote a user space utility to reprogram the flash.
It worked by doing mmap of /dev/mem in that range
in order to gain access to the area.
The problem was when I tried to mmap the whole range,
mmap would fail. It is because
start=0xffe00000
size=0x200000
start + size = 0
In the file include/linux/mm.h there is a function
do_mmap that has this code:
if ((offset + PAGE_ALIGN(len)) < offset)
goto out;
in this case offset=0xffe00000, len = 0x200000.
PAGE_ALIGN correctly comes out to 0x200000 also.
So offet + PAGE_ALIGN(len) = 0, due to 32 bit
addressing. And 0 is less than 0xffe00000. So the
condition is true, and it goes to out, and the mmap
fails.
Simple enough? I passed this on to Alan Cox and he
didn't get it. The fix is very easy. Just change it to
if ((offset + PAGE_ALIGN(len)-1) < offset)
goto out;
Then I can mmap all the way to the end of memory.
This hurts absolutely nothing. It fixes a bug. It
should be in the kernel. And this fix was just totally
forgotten. I can't even find reference to it in the
linux kernel mailing list, and I did email to that
list. WTF!