diff --git a/vm-allocator/src/lib.rs b/vm-allocator/src/lib.rs index 801eff9faa..d560482889 100644 --- a/vm-allocator/src/lib.rs +++ b/vm-allocator/src/lib.rs @@ -21,3 +21,5 @@ pub use crate::gsi::GsiAllocator; #[cfg(target_arch = "x86_64")] pub use crate::gsi::GsiApic; pub use crate::system::SystemAllocator; +mod memory_slot; +pub use memory_slot::MemorySlotAllocator; diff --git a/vm-allocator/src/memory_slot.rs b/vm-allocator/src/memory_slot.rs new file mode 100644 index 0000000000..63a41d9c53 --- /dev/null +++ b/vm-allocator/src/memory_slot.rs @@ -0,0 +1,39 @@ +// Copyright © 2024 Rivos Inc +// +// SPDX-License-Identifier: Apache-2.0 +// + +use std::sync::atomic::{AtomicU32, Ordering}; +use std::sync::{Arc, Mutex}; + +/// Allocator for KVM memory slots +pub struct MemorySlotAllocator { + next_memory_slot: Arc, + memory_slot_free_list: Arc>>, +} + +impl MemorySlotAllocator { + /// Next free memory slot + pub fn next_memory_slot(&self) -> u32 { + if let Some(slot_id) = self.memory_slot_free_list.lock().unwrap().pop() { + return slot_id; + } + self.next_memory_slot.fetch_add(1, Ordering::SeqCst) + } + + /// Release memory slot for reuse + pub fn free_memory_slot(&mut self, slot: u32) { + self.memory_slot_free_list.lock().unwrap().push(slot) + } + + /// Instantiate struct + pub fn new( + next_memory_slot: Arc, + memory_slot_free_list: Arc>>, + ) -> Self { + Self { + next_memory_slot, + memory_slot_free_list, + } + } +}