Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rust: treewide: switch to the kernel `Vec` type

Now that we got the kernel `Vec` in place, convert all existing `Vec`
users to make use of it.

Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20241004154149.93856-20-dakr@kernel.org
[ Converted `kasan_test_rust.rs` too, as discussed. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>

authored by

Danilo Krummrich and committed by
Miguel Ojeda
58eff8e8 93e60231

+20 -25
+1 -1
mm/kasan/kasan_test_rust.rs
··· 11 11 /// drop the vector, and touch it. 12 12 #[no_mangle] 13 13 pub extern "C" fn kasan_test_rust_uaf() -> u8 { 14 - let mut v: Vec<u8> = Vec::new(); 14 + let mut v: KVec<u8> = KVec::new(); 15 15 for _ in 0..4096 { 16 16 v.push(0x42, GFP_KERNEL).unwrap(); 17 17 }
+5 -7
rust/kernel/str.rs
··· 2 2 3 3 //! String representations. 4 4 5 - use crate::alloc::{flags::*, vec_ext::VecExt, AllocError}; 6 - use alloc::vec::Vec; 5 + use crate::alloc::{flags::*, AllocError, KVec}; 7 6 use core::fmt::{self, Write}; 8 7 use core::ops::{self, Deref, DerefMut, Index}; 9 8 ··· 790 791 /// assert_eq!(s.is_ok(), false); 791 792 /// ``` 792 793 pub struct CString { 793 - buf: Vec<u8>, 794 + buf: KVec<u8>, 794 795 } 795 796 796 797 impl CString { ··· 803 804 let size = f.bytes_written(); 804 805 805 806 // Allocate a vector with the required number of bytes, and write to it. 806 - let mut buf = <Vec<_> as VecExt<_>>::with_capacity(size, GFP_KERNEL)?; 807 + let mut buf = KVec::with_capacity(size, GFP_KERNEL)?; 807 808 // SAFETY: The buffer stored in `buf` is at least of size `size` and is valid for writes. 808 809 let mut f = unsafe { Formatter::from_buffer(buf.as_mut_ptr(), size) }; 809 810 f.write_fmt(args)?; ··· 850 851 type Error = AllocError; 851 852 852 853 fn try_from(cstr: &'a CStr) -> Result<CString, AllocError> { 853 - let mut buf = Vec::new(); 854 + let mut buf = KVec::new(); 854 855 855 - <Vec<_> as VecExt<_>>::extend_from_slice(&mut buf, cstr.as_bytes_with_nul(), GFP_KERNEL) 856 - .map_err(|_| AllocError)?; 856 + buf.extend_from_slice(cstr.as_bytes_with_nul(), GFP_KERNEL)?; 857 857 858 858 // INVARIANT: The `CStr` and `CString` types have the same invariants for 859 859 // the string data, and we copied it over without changes.
+1 -1
rust/kernel/sync/locked_by.rs
··· 43 43 /// struct InnerDirectory { 44 44 /// /// The sum of the bytes used by all files. 45 45 /// bytes_used: u64, 46 - /// _files: Vec<File>, 46 + /// _files: KVec<File>, 47 47 /// } 48 48 /// 49 49 /// struct Directory {
+1 -1
rust/kernel/types.rs
··· 135 135 /// # use kernel::types::ScopeGuard; 136 136 /// fn example3(arg: bool) -> Result { 137 137 /// let mut vec = 138 - /// ScopeGuard::new_with_data(Vec::new(), |v| pr_info!("vec had {} elements\n", v.len())); 138 + /// ScopeGuard::new_with_data(KVec::new(), |v| pr_info!("vec had {} elements\n", v.len())); 139 139 /// 140 140 /// vec.push(10u8, GFP_KERNEL)?; 141 141 /// if arg {
+7 -10
rust/kernel/uaccess.rs
··· 11 11 prelude::*, 12 12 transmute::{AsBytes, FromBytes}, 13 13 }; 14 - use alloc::vec::Vec; 15 14 use core::ffi::{c_ulong, c_void}; 16 15 use core::mem::{size_of, MaybeUninit}; 17 16 ··· 45 46 /// every byte in the region. 46 47 /// 47 48 /// ```no_run 48 - /// use alloc::vec::Vec; 49 49 /// use core::ffi::c_void; 50 50 /// use kernel::error::Result; 51 51 /// use kernel::uaccess::{UserPtr, UserSlice}; ··· 52 54 /// fn bytes_add_one(uptr: UserPtr, len: usize) -> Result<()> { 53 55 /// let (read, mut write) = UserSlice::new(uptr, len).reader_writer(); 54 56 /// 55 - /// let mut buf = Vec::new(); 57 + /// let mut buf = KVec::new(); 56 58 /// read.read_all(&mut buf, GFP_KERNEL)?; 57 59 /// 58 60 /// for b in &mut buf { ··· 67 69 /// Example illustrating a TOCTOU (time-of-check to time-of-use) bug. 68 70 /// 69 71 /// ```no_run 70 - /// use alloc::vec::Vec; 71 72 /// use core::ffi::c_void; 72 73 /// use kernel::error::{code::EINVAL, Result}; 73 74 /// use kernel::uaccess::{UserPtr, UserSlice}; ··· 75 78 /// fn is_valid(uptr: UserPtr, len: usize) -> Result<bool> { 76 79 /// let read = UserSlice::new(uptr, len).reader(); 77 80 /// 78 - /// let mut buf = Vec::new(); 81 + /// let mut buf = KVec::new(); 79 82 /// read.read_all(&mut buf, GFP_KERNEL)?; 80 83 /// 81 84 /// todo!() 82 85 /// } 83 86 /// 84 87 /// /// Returns the bytes behind this user pointer if they are valid. 85 - /// fn get_bytes_if_valid(uptr: UserPtr, len: usize) -> Result<Vec<u8>> { 88 + /// fn get_bytes_if_valid(uptr: UserPtr, len: usize) -> Result<KVec<u8>> { 86 89 /// if !is_valid(uptr, len)? { 87 90 /// return Err(EINVAL); 88 91 /// } 89 92 /// 90 93 /// let read = UserSlice::new(uptr, len).reader(); 91 94 /// 92 - /// let mut buf = Vec::new(); 95 + /// let mut buf = KVec::new(); 93 96 /// read.read_all(&mut buf, GFP_KERNEL)?; 94 97 /// 95 98 /// // THIS IS A BUG! The bytes could have changed since we checked them. ··· 127 130 /// Reads the entirety of the user slice, appending it to the end of the provided buffer. 128 131 /// 129 132 /// Fails with [`EFAULT`] if the read happens on a bad address. 130 - pub fn read_all(self, buf: &mut Vec<u8>, flags: Flags) -> Result { 133 + pub fn read_all(self, buf: &mut KVec<u8>, flags: Flags) -> Result { 131 134 self.reader().read_all(buf, flags) 132 135 } 133 136 ··· 288 291 /// Reads the entirety of the user slice, appending it to the end of the provided buffer. 289 292 /// 290 293 /// Fails with [`EFAULT`] if the read happens on a bad address. 291 - pub fn read_all(mut self, buf: &mut Vec<u8>, flags: Flags) -> Result { 294 + pub fn read_all(mut self, buf: &mut KVec<u8>, flags: Flags) -> Result { 292 295 let len = self.length; 293 - VecExt::<u8>::reserve(buf, len, flags)?; 296 + buf.reserve(len, flags)?; 294 297 295 298 // The call to `try_reserve` was successful, so the spare capacity is at least `len` bytes 296 299 // long.
+3 -3
rust/macros/lib.rs
··· 242 242 /// #[pin_data] 243 243 /// struct DriverData { 244 244 /// #[pin] 245 - /// queue: Mutex<Vec<Command>>, 245 + /// queue: Mutex<KVec<Command>>, 246 246 /// buf: KBox<[u8; 1024 * 1024]>, 247 247 /// } 248 248 /// ``` ··· 251 251 /// #[pin_data(PinnedDrop)] 252 252 /// struct DriverData { 253 253 /// #[pin] 254 - /// queue: Mutex<Vec<Command>>, 254 + /// queue: Mutex<KVec<Command>>, 255 255 /// buf: KBox<[u8; 1024 * 1024]>, 256 256 /// raw_info: *mut Info, 257 257 /// } ··· 281 281 /// #[pin_data(PinnedDrop)] 282 282 /// struct DriverData { 283 283 /// #[pin] 284 - /// queue: Mutex<Vec<Command>>, 284 + /// queue: Mutex<KVec<Command>>, 285 285 /// buf: KBox<[u8; 1024 * 1024]>, 286 286 /// raw_info: *mut Info, 287 287 /// }
+2 -2
samples/rust/rust_minimal.rs
··· 13 13 } 14 14 15 15 struct RustMinimal { 16 - numbers: Vec<i32>, 16 + numbers: KVec<i32>, 17 17 } 18 18 19 19 impl kernel::Module for RustMinimal { ··· 21 21 pr_info!("Rust minimal sample (init)\n"); 22 22 pr_info!("Am I built-in? {}\n", !cfg!(MODULE)); 23 23 24 - let mut numbers = Vec::new(); 24 + let mut numbers = KVec::new(); 25 25 numbers.push(72, GFP_KERNEL)?; 26 26 numbers.push(108, GFP_KERNEL)?; 27 27 numbers.push(200, GFP_KERNEL)?;