€•üžŒsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ$/translations/zh_CN/driver-api/ioctl”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ$/translations/zh_TW/driver-api/ioctl”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ$/translations/it_IT/driver-api/ioctl”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ$/translations/ja_JP/driver-api/ioctl”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ$/translations/ko_KR/driver-api/ioctl”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ$/translations/pt_BR/driver-api/ioctl”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ$/translations/sp_SP/driver-api/ioctl”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒioctl based interfaces”h]”hŒioctl based interfaces”…””}”(hh¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhh·h²hh³Œ>/var/lib/git/docbuild/linux/Documentation/driver-api/ioctl.rst”h´KubhŒ paragraph”“”)”}”(hŒýioctl() is the most common way for applications to interface with device drivers. It is flexible and easily extended by adding new commands and can be passed through character devices, block devices as well as sockets and other special file descriptors.”h]”hŒýioctl() is the most common way for applications to interface with device drivers. It is flexible and easily extended by adding new commands and can be passed through character devices, block devices as well as sockets and other special file descriptors.”…””}”(hhÍh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khh·h²hubhÌ)”}”(hŒÅHowever, it is also very easy to get ioctl command definitions wrong, and hard to fix them later without breaking existing applications, so this documentation tries to help developers get it right.”h]”hŒÅHowever, it is also very easy to get ioctl command definitions wrong, and hard to fix them later without breaking existing applications, so this documentation tries to help developers get it right.”…””}”(hhÛh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K hh·h²hubh¶)”}”(hhh]”(h»)”}”(hŒCommand number definitions”h]”hŒCommand number definitions”…””}”(hhìh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhhéh²hh³hÊh´KubhÌ)”}”(hŒöThe command number, or request number, is the second argument passed to the ioctl system call. While this can be any 32-bit number that uniquely identifies an action for a particular driver, there are a number of conventions around defining them.”h]”hŒöThe command number, or request number, is the second argument passed to the ioctl system call. While this can be any 32-bit number that uniquely identifies an action for a particular driver, there are a number of conventions around defining them.”…””}”(hhúh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khhéh²hubhÌ)”}”(hŒé``include/uapi/asm-generic/ioctl.h`` provides four macros for defining ioctl commands that follow modern conventions: ``_IO``, ``_IOR``, ``_IOW``, and ``_IOWR``. These should be used for all new commands, with the correct parameters:”h]”(hŒliteral”“”)”}”(hŒ$``include/uapi/asm-generic/ioctl.h``”h]”hŒ include/uapi/asm-generic/ioctl.h”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjubhŒR provides four macros for defining ioctl commands that follow modern conventions: ”…””}”(hjh²hh³Nh´Nubj )”}”(hŒ``_IO``”h]”hŒ_IO”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjubhŒ, ”…””}”(hjh²hh³Nh´Nubj )”}”(hŒ``_IOR``”h]”hŒ_IOR”…””}”(hj2h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjubhŒ, ”…””}”(hjh²hh³Nh´Nubj )”}”(hŒ``_IOW``”h]”hŒ_IOW”…””}”(hjDh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjubhŒ, and ”…””}”(hjh²hh³Nh´Nubj )”}”(hŒ ``_IOWR``”h]”hŒ_IOWR”…””}”(hjVh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjubhŒI. These should be used for all new commands, with the correct parameters:”…””}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khhéh²hubhŒdefinition_list”“”)”}”(hhh]”(hŒdefinition_list_item”“”)”}”(hX‰_IO/_IOR/_IOW/_IOWR The macro name specifies how the argument will be used. It may be a pointer to data to be passed into the kernel (_IOW), out of the kernel (_IOR), or both (_IOWR). _IO can indicate either commands with no argument or those passing an integer value instead of a pointer. It is recommended to only use _IO for commands without arguments, and use pointers for passing data. ”h]”(hŒterm”“”)”}”(hŒ_IO/_IOR/_IOW/_IOWR”h]”hŒ_IO/_IOR/_IOW/_IOWR”…””}”(hj{h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jyh³hÊh´K!hjuubhŒ definition”“”)”}”(hhh]”hÌ)”}”(hXtThe macro name specifies how the argument will be used. It may be a pointer to data to be passed into the kernel (_IOW), out of the kernel (_IOR), or both (_IOWR). _IO can indicate either commands with no argument or those passing an integer value instead of a pointer. It is recommended to only use _IO for commands without arguments, and use pointers for passing data.”h]”hXtThe macro name specifies how the argument will be used. It may be a pointer to data to be passed into the kernel (_IOW), out of the kernel (_IOR), or both (_IOWR). _IO can indicate either commands with no argument or those passing an integer value instead of a pointer. It is recommended to only use _IO for commands without arguments, and use pointers for passing data.”…””}”(hjŽh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj‹ubah}”(h]”h ]”h"]”h$]”h&]”uh1j‰hjuubeh}”(h]”h ]”h"]”h$]”h&]”uh1jsh³hÊh´K!hjpubjt)”}”(hŒ•type An 8-bit number, often a character literal, specific to a subsystem or driver, and listed in Documentation/userspace-api/ioctl/ioctl-number.rst ”h]”(jz)”}”(hŒtype”h]”hŒtype”…””}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jyh³hÊh´K%hj¨ubjŠ)”}”(hhh]”hÌ)”}”(hŒAn 8-bit number, often a character literal, specific to a subsystem or driver, and listed in Documentation/userspace-api/ioctl/ioctl-number.rst”h]”hŒAn 8-bit number, often a character literal, specific to a subsystem or driver, and listed in Documentation/userspace-api/ioctl/ioctl-number.rst”…””}”(hj½h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K$hjºubah}”(h]”h ]”h"]”h$]”h&]”uh1j‰hj¨ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jsh³hÊh´K%hjph²hubjt)”}”(hŒWnr An 8-bit number identifying the specific command, unique for a give value of 'type' ”h]”(jz)”}”(hŒnr”h]”hŒnr”…””}”(hjÛh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jyh³hÊh´K)hj×ubjŠ)”}”(hhh]”hÌ)”}”(hŒSAn 8-bit number identifying the specific command, unique for a give value of 'type'”h]”hŒWAn 8-bit number identifying the specific command, unique for a give value of ‘type’”…””}”(hjìh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K(hjéubah}”(h]”h ]”h"]”h$]”h&]”uh1j‰hj×ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jsh³hÊh´K)hjph²hubjt)”}”(hX—data_type The name of the data type pointed to by the argument, the command number encodes the ``sizeof(data_type)`` value in a 13-bit or 14-bit integer, leading to a limit of 8191 bytes for the maximum size of the argument. Note: do not pass sizeof(data_type) type into _IOR/_IOW/IOWR, as that will lead to encoding sizeof(sizeof(data_type)), i.e. sizeof(size_t). _IO does not have a data_type parameter. ”h]”(jz)”}”(hŒ data_type”h]”hŒ data_type”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jyh³hÊh´K2hjubjŠ)”}”(hhh]”hÌ)”}”(hX‹The name of the data type pointed to by the argument, the command number encodes the ``sizeof(data_type)`` value in a 13-bit or 14-bit integer, leading to a limit of 8191 bytes for the maximum size of the argument. Note: do not pass sizeof(data_type) type into _IOR/_IOW/IOWR, as that will lead to encoding sizeof(sizeof(data_type)), i.e. sizeof(size_t). _IO does not have a data_type parameter.”h]”(hŒUThe name of the data type pointed to by the argument, the command number encodes the ”…””}”(hjh²hh³Nh´Nubj )”}”(hŒ``sizeof(data_type)``”h]”hŒsizeof(data_type)”…””}”(hj#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjubhX! value in a 13-bit or 14-bit integer, leading to a limit of 8191 bytes for the maximum size of the argument. Note: do not pass sizeof(data_type) type into _IOR/_IOW/IOWR, as that will lead to encoding sizeof(sizeof(data_type)), i.e. sizeof(size_t). _IO does not have a data_type parameter.”…””}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K,hjubah}”(h]”h ]”h"]”h$]”h&]”uh1j‰hjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jsh³hÊh´K2hjph²hubeh}”(h]”h ]”h"]”h$]”h&]”uh1jnhhéh²hh³hÊh´Nubeh}”(h]”Œcommand-number-definitions”ah ]”h"]”Œcommand number definitions”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kubh¶)”}”(hhh]”(h»)”}”(hŒInterface versions”h]”hŒInterface versions”…””}”(hjXh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjUh²hh³hÊh´K5ubhÌ)”}”(hŒ{Some subsystems use version numbers in data structures to overload commands with different interpretations of the argument.”h]”hŒ{Some subsystems use version numbers in data structures to overload commands with different interpretations of the argument.”…””}”(hjfh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K7hjUh²hubhÌ)”}”(hŒeThis is generally a bad idea, since changes to existing commands tend to break existing applications.”h]”hŒeThis is generally a bad idea, since changes to existing commands tend to break existing applications.”…””}”(hjth²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K:hjUh²hubhÌ)”}”(hŒÊA better approach is to add a new ioctl command with a new number. The old command still needs to be implemented in the kernel for compatibility, but this can be a wrapper around the new implementation.”h]”hŒÊA better approach is to add a new ioctl command with a new number. The old command still needs to be implemented in the kernel for compatibility, but this can be a wrapper around the new implementation.”…””}”(hj‚h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K=hjUh²hubeh}”(h]”Œinterface-versions”ah ]”h"]”Œinterface versions”ah$]”h&]”uh1hµhh·h²hh³hÊh´K5ubh¶)”}”(hhh]”(h»)”}”(hŒ Return code”h]”hŒ Return code”…””}”(hj›h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj˜h²hh³hÊh´KBubhÌ)”}”(hŒòioctl commands can return negative error codes as documented in errno(3); these get turned into errno values in user space. On success, the return code should be zero. It is also possible but not recommended to return a positive 'long' value.”h]”hŒöioctl commands can return negative error codes as documented in errno(3); these get turned into errno values in user space. On success, the return code should be zero. It is also possible but not recommended to return a positive ‘long’ value.”…””}”(hj©h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KDhj˜h²hubhÌ)”}”(hXWhen the ioctl callback is called with an unknown command number, the handler returns either -ENOTTY or -ENOIOCTLCMD, which also results in -ENOTTY being returned from the system call. Some subsystems return -ENOSYS or -EINVAL here for historic reasons, but this is wrong.”h]”hXWhen the ioctl callback is called with an unknown command number, the handler returns either -ENOTTY or -ENOIOCTLCMD, which also results in -ENOTTY being returned from the system call. Some subsystems return -ENOSYS or -EINVAL here for historic reasons, but this is wrong.”…””}”(hj·h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KIhj˜h²hubhÌ)”}”(hXBPrior to Linux 5.5, compat_ioctl handlers were required to return -ENOIOCTLCMD in order to use the fallback conversion into native commands. As all subsystems are now responsible for handling compat mode themselves, this is no longer needed, but it may be important to consider when backporting bug fixes to older kernels.”h]”hXBPrior to Linux 5.5, compat_ioctl handlers were required to return -ENOIOCTLCMD in order to use the fallback conversion into native commands. As all subsystems are now responsible for handling compat mode themselves, this is no longer needed, but it may be important to consider when backporting bug fixes to older kernels.”…””}”(hjÅh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KNhj˜h²hubeh}”(h]”Œ return-code”ah ]”h"]”Œ return code”ah$]”h&]”uh1hµhh·h²hh³hÊh´KBubh¶)”}”(hhh]”(h»)”}”(hŒ Timestamps”h]”hŒ Timestamps”…””}”(hjÞh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjÛh²hh³hÊh´KUubhÌ)”}”(hŒæTraditionally, timestamps and timeout values are passed as ``struct timespec`` or ``struct timeval``, but these are problematic because of incompatible definitions of these structures in user space after the move to 64-bit time_t.”h]”(hŒ;Traditionally, timestamps and timeout values are passed as ”…””}”(hjìh²hh³Nh´Nubj )”}”(hŒ``struct timespec``”h]”hŒstruct timespec”…””}”(hjôh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjìubhŒ or ”…””}”(hjìh²hh³Nh´Nubj )”}”(hŒ``struct timeval``”h]”hŒstruct timeval”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjìubhŒ‚, but these are problematic because of incompatible definitions of these structures in user space after the move to 64-bit time_t.”…””}”(hjìh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KWhjÛh²hubhÌ)”}”(hXßThe ``struct __kernel_timespec`` type can be used instead to be embedded in other data structures when separate second/nanosecond values are desired, or passed to user space directly. This is still not ideal though, as the structure matches neither the kernel's timespec64 nor the user space timespec exactly. The get_timespec64() and put_timespec64() helper functions can be used to ensure that the layout remains compatible with user space and the padding is treated correctly.”h]”(hŒThe ”…””}”(hjh²hh³Nh´Nubj )”}”(hŒ``struct __kernel_timespec``”h]”hŒstruct __kernel_timespec”…””}”(hj&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjubhXÁ type can be used instead to be embedded in other data structures when separate second/nanosecond values are desired, or passed to user space directly. This is still not ideal though, as the structure matches neither the kernel’s timespec64 nor the user space timespec exactly. The get_timespec64() and put_timespec64() helper functions can be used to ensure that the layout remains compatible with user space and the padding is treated correctly.”…””}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K\hjÛh²hubhÌ)”}”(hŒ¬As it is cheap to convert seconds to nanoseconds, but the opposite requires an expensive 64-bit division, a simple __u64 nanosecond value can be simpler and more efficient.”h]”hŒ¬As it is cheap to convert seconds to nanoseconds, but the opposite requires an expensive 64-bit division, a simple __u64 nanosecond value can be simpler and more efficient.”…””}”(hj>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KdhjÛh²hubhÌ)”}”(hXTimeout values and timestamps should ideally use CLOCK_MONOTONIC time, as returned by ktime_get_ns() or ktime_get_ts64(). Unlike CLOCK_REALTIME, this makes the timestamps immune from jumping backwards or forwards due to leap second adjustments and clock_settime() calls.”h]”hXTimeout values and timestamps should ideally use CLOCK_MONOTONIC time, as returned by ktime_get_ns() or ktime_get_ts64(). Unlike CLOCK_REALTIME, this makes the timestamps immune from jumping backwards or forwards due to leap second adjustments and clock_settime() calls.”…””}”(hjLh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhhjÛh²hubhÌ)”}”(hŒ†ktime_get_real_ns() can be used for CLOCK_REALTIME timestamps that need to be persistent across a reboot or between multiple machines.”h]”hŒ†ktime_get_real_ns() can be used for CLOCK_REALTIME timestamps that need to be persistent across a reboot or between multiple machines.”…””}”(hjZh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KmhjÛh²hubeh}”(h]”Œ timestamps”ah ]”h"]”Œ timestamps”ah$]”h&]”uh1hµhh·h²hh³hÊh´KUubh¶)”}”(hhh]”(h»)”}”(hŒ32-bit compat mode”h]”hŒ32-bit compat mode”…””}”(hjsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjph²hh³hÊh´KqubhÌ)”}”(hŒÁIn order to support 32-bit user space running on a 64-bit machine, each subsystem or driver that implements an ioctl callback handler must also implement the corresponding compat_ioctl handler.”h]”hŒÁIn order to support 32-bit user space running on a 64-bit machine, each subsystem or driver that implements an ioctl callback handler must also implement the corresponding compat_ioctl handler.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kshjph²hubhÌ)”}”(hŒ½As long as all the rules for data structures are followed, this is as easy as setting the .compat_ioctl pointer to a helper function such as compat_ptr_ioctl() or blkdev_compat_ptr_ioctl().”h]”hŒ½As long as all the rules for data structures are followed, this is as easy as setting the .compat_ioctl pointer to a helper function such as compat_ptr_ioctl() or blkdev_compat_ptr_ioctl().”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kwhjph²hubh¶)”}”(hhh]”(h»)”}”(hŒ compat_ptr()”h]”hŒ compat_ptr()”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjh²hh³hÊh´K|ubhÌ)”}”(hX{On the s390 architecture, 31-bit user space has ambiguous representations for data pointers, with the upper bit being ignored. When running such a process in compat mode, the compat_ptr() helper must be used to clear the upper bit of a compat_uptr_t and turn it into a valid 64-bit pointer. On other architectures, this macro only performs a cast to a ``void __user *`` pointer.”h]”(hXaOn the s390 architecture, 31-bit user space has ambiguous representations for data pointers, with the upper bit being ignored. When running such a process in compat mode, the compat_ptr() helper must be used to clear the upper bit of a compat_uptr_t and turn it into a valid 64-bit pointer. On other architectures, this macro only performs a cast to a ”…””}”(hj®h²hh³Nh´Nubj )”}”(hŒ``void __user *``”h]”hŒ void __user *”…””}”(hj¶h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj®ubhŒ pointer.”…””}”(hj®h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K~hjh²hubhÌ)”}”(hX>In an compat_ioctl() callback, the last argument is an unsigned long, which can be interpreted as either a pointer or a scalar depending on the command. If it is a scalar, then compat_ptr() must not be used, to ensure that the 64-bit kernel behaves the same way as a 32-bit kernel for arguments with the upper bit set.”h]”hX>In an compat_ioctl() callback, the last argument is an unsigned long, which can be interpreted as either a pointer or a scalar depending on the command. If it is a scalar, then compat_ptr() must not be used, to ensure that the 64-bit kernel behaves the same way as a 32-bit kernel for arguments with the upper bit set.”…””}”(hjÎh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K…hjh²hubhÌ)”}”(hŒ°The compat_ptr_ioctl() helper can be used in place of a custom compat_ioctl file operation for drivers that only take arguments that are pointers to compatible data structures.”h]”hŒ°The compat_ptr_ioctl() helper can be used in place of a custom compat_ioctl file operation for drivers that only take arguments that are pointers to compatible data structures.”…””}”(hjÜh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K‹hjh²hubeh}”(h]”Œ compat-ptr”ah ]”h"]”Œ compat_ptr()”ah$]”h&]”uh1hµhjph²hh³hÊh´K|ubh¶)”}”(hhh]”(h»)”}”(hŒStructure layout”h]”hŒStructure layout”…””}”(hjõh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjòh²hh³hÊh´KubhÌ)”}”(hŒgCompatible data structures have the same layout on all architectures, avoiding all problematic members:”h]”hŒgCompatible data structures have the same layout on all architectures, avoiding all problematic members:”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K’hjòh²hubhŒ bullet_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒä``long`` and ``unsigned long`` are the size of a register, so they can be either 32-bit or 64-bit wide and cannot be used in portable data structures. Fixed-length replacements are ``__s32``, ``__u32``, ``__s64`` and ``__u64``. ”h]”hÌ)”}”(hŒã``long`` and ``unsigned long`` are the size of a register, so they can be either 32-bit or 64-bit wide and cannot be used in portable data structures. Fixed-length replacements are ``__s32``, ``__u32``, ``__s64`` and ``__u64``.”h]”(j )”}”(hŒ``long``”h]”hŒlong”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjubhŒ and ”…””}”(hjh²hh³Nh´Nubj )”}”(hŒ``unsigned long``”h]”hŒ unsigned long”…””}”(hj2h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjubhŒ— are the size of a register, so they can be either 32-bit or 64-bit wide and cannot be used in portable data structures. Fixed-length replacements are ”…””}”(hjh²hh³Nh´Nubj )”}”(hŒ ``__s32``”h]”hŒ__s32”…””}”(hjDh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjubhŒ, ”…””}”(hjh²hh³Nh´Nubj )”}”(hŒ ``__u32``”h]”hŒ__u32”…””}”(hjVh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjubhŒ, ”…””}”(hjh²hh³Nh´Nubj )”}”(hŒ ``__s64``”h]”hŒ__s64”…””}”(hjhh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjubhŒ and ”…””}”hjsbj )”}”(hŒ ``__u64``”h]”hŒ__u64”…””}”(hjzh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjubhŒ.”…””}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K•hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjh²hh³hÊh´Nubj)”}”(hXPointers have the same problem, in addition to requiring the use of compat_ptr(). The best workaround is to use ``__u64`` in place of pointers, which requires a cast to ``uintptr_t`` in user space, and the use of u64_to_user_ptr() in the kernel to convert it back into a user pointer. ”h]”hÌ)”}”(hXPointers have the same problem, in addition to requiring the use of compat_ptr(). The best workaround is to use ``__u64`` in place of pointers, which requires a cast to ``uintptr_t`` in user space, and the use of u64_to_user_ptr() in the kernel to convert it back into a user pointer.”h]”(hŒpPointers have the same problem, in addition to requiring the use of compat_ptr(). The best workaround is to use ”…””}”(hjœh²hh³Nh´Nubj )”}”(hŒ ``__u64``”h]”hŒ__u64”…””}”(hj¤h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjœubhŒ0 in place of pointers, which requires a cast to ”…””}”(hjœh²hh³Nh´Nubj )”}”(hŒ ``uintptr_t``”h]”hŒ uintptr_t”…””}”(hj¶h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjœubhŒf in user space, and the use of u64_to_user_ptr() in the kernel to convert it back into a user pointer.”…””}”(hjœh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kšhj˜ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjh²hh³hÊh´Nubj)”}”(hX¨On the x86-32 (i386) architecture, the alignment of 64-bit variables is only 32-bit, but they are naturally aligned on most other architectures including x86-64. This means a structure like:: struct foo { __u32 a; __u64 b; __u32 c; }; has four bytes of padding between a and b on x86-64, plus another four bytes of padding at the end, but no padding on i386, and it needs a compat_ioctl conversion handler to translate between the two formats. To avoid this problem, all structures should have their members naturally aligned, or explicit reserved fields added in place of the implicit padding. The ``pahole`` tool can be used for checking the alignment. ”h]”(hÌ)”}”(hŒ¿On the x86-32 (i386) architecture, the alignment of 64-bit variables is only 32-bit, but they are naturally aligned on most other architectures including x86-64. This means a structure like::”h]”hŒ¾On the x86-32 (i386) architecture, the alignment of 64-bit variables is only 32-bit, but they are naturally aligned on most other architectures including x86-64. This means a structure like:”…””}”(hjØh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K hjÔubhŒ literal_block”“”)”}”(hŒ6struct foo { __u32 a; __u64 b; __u32 c; };”h]”hŒ6struct foo { __u32 a; __u64 b; __u32 c; };”…””}”hjèsbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1jæh³hÊh´K¤hjÔubhÌ)”}”(hŒÐhas four bytes of padding between a and b on x86-64, plus another four bytes of padding at the end, but no padding on i386, and it needs a compat_ioctl conversion handler to translate between the two formats.”h]”hŒÐhas four bytes of padding between a and b on x86-64, plus another four bytes of padding at the end, but no padding on i386, and it needs a compat_ioctl conversion handler to translate between the two formats.”…””}”(hjøh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KªhjÔubhÌ)”}”(hŒÒTo avoid this problem, all structures should have their members naturally aligned, or explicit reserved fields added in place of the implicit padding. The ``pahole`` tool can be used for checking the alignment.”h]”(hŒ›To avoid this problem, all structures should have their members naturally aligned, or explicit reserved fields added in place of the implicit padding. The ”…””}”(hjh²hh³Nh´Nubj )”}”(hŒ ``pahole``”h]”hŒpahole”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjubhŒ- tool can be used for checking the alignment.”…””}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K®hjÔubeh}”(h]”h ]”h"]”h$]”h&]”uh1jhjh²hh³hÊh´Nubj)”}”(hŒ©On ARM OABI user space, structures are padded to multiples of 32-bit, making some structs incompatible with modern EABI kernels if they do not end on a 32-bit boundary. ”h]”hÌ)”}”(hŒ¨On ARM OABI user space, structures are padded to multiples of 32-bit, making some structs incompatible with modern EABI kernels if they do not end on a 32-bit boundary.”h]”hŒ¨On ARM OABI user space, structures are padded to multiples of 32-bit, making some structs incompatible with modern EABI kernels if they do not end on a 32-bit boundary.”…””}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K³hj,ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjh²hh³hÊh´Nubj)”}”(hŒ›On the m68k architecture, struct members are not guaranteed to have an alignment greater than 16-bit, which is a problem when relying on implicit padding. ”h]”hÌ)”}”(hŒšOn the m68k architecture, struct members are not guaranteed to have an alignment greater than 16-bit, which is a problem when relying on implicit padding.”h]”hŒšOn the m68k architecture, struct members are not guaranteed to have an alignment greater than 16-bit, which is a problem when relying on implicit padding.”…””}”(hjHh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K·hjDubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjh²hh³hÊh´Nubj)”}”(hŒ¶Bitfields and enums generally work as one would expect them to, but some properties of them are implementation-defined, so it is better to avoid them completely in ioctl interfaces. ”h]”hÌ)”}”(hŒµBitfields and enums generally work as one would expect them to, but some properties of them are implementation-defined, so it is better to avoid them completely in ioctl interfaces.”h]”hŒµBitfields and enums generally work as one would expect them to, but some properties of them are implementation-defined, so it is better to avoid them completely in ioctl interfaces.”…””}”(hj`h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K»hj\ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjh²hh³hÊh´Nubj)”}”(hŒÏ``char`` members can be either signed or unsigned, depending on the architecture, so the __u8 and __s8 types should be used for 8-bit integer values, though char arrays are clearer for fixed-length strings. ”h]”hÌ)”}”(hŒÎ``char`` members can be either signed or unsigned, depending on the architecture, so the __u8 and __s8 types should be used for 8-bit integer values, though char arrays are clearer for fixed-length strings.”h]”(j )”}”(hŒ``char``”h]”hŒchar”…””}”(hj|h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjxubhŒÆ members can be either signed or unsigned, depending on the architecture, so the __u8 and __s8 types should be used for 8-bit integer values, though char arrays are clearer for fixed-length strings.”…””}”(hjxh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K¿hjtubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjh²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ*”uh1jh³hÊh´K•hjòh²hubeh}”(h]”Œstructure-layout”ah ]”h"]”Œstructure layout”ah$]”h&]”uh1hµhjph²hh³hÊh´Kubeh}”(h]”Œbit-compat-mode”ah ]”h"]”Œ32-bit compat mode”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kqubh¶)”}”(hhh]”(h»)”}”(hŒInformation leaks”h]”hŒInformation leaks”…””}”(hjµh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj²h²hh³hÊh´KÄubhÌ)”}”(hŒÅUninitialized data must not be copied back to user space, as this can cause an information leak, which can be used to defeat kernel address space layout randomization (KASLR), helping in an attack.”h]”hŒÅUninitialized data must not be copied back to user space, as this can cause an information leak, which can be used to defeat kernel address space layout randomization (KASLR), helping in an attack.”…””}”(hjÃh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÆhj²h²hubhÌ)”}”(hXcFor this reason (and for compat support) it is best to avoid any implicit padding in data structures. Where there is implicit padding in an existing structure, kernel drivers must be careful to fully initialize an instance of the structure before copying it to user space. This is usually done by calling memset() before assigning to individual members.”h]”hXcFor this reason (and for compat support) it is best to avoid any implicit padding in data structures. Where there is implicit padding in an existing structure, kernel drivers must be careful to fully initialize an instance of the structure before copying it to user space. This is usually done by calling memset() before assigning to individual members.”…””}”(hjÑh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÊhj²h²hubeh}”(h]”Œinformation-leaks”ah ]”h"]”Œinformation leaks”ah$]”h&]”uh1hµhh·h²hh³hÊh´KÄubh¶)”}”(hhh]”(h»)”}”(hŒSubsystem abstractions”h]”hŒSubsystem abstractions”…””}”(hjêh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjçh²hh³hÊh´KÒubhÌ)”}”(hX7While some device drivers implement their own ioctl function, most subsystems implement the same command for multiple drivers. Ideally the subsystem has an .ioctl() handler that copies the arguments from and to user space, passing them into subsystem specific callback functions through normal kernel pointers.”h]”hX7While some device drivers implement their own ioctl function, most subsystems implement the same command for multiple drivers. Ideally the subsystem has an .ioctl() handler that copies the arguments from and to user space, passing them into subsystem specific callback functions through normal kernel pointers.”…””}”(hjøh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÔhjçh²hubhÌ)”}”(hŒThis helps in various ways:”h]”hŒThis helps in various ways:”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÚhjçh²hubj)”}”(hhh]”(j)”}”(hŒœApplications written for one driver are more likely to work for another one in the same subsystem if there are no subtle differences in the user space ABI. ”h]”hÌ)”}”(hŒ›Applications written for one driver are more likely to work for another one in the same subsystem if there are no subtle differences in the user space ABI.”h]”hŒ›Applications written for one driver are more likely to work for another one in the same subsystem if there are no subtle differences in the user space ABI.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÜhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjh²hh³hÊh´Nubj)”}”(hŒ„The complexity of user space access and data structure layout is done in one place, reducing the potential for implementation bugs. ”h]”hÌ)”}”(hŒƒThe complexity of user space access and data structure layout is done in one place, reducing the potential for implementation bugs.”h]”hŒƒThe complexity of user space access and data structure layout is done in one place, reducing the potential for implementation bugs.”…””}”(hj3h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kàhj/ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjh²hh³hÊh´Nubj)”}”(hŒÃIt is more likely to be reviewed by experienced developers that can spot problems in the interface when the ioctl is shared between multiple drivers than when it is only used in a single driver. ”h]”hÌ)”}”(hŒÂIt is more likely to be reviewed by experienced developers that can spot problems in the interface when the ioctl is shared between multiple drivers than when it is only used in a single driver.”h]”hŒÂIt is more likely to be reviewed by experienced developers that can spot problems in the interface when the ioctl is shared between multiple drivers than when it is only used in a single driver.”…””}”(hjKh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KãhjGubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjh²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”j j¡uh1jh³hÊh´KÜhjçh²hubeh}”(h]”Œsubsystem-abstractions”ah ]”h"]”Œsubsystem abstractions”ah$]”h&]”uh1hµhh·h²hh³hÊh´KÒubh¶)”}”(hhh]”(h»)”}”(hŒAlternatives to ioctl”h]”hŒAlternatives to ioctl”…””}”(hjph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjmh²hh³hÊh´KèubhÌ)”}”(hŒaThere are many cases in which ioctl is not the best solution for a problem. Alternatives include:”h]”hŒaThere are many cases in which ioctl is not the best solution for a problem. Alternatives include:”…””}”(hj~h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kêhjmh²hubj)”}”(hhh]”(j)”}”(hŒªSystem calls are a better choice for a system-wide feature that is not tied to a physical device or constrained by the file system permissions of a character device node ”h]”hÌ)”}”(hŒ©System calls are a better choice for a system-wide feature that is not tied to a physical device or constrained by the file system permissions of a character device node”h]”hŒ©System calls are a better choice for a system-wide feature that is not tied to a physical device or constrained by the file system permissions of a character device node”…””}”(hj“h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kíhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjŒh²hh³hÊh´Nubj)”}”(hŒYnetlink is the preferred way of configuring any network related objects through sockets. ”h]”hÌ)”}”(hŒXnetlink is the preferred way of configuring any network related objects through sockets.”h]”hŒXnetlink is the preferred way of configuring any network related objects through sockets.”…””}”(hj«h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kñhj§ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjŒh²hh³hÊh´Nubj)”}”(hŒŠdebugfs is used for ad-hoc interfaces for debugging functionality that does not need to be exposed as a stable interface to applications. ”h]”hÌ)”}”(hŒ‰debugfs is used for ad-hoc interfaces for debugging functionality that does not need to be exposed as a stable interface to applications.”h]”hŒ‰debugfs is used for ad-hoc interfaces for debugging functionality that does not need to be exposed as a stable interface to applications.”…””}”(hjÃh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kôhj¿ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjŒh²hh³hÊh´Nubj)”}”(hŒfsysfs is a good way to expose the state of an in-kernel object that is not tied to a file descriptor. ”h]”hÌ)”}”(hŒesysfs is a good way to expose the state of an in-kernel object that is not tied to a file descriptor.”h]”hŒesysfs is a good way to expose the state of an in-kernel object that is not tied to a file descriptor.”…””}”(hjÛh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K÷hj×ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjŒh²hh³hÊh´Nubj)”}”(hŒ?configfs can be used for more complex configuration than sysfs ”h]”hÌ)”}”(hŒ>configfs can be used for more complex configuration than sysfs”h]”hŒ>configfs can be used for more complex configuration than sysfs”…””}”(hjóh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kúhjïubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjŒh²hh³hÊh´Nubj)”}”(hŒƒA custom file system can provide extra flexibility with a simple user interface but adds a lot of complexity to the implementation.”h]”hÌ)”}”(hŒƒA custom file system can provide extra flexibility with a simple user interface but adds a lot of complexity to the implementation.”h]”hŒƒA custom file system can provide extra flexibility with a simple user interface but adds a lot of complexity to the implementation.”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kühjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjŒh²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”j j¡uh1jh³hÊh´Kíhjmh²hubeh}”(h]”Œalternatives-to-ioctl”ah ]”h"]”Œalternatives to ioctl”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kèubeh}”(h]”Œioctl-based-interfaces”ah ]”h"]”Œioctl based interfaces”ah$]”h&]”uh1hµhhh²hh³hÊh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÊuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(hºNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”jXŒerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÊŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(j2j/jRjOj•j’jØjÕjmjjj¯j¬jïjìj§j¤jäjájjjgj*j'uŒ nametypes”}”(j2‰jR‰j•‰j؉jm‰j¯‰jï‰j§‰jä‰jj‰j*‰uh}”(j/h·jOhéj’jUjÕj˜jjjÛj¬jpjìjj¤jòjáj²jgjçj'jmuŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.