mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	rust: use custom FFI integer types
Currently FFI integer types are defined in libcore. This commit creates the `ffi` crate and asks bindgen to use that crate for FFI integer types instead of `core::ffi`. This commit is preparatory and no type changes are made in this commit yet. Signed-off-by: Gary Guo <gary@garyguo.net> Link: https://lore.kernel.org/r/20240913213041.395655-4-gary@garyguo.net [ Added `rustdoc`, `rusttest` and KUnit tests support. Rebased on top of `rust-next` (e.g. migrated more `core::ffi` cases). Reworded crate docs slightly and formatted. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
		
							parent
							
								
									2fd6f55c04
								
							
						
					
					
						commit
						d072acda48
					
				
					 23 changed files with 107 additions and 83 deletions
				
			
		|  | @ -3,7 +3,7 @@ | ||||||
| # Where to place rustdoc generated documentation
 | # Where to place rustdoc generated documentation
 | ||||||
| rustdoc_output := $(objtree)/Documentation/output/rust/rustdoc | rustdoc_output := $(objtree)/Documentation/output/rust/rustdoc | ||||||
| 
 | 
 | ||||||
| obj-$(CONFIG_RUST) += core.o compiler_builtins.o | obj-$(CONFIG_RUST) += core.o compiler_builtins.o ffi.o | ||||||
| always-$(CONFIG_RUST) += exports_core_generated.h | always-$(CONFIG_RUST) += exports_core_generated.h | ||||||
| 
 | 
 | ||||||
| # Missing prototypes are expected in the helpers since these are exported
 | # Missing prototypes are expected in the helpers since these are exported
 | ||||||
|  | @ -103,10 +103,13 @@ rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs FORCE | ||||||
| rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE | rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE | ||||||
| 	+$(call if_changed,rustdoc) | 	+$(call if_changed,rustdoc) | ||||||
| 
 | 
 | ||||||
| rustdoc-kernel: private rustc_target_flags = \ | rustdoc-ffi: $(src)/ffi.rs rustdoc-core FORCE | ||||||
|  | 	+$(call if_changed,rustdoc) | ||||||
|  | 
 | ||||||
|  | rustdoc-kernel: private rustc_target_flags = --extern ffi \ | ||||||
|     --extern build_error --extern macros=$(objtree)/$(obj)/libmacros.so \
 |     --extern build_error --extern macros=$(objtree)/$(obj)/libmacros.so \
 | ||||||
|     --extern bindings --extern uapi |     --extern bindings --extern uapi | ||||||
| rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-macros \ | rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-ffi rustdoc-macros \ | ||||||
|     rustdoc-compiler_builtins $(obj)/libmacros.so \
 |     rustdoc-compiler_builtins $(obj)/libmacros.so \
 | ||||||
|     $(obj)/bindings.o FORCE |     $(obj)/bindings.o FORCE | ||||||
| 	+$(call if_changed,rustdoc) | 	+$(call if_changed,rustdoc) | ||||||
|  | @ -124,12 +127,15 @@ quiet_cmd_rustc_test_library = RUSTC TL $< | ||||||
| rusttestlib-build_error: $(src)/build_error.rs FORCE | rusttestlib-build_error: $(src)/build_error.rs FORCE | ||||||
| 	+$(call if_changed,rustc_test_library) | 	+$(call if_changed,rustc_test_library) | ||||||
| 
 | 
 | ||||||
|  | rusttestlib-ffi: $(src)/ffi.rs FORCE | ||||||
|  | 	+$(call if_changed,rustc_test_library) | ||||||
|  | 
 | ||||||
| rusttestlib-macros: private rustc_target_flags = --extern proc_macro | rusttestlib-macros: private rustc_target_flags = --extern proc_macro | ||||||
| rusttestlib-macros: private rustc_test_library_proc = yes | rusttestlib-macros: private rustc_test_library_proc = yes | ||||||
| rusttestlib-macros: $(src)/macros/lib.rs FORCE | rusttestlib-macros: $(src)/macros/lib.rs FORCE | ||||||
| 	+$(call if_changed,rustc_test_library) | 	+$(call if_changed,rustc_test_library) | ||||||
| 
 | 
 | ||||||
| rusttestlib-kernel: private rustc_target_flags = \ | rusttestlib-kernel: private rustc_target_flags = --extern ffi \ | ||||||
|     --extern build_error --extern macros \
 |     --extern build_error --extern macros \
 | ||||||
|     --extern bindings --extern uapi |     --extern bindings --extern uapi | ||||||
| rusttestlib-kernel: $(src)/kernel/lib.rs \ | rusttestlib-kernel: $(src)/kernel/lib.rs \ | ||||||
|  | @ -137,10 +143,12 @@ rusttestlib-kernel: $(src)/kernel/lib.rs \ | ||||||
|     $(obj)/libmacros.so $(obj)/bindings.o FORCE |     $(obj)/libmacros.so $(obj)/bindings.o FORCE | ||||||
| 	+$(call if_changed,rustc_test_library) | 	+$(call if_changed,rustc_test_library) | ||||||
| 
 | 
 | ||||||
| rusttestlib-bindings: $(src)/bindings/lib.rs FORCE | rusttestlib-bindings: private rustc_target_flags = --extern ffi | ||||||
|  | rusttestlib-bindings: $(src)/bindings/lib.rs rusttestlib-ffi FORCE | ||||||
| 	+$(call if_changed,rustc_test_library) | 	+$(call if_changed,rustc_test_library) | ||||||
| 
 | 
 | ||||||
| rusttestlib-uapi: $(src)/uapi/lib.rs FORCE | rusttestlib-uapi: private rustc_target_flags = --extern ffi | ||||||
|  | rusttestlib-uapi: $(src)/uapi/lib.rs rusttestlib-ffi FORCE | ||||||
| 	+$(call if_changed,rustc_test_library) | 	+$(call if_changed,rustc_test_library) | ||||||
| 
 | 
 | ||||||
| quiet_cmd_rustdoc_test = RUSTDOC T $< | quiet_cmd_rustdoc_test = RUSTDOC T $< | ||||||
|  | @ -160,7 +168,7 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC TK $< | ||||||
| 	mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \
 | 	mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \
 | ||||||
| 	OBJTREE=$(abspath $(objtree)) \
 | 	OBJTREE=$(abspath $(objtree)) \
 | ||||||
| 	$(RUSTDOC) --test $(rust_flags) \
 | 	$(RUSTDOC) --test $(rust_flags) \
 | ||||||
| 		-L$(objtree)/$(obj) --extern kernel \
 | 		-L$(objtree)/$(obj) --extern ffi --extern kernel \
 | ||||||
| 		--extern build_error --extern macros \
 | 		--extern build_error --extern macros \
 | ||||||
| 		--extern bindings --extern uapi \
 | 		--extern bindings --extern uapi \
 | ||||||
| 		--no-run --crate-name kernel -Zunstable-options \
 | 		--no-run --crate-name kernel -Zunstable-options \
 | ||||||
|  | @ -198,9 +206,9 @@ rusttest-macros: $(src)/macros/lib.rs \ | ||||||
| 	+$(call if_changed,rustc_test) | 	+$(call if_changed,rustc_test) | ||||||
| 	+$(call if_changed,rustdoc_test) | 	+$(call if_changed,rustdoc_test) | ||||||
| 
 | 
 | ||||||
| rusttest-kernel: private rustc_target_flags = \ | rusttest-kernel: private rustc_target_flags = --extern ffi \ | ||||||
|     --extern build_error --extern macros --extern bindings --extern uapi |     --extern build_error --extern macros --extern bindings --extern uapi | ||||||
| rusttest-kernel: $(src)/kernel/lib.rs rusttestlib-kernel \ | rusttest-kernel: $(src)/kernel/lib.rs rusttestlib-ffi rusttestlib-kernel \ | ||||||
|     rusttestlib-build_error rusttestlib-macros rusttestlib-bindings \
 |     rusttestlib-build_error rusttestlib-macros rusttestlib-bindings \
 | ||||||
|     rusttestlib-uapi FORCE |     rusttestlib-uapi FORCE | ||||||
| 	+$(call if_changed,rustc_test) | 	+$(call if_changed,rustc_test) | ||||||
|  | @ -273,7 +281,7 @@ bindgen_c_flags_final = $(bindgen_c_flags_lto) -fno-builtin -D__BINDGEN__ | ||||||
| quiet_cmd_bindgen = BINDGEN $@ | quiet_cmd_bindgen = BINDGEN $@ | ||||||
|       cmd_bindgen = \
 |       cmd_bindgen = \
 | ||||||
| 	$(BINDGEN) $< $(bindgen_target_flags) \
 | 	$(BINDGEN) $< $(bindgen_target_flags) \
 | ||||||
| 		--use-core --with-derive-default --ctypes-prefix core::ffi --no-layout-tests \
 | 		--use-core --with-derive-default --ctypes-prefix ffi --no-layout-tests \
 | ||||||
| 		--no-debug '.*' --enable-function-attribute-detection \
 | 		--no-debug '.*' --enable-function-attribute-detection \
 | ||||||
| 		-o $@ -- $(bindgen_c_flags_final) -DMODULE \
 | 		-o $@ -- $(bindgen_c_flags_final) -DMODULE \
 | ||||||
| 		$(bindgen_target_cflags) $(bindgen_target_extra) | 		$(bindgen_target_cflags) $(bindgen_target_extra) | ||||||
|  | @ -401,18 +409,23 @@ $(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE | ||||||
| $(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE | $(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE | ||||||
| 	+$(call if_changed_rule,rustc_library) | 	+$(call if_changed_rule,rustc_library) | ||||||
| 
 | 
 | ||||||
|  | $(obj)/ffi.o: $(src)/ffi.rs $(obj)/compiler_builtins.o FORCE | ||||||
|  | 	+$(call if_changed_rule,rustc_library) | ||||||
|  | 
 | ||||||
|  | $(obj)/bindings.o: private rustc_target_flags = --extern ffi | ||||||
| $(obj)/bindings.o: $(src)/bindings/lib.rs \ | $(obj)/bindings.o: $(src)/bindings/lib.rs \ | ||||||
|     $(obj)/compiler_builtins.o \
 |     $(obj)/ffi.o \
 | ||||||
|     $(obj)/bindings/bindings_generated.rs \
 |     $(obj)/bindings/bindings_generated.rs \
 | ||||||
|     $(obj)/bindings/bindings_helpers_generated.rs FORCE |     $(obj)/bindings/bindings_helpers_generated.rs FORCE | ||||||
| 	+$(call if_changed_rule,rustc_library) | 	+$(call if_changed_rule,rustc_library) | ||||||
| 
 | 
 | ||||||
|  | $(obj)/uapi.o: private rustc_target_flags = --extern ffi | ||||||
| $(obj)/uapi.o: $(src)/uapi/lib.rs \ | $(obj)/uapi.o: $(src)/uapi/lib.rs \ | ||||||
|     $(obj)/compiler_builtins.o \
 |     $(obj)/ffi.o \
 | ||||||
|     $(obj)/uapi/uapi_generated.rs FORCE |     $(obj)/uapi/uapi_generated.rs FORCE | ||||||
| 	+$(call if_changed_rule,rustc_library) | 	+$(call if_changed_rule,rustc_library) | ||||||
| 
 | 
 | ||||||
| $(obj)/kernel.o: private rustc_target_flags = \ | $(obj)/kernel.o: private rustc_target_flags = --extern ffi \ | ||||||
|     --extern build_error --extern macros --extern bindings --extern uapi |     --extern build_error --extern macros --extern bindings --extern uapi | ||||||
| $(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/build_error.o \ | $(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/build_error.o \ | ||||||
|     $(obj)/libmacros.so $(obj)/bindings.o $(obj)/uapi.o FORCE |     $(obj)/libmacros.so $(obj)/bindings.o $(obj)/uapi.o FORCE | ||||||
|  |  | ||||||
							
								
								
									
										13
									
								
								rust/ffi.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								rust/ffi.rs
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | ||||||
|  | // SPDX-License-Identifier: GPL-2.0
 | ||||||
|  | 
 | ||||||
|  | //! Foreign function interface (FFI) types.
 | ||||||
|  | //!
 | ||||||
|  | //! This crate provides mapping from C primitive types to Rust ones.
 | ||||||
|  | //!
 | ||||||
|  | //! The Rust [`core`] crate provides [`core::ffi`], which maps integer types to the platform default
 | ||||||
|  | //! C ABI. The kernel does not use [`core::ffi`], so it can customise the mapping that deviates from
 | ||||||
|  | //! the platform default.
 | ||||||
|  | 
 | ||||||
|  | #![no_std] | ||||||
|  | 
 | ||||||
|  | pub use core::ffi::*; | ||||||
|  | @ -58,7 +58,7 @@ fn aligned_size(new_layout: Layout) -> usize { | ||||||
| ///
 | ///
 | ||||||
| /// One of the following: `krealloc`, `vrealloc`, `kvrealloc`.
 | /// One of the following: `krealloc`, `vrealloc`, `kvrealloc`.
 | ||||||
| struct ReallocFunc( | struct ReallocFunc( | ||||||
|     unsafe extern "C" fn(*const core::ffi::c_void, usize, u32) -> *mut core::ffi::c_void, |     unsafe extern "C" fn(*const crate::ffi::c_void, usize, u32) -> *mut crate::ffi::c_void, | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| impl ReallocFunc { | impl ReallocFunc { | ||||||
|  |  | ||||||
|  | @ -24,10 +24,10 @@ | ||||||
| 
 | 
 | ||||||
| extern "C" { | extern "C" { | ||||||
|     #[link_name = "aligned_alloc"] |     #[link_name = "aligned_alloc"] | ||||||
|     fn libc_aligned_alloc(align: usize, size: usize) -> *mut core::ffi::c_void; |     fn libc_aligned_alloc(align: usize, size: usize) -> *mut crate::ffi::c_void; | ||||||
| 
 | 
 | ||||||
|     #[link_name = "free"] |     #[link_name = "free"] | ||||||
|     fn libc_free(ptr: *mut core::ffi::c_void); |     fn libc_free(ptr: *mut crate::ffi::c_void); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SAFETY:
 | // SAFETY:
 | ||||||
|  |  | ||||||
|  | @ -355,17 +355,17 @@ impl<T: 'static, A> ForeignOwnable for Box<T, A> | ||||||
| { | { | ||||||
|     type Borrowed<'a> = &'a T; |     type Borrowed<'a> = &'a T; | ||||||
| 
 | 
 | ||||||
|     fn into_foreign(self) -> *const core::ffi::c_void { |     fn into_foreign(self) -> *const crate::ffi::c_void { | ||||||
|         Box::into_raw(self) as _ |         Box::into_raw(self) as _ | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { |     unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self { | ||||||
|         // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
 |         // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
 | ||||||
|         // call to `Self::into_foreign`.
 |         // call to `Self::into_foreign`.
 | ||||||
|         unsafe { Box::from_raw(ptr as _) } |         unsafe { Box::from_raw(ptr as _) } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> &'a T { |     unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> &'a T { | ||||||
|         // SAFETY: The safety requirements of this method ensure that the object remains alive and
 |         // SAFETY: The safety requirements of this method ensure that the object remains alive and
 | ||||||
|         // immutable for the duration of 'a.
 |         // immutable for the duration of 'a.
 | ||||||
|         unsafe { &*ptr.cast() } |         unsafe { &*ptr.cast() } | ||||||
|  | @ -378,18 +378,18 @@ impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>> | ||||||
| { | { | ||||||
|     type Borrowed<'a> = Pin<&'a T>; |     type Borrowed<'a> = Pin<&'a T>; | ||||||
| 
 | 
 | ||||||
|     fn into_foreign(self) -> *const core::ffi::c_void { |     fn into_foreign(self) -> *const crate::ffi::c_void { | ||||||
|         // SAFETY: We are still treating the box as pinned.
 |         // SAFETY: We are still treating the box as pinned.
 | ||||||
|         Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) as _ |         Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) as _ | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { |     unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self { | ||||||
|         // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
 |         // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous
 | ||||||
|         // call to `Self::into_foreign`.
 |         // call to `Self::into_foreign`.
 | ||||||
|         unsafe { Pin::new_unchecked(Box::from_raw(ptr as _)) } |         unsafe { Pin::new_unchecked(Box::from_raw(ptr as _)) } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Pin<&'a T> { |     unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Pin<&'a T> { | ||||||
|         // SAFETY: The safety requirements for this function ensure that the object is still alive,
 |         // SAFETY: The safety requirements for this function ensure that the object is still alive,
 | ||||||
|         // so it is safe to dereference the raw pointer.
 |         // so it is safe to dereference the raw pointer.
 | ||||||
|         // The safety requirements of `from_foreign` also ensure that the object remains alive for
 |         // The safety requirements of `from_foreign` also ensure that the object remains alive for
 | ||||||
|  |  | ||||||
|  | @ -131,7 +131,7 @@ impl<T: Operations> OperationsVTable<T> { | ||||||
|     unsafe extern "C" fn poll_callback( |     unsafe extern "C" fn poll_callback( | ||||||
|         _hctx: *mut bindings::blk_mq_hw_ctx, |         _hctx: *mut bindings::blk_mq_hw_ctx, | ||||||
|         _iob: *mut bindings::io_comp_batch, |         _iob: *mut bindings::io_comp_batch, | ||||||
|     ) -> core::ffi::c_int { |     ) -> crate::ffi::c_int { | ||||||
|         T::poll().into() |         T::poll().into() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -145,9 +145,9 @@ impl<T: Operations> OperationsVTable<T> { | ||||||
|     /// for the same context.
 |     /// for the same context.
 | ||||||
|     unsafe extern "C" fn init_hctx_callback( |     unsafe extern "C" fn init_hctx_callback( | ||||||
|         _hctx: *mut bindings::blk_mq_hw_ctx, |         _hctx: *mut bindings::blk_mq_hw_ctx, | ||||||
|         _tagset_data: *mut core::ffi::c_void, |         _tagset_data: *mut crate::ffi::c_void, | ||||||
|         _hctx_idx: core::ffi::c_uint, |         _hctx_idx: crate::ffi::c_uint, | ||||||
|     ) -> core::ffi::c_int { |     ) -> crate::ffi::c_int { | ||||||
|         from_result(|| Ok(0)) |         from_result(|| Ok(0)) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -159,7 +159,7 @@ impl<T: Operations> OperationsVTable<T> { | ||||||
|     /// This function may only be called by blk-mq C infrastructure.
 |     /// This function may only be called by blk-mq C infrastructure.
 | ||||||
|     unsafe extern "C" fn exit_hctx_callback( |     unsafe extern "C" fn exit_hctx_callback( | ||||||
|         _hctx: *mut bindings::blk_mq_hw_ctx, |         _hctx: *mut bindings::blk_mq_hw_ctx, | ||||||
|         _hctx_idx: core::ffi::c_uint, |         _hctx_idx: crate::ffi::c_uint, | ||||||
|     ) { |     ) { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -176,9 +176,9 @@ impl<T: Operations> OperationsVTable<T> { | ||||||
|     unsafe extern "C" fn init_request_callback( |     unsafe extern "C" fn init_request_callback( | ||||||
|         _set: *mut bindings::blk_mq_tag_set, |         _set: *mut bindings::blk_mq_tag_set, | ||||||
|         rq: *mut bindings::request, |         rq: *mut bindings::request, | ||||||
|         _hctx_idx: core::ffi::c_uint, |         _hctx_idx: crate::ffi::c_uint, | ||||||
|         _numa_node: core::ffi::c_uint, |         _numa_node: crate::ffi::c_uint, | ||||||
|     ) -> core::ffi::c_int { |     ) -> crate::ffi::c_int { | ||||||
|         from_result(|| { |         from_result(|| { | ||||||
|             // SAFETY: By the safety requirements of this function, `rq` points
 |             // SAFETY: By the safety requirements of this function, `rq` points
 | ||||||
|             // to a valid allocation.
 |             // to a valid allocation.
 | ||||||
|  | @ -203,7 +203,7 @@ impl<T: Operations> OperationsVTable<T> { | ||||||
|     unsafe extern "C" fn exit_request_callback( |     unsafe extern "C" fn exit_request_callback( | ||||||
|         _set: *mut bindings::blk_mq_tag_set, |         _set: *mut bindings::blk_mq_tag_set, | ||||||
|         rq: *mut bindings::request, |         rq: *mut bindings::request, | ||||||
|         _hctx_idx: core::ffi::c_uint, |         _hctx_idx: crate::ffi::c_uint, | ||||||
|     ) { |     ) { | ||||||
|         // SAFETY: The tagset invariants guarantee that all requests are allocated with extra memory
 |         // SAFETY: The tagset invariants guarantee that all requests are allocated with extra memory
 | ||||||
|         // for the request data.
 |         // for the request data.
 | ||||||
|  |  | ||||||
|  | @ -25,7 +25,7 @@ fn new(buffer: &'a mut [u8]) -> Result<RawWriter<'a>> { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub(crate) fn from_array<const N: usize>( |     pub(crate) fn from_array<const N: usize>( | ||||||
|         a: &'a mut [core::ffi::c_char; N], |         a: &'a mut [crate::ffi::c_char; N], | ||||||
|     ) -> Result<RawWriter<'a>> { |     ) -> Result<RawWriter<'a>> { | ||||||
|         Self::new( |         Self::new( | ||||||
|             // SAFETY: the buffer of `a` is valid for read and write as `u8` for
 |             // SAFETY: the buffer of `a` is valid for read and write as `u8` for
 | ||||||
|  |  | ||||||
|  | @ -53,7 +53,7 @@ pub fn new( | ||||||
|                     queue_depth: num_tags, |                     queue_depth: num_tags, | ||||||
|                     cmd_size, |                     cmd_size, | ||||||
|                     flags: bindings::BLK_MQ_F_SHOULD_MERGE, |                     flags: bindings::BLK_MQ_F_SHOULD_MERGE, | ||||||
|                     driver_data: core::ptr::null_mut::<core::ffi::c_void>(), |                     driver_data: core::ptr::null_mut::<crate::ffi::c_void>(), | ||||||
|                     nr_maps: num_maps, |                     nr_maps: num_maps, | ||||||
|                     ..tag_set |                     ..tag_set | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|  | @ -100,7 +100,7 @@ impl Error { | ||||||
|     ///
 |     ///
 | ||||||
|     /// It is a bug to pass an out-of-range `errno`. `EINVAL` would
 |     /// It is a bug to pass an out-of-range `errno`. `EINVAL` would
 | ||||||
|     /// be returned in such a case.
 |     /// be returned in such a case.
 | ||||||
|     pub fn from_errno(errno: core::ffi::c_int) -> Error { |     pub fn from_errno(errno: crate::ffi::c_int) -> Error { | ||||||
|         if errno < -(bindings::MAX_ERRNO as i32) || errno >= 0 { |         if errno < -(bindings::MAX_ERRNO as i32) || errno >= 0 { | ||||||
|             // TODO: Make it a `WARN_ONCE` once available.
 |             // TODO: Make it a `WARN_ONCE` once available.
 | ||||||
|             crate::pr_warn!( |             crate::pr_warn!( | ||||||
|  | @ -119,7 +119,7 @@ pub fn from_errno(errno: core::ffi::c_int) -> Error { | ||||||
|     /// Creates an [`Error`] from a kernel error code.
 |     /// Creates an [`Error`] from a kernel error code.
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// Returns [`None`] if `errno` is out-of-range.
 |     /// Returns [`None`] if `errno` is out-of-range.
 | ||||||
|     const fn try_from_errno(errno: core::ffi::c_int) -> Option<Error> { |     const fn try_from_errno(errno: crate::ffi::c_int) -> Option<Error> { | ||||||
|         if errno < -(bindings::MAX_ERRNO as i32) || errno >= 0 { |         if errno < -(bindings::MAX_ERRNO as i32) || errno >= 0 { | ||||||
|             return None; |             return None; | ||||||
|         } |         } | ||||||
|  | @ -133,7 +133,7 @@ const fn try_from_errno(errno: core::ffi::c_int) -> Option<Error> { | ||||||
|     /// # Safety
 |     /// # Safety
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// `errno` must be within error code range (i.e. `>= -MAX_ERRNO && < 0`).
 |     /// `errno` must be within error code range (i.e. `>= -MAX_ERRNO && < 0`).
 | ||||||
|     const unsafe fn from_errno_unchecked(errno: core::ffi::c_int) -> Error { |     const unsafe fn from_errno_unchecked(errno: crate::ffi::c_int) -> Error { | ||||||
|         // INVARIANT: The contract ensures the type invariant
 |         // INVARIANT: The contract ensures the type invariant
 | ||||||
|         // will hold.
 |         // will hold.
 | ||||||
|         // SAFETY: The caller guarantees `errno` is non-zero.
 |         // SAFETY: The caller guarantees `errno` is non-zero.
 | ||||||
|  | @ -141,7 +141,7 @@ const fn try_from_errno(errno: core::ffi::c_int) -> Option<Error> { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Returns the kernel error code.
 |     /// Returns the kernel error code.
 | ||||||
|     pub fn to_errno(self) -> core::ffi::c_int { |     pub fn to_errno(self) -> crate::ffi::c_int { | ||||||
|         self.0.get() |         self.0.get() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -259,7 +259,7 @@ fn from(e: core::convert::Infallible) -> Error { | ||||||
| 
 | 
 | ||||||
| /// Converts an integer as returned by a C kernel function to an error if it's negative, and
 | /// Converts an integer as returned by a C kernel function to an error if it's negative, and
 | ||||||
| /// `Ok(())` otherwise.
 | /// `Ok(())` otherwise.
 | ||||||
| pub fn to_result(err: core::ffi::c_int) -> Result { | pub fn to_result(err: crate::ffi::c_int) -> Result { | ||||||
|     if err < 0 { |     if err < 0 { | ||||||
|         Err(Error::from_errno(err)) |         Err(Error::from_errno(err)) | ||||||
|     } else { |     } else { | ||||||
|  | @ -282,15 +282,15 @@ pub fn to_result(err: core::ffi::c_int) -> Result { | ||||||
| /// fn devm_platform_ioremap_resource(
 | /// fn devm_platform_ioremap_resource(
 | ||||||
| ///     pdev: &mut PlatformDevice,
 | ///     pdev: &mut PlatformDevice,
 | ||||||
| ///     index: u32,
 | ///     index: u32,
 | ||||||
| /// ) -> Result<*mut core::ffi::c_void> {
 | /// ) -> Result<*mut kernel::ffi::c_void> {
 | ||||||
| ///     // SAFETY: `pdev` points to a valid platform device. There are no safety requirements
 | ///     // SAFETY: `pdev` points to a valid platform device. There are no safety requirements
 | ||||||
| ///     // on `index`.
 | ///     // on `index`.
 | ||||||
| ///     from_err_ptr(unsafe { bindings::devm_platform_ioremap_resource(pdev.to_ptr(), index) })
 | ///     from_err_ptr(unsafe { bindings::devm_platform_ioremap_resource(pdev.to_ptr(), index) })
 | ||||||
| /// }
 | /// }
 | ||||||
| /// ```
 | /// ```
 | ||||||
| pub fn from_err_ptr<T>(ptr: *mut T) -> Result<*mut T> { | pub fn from_err_ptr<T>(ptr: *mut T) -> Result<*mut T> { | ||||||
|     // CAST: Casting a pointer to `*const core::ffi::c_void` is always valid.
 |     // CAST: Casting a pointer to `*const crate::ffi::c_void` is always valid.
 | ||||||
|     let const_ptr: *const core::ffi::c_void = ptr.cast(); |     let const_ptr: *const crate::ffi::c_void = ptr.cast(); | ||||||
|     // SAFETY: The FFI function does not deref the pointer.
 |     // SAFETY: The FFI function does not deref the pointer.
 | ||||||
|     if unsafe { bindings::IS_ERR(const_ptr) } { |     if unsafe { bindings::IS_ERR(const_ptr) } { | ||||||
|         // SAFETY: The FFI function does not deref the pointer.
 |         // SAFETY: The FFI function does not deref the pointer.
 | ||||||
|  | @ -306,7 +306,7 @@ pub fn from_err_ptr<T>(ptr: *mut T) -> Result<*mut T> { | ||||||
|         //
 |         //
 | ||||||
|         // SAFETY: `IS_ERR()` ensures `err` is a
 |         // SAFETY: `IS_ERR()` ensures `err` is a
 | ||||||
|         // negative value greater-or-equal to `-bindings::MAX_ERRNO`.
 |         // negative value greater-or-equal to `-bindings::MAX_ERRNO`.
 | ||||||
|         return Err(unsafe { Error::from_errno_unchecked(err as core::ffi::c_int) }); |         return Err(unsafe { Error::from_errno_unchecked(err as crate::ffi::c_int) }); | ||||||
|     } |     } | ||||||
|     Ok(ptr) |     Ok(ptr) | ||||||
| } | } | ||||||
|  | @ -326,7 +326,7 @@ pub fn from_err_ptr<T>(ptr: *mut T) -> Result<*mut T> { | ||||||
| /// # use kernel::bindings;
 | /// # use kernel::bindings;
 | ||||||
| /// unsafe extern "C" fn probe_callback(
 | /// unsafe extern "C" fn probe_callback(
 | ||||||
| ///     pdev: *mut bindings::platform_device,
 | ///     pdev: *mut bindings::platform_device,
 | ||||||
| /// ) -> core::ffi::c_int {
 | /// ) -> kernel::ffi::c_int {
 | ||||||
| ///     from_result(|| {
 | ///     from_result(|| {
 | ||||||
| ///         let ptr = devm_alloc(pdev)?;
 | ///         let ptr = devm_alloc(pdev)?;
 | ||||||
| ///         bindings::platform_set_drvdata(pdev, ptr);
 | ///         bindings::platform_set_drvdata(pdev, ptr);
 | ||||||
|  |  | ||||||
|  | @ -133,7 +133,7 @@ | ||||||
| //! # }
 | //! # }
 | ||||||
| //! # // `Error::from_errno` is `pub(crate)` in the `kernel` crate, thus provide a workaround.
 | //! # // `Error::from_errno` is `pub(crate)` in the `kernel` crate, thus provide a workaround.
 | ||||||
| //! # trait FromErrno {
 | //! # trait FromErrno {
 | ||||||
| //! #     fn from_errno(errno: core::ffi::c_int) -> Error {
 | //! #     fn from_errno(errno: kernel::ffi::c_int) -> Error {
 | ||||||
| //! #         // Dummy error that can be constructed outside the `kernel` crate.
 | //! #         // Dummy error that can be constructed outside the `kernel` crate.
 | ||||||
| //! #         Error::from(core::fmt::Error)
 | //! #         Error::from(core::fmt::Error)
 | ||||||
| //! #     }
 | //! #     }
 | ||||||
|  |  | ||||||
|  | @ -27,6 +27,8 @@ | ||||||
| // Allow proc-macros to refer to `::kernel` inside the `kernel` crate (this crate).
 | // Allow proc-macros to refer to `::kernel` inside the `kernel` crate (this crate).
 | ||||||
| extern crate self as kernel; | extern crate self as kernel; | ||||||
| 
 | 
 | ||||||
|  | pub use ffi; | ||||||
|  | 
 | ||||||
| pub mod alloc; | pub mod alloc; | ||||||
| #[cfg(CONFIG_BLOCK)] | #[cfg(CONFIG_BLOCK)] | ||||||
| pub mod block; | pub mod block; | ||||||
|  |  | ||||||
|  | @ -314,7 +314,7 @@ impl<T: Driver> Adapter<T> { | ||||||
|     /// `phydev` must be passed by the corresponding callback in `phy_driver`.
 |     /// `phydev` must be passed by the corresponding callback in `phy_driver`.
 | ||||||
|     unsafe extern "C" fn soft_reset_callback( |     unsafe extern "C" fn soft_reset_callback( | ||||||
|         phydev: *mut bindings::phy_device, |         phydev: *mut bindings::phy_device, | ||||||
|     ) -> core::ffi::c_int { |     ) -> crate::ffi::c_int { | ||||||
|         from_result(|| { |         from_result(|| { | ||||||
|             // SAFETY: This callback is called only in contexts
 |             // SAFETY: This callback is called only in contexts
 | ||||||
|             // where we hold `phy_device->lock`, so the accessors on
 |             // where we hold `phy_device->lock`, so the accessors on
 | ||||||
|  | @ -328,7 +328,7 @@ impl<T: Driver> Adapter<T> { | ||||||
|     /// # Safety
 |     /// # Safety
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// `phydev` must be passed by the corresponding callback in `phy_driver`.
 |     /// `phydev` must be passed by the corresponding callback in `phy_driver`.
 | ||||||
|     unsafe extern "C" fn probe_callback(phydev: *mut bindings::phy_device) -> core::ffi::c_int { |     unsafe extern "C" fn probe_callback(phydev: *mut bindings::phy_device) -> crate::ffi::c_int { | ||||||
|         from_result(|| { |         from_result(|| { | ||||||
|             // SAFETY: This callback is called only in contexts
 |             // SAFETY: This callback is called only in contexts
 | ||||||
|             // where we can exclusively access `phy_device` because
 |             // where we can exclusively access `phy_device` because
 | ||||||
|  | @ -345,7 +345,7 @@ impl<T: Driver> Adapter<T> { | ||||||
|     /// `phydev` must be passed by the corresponding callback in `phy_driver`.
 |     /// `phydev` must be passed by the corresponding callback in `phy_driver`.
 | ||||||
|     unsafe extern "C" fn get_features_callback( |     unsafe extern "C" fn get_features_callback( | ||||||
|         phydev: *mut bindings::phy_device, |         phydev: *mut bindings::phy_device, | ||||||
|     ) -> core::ffi::c_int { |     ) -> crate::ffi::c_int { | ||||||
|         from_result(|| { |         from_result(|| { | ||||||
|             // SAFETY: This callback is called only in contexts
 |             // SAFETY: This callback is called only in contexts
 | ||||||
|             // where we hold `phy_device->lock`, so the accessors on
 |             // where we hold `phy_device->lock`, so the accessors on
 | ||||||
|  | @ -359,7 +359,7 @@ impl<T: Driver> Adapter<T> { | ||||||
|     /// # Safety
 |     /// # Safety
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// `phydev` must be passed by the corresponding callback in `phy_driver`.
 |     /// `phydev` must be passed by the corresponding callback in `phy_driver`.
 | ||||||
|     unsafe extern "C" fn suspend_callback(phydev: *mut bindings::phy_device) -> core::ffi::c_int { |     unsafe extern "C" fn suspend_callback(phydev: *mut bindings::phy_device) -> crate::ffi::c_int { | ||||||
|         from_result(|| { |         from_result(|| { | ||||||
|             // SAFETY: The C core code ensures that the accessors on
 |             // SAFETY: The C core code ensures that the accessors on
 | ||||||
|             // `Device` are okay to call even though `phy_device->lock`
 |             // `Device` are okay to call even though `phy_device->lock`
 | ||||||
|  | @ -373,7 +373,7 @@ impl<T: Driver> Adapter<T> { | ||||||
|     /// # Safety
 |     /// # Safety
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// `phydev` must be passed by the corresponding callback in `phy_driver`.
 |     /// `phydev` must be passed by the corresponding callback in `phy_driver`.
 | ||||||
|     unsafe extern "C" fn resume_callback(phydev: *mut bindings::phy_device) -> core::ffi::c_int { |     unsafe extern "C" fn resume_callback(phydev: *mut bindings::phy_device) -> crate::ffi::c_int { | ||||||
|         from_result(|| { |         from_result(|| { | ||||||
|             // SAFETY: The C core code ensures that the accessors on
 |             // SAFETY: The C core code ensures that the accessors on
 | ||||||
|             // `Device` are okay to call even though `phy_device->lock`
 |             // `Device` are okay to call even though `phy_device->lock`
 | ||||||
|  | @ -389,7 +389,7 @@ impl<T: Driver> Adapter<T> { | ||||||
|     /// `phydev` must be passed by the corresponding callback in `phy_driver`.
 |     /// `phydev` must be passed by the corresponding callback in `phy_driver`.
 | ||||||
|     unsafe extern "C" fn config_aneg_callback( |     unsafe extern "C" fn config_aneg_callback( | ||||||
|         phydev: *mut bindings::phy_device, |         phydev: *mut bindings::phy_device, | ||||||
|     ) -> core::ffi::c_int { |     ) -> crate::ffi::c_int { | ||||||
|         from_result(|| { |         from_result(|| { | ||||||
|             // SAFETY: This callback is called only in contexts
 |             // SAFETY: This callback is called only in contexts
 | ||||||
|             // where we hold `phy_device->lock`, so the accessors on
 |             // where we hold `phy_device->lock`, so the accessors on
 | ||||||
|  | @ -405,7 +405,7 @@ impl<T: Driver> Adapter<T> { | ||||||
|     /// `phydev` must be passed by the corresponding callback in `phy_driver`.
 |     /// `phydev` must be passed by the corresponding callback in `phy_driver`.
 | ||||||
|     unsafe extern "C" fn read_status_callback( |     unsafe extern "C" fn read_status_callback( | ||||||
|         phydev: *mut bindings::phy_device, |         phydev: *mut bindings::phy_device, | ||||||
|     ) -> core::ffi::c_int { |     ) -> crate::ffi::c_int { | ||||||
|         from_result(|| { |         from_result(|| { | ||||||
|             // SAFETY: This callback is called only in contexts
 |             // SAFETY: This callback is called only in contexts
 | ||||||
|             // where we hold `phy_device->lock`, so the accessors on
 |             // where we hold `phy_device->lock`, so the accessors on
 | ||||||
|  | @ -421,7 +421,7 @@ impl<T: Driver> Adapter<T> { | ||||||
|     /// `phydev` must be passed by the corresponding callback in `phy_driver`.
 |     /// `phydev` must be passed by the corresponding callback in `phy_driver`.
 | ||||||
|     unsafe extern "C" fn match_phy_device_callback( |     unsafe extern "C" fn match_phy_device_callback( | ||||||
|         phydev: *mut bindings::phy_device, |         phydev: *mut bindings::phy_device, | ||||||
|     ) -> core::ffi::c_int { |     ) -> crate::ffi::c_int { | ||||||
|         // SAFETY: This callback is called only in contexts
 |         // SAFETY: This callback is called only in contexts
 | ||||||
|         // where we hold `phy_device->lock`, so the accessors on
 |         // where we hold `phy_device->lock`, so the accessors on
 | ||||||
|         // `Device` are okay to call.
 |         // `Device` are okay to call.
 | ||||||
|  |  | ||||||
|  | @ -184,7 +184,7 @@ pub const fn is_empty(&self) -> bool { | ||||||
|     /// last at least `'a`. When `CStr` is alive, the memory pointed by `ptr`
 |     /// last at least `'a`. When `CStr` is alive, the memory pointed by `ptr`
 | ||||||
|     /// must not be mutated.
 |     /// must not be mutated.
 | ||||||
|     #[inline] |     #[inline] | ||||||
|     pub unsafe fn from_char_ptr<'a>(ptr: *const core::ffi::c_char) -> &'a Self { |     pub unsafe fn from_char_ptr<'a>(ptr: *const crate::ffi::c_char) -> &'a Self { | ||||||
|         // SAFETY: The safety precondition guarantees `ptr` is a valid pointer
 |         // SAFETY: The safety precondition guarantees `ptr` is a valid pointer
 | ||||||
|         // to a `NUL`-terminated C string.
 |         // to a `NUL`-terminated C string.
 | ||||||
|         let len = unsafe { bindings::strlen(ptr) } + 1; |         let len = unsafe { bindings::strlen(ptr) } + 1; | ||||||
|  | @ -247,7 +247,7 @@ pub unsafe fn from_bytes_with_nul_unchecked_mut(bytes: &mut [u8]) -> &mut CStr { | ||||||
| 
 | 
 | ||||||
|     /// Returns a C pointer to the string.
 |     /// Returns a C pointer to the string.
 | ||||||
|     #[inline] |     #[inline] | ||||||
|     pub const fn as_char_ptr(&self) -> *const core::ffi::c_char { |     pub const fn as_char_ptr(&self) -> *const crate::ffi::c_char { | ||||||
|         self.0.as_ptr() as _ |         self.0.as_ptr() as _ | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -332,11 +332,11 @@ pub fn into_unique_or_drop(self) -> Option<Pin<UniqueArc<T>>> { | ||||||
| impl<T: 'static> ForeignOwnable for Arc<T> { | impl<T: 'static> ForeignOwnable for Arc<T> { | ||||||
|     type Borrowed<'a> = ArcBorrow<'a, T>; |     type Borrowed<'a> = ArcBorrow<'a, T>; | ||||||
| 
 | 
 | ||||||
|     fn into_foreign(self) -> *const core::ffi::c_void { |     fn into_foreign(self) -> *const crate::ffi::c_void { | ||||||
|         ManuallyDrop::new(self).ptr.as_ptr() as _ |         ManuallyDrop::new(self).ptr.as_ptr() as _ | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> ArcBorrow<'a, T> { |     unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> ArcBorrow<'a, T> { | ||||||
|         // By the safety requirement of this function, we know that `ptr` came from
 |         // By the safety requirement of this function, we know that `ptr` came from
 | ||||||
|         // a previous call to `Arc::into_foreign`.
 |         // a previous call to `Arc::into_foreign`.
 | ||||||
|         let inner = NonNull::new(ptr as *mut ArcInner<T>).unwrap(); |         let inner = NonNull::new(ptr as *mut ArcInner<T>).unwrap(); | ||||||
|  | @ -346,7 +346,7 @@ unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> ArcBorrow<'a, T> { | ||||||
|         unsafe { ArcBorrow::new(inner) } |         unsafe { ArcBorrow::new(inner) } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { |     unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self { | ||||||
|         // SAFETY: By the safety requirement of this function, we know that `ptr` came from
 |         // SAFETY: By the safety requirement of this function, we know that `ptr` came from
 | ||||||
|         // a previous call to `Arc::into_foreign`, which guarantees that `ptr` is valid and
 |         // a previous call to `Arc::into_foreign`, which guarantees that `ptr` is valid and
 | ||||||
|         // holds a reference count increment that is transferrable to us.
 |         // holds a reference count increment that is transferrable to us.
 | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ | ||||||
| 
 | 
 | ||||||
| use super::{lock::Backend, lock::Guard, LockClassKey}; | use super::{lock::Backend, lock::Guard, LockClassKey}; | ||||||
| use crate::{ | use crate::{ | ||||||
|  |     ffi::{c_int, c_long}, | ||||||
|     init::PinInit, |     init::PinInit, | ||||||
|     pin_init, |     pin_init, | ||||||
|     str::CStr, |     str::CStr, | ||||||
|  | @ -14,7 +15,6 @@ | ||||||
|     time::Jiffies, |     time::Jiffies, | ||||||
|     types::Opaque, |     types::Opaque, | ||||||
| }; | }; | ||||||
| use core::ffi::{c_int, c_long}; |  | ||||||
| use core::marker::PhantomPinned; | use core::marker::PhantomPinned; | ||||||
| use core::ptr; | use core::ptr; | ||||||
| use macros::pin_data; | use macros::pin_data; | ||||||
|  |  | ||||||
|  | @ -49,7 +49,7 @@ pub unsafe trait Backend { | ||||||
|     /// remain valid for read indefinitely.
 |     /// remain valid for read indefinitely.
 | ||||||
|     unsafe fn init( |     unsafe fn init( | ||||||
|         ptr: *mut Self::State, |         ptr: *mut Self::State, | ||||||
|         name: *const core::ffi::c_char, |         name: *const crate::ffi::c_char, | ||||||
|         key: *mut bindings::lock_class_key, |         key: *mut bindings::lock_class_key, | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -96,7 +96,7 @@ unsafe impl super::Backend for MutexBackend { | ||||||
| 
 | 
 | ||||||
|     unsafe fn init( |     unsafe fn init( | ||||||
|         ptr: *mut Self::State, |         ptr: *mut Self::State, | ||||||
|         name: *const core::ffi::c_char, |         name: *const crate::ffi::c_char, | ||||||
|         key: *mut bindings::lock_class_key, |         key: *mut bindings::lock_class_key, | ||||||
|     ) { |     ) { | ||||||
|         // SAFETY: The safety requirements ensure that `ptr` is valid for writes, and `name` and
 |         // SAFETY: The safety requirements ensure that `ptr` is valid for writes, and `name` and
 | ||||||
|  |  | ||||||
|  | @ -95,7 +95,7 @@ unsafe impl super::Backend for SpinLockBackend { | ||||||
| 
 | 
 | ||||||
|     unsafe fn init( |     unsafe fn init( | ||||||
|         ptr: *mut Self::State, |         ptr: *mut Self::State, | ||||||
|         name: *const core::ffi::c_char, |         name: *const crate::ffi::c_char, | ||||||
|         key: *mut bindings::lock_class_key, |         key: *mut bindings::lock_class_key, | ||||||
|     ) { |     ) { | ||||||
|         // SAFETY: The safety requirements ensure that `ptr` is valid for writes, and `name` and
 |         // SAFETY: The safety requirements ensure that `ptr` is valid for writes, and `name` and
 | ||||||
|  |  | ||||||
|  | @ -4,13 +4,9 @@ | ||||||
| //!
 | //!
 | ||||||
| //! C header: [`include/linux/sched.h`](srctree/include/linux/sched.h).
 | //! C header: [`include/linux/sched.h`](srctree/include/linux/sched.h).
 | ||||||
| 
 | 
 | ||||||
|  | use crate::ffi::{c_int, c_long, c_uint}; | ||||||
| use crate::types::Opaque; | use crate::types::Opaque; | ||||||
| use core::{ | use core::{marker::PhantomData, ops::Deref, ptr}; | ||||||
|     ffi::{c_int, c_long, c_uint}, |  | ||||||
|     marker::PhantomData, |  | ||||||
|     ops::Deref, |  | ||||||
|     ptr, |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| /// A sentinel value used for infinite timeouts.
 | /// A sentinel value used for infinite timeouts.
 | ||||||
| pub const MAX_SCHEDULE_TIMEOUT: c_long = c_long::MAX; | pub const MAX_SCHEDULE_TIMEOUT: c_long = c_long::MAX; | ||||||
|  |  | ||||||
|  | @ -12,10 +12,10 @@ | ||||||
| pub const NSEC_PER_MSEC: i64 = bindings::NSEC_PER_MSEC as i64; | pub const NSEC_PER_MSEC: i64 = bindings::NSEC_PER_MSEC as i64; | ||||||
| 
 | 
 | ||||||
| /// The time unit of Linux kernel. One jiffy equals (1/HZ) second.
 | /// The time unit of Linux kernel. One jiffy equals (1/HZ) second.
 | ||||||
| pub type Jiffies = core::ffi::c_ulong; | pub type Jiffies = crate::ffi::c_ulong; | ||||||
| 
 | 
 | ||||||
| /// The millisecond time unit.
 | /// The millisecond time unit.
 | ||||||
| pub type Msecs = core::ffi::c_uint; | pub type Msecs = crate::ffi::c_uint; | ||||||
| 
 | 
 | ||||||
| /// Converts milliseconds to jiffies.
 | /// Converts milliseconds to jiffies.
 | ||||||
| #[inline] | #[inline] | ||||||
|  |  | ||||||
|  | @ -29,7 +29,7 @@ pub trait ForeignOwnable: Sized { | ||||||
|     /// For example, it might be invalid, dangling or pointing to uninitialized memory. Using it in
 |     /// For example, it might be invalid, dangling or pointing to uninitialized memory. Using it in
 | ||||||
|     /// any way except for [`ForeignOwnable::from_foreign`], [`ForeignOwnable::borrow`],
 |     /// any way except for [`ForeignOwnable::from_foreign`], [`ForeignOwnable::borrow`],
 | ||||||
|     /// [`ForeignOwnable::try_from_foreign`] can result in undefined behavior.
 |     /// [`ForeignOwnable::try_from_foreign`] can result in undefined behavior.
 | ||||||
|     fn into_foreign(self) -> *const core::ffi::c_void; |     fn into_foreign(self) -> *const crate::ffi::c_void; | ||||||
| 
 | 
 | ||||||
|     /// Borrows a foreign-owned object.
 |     /// Borrows a foreign-owned object.
 | ||||||
|     ///
 |     ///
 | ||||||
|  | @ -37,7 +37,7 @@ pub trait ForeignOwnable: Sized { | ||||||
|     ///
 |     ///
 | ||||||
|     /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
 |     /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
 | ||||||
|     /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
 |     /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
 | ||||||
|     unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Self::Borrowed<'a>; |     unsafe fn borrow<'a>(ptr: *const crate::ffi::c_void) -> Self::Borrowed<'a>; | ||||||
| 
 | 
 | ||||||
|     /// Converts a foreign-owned object back to a Rust-owned one.
 |     /// Converts a foreign-owned object back to a Rust-owned one.
 | ||||||
|     ///
 |     ///
 | ||||||
|  | @ -47,7 +47,7 @@ pub trait ForeignOwnable: Sized { | ||||||
|     /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
 |     /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
 | ||||||
|     /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] for
 |     /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] for
 | ||||||
|     /// this object must have been dropped.
 |     /// this object must have been dropped.
 | ||||||
|     unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self; |     unsafe fn from_foreign(ptr: *const crate::ffi::c_void) -> Self; | ||||||
| 
 | 
 | ||||||
|     /// Tries to convert a foreign-owned object back to a Rust-owned one.
 |     /// Tries to convert a foreign-owned object back to a Rust-owned one.
 | ||||||
|     ///
 |     ///
 | ||||||
|  | @ -58,7 +58,7 @@ pub trait ForeignOwnable: Sized { | ||||||
|     ///
 |     ///
 | ||||||
|     /// `ptr` must either be null or satisfy the safety requirements for
 |     /// `ptr` must either be null or satisfy the safety requirements for
 | ||||||
|     /// [`ForeignOwnable::from_foreign`].
 |     /// [`ForeignOwnable::from_foreign`].
 | ||||||
|     unsafe fn try_from_foreign(ptr: *const core::ffi::c_void) -> Option<Self> { |     unsafe fn try_from_foreign(ptr: *const crate::ffi::c_void) -> Option<Self> { | ||||||
|         if ptr.is_null() { |         if ptr.is_null() { | ||||||
|             None |             None | ||||||
|         } else { |         } else { | ||||||
|  | @ -72,13 +72,13 @@ unsafe fn try_from_foreign(ptr: *const core::ffi::c_void) -> Option<Self> { | ||||||
| impl ForeignOwnable for () { | impl ForeignOwnable for () { | ||||||
|     type Borrowed<'a> = (); |     type Borrowed<'a> = (); | ||||||
| 
 | 
 | ||||||
|     fn into_foreign(self) -> *const core::ffi::c_void { |     fn into_foreign(self) -> *const crate::ffi::c_void { | ||||||
|         core::ptr::NonNull::dangling().as_ptr() |         core::ptr::NonNull::dangling().as_ptr() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     unsafe fn borrow<'a>(_: *const core::ffi::c_void) -> Self::Borrowed<'a> {} |     unsafe fn borrow<'a>(_: *const crate::ffi::c_void) -> Self::Borrowed<'a> {} | ||||||
| 
 | 
 | ||||||
|     unsafe fn from_foreign(_: *const core::ffi::c_void) -> Self {} |     unsafe fn from_foreign(_: *const crate::ffi::c_void) -> Self {} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Runs a cleanup function/closure when dropped.
 | /// Runs a cleanup function/closure when dropped.
 | ||||||
|  |  | ||||||
|  | @ -8,10 +8,10 @@ | ||||||
|     alloc::Flags, |     alloc::Flags, | ||||||
|     bindings, |     bindings, | ||||||
|     error::Result, |     error::Result, | ||||||
|  |     ffi::{c_ulong, c_void}, | ||||||
|     prelude::*, |     prelude::*, | ||||||
|     transmute::{AsBytes, FromBytes}, |     transmute::{AsBytes, FromBytes}, | ||||||
| }; | }; | ||||||
| use core::ffi::{c_ulong, c_void}; |  | ||||||
| use core::mem::{size_of, MaybeUninit}; | use core::mem::{size_of, MaybeUninit}; | ||||||
| 
 | 
 | ||||||
| /// The type used for userspace addresses.
 | /// The type used for userspace addresses.
 | ||||||
|  | @ -45,7 +45,7 @@ | ||||||
| /// every byte in the region.
 | /// every byte in the region.
 | ||||||
| ///
 | ///
 | ||||||
| /// ```no_run
 | /// ```no_run
 | ||||||
| /// use core::ffi::c_void;
 | /// use kernel::ffi::c_void;
 | ||||||
| /// use kernel::error::Result;
 | /// use kernel::error::Result;
 | ||||||
| /// use kernel::uaccess::{UserPtr, UserSlice};
 | /// use kernel::uaccess::{UserPtr, UserSlice};
 | ||||||
| ///
 | ///
 | ||||||
|  | @ -67,7 +67,7 @@ | ||||||
| /// Example illustrating a TOCTOU (time-of-check to time-of-use) bug.
 | /// Example illustrating a TOCTOU (time-of-check to time-of-use) bug.
 | ||||||
| ///
 | ///
 | ||||||
| /// ```no_run
 | /// ```no_run
 | ||||||
| /// use core::ffi::c_void;
 | /// use kernel::ffi::c_void;
 | ||||||
| /// use kernel::error::{code::EINVAL, Result};
 | /// use kernel::error::{code::EINVAL, Result};
 | ||||||
| /// use kernel::uaccess::{UserPtr, UserSlice};
 | /// use kernel::uaccess::{UserPtr, UserSlice};
 | ||||||
| ///
 | ///
 | ||||||
|  |  | ||||||
|  | @ -253,7 +253,7 @@ mod __module_init {{ | ||||||
|                     #[doc(hidden)] |                     #[doc(hidden)] | ||||||
|                     #[no_mangle] |                     #[no_mangle] | ||||||
|                     #[link_section = \".init.text\"]
 |                     #[link_section = \".init.text\"]
 | ||||||
|                     pub unsafe extern \"C\" fn init_module() -> core::ffi::c_int {{
 |                     pub unsafe extern \"C\" fn init_module() -> kernel::ffi::c_int {{
 | ||||||
|                         // SAFETY: This function is inaccessible to the outside due to the double
 |                         // SAFETY: This function is inaccessible to the outside due to the double
 | ||||||
|                         // module wrapping it. It is called exactly once by the C side via its
 |                         // module wrapping it. It is called exactly once by the C side via its
 | ||||||
|                         // unique name.
 |                         // unique name.
 | ||||||
|  | @ -292,7 +292,7 @@ mod __module_init {{ | ||||||
|                     #[doc(hidden)] |                     #[doc(hidden)] | ||||||
|                     #[link_section = \"{initcall_section}\"]
 |                     #[link_section = \"{initcall_section}\"]
 | ||||||
|                     #[used] |                     #[used] | ||||||
|                     pub static __{name}_initcall: extern \"C\" fn() -> core::ffi::c_int = __{name}_init;
 |                     pub static __{name}_initcall: extern \"C\" fn() -> kernel::ffi::c_int = __{name}_init;
 | ||||||
| 
 | 
 | ||||||
|                     #[cfg(not(MODULE))] |                     #[cfg(not(MODULE))] | ||||||
|                     #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)] |                     #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)] | ||||||
|  | @ -307,7 +307,7 @@ mod __module_init {{ | ||||||
|                     #[cfg(not(MODULE))] |                     #[cfg(not(MODULE))] | ||||||
|                     #[doc(hidden)] |                     #[doc(hidden)] | ||||||
|                     #[no_mangle] |                     #[no_mangle] | ||||||
|                     pub extern \"C\" fn __{name}_init() -> core::ffi::c_int {{
 |                     pub extern \"C\" fn __{name}_init() -> kernel::ffi::c_int {{
 | ||||||
|                         // SAFETY: This function is inaccessible to the outside due to the double
 |                         // SAFETY: This function is inaccessible to the outside due to the double
 | ||||||
|                         // module wrapping it. It is called exactly once by the C side via its
 |                         // module wrapping it. It is called exactly once by the C side via its
 | ||||||
|                         // placement above in the initcall section.
 |                         // placement above in the initcall section.
 | ||||||
|  | @ -330,7 +330,7 @@ mod __module_init {{ | ||||||
|                     /// # Safety
 |                     /// # Safety
 | ||||||
|                     ///
 |                     ///
 | ||||||
|                     /// This function must only be called once.
 |                     /// This function must only be called once.
 | ||||||
|                     unsafe fn __init() -> core::ffi::c_int {{ |                     unsafe fn __init() -> kernel::ffi::c_int {{ | ||||||
|                         match <{type_} as kernel::Module>::init(&super::super::THIS_MODULE) {{ |                         match <{type_} as kernel::Module>::init(&super::super::THIS_MODULE) {{ | ||||||
|                             Ok(m) => {{ |                             Ok(m) => {{ | ||||||
|                                 // SAFETY: No data race, since `__MOD` can only be accessed by this
 |                                 // SAFETY: No data race, since `__MOD` can only be accessed by this
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Gary Guo
						Gary Guo