@@ -199,17 +199,6 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
199
199
/// Used by the printing macros, e.g. [`info!`].
200
200
const __LOG_PREFIX: &[u8] = b\" {name}\\ 0\" ;
201
201
202
- /// The \" Rust loadable module\" mark.
203
- //
204
- // This may be best done another way later on, e.g. as a new modinfo
205
- // key or a new section. For the moment, keep it simple.
206
- #[cfg(MODULE)]
207
- #[doc(hidden)]
208
- #[used]
209
- static __IS_RUST_MODULE: () = ();
210
-
211
- static mut __MOD: Option<{type_}> = None;
212
-
213
202
// SAFETY: `__this_module` is constructed by the kernel at load time and will not be
214
203
// freed until the module is unloaded.
215
204
#[cfg(MODULE)]
@@ -221,81 +210,132 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
221
210
kernel::ThisModule::from_ptr(core::ptr::null_mut())
222
211
}};
223
212
224
- // Loadable modules need to export the `{{init,cleanup}}_module` identifiers.
225
- /// # Safety
226
- ///
227
- /// This function must not be called after module initialization, because it may be
228
- /// freed after that completes.
229
- #[cfg(MODULE)]
230
- #[doc(hidden)]
231
- #[no_mangle]
232
- #[link_section = \" .init.text\" ]
233
- pub unsafe extern \" C\" fn init_module() -> core::ffi::c_int {{
234
- __init()
235
- }}
236
-
237
- #[cfg(MODULE)]
238
- #[doc(hidden)]
239
- #[no_mangle]
240
- pub extern \" C\" fn cleanup_module() {{
241
- __exit()
242
- }}
213
+ // Double nested modules, since then nobody can access the public items inside.
214
+ mod __module_init {{
215
+ mod __module_init {{
216
+ use super::super::{type_};
217
+
218
+ /// The \" Rust loadable module\" mark.
219
+ //
220
+ // This may be best done another way later on, e.g. as a new modinfo
221
+ // key or a new section. For the moment, keep it simple.
222
+ #[cfg(MODULE)]
223
+ #[doc(hidden)]
224
+ #[used]
225
+ static __IS_RUST_MODULE: () = ();
226
+
227
+ static mut __MOD: Option<{type_}> = None;
228
+
229
+ // Loadable modules need to export the `{{init,cleanup}}_module` identifiers.
230
+ /// # Safety
231
+ ///
232
+ /// This function must not be called after module initialization, because it may be
233
+ /// freed after that completes.
234
+ #[cfg(MODULE)]
235
+ #[doc(hidden)]
236
+ #[no_mangle]
237
+ #[link_section = \" .init.text\" ]
238
+ pub unsafe extern \" C\" fn init_module() -> core::ffi::c_int {{
239
+ // SAFETY: This function is inaccessible to the outside due to the double
240
+ // module wrapping it. It is called exactly once by the C side via its
241
+ // unique name.
242
+ unsafe {{ __init() }}
243
+ }}
243
244
244
- // Built-in modules are initialized through an initcall pointer
245
- // and the identifiers need to be unique.
246
- #[cfg(not(MODULE))]
247
- #[cfg(not(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS))]
248
- #[doc(hidden)]
249
- #[link_section = \" {initcall_section}\" ]
250
- #[used]
251
- pub static __{name}_initcall: extern \" C\" fn() -> core::ffi::c_int = __{name}_init;
245
+ #[cfg(MODULE)]
246
+ #[doc(hidden)]
247
+ #[no_mangle]
248
+ pub extern \" C\" fn cleanup_module() {{
249
+ // SAFETY:
250
+ // - This function is inaccessible to the outside due to the double
251
+ // module wrapping it. It is called exactly once by the C side via its
252
+ // unique name,
253
+ // - furthermore it is only called after `init_module` has returned `0`
254
+ // (which delegates to `__init`).
255
+ unsafe {{ __exit() }}
256
+ }}
252
257
253
- #[cfg(not(MODULE))]
254
- #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)]
255
- core::arch::global_asm!(
256
- r#\" .section \" {initcall_section}\" , \" a\"
257
- __{name}_initcall:
258
- .long __{name}_init - .
259
- .previous
260
- \" #
261
- );
258
+ // Built-in modules are initialized through an initcall pointer
259
+ // and the identifiers need to be unique.
260
+ #[cfg(not(MODULE))]
261
+ #[cfg(not(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS))]
262
+ #[doc(hidden)]
263
+ #[link_section = \" {initcall_section}\" ]
264
+ #[used]
265
+ pub static __{name}_initcall: extern \" C\" fn() -> core::ffi::c_int = __{name}_init;
266
+
267
+ #[cfg(not(MODULE))]
268
+ #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)]
269
+ core::arch::global_asm!(
270
+ r#\" .section \" {initcall_section}\" , \" a\"
271
+ __{name}_initcall:
272
+ .long __{name}_init - .
273
+ .previous
274
+ \" #
275
+ );
276
+
277
+ #[cfg(not(MODULE))]
278
+ #[doc(hidden)]
279
+ #[no_mangle]
280
+ pub extern \" C\" fn __{name}_init() -> core::ffi::c_int {{
281
+ // SAFETY: This function is inaccessible to the outside due to the double
282
+ // module wrapping it. It is called exactly once by the C side via its
283
+ // placement above in the initcall section.
284
+ unsafe {{ __init() }}
285
+ }}
262
286
263
- #[cfg(not(MODULE))]
264
- #[doc(hidden)]
265
- #[no_mangle]
266
- pub extern \" C\" fn __{name}_init() -> core::ffi::c_int {{
267
- __init()
268
- }}
287
+ #[cfg(not(MODULE))]
288
+ #[doc(hidden)]
289
+ #[no_mangle]
290
+ pub extern \" C\" fn __{name}_exit() {{
291
+ // SAFETY:
292
+ // - This function is inaccessible to the outside due to the double
293
+ // module wrapping it. It is called exactly once by the C side via its
294
+ // unique name,
295
+ // - furthermore it is only called after `__{name}_init` has returned `0`
296
+ // (which delegates to `__init`).
297
+ unsafe {{ __exit() }}
298
+ }}
269
299
270
- #[cfg(not(MODULE))]
271
- #[doc(hidden)]
272
- #[no_mangle]
273
- pub extern \" C\" fn __{name}_exit() {{
274
- __exit()
275
- }}
300
+ /// # Safety
301
+ ///
302
+ /// This function must only be called once.
303
+ unsafe fn __init() -> core::ffi::c_int {{
304
+ match <{type_} as kernel::Module>::init(&super::super::THIS_MODULE) {{
305
+ Ok(m) => {{
306
+ // SAFETY: No data race, since `__MOD` can only be accessed by this
307
+ // module and there only `__init` and `__exit` access it. These
308
+ // functions are only called once and `__exit` cannot be called
309
+ // before or during `__init`.
310
+ unsafe {{
311
+ __MOD = Some(m);
312
+ }}
313
+ return 0;
314
+ }}
315
+ Err(e) => {{
316
+ return e.to_errno();
317
+ }}
318
+ }}
319
+ }}
276
320
277
- fn __init() -> core::ffi::c_int {{
278
- match <{type_} as kernel::Module>::init(&THIS_MODULE) {{
279
- Ok(m) => {{
321
+ /// # Safety
322
+ ///
323
+ /// This function must
324
+ /// - only be called once,
325
+ /// - be called after `__init` has been called and returned `0`.
326
+ unsafe fn __exit() {{
327
+ // SAFETY: No data race, since `__MOD` can only be accessed by this module
328
+ // and there only `__init` and `__exit` access it. These functions are only
329
+ // called once and `__init` was already called.
280
330
unsafe {{
281
- __MOD = Some(m);
331
+ // Invokes `drop()` on `__MOD`, which should be used for cleanup.
332
+ __MOD = None;
282
333
}}
283
- return 0;
284
- }}
285
- Err(e) => {{
286
- return e.to_errno();
287
334
}}
288
- }}
289
- }}
290
335
291
- fn __exit() {{
292
- unsafe {{
293
- // Invokes `drop()` on `__MOD`, which should be used for cleanup.
294
- __MOD = None;
336
+ {modinfo}
295
337
}}
296
338
}}
297
-
298
- {modinfo}
299
339
" ,
300
340
type_ = info. type_,
301
341
name = info. name,
0 commit comments