6.2 Reading and Writing Data from or to User Space

You can use the copy_from_user() and copy_to_user() functions to move data between kernel space and user space. Alternatively, when moving one, two, four, or eight bytes of data, you can use either put_user() and get_user() or access_ok() to validate the user-space address followed by either __put_user() or __get_user().

If user programs require direct access to device memory, you can use the mmap() system call, which maps device memory directly into user space. For example, the X server uses mmap() to write to video adapter memory and PCI devices usually memory map their control registers to improve performance. A limitation is that the area being mapped has to be a multiple of PAGE_SIZE and start at a physical memory address that is also a multiple of PAGE_SIZE.

The direct I/O get_user_pages() function allows drivers to use user-space buffers without the overhead of copy data between user space and kernel space. However, most block and network drivers do not need to implement direct I/O as the hardware abstraction built into the kernel can use direct I/O when required. A driver that uses direct I/O to perform DMA operations will typically set up a scatter/gather list in the buffer. When using get_user_pages(), you must also use down_read() and up_read() to set up a read-mode semaphore around the call.

An alternative to using a direct I/O buffer that also supports asynchronous I/O is to use the aio_read() and aio_write() methods to read or write data. When the read or write operation completes, the driver informs the kernel by calling aio_complete().