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