1. Low-Level Requirements
1.1. devmem
1.1.1. Requirements
read_mem - read from physical memory (/dev/mem).
@file: struct file associated with /dev/mem.
@buf: user-space buffer to copy data to.
@count: number of bytes to read.
@ppos: pointer to the current file position, representing the physical
address to read from.
This function checks if the requested physical memory range is valid
and accessible by the user, then it copies data to the input
user-space buffer up to the requested number of bytes.
Function's expectations:
1. This function shall check if the value pointed by ppos exceeds the
maximum addressable physical address;
2. This function shall check if the physical address range to be read
is valid (i.e. it falls within a memory block and if it can be mapped
to the kernel address space);
3. For each memory page falling in the requested physical range
[ppos, ppos + count - 1]:
3.1. this function shall check if user space access is allowed (if
config STRICT_DEVMEM is not set, access is always granted);
3.2. if access is allowed, the memory content from the page range falling
within the requested physical range shall be copied to the user space
buffer;
3.3. zeros shall be copied to the user space buffer (for the page range
falling within the requested physical range):
3.3.1. if access to the memory page is restricted or,
3.2.2. if the current page is page 0 on HW architectures where page 0 is
not mapped.
4. The file position '*ppos' shall be advanced by the number of bytes
successfully copied to user space (including zeros).
Context: process context.
Return:
* the number of bytes copied to user on success
* %-EFAULT - the requested address range is not valid or a fault happened
when copying to user-space (i.e. copy_from_kernel_nofault() failed)
* %-EPERM - access to any of the required physical pages is not allowed
* %-ENOMEM - out of memory error for auxiliary kernel buffers supporting
the operation of copying content from the physical pages
-
1.1.2.4. read_mem FE_1 selftests/devmem:read_at_addr_32bit_ge Test read 64bit ppos vs 32 bit addr -
1.1.2.5. read_mem FE_2 selftests/devmem:read_outside_linear_map Test read outside linear map -
1.1.2.7. read_mem FE_3.2 selftests/devmem:read_allowed_area test read allowed area -
1.1.2.8. read_mem FE_4 selftests/devmem:read_allowed_area_ppos_advance test read allowed area increments ppos -
1.1.2.9. read_mem FE_3.3, FE_3.3.1, FE_3.2.2 selftests/devmem:read_restricted_area test read restricted returns zeros -
1.1.2.6. read_mem FE_??? selftests/devmem:read_secret_area Test read memfd_secret area can not being accessed
write_mem - write to physical memory (/dev/mem).
@file: struct file associated with /dev/mem.
@buf: user-space buffer containing the data to write.
@count: number of bytes to write.
@ppos: pointer to the current file position, representing the physical
address to write to.
This function checks if the target physical memory range is valid
and accessible by the user, then it writes data from the input
user-space buffer up to the requested number of bytes.
Function's expectations:
1. This function shall check if the value pointed by ppos exceeds the
maximum addressable physical address;
2. This function shall check if the physical address range to be written
is valid (i.e. it falls within a memory block and if it can be mapped
to the kernel address space);
3. For each memory page falling in the physical range to be written
[ppos, ppos + count - 1]:
3.1. this function shall check if user space access is allowed (if
config STRICT_DEVMEM is not set, access is always granted);
3.2. the content from the user space buffer shall be copied to the page
range falling within the physical range to be written if access is
allowed;
3.3. the data to be copied from the user space buffer (for the page range
falling within the range to be written) shall be skipped:
3.3.1. if access to the memory page is restricted or,
3.3.2. if the current page is page 0 on HW architectures where page 0
is not mapped.
4. The file position '*ppos' shall be advanced by the number of bytes
successfully copied from user space (including skipped bytes).
Context: process context.
Return:
* the number of bytes copied from user-space on success
* %-EFBIG - the value pointed by ppos exceeds the maximum addressable
physical address
* %-EFAULT - the physical address range is not valid or no bytes could
be copied from user-space
* %-EPERM - access to any of the required pages is not allowed
-
1.1.2.10. write_mem - FE_2 selftests/devmem:write_outside_area test write outside
mmap_mem - map physical memory into user space (/dev/mem).
@file: file structure for the device.
@vma: virtual memory area structure describing the user mapping.
This function checks if the requested physical memory range is valid
and accessible by the user, then it maps the physical memory range to
user-mode address space.
Function's expectations:
1. This function shall check if the requested physical address range to be
mapped fits within the maximum addressable physical range;
2. This function shall check if the requested physical range corresponds to
a valid physical range and if access is allowed on it (if config STRICT_DEVMEM
is not set, access is always allowed);
3. This function shall check if the input virtual memory area can be used for
a private mapping (always OK if there is an MMU);
4. This function shall set the virtual memory area operations to
&mmap_mem_ops;
5. This function shall establish a mapping between the user-space
virtual memory area described by vma and the physical memory
range specified by vma->vm_pgoff and size;
Context: process context.
Return:
* 0 on success
* %-EAGAIN - invalid or unsupported mapping requested (remap_pfn_range()
fails)
* %-EINVAL - requested physical range to be mapped is not valid
* %-EPERM - no permission to access the requested physical range
memory_lseek - change the file position.
@file: file structure for the device.
@offset: file offset to seek to.
@orig: where to start seeking from (see whence in the llseek manpage).
This function changes the file position according to the input offset
and orig parameters.
Function's expectations:
1. This function shall lock the semaphore of the inode corresponding to the
input file before any operation and unlock it before returning.
2. This function shall check the orig value and accordingly:
2.1. if it is equal to SEEK_CUR, the current file position shall be
incremented by the input offset;
2.2. if it is equal to SEEK_SET, the current file position shall be
set to the input offset value;
2.3. any other value shall result in an error condition.
3. Before writing the current file position, the new position value
shall be checked to not overlap with Linux ERRNO values.
Assumptions of Use:
1. the input file pointer is expected to be valid.
Notes:
The memory devices use the full 32/64 bits of the offset, and so we cannot
check against negative addresses: they are ok. The return value is weird,
though, in that case (0).
Also note that seeking relative to the "end of file" isn't supported:
it has no meaning, so passing orig equal to SEEK_END returns -EINVAL.
Context: process context, locks/unlocks inode->i_rwsem
Return:
* the new file position on success
* %-EOVERFLOW - the new position value equals or exceeds
(unsigned long long) -MAX_ERRNO
* %-EINVAL - the orig parameter is invalid
-
1.1.2.11. memory_lseek FE_2, FE_2.2 selftests/devmem:seek_seek_set test seek funcction SEEK_SET -
1.1.2.12. memory_lseek FE_2, FE_2.1 selftests/devmem:seek_seek_cur test seek function SEEK_CUR -
1.1.2.13. memory_lseek FE_2, FE2.3 selftests/devmem:seek_seek_other test seek function SEEK_END other
open_port - open the I/O port device (/dev/port).
@inode: inode of the device file.
@filp: file structure for the device.
This function checks if the caller can access the port device and sets
the f_mapping pointer of filp to the i_mapping pointer of inode.
Function's expectations:
1. This function shall check if the caller has sufficient capabilities to
perform raw I/O access;
2. This function shall check if the kernel is locked down with the
&LOCKDOWN_DEV_MEM restriction;
3. If the input inode corresponds to /dev/mem, the f_mapping pointer
of the input file structure shall be set to the i_mapping pointer
of the input inode;
Assumptions of Use:
1. The input inode and filp are expected to be valid.
Context: process context.
Return:
* 0 on success
* %-EPERM - caller lacks the required capability (CAP_SYS_RAWIO)
* any error returned by securty_locked_down()
memory_open - set the filp f_op to the memory device fops and invoke open().
@inode: inode of the device file.
@filp: file structure for the device.
Function's expectations:
1. This function shall retrieve the minor number associated with the input
inode and the memory device corresponding to such minor number;
2. The file operations pointer shall be set to the memory device file operations;
3. The file mode member of the input filp shall be OR'd with the device mode;
4. The memory device open() file operation shall be invoked.
Assumptions of Use:
1. The input inode and filp are expected to be non-NULL.
Context: process context.
Return:
* 0 on success
* %-ENXIO - the minor number corresponding to the input inode cannot be
associated with any device or the corresponding device has a NULL fops
pointer
* any error returned by the device specific open function pointer
-
1.1.2.1. memory_open FE_1, FE_2, FE_4 selftests/devmem:access Test whether /dev/mem is accessible -
1.1.2.2. memory_open FE_3 selftests/devmem:open_devnum Test open /dev/mem provides the correct min, maj
1.1.2. Tests
-
1.1.1.6. memory_open 46dc914c8b39c0763e1d407cf985e16e68b5c153cdbdae6e03173972db455da0
memory_open - set the filp f_op to the memory device fops and invoke open().
@inode: inode of the device file.
@filp: file structure for the device.
Function's expectations:
1. This function shall retrieve the minor number associated with the input
inode and the memory device corresponding to such minor number;
2. The file operations pointer shall be set to the memory device file operations;
3. The file mode member of the input filp shall be OR'd with the device mode;
4. The memory device open() file operation shall be invoked.
Assumptions of Use:
1. The input inode and filp are expected to be non-NULL.
Context: process context.
Return:
* 0 on success
* %-ENXIO - the minor number corresponding to the input inode cannot be
associated with any device or the corresponding device has a NULL fops
pointer
* any error returned by the device specific open function pointer
-
1.1.1.6. memory_open 46dc914c8b39c0763e1d407cf985e16e68b5c153cdbdae6e03173972db455da0
memory_open - set the filp f_op to the memory device fops and invoke open().
@inode: inode of the device file.
@filp: file structure for the device.
Function's expectations:
1. This function shall retrieve the minor number associated with the input
inode and the memory device corresponding to such minor number;
2. The file operations pointer shall be set to the memory device file operations;
3. The file mode member of the input filp shall be OR'd with the device mode;
4. The memory device open() file operation shall be invoked.
Assumptions of Use:
1. The input inode and filp are expected to be non-NULL.
Context: process context.
Return:
* 0 on success
* %-ENXIO - the minor number corresponding to the input inode cannot be
associated with any device or the corresponding device has a NULL fops
pointer
* any error returned by the device specific open function pointer
-
1.1.1.1. read_mem a89784c55426aec4b8ba345f281a0ec478d43897a0a248618cb140c03c770c75
read_mem - read from physical memory (/dev/mem).
@file: struct file associated with /dev/mem.
@buf: user-space buffer to copy data to.
@count: number of bytes to read.
@ppos: pointer to the current file position, representing the physical
address to read from.
This function checks if the requested physical memory range is valid
and accessible by the user, then it copies data to the input
user-space buffer up to the requested number of bytes.
Function's expectations:
1. This function shall check if the value pointed by ppos exceeds the
maximum addressable physical address;
2. This function shall check if the physical address range to be read
is valid (i.e. it falls within a memory block and if it can be mapped
to the kernel address space);
3. For each memory page falling in the requested physical range
[ppos, ppos + count - 1]:
3.1. this function shall check if user space access is allowed (if
config STRICT_DEVMEM is not set, access is always granted);
3.2. if access is allowed, the memory content from the page range falling
within the requested physical range shall be copied to the user space
buffer;
3.3. zeros shall be copied to the user space buffer (for the page range
falling within the requested physical range):
3.3.1. if access to the memory page is restricted or,
3.2.2. if the current page is page 0 on HW architectures where page 0 is
not mapped.
4. The file position '*ppos' shall be advanced by the number of bytes
successfully copied to user space (including zeros).
Context: process context.
Return:
* the number of bytes copied to user on success
* %-EFAULT - the requested address range is not valid or a fault happened
when copying to user-space (i.e. copy_from_kernel_nofault() failed)
* %-EPERM - access to any of the required physical pages is not allowed
* %-ENOMEM - out of memory error for auxiliary kernel buffers supporting
the operation of copying content from the physical pages
-
1.1.1.1. read_mem a89784c55426aec4b8ba345f281a0ec478d43897a0a248618cb140c03c770c75
read_mem - read from physical memory (/dev/mem).
@file: struct file associated with /dev/mem.
@buf: user-space buffer to copy data to.
@count: number of bytes to read.
@ppos: pointer to the current file position, representing the physical
address to read from.
This function checks if the requested physical memory range is valid
and accessible by the user, then it copies data to the input
user-space buffer up to the requested number of bytes.
Function's expectations:
1. This function shall check if the value pointed by ppos exceeds the
maximum addressable physical address;
2. This function shall check if the physical address range to be read
is valid (i.e. it falls within a memory block and if it can be mapped
to the kernel address space);
3. For each memory page falling in the requested physical range
[ppos, ppos + count - 1]:
3.1. this function shall check if user space access is allowed (if
config STRICT_DEVMEM is not set, access is always granted);
3.2. if access is allowed, the memory content from the page range falling
within the requested physical range shall be copied to the user space
buffer;
3.3. zeros shall be copied to the user space buffer (for the page range
falling within the requested physical range):
3.3.1. if access to the memory page is restricted or,
3.2.2. if the current page is page 0 on HW architectures where page 0 is
not mapped.
4. The file position '*ppos' shall be advanced by the number of bytes
successfully copied to user space (including zeros).
Context: process context.
Return:
* the number of bytes copied to user on success
* %-EFAULT - the requested address range is not valid or a fault happened
when copying to user-space (i.e. copy_from_kernel_nofault() failed)
* %-EPERM - access to any of the required physical pages is not allowed
* %-ENOMEM - out of memory error for auxiliary kernel buffers supporting
the operation of copying content from the physical pages
-
1.1.1.1. read_mem a89784c55426aec4b8ba345f281a0ec478d43897a0a248618cb140c03c770c75
read_mem - read from physical memory (/dev/mem).
@file: struct file associated with /dev/mem.
@buf: user-space buffer to copy data to.
@count: number of bytes to read.
@ppos: pointer to the current file position, representing the physical
address to read from.
This function checks if the requested physical memory range is valid
and accessible by the user, then it copies data to the input
user-space buffer up to the requested number of bytes.
Function's expectations:
1. This function shall check if the value pointed by ppos exceeds the
maximum addressable physical address;
2. This function shall check if the physical address range to be read
is valid (i.e. it falls within a memory block and if it can be mapped
to the kernel address space);
3. For each memory page falling in the requested physical range
[ppos, ppos + count - 1]:
3.1. this function shall check if user space access is allowed (if
config STRICT_DEVMEM is not set, access is always granted);
3.2. if access is allowed, the memory content from the page range falling
within the requested physical range shall be copied to the user space
buffer;
3.3. zeros shall be copied to the user space buffer (for the page range
falling within the requested physical range):
3.3.1. if access to the memory page is restricted or,
3.2.2. if the current page is page 0 on HW architectures where page 0 is
not mapped.
4. The file position '*ppos' shall be advanced by the number of bytes
successfully copied to user space (including zeros).
Context: process context.
Return:
* the number of bytes copied to user on success
* %-EFAULT - the requested address range is not valid or a fault happened
when copying to user-space (i.e. copy_from_kernel_nofault() failed)
* %-EPERM - access to any of the required physical pages is not allowed
* %-ENOMEM - out of memory error for auxiliary kernel buffers supporting
the operation of copying content from the physical pages
-
1.1.1.1. read_mem a89784c55426aec4b8ba345f281a0ec478d43897a0a248618cb140c03c770c75
read_mem - read from physical memory (/dev/mem).
@file: struct file associated with /dev/mem.
@buf: user-space buffer to copy data to.
@count: number of bytes to read.
@ppos: pointer to the current file position, representing the physical
address to read from.
This function checks if the requested physical memory range is valid
and accessible by the user, then it copies data to the input
user-space buffer up to the requested number of bytes.
Function's expectations:
1. This function shall check if the value pointed by ppos exceeds the
maximum addressable physical address;
2. This function shall check if the physical address range to be read
is valid (i.e. it falls within a memory block and if it can be mapped
to the kernel address space);
3. For each memory page falling in the requested physical range
[ppos, ppos + count - 1]:
3.1. this function shall check if user space access is allowed (if
config STRICT_DEVMEM is not set, access is always granted);
3.2. if access is allowed, the memory content from the page range falling
within the requested physical range shall be copied to the user space
buffer;
3.3. zeros shall be copied to the user space buffer (for the page range
falling within the requested physical range):
3.3.1. if access to the memory page is restricted or,
3.2.2. if the current page is page 0 on HW architectures where page 0 is
not mapped.
4. The file position '*ppos' shall be advanced by the number of bytes
successfully copied to user space (including zeros).
Context: process context.
Return:
* the number of bytes copied to user on success
* %-EFAULT - the requested address range is not valid or a fault happened
when copying to user-space (i.e. copy_from_kernel_nofault() failed)
* %-EPERM - access to any of the required physical pages is not allowed
* %-ENOMEM - out of memory error for auxiliary kernel buffers supporting
the operation of copying content from the physical pages
-
1.1.1.1. read_mem a89784c55426aec4b8ba345f281a0ec478d43897a0a248618cb140c03c770c75
read_mem - read from physical memory (/dev/mem).
@file: struct file associated with /dev/mem.
@buf: user-space buffer to copy data to.
@count: number of bytes to read.
@ppos: pointer to the current file position, representing the physical
address to read from.
This function checks if the requested physical memory range is valid
and accessible by the user, then it copies data to the input
user-space buffer up to the requested number of bytes.
Function's expectations:
1. This function shall check if the value pointed by ppos exceeds the
maximum addressable physical address;
2. This function shall check if the physical address range to be read
is valid (i.e. it falls within a memory block and if it can be mapped
to the kernel address space);
3. For each memory page falling in the requested physical range
[ppos, ppos + count - 1]:
3.1. this function shall check if user space access is allowed (if
config STRICT_DEVMEM is not set, access is always granted);
3.2. if access is allowed, the memory content from the page range falling
within the requested physical range shall be copied to the user space
buffer;
3.3. zeros shall be copied to the user space buffer (for the page range
falling within the requested physical range):
3.3.1. if access to the memory page is restricted or,
3.2.2. if the current page is page 0 on HW architectures where page 0 is
not mapped.
4. The file position '*ppos' shall be advanced by the number of bytes
successfully copied to user space (including zeros).
Context: process context.
Return:
* the number of bytes copied to user on success
* %-EFAULT - the requested address range is not valid or a fault happened
when copying to user-space (i.e. copy_from_kernel_nofault() failed)
* %-EPERM - access to any of the required physical pages is not allowed
* %-ENOMEM - out of memory error for auxiliary kernel buffers supporting
the operation of copying content from the physical pages
-
1.1.1.1. read_mem a89784c55426aec4b8ba345f281a0ec478d43897a0a248618cb140c03c770c75
read_mem - read from physical memory (/dev/mem).
@file: struct file associated with /dev/mem.
@buf: user-space buffer to copy data to.
@count: number of bytes to read.
@ppos: pointer to the current file position, representing the physical
address to read from.
This function checks if the requested physical memory range is valid
and accessible by the user, then it copies data to the input
user-space buffer up to the requested number of bytes.
Function's expectations:
1. This function shall check if the value pointed by ppos exceeds the
maximum addressable physical address;
2. This function shall check if the physical address range to be read
is valid (i.e. it falls within a memory block and if it can be mapped
to the kernel address space);
3. For each memory page falling in the requested physical range
[ppos, ppos + count - 1]:
3.1. this function shall check if user space access is allowed (if
config STRICT_DEVMEM is not set, access is always granted);
3.2. if access is allowed, the memory content from the page range falling
within the requested physical range shall be copied to the user space
buffer;
3.3. zeros shall be copied to the user space buffer (for the page range
falling within the requested physical range):
3.3.1. if access to the memory page is restricted or,
3.2.2. if the current page is page 0 on HW architectures where page 0 is
not mapped.
4. The file position '*ppos' shall be advanced by the number of bytes
successfully copied to user space (including zeros).
Context: process context.
Return:
* the number of bytes copied to user on success
* %-EFAULT - the requested address range is not valid or a fault happened
when copying to user-space (i.e. copy_from_kernel_nofault() failed)
* %-EPERM - access to any of the required physical pages is not allowed
* %-ENOMEM - out of memory error for auxiliary kernel buffers supporting
the operation of copying content from the physical pages
-
1.1.1.2. write_mem 6e16917c09ee583de5dc9e8a24a406e75bb229554699a501cfa8efdb308862d7
write_mem - write to physical memory (/dev/mem).
@file: struct file associated with /dev/mem.
@buf: user-space buffer containing the data to write.
@count: number of bytes to write.
@ppos: pointer to the current file position, representing the physical
address to write to.
This function checks if the target physical memory range is valid
and accessible by the user, then it writes data from the input
user-space buffer up to the requested number of bytes.
Function's expectations:
1. This function shall check if the value pointed by ppos exceeds the
maximum addressable physical address;
2. This function shall check if the physical address range to be written
is valid (i.e. it falls within a memory block and if it can be mapped
to the kernel address space);
3. For each memory page falling in the physical range to be written
[ppos, ppos + count - 1]:
3.1. this function shall check if user space access is allowed (if
config STRICT_DEVMEM is not set, access is always granted);
3.2. the content from the user space buffer shall be copied to the page
range falling within the physical range to be written if access is
allowed;
3.3. the data to be copied from the user space buffer (for the page range
falling within the range to be written) shall be skipped:
3.3.1. if access to the memory page is restricted or,
3.3.2. if the current page is page 0 on HW architectures where page 0
is not mapped.
4. The file position '*ppos' shall be advanced by the number of bytes
successfully copied from user space (including skipped bytes).
Context: process context.
Return:
* the number of bytes copied from user-space on success
* %-EFBIG - the value pointed by ppos exceeds the maximum addressable
physical address
* %-EFAULT - the physical address range is not valid or no bytes could
be copied from user-space
* %-EPERM - access to any of the required pages is not allowed
-
1.1.1.4. memory_lseek feb4cb915f91d319078204293f6cf99eb50e775a8f670e478e30e84bd6979a14
memory_lseek - change the file position.
@file: file structure for the device.
@offset: file offset to seek to.
@orig: where to start seeking from (see whence in the llseek manpage).
This function changes the file position according to the input offset
and orig parameters.
Function's expectations:
1. This function shall lock the semaphore of the inode corresponding to the
input file before any operation and unlock it before returning.
2. This function shall check the orig value and accordingly:
2.1. if it is equal to SEEK_CUR, the current file position shall be
incremented by the input offset;
2.2. if it is equal to SEEK_SET, the current file position shall be
set to the input offset value;
2.3. any other value shall result in an error condition.
3. Before writing the current file position, the new position value
shall be checked to not overlap with Linux ERRNO values.
Assumptions of Use:
1. the input file pointer is expected to be valid.
Notes:
The memory devices use the full 32/64 bits of the offset, and so we cannot
check against negative addresses: they are ok. The return value is weird,
though, in that case (0).
Also note that seeking relative to the "end of file" isn't supported:
it has no meaning, so passing orig equal to SEEK_END returns -EINVAL.
Context: process context, locks/unlocks inode->i_rwsem
Return:
* the new file position on success
* %-EOVERFLOW - the new position value equals or exceeds
(unsigned long long) -MAX_ERRNO
* %-EINVAL - the orig parameter is invalid
-
1.1.1.4. memory_lseek feb4cb915f91d319078204293f6cf99eb50e775a8f670e478e30e84bd6979a14
memory_lseek - change the file position.
@file: file structure for the device.
@offset: file offset to seek to.
@orig: where to start seeking from (see whence in the llseek manpage).
This function changes the file position according to the input offset
and orig parameters.
Function's expectations:
1. This function shall lock the semaphore of the inode corresponding to the
input file before any operation and unlock it before returning.
2. This function shall check the orig value and accordingly:
2.1. if it is equal to SEEK_CUR, the current file position shall be
incremented by the input offset;
2.2. if it is equal to SEEK_SET, the current file position shall be
set to the input offset value;
2.3. any other value shall result in an error condition.
3. Before writing the current file position, the new position value
shall be checked to not overlap with Linux ERRNO values.
Assumptions of Use:
1. the input file pointer is expected to be valid.
Notes:
The memory devices use the full 32/64 bits of the offset, and so we cannot
check against negative addresses: they are ok. The return value is weird,
though, in that case (0).
Also note that seeking relative to the "end of file" isn't supported:
it has no meaning, so passing orig equal to SEEK_END returns -EINVAL.
Context: process context, locks/unlocks inode->i_rwsem
Return:
* the new file position on success
* %-EOVERFLOW - the new position value equals or exceeds
(unsigned long long) -MAX_ERRNO
* %-EINVAL - the orig parameter is invalid
-
1.1.1.4. memory_lseek feb4cb915f91d319078204293f6cf99eb50e775a8f670e478e30e84bd6979a14
memory_lseek - change the file position.
@file: file structure for the device.
@offset: file offset to seek to.
@orig: where to start seeking from (see whence in the llseek manpage).
This function changes the file position according to the input offset
and orig parameters.
Function's expectations:
1. This function shall lock the semaphore of the inode corresponding to the
input file before any operation and unlock it before returning.
2. This function shall check the orig value and accordingly:
2.1. if it is equal to SEEK_CUR, the current file position shall be
incremented by the input offset;
2.2. if it is equal to SEEK_SET, the current file position shall be
set to the input offset value;
2.3. any other value shall result in an error condition.
3. Before writing the current file position, the new position value
shall be checked to not overlap with Linux ERRNO values.
Assumptions of Use:
1. the input file pointer is expected to be valid.
Notes:
The memory devices use the full 32/64 bits of the offset, and so we cannot
check against negative addresses: they are ok. The return value is weird,
though, in that case (0).
Also note that seeking relative to the "end of file" isn't supported:
it has no meaning, so passing orig equal to SEEK_END returns -EINVAL.
Context: process context, locks/unlocks inode->i_rwsem
Return:
* the new file position on success
* %-EOVERFLOW - the new position value equals or exceeds
(unsigned long long) -MAX_ERRNO
* %-EINVAL - the orig parameter is invalid