@@ -20,6 +20,9 @@ pub enum MachineConfigError {
2020 IncompatibleBalloonSize ,
2121 /// The memory size (MiB) is either 0, or not a multiple of the configured page size.
2222 InvalidMemorySize ,
23+ /// The specified swiotlb region matches or exceeds the total VM memory, or not a multiple of the configured page size.
24+ #[ cfg( target_arch = "aarch64" ) ]
25+ InvalidSwiotlbRegionSize ,
2326 /// The number of vCPUs must be greater than 0, less than {MAX_SUPPORTED_VCPUS:} and must be 1 or an even number if SMT is enabled.
2427 InvalidVcpuCount ,
2528 /// Could not get the configuration of the previously installed balloon device to validate the memory size.
@@ -89,6 +92,17 @@ impl From<HugePageConfig> for Option<memfd::HugetlbSize> {
8992 }
9093}
9194
95+ /// Structure containing options for tweaking guest memory configuration.
96+ #[ derive( Clone , Copy , Debug , Default , PartialEq , Eq , Deserialize , Serialize ) ]
97+ pub struct MemoryConfig {
98+ /// The initial size of the swiotlb region. If 0, no swiotlb region will be created.
99+ /// If non-zero, all device will be forced to bounce buffers through a swiotlb region
100+ /// of the specified size that will have been placed into a dedicated kvm memslot.
101+ #[ cfg( target_arch = "aarch64" ) ]
102+ #[ serde( default ) ]
103+ pub initial_swiotlb_size : usize ,
104+ }
105+
92106/// Struct used in PUT `/machine-config` API call.
93107#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
94108#[ serde( deny_unknown_fields) ]
@@ -97,6 +111,10 @@ pub struct MachineConfig {
97111 pub vcpu_count : u8 ,
98112 /// The memory size in MiB.
99113 pub mem_size_mib : usize ,
114+ /// Additional configuration options for guest memory
115+ #[ serde( default ) ]
116+ #[ serde( skip_serializing_if = "is_default" ) ]
117+ pub mem_config : MemoryConfig ,
100118 /// Enables or disabled SMT.
101119 #[ serde( default ) ]
102120 pub smt : bool ,
@@ -121,6 +139,10 @@ pub struct MachineConfig {
121139 pub gdb_socket_path : Option < String > ,
122140}
123141
142+ fn is_default < T : Default + Eq > ( t : & T ) -> bool {
143+ t == & T :: default ( )
144+ }
145+
124146fn is_none_or_custom_template ( template : & Option < CpuTemplateType > ) -> bool {
125147 matches ! ( template, None | Some ( CpuTemplateType :: Custom ( _) ) )
126148}
@@ -153,6 +175,7 @@ impl Default for MachineConfig {
153175 Self {
154176 vcpu_count : 1 ,
155177 mem_size_mib : DEFAULT_MEM_SIZE_MIB ,
178+ mem_config : Default :: default ( ) ,
156179 smt : false ,
157180 cpu_template : None ,
158181 track_dirty_pages : false ,
@@ -178,6 +201,9 @@ pub struct MachineConfigUpdate {
178201 /// The memory size in MiB.
179202 #[ serde( default ) ]
180203 pub mem_size_mib : Option < usize > ,
204+ /// The memory configuration
205+ #[ serde( default ) ]
206+ pub mem_config : Option < MemoryConfig > ,
181207 /// Enables or disabled SMT.
182208 #[ serde( default ) ]
183209 pub smt : Option < bool > ,
@@ -210,6 +236,7 @@ impl From<MachineConfig> for MachineConfigUpdate {
210236 MachineConfigUpdate {
211237 vcpu_count : Some ( cfg. vcpu_count ) ,
212238 mem_size_mib : Some ( cfg. mem_size_mib ) ,
239+ mem_config : Some ( cfg. mem_config ) ,
213240 smt : Some ( cfg. smt ) ,
214241 cpu_template : cfg. static_template ( ) ,
215242 track_dirty_pages : Some ( cfg. track_dirty_pages ) ,
@@ -263,11 +290,19 @@ impl MachineConfig {
263290
264291 let mem_size_mib = update. mem_size_mib . unwrap_or ( self . mem_size_mib ) ;
265292 let page_config = update. huge_pages . unwrap_or ( self . huge_pages ) ;
293+ let mem_config = update. mem_config . unwrap_or ( self . mem_config ) ;
266294
267295 if mem_size_mib == 0 || !page_config. is_valid_mem_size ( mem_size_mib) {
268296 return Err ( MachineConfigError :: InvalidMemorySize ) ;
269297 }
270298
299+ #[ cfg( target_arch = "aarch64" ) ]
300+ if mem_config. initial_swiotlb_size >= mem_size_mib
301+ || !page_config. is_valid_mem_size ( mem_config. initial_swiotlb_size )
302+ {
303+ return Err ( MachineConfigError :: InvalidSwiotlbRegionSize ) ;
304+ }
305+
271306 let cpu_template = match update. cpu_template {
272307 None => self . cpu_template . clone ( ) ,
273308 Some ( StaticCpuTemplate :: None ) => None ,
@@ -277,6 +312,7 @@ impl MachineConfig {
277312 Ok ( MachineConfig {
278313 vcpu_count,
279314 mem_size_mib,
315+ mem_config,
280316 smt,
281317 cpu_template,
282318 track_dirty_pages : update. track_dirty_pages . unwrap_or ( self . track_dirty_pages ) ,
0 commit comments