@@ -9,6 +9,7 @@ use std::collections::HashMap;
99use std:: fs:: OpenOptions ;
1010use std:: io:: Write ;
1111use std:: path:: Path ;
12+ use std:: sync:: atomic:: { AtomicU32 , Ordering } ;
1213use std:: sync:: { Arc , Mutex , MutexGuard } ;
1314
1415use anyhow:: anyhow;
@@ -55,6 +56,7 @@ pub struct VmCommon {
5556 max_memslots : u32 ,
5657 /// The guest memory of this Vm.
5758 pub guest_memory : GuestMemoryMmap ,
59+ next_kvm_slot : AtomicU32 ,
5860 /// Interrupts used by Vm's devices
5961 pub interrupts : Mutex < HashMap < u32 , RoutingEntry > > ,
6062 /// Allocator for VM resources
@@ -134,6 +136,7 @@ impl Vm {
134136 fd,
135137 max_memslots : kvm. max_nr_memslots ( ) ,
136138 guest_memory : GuestMemoryMmap :: default ( ) ,
139+ next_kvm_slot : AtomicU32 :: new ( 0 ) ,
137140 interrupts : Mutex :: new ( HashMap :: with_capacity ( GSI_MSI_END as usize + 1 ) ) ,
138141 resource_allocator : Mutex :: new ( ResourceAllocator :: new ( ) ) ,
139142 mmio_bus : Arc :: new ( Bus :: new ( ) ) ,
@@ -160,6 +163,17 @@ impl Vm {
160163 Ok ( ( vcpus, exit_evt) )
161164 }
162165
166+ /// Obtain the next free kvm slot id
167+ pub fn next_kvm_slot ( & self ) -> Option < u32 > {
168+ let next = self . common . next_kvm_slot . load ( Ordering :: Relaxed ) ;
169+ if next == self . common . max_memslots {
170+ None
171+ } else {
172+ self . common . next_kvm_slot . store ( next + 1 , Ordering :: Relaxed ) ;
173+ Some ( next)
174+ }
175+ }
176+
163177 /// Register a list of new memory regions to this [`Vm`].
164178 pub fn register_memory_regions (
165179 & mut self ,
@@ -175,13 +189,8 @@ impl Vm {
175189 /// Register a new memory region to this [`Vm`].
176190 pub fn register_memory_region ( & mut self , region : GuestRegionMmap ) -> Result < ( ) , VmError > {
177191 let next_slot = self
178- . guest_memory ( )
179- . num_regions ( )
180- . try_into ( )
181- . expect ( "Number of existing memory regions exceeds u32::MAX" ) ;
182- if self . common . max_memslots <= next_slot {
183- return Err ( VmError :: NotEnoughMemorySlots ( self . common . max_memslots ) ) ;
184- }
192+ . next_kvm_slot ( )
193+ . ok_or ( VmError :: NotEnoughMemorySlots ( self . common . max_memslots ) ) ?;
185194
186195 let flags = if region. bitmap ( ) . is_some ( ) {
187196 KVM_MEM_LOG_DIRTY_PAGES
0 commit comments