As per the linux design on x86 and ppc, the 4g virtual address space is divided into 3:1开发者_JAVA技巧. User virtual address's are till 3g.
Now if user app does an ioctl passing a pointer to buffer, the kernel module, can directly do a memcpy, I tried and it worked. => Why do we then need a copy_to/copy_from user.
Note: If the page is swapped out, then the kernel pagefault handler would bring that back, and it is invisible to kernel module.
need yr ideas ... comments
There are several good reasons that copy_to_user
/ copy_from_user
are the correct functions to use:
On some architectures a simple
memcpy()
does not work, so using those functions allows your code to work there. I believe even x86 with theHIGHMEM
config option selected is in this boat.Those functions do an
access_ok()
check to ensure that the user space addresses referenced really are genuine user space addresses. If you just do amemcpy()
, the caller of theioctl()
can supply an address range that overlaps kernel addresses, which is a security hole.However, the major reason is to properly handle bad user addresses. If you just use a bare
memcpy()
, the unhandled fault will result in a kernel oops. The user access functions use the "fixup" mechanism, which allows the fault to be handled (the read or write is short, and usuallyEFAULT
is returned to userspace in this case).
You were lucky it worked.
User space and kernel space operate in completely different address spaces. When you copy_to_user the kernel translates user spaces virtual address into a real physical address and copies the data there. A similar process occurs the other way around.
It is possible to skip the copy to/from steps directly if your hardware supports scatter/gather DMA. Here you map a contiguous chunk of virtual memory into a series of physical pages and then use that information to DMA directly into user space. Of course this has complications if any of the virtual address space isn't currently mapped into physical memory (think swap or file backed mmaps).
精彩评论