@@ -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
1415#[ cfg( target_arch = "x86_64" ) ]
@@ -54,6 +55,7 @@ pub struct VmCommon {
5455 max_memslots : u32 ,
5556 /// The guest memory of this Vm.
5657 pub guest_memory : GuestMemoryMmap ,
58+ next_kvm_slot : AtomicU32 ,
5759 /// Interrupts used by Vm's devices
5860 pub interrupts : Mutex < HashMap < u32 , RoutingEntry > > ,
5961 /// Allocator for VM resources
@@ -133,6 +135,7 @@ impl Vm {
133135 fd,
134136 max_memslots : kvm. max_nr_memslots ( ) ,
135137 guest_memory : GuestMemoryMmap :: default ( ) ,
138+ next_kvm_slot : AtomicU32 :: new ( 0 ) ,
136139 interrupts : Mutex :: new ( HashMap :: with_capacity ( GSI_MSI_END as usize + 1 ) ) ,
137140 resource_allocator : Mutex :: new ( ResourceAllocator :: new ( ) ) ,
138141 mmio_bus : Arc :: new ( Bus :: new ( ) ) ,
@@ -159,6 +162,16 @@ impl Vm {
159162 Ok ( ( vcpus, exit_evt) )
160163 }
161164
165+ /// Obtain the next free kvm slot id
166+ pub fn next_kvm_slot ( & self ) -> Option < u32 > {
167+ let next = self . common . next_kvm_slot . fetch_add ( 1 , Ordering :: Relaxed ) ;
168+ if self . common . max_memslots <= next {
169+ None
170+ } else {
171+ Some ( next)
172+ }
173+ }
174+
162175 /// Register a list of new memory regions to this [`Vm`].
163176 pub fn register_memory_regions (
164177 & mut self ,
@@ -174,13 +187,8 @@ impl Vm {
174187 /// Register a new memory region to this [`Vm`].
175188 pub fn register_memory_region ( & mut self , region : GuestRegionMmap ) -> Result < ( ) , VmError > {
176189 let next_slot = self
177- . guest_memory ( )
178- . num_regions ( )
179- . try_into ( )
180- . expect ( "Number of existing memory regions exceeds u32::MAX" ) ;
181- if self . common . max_memslots <= next_slot {
182- return Err ( VmError :: NotEnoughMemorySlots ( self . common . max_memslots ) ) ;
183- }
190+ . next_kvm_slot ( )
191+ . ok_or ( VmError :: NotEnoughMemorySlots ( self . common . max_memslots ) ) ?;
184192
185193 let flags = if region. bitmap ( ) . is_some ( ) {
186194 KVM_MEM_LOG_DIRTY_PAGES
0 commit comments