@@ -9,6 +9,7 @@ use std::collections::HashMap;
9
9
use std:: fs:: OpenOptions ;
10
10
use std:: io:: Write ;
11
11
use std:: path:: Path ;
12
+ use std:: sync:: atomic:: { AtomicU32 , Ordering } ;
12
13
use std:: sync:: { Arc , Mutex , MutexGuard } ;
13
14
14
15
#[ cfg( target_arch = "x86_64" ) ]
@@ -54,6 +55,7 @@ pub struct VmCommon {
54
55
max_memslots : u32 ,
55
56
/// The guest memory of this Vm.
56
57
pub guest_memory : GuestMemoryMmap ,
58
+ next_kvm_slot : AtomicU32 ,
57
59
/// Interrupts used by Vm's devices
58
60
pub interrupts : Mutex < HashMap < u32 , RoutingEntry > > ,
59
61
/// Allocator for VM resources
@@ -133,6 +135,7 @@ impl Vm {
133
135
fd,
134
136
max_memslots : kvm. max_nr_memslots ( ) ,
135
137
guest_memory : GuestMemoryMmap :: default ( ) ,
138
+ next_kvm_slot : AtomicU32 :: new ( 0 ) ,
136
139
interrupts : Mutex :: new ( HashMap :: with_capacity ( GSI_MSI_END as usize + 1 ) ) ,
137
140
resource_allocator : Mutex :: new ( ResourceAllocator :: new ( ) ) ,
138
141
mmio_bus : Arc :: new ( Bus :: new ( ) ) ,
@@ -159,6 +162,16 @@ impl Vm {
159
162
Ok ( ( vcpus, exit_evt) )
160
163
}
161
164
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
+
162
175
/// Register a list of new memory regions to this [`Vm`].
163
176
pub fn register_memory_regions (
164
177
& mut self ,
@@ -174,13 +187,8 @@ impl Vm {
174
187
/// Register a new memory region to this [`Vm`].
175
188
pub fn register_memory_region ( & mut self , region : GuestRegionMmap ) -> Result < ( ) , VmError > {
176
189
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 ) ) ?;
184
192
185
193
let flags = if region. bitmap ( ) . is_some ( ) {
186
194
KVM_MEM_LOG_DIRTY_PAGES
0 commit comments