In system call processing or in some exception handler, you might need to get some data from user address space or put some data to user space. In 2.0 kernels and earlier, it was a lengthy process, in which kernel was checking if the address you are accessing is actually mapped in and with correct permissions. In recent kernels that's already history. In the C module you want to access user space from, you must include
In this header file, there are defined macros and inline functions you should use.
put_usertake two arguments, one is the variable where to store the value from user space or what to put into user space (
get/put_userare macros, so the first argument really is the variable you want to fill, not address of it nor anything else), the second one is some pointer to user space, at which address the transfer should take place. The size of the transfer is determined by size of the type pointer is pointing at, only 8, 16, 32 and sometimes 64bit transfers are allowed. These functions return zero, if the move was successful and error code otherwise. There are also functions which transfer larger blocks of data
copy_to_user, on some architectures also
copy_in_user(all these take two pointers and length).
clear_usercan be used to clear some region in user space,
strncpy_from_useris being used to transfer some null terminated string from user space. All these functions have their
__copy_from_user). Variants starting with two underscores do less checking on the address you pass to it. First time you dereference some pointer to user memory, you should thus use the variant without leading underscores and once you succeed in getting data from some address or putting data to it, you can use the underscored variants for accesses around that address (e.g. to access other members of the same data structure). There are also functions
verify_area. These basically do the extra checks, which constitutes the difference between
__get_userand similar functions; if you call
verify_area, you can then use just user access macros with two leading underscores.
Now, how this works: most of the time programs pass correct pointers, so Linux optimizes for this case. Some platforms in the non-underscore variants do some quick checks for address validity and then all platforms just dereference that pointer. If some exception happens, during platform specific fault processing kernel checks a special ELF section, __ex_table, and if the fault was caused by some instruction pointed by that table, a special fixup code is executed. Such code usually takes care about returning EFAULT from the inline user access functions.