I am afraid I have to report a minor bug in Linux 1.2.10 and Linux 1.3.6,
that may bother only a few people, but bothers me. But maybe, it is just
my minor knowledge of Linux memory-management.
As some might remember, I have to remap kernel-memory-space to user-space.
After some discussions on this channel, I decided to allocate kernel-space
via kmalloc with priority (GFP_BUFFER | GFP_DMA) and then remap it to
user-space via opening /dev/mem as a file and mapping it to user-space.
This works fine for the first page, at least using Linux 1.2.10.
Any subsequent pages are *not* mapped. When debugging this, I found out
that mem_map only shows for the first kmalloced page a PRESENT-flag,
the mem_map value of all subsequent pages is set to zero. The
remap-page-range-call (in mm/memory), that is done by the mmap-routine
of the mem-device, only remaps present pages or - to say better - pages
that are declared to be present by mem_map.
My pages I got from kmalloc *are* present, and when I added mem_map to
ksyms.c, and set every mem_map-entry for every allocated page to 1,
everything worked fine: the dma and the mapping to user-space.
This workaround is quite bad for my application, because it means, that
the user has to modify the kernel to export mem_map.
Using Linux 1.3.6, no pages are remapped at all. A workaround for
both versions is to tag the pages in mem_map with a MAP_PAGE_RESERVED-flag.
Is there any reason, why only the first page of several got by a
kmalloc-call is tagged as present? Is there a reason, why mmap applied to
/dev/map only should remap pages tagged as PAGE_RESERVED?
Is this a bug or a feature?
And, is there a workaround without changing the kernel?
Please, gurus of Linux-memory-management, gimme a sign!!
Thanks,
Georg
P.S. Whats about adding bad_user_access_length to the ksyms? It is
needed for every module, that includes asm/segment.h.