1 // SPDX-License-Identifier: GPL-2.0 2 3 //! Allocator support. 4 5 use core::alloc::{GlobalAlloc, Layout}; 6 use core::ptr; 7 8 use crate::bindings; 9 10 struct KernelAllocator; 11 12 unsafe impl GlobalAlloc for KernelAllocator { 13 unsafe fn alloc(&self, layout: Layout) -> *mut u8 { 14 // `krealloc()` is used instead of `kmalloc()` because the latter is 15 // an inline function and cannot be bound to as a result. 16 unsafe { bindings::krealloc(ptr::null(), layout.size(), bindings::GFP_KERNEL) as *mut u8 } 17 } 18 19 unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { 20 unsafe { 21 bindings::kfree(ptr as *const core::ffi::c_void); 22 } 23 } 24 } 25 26 #[global_allocator] 27 static ALLOCATOR: KernelAllocator = KernelAllocator; 28 29 // `rustc` only generates these for some crate types. Even then, we would need 30 // to extract the object file that has them from the archive. For the moment, 31 // let's generate them ourselves instead. 32 // 33 // Note that `#[no_mangle]` implies exported too, nowadays. 34 #[no_mangle] 35 fn __rust_alloc(size: usize, _align: usize) -> *mut u8 { 36 unsafe { bindings::krealloc(core::ptr::null(), size, bindings::GFP_KERNEL) as *mut u8 } 37 } 38 39 #[no_mangle] 40 fn __rust_dealloc(ptr: *mut u8, _size: usize, _align: usize) { 41 unsafe { bindings::kfree(ptr as *const core::ffi::c_void) }; 42 } 43 44 #[no_mangle] 45 fn __rust_realloc(ptr: *mut u8, _old_size: usize, _align: usize, new_size: usize) -> *mut u8 { 46 unsafe { 47 bindings::krealloc( 48 ptr as *const core::ffi::c_void, 49 new_size, 50 bindings::GFP_KERNEL, 51 ) as *mut u8 52 } 53 } 54 55 #[no_mangle] 56 fn __rust_alloc_zeroed(size: usize, _align: usize) -> *mut u8 { 57 unsafe { 58 bindings::krealloc( 59 core::ptr::null(), 60 size, 61 bindings::GFP_KERNEL | bindings::__GFP_ZERO, 62 ) as *mut u8 63 } 64 } 65