@@ -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,16 @@ 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+ pub initial_swiotlb_size : usize ,
103+ }
104+
92105/// Struct used in PUT `/machine-config` API call.
93106#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
94107#[ serde( deny_unknown_fields) ]
@@ -97,6 +110,8 @@ pub struct MachineConfig {
97110 pub vcpu_count : u8 ,
98111 /// The memory size in MiB.
99112 pub mem_size_mib : usize ,
113+ /// Additional configuration options for guest memory
114+ pub mem_config : MemoryConfig ,
100115 /// Enables or disabled SMT.
101116 #[ serde( default ) ]
102117 pub smt : bool ,
@@ -153,6 +168,7 @@ impl Default for MachineConfig {
153168 Self {
154169 vcpu_count : 1 ,
155170 mem_size_mib : DEFAULT_MEM_SIZE_MIB ,
171+ mem_config : Default :: default ( ) ,
156172 smt : false ,
157173 cpu_template : None ,
158174 track_dirty_pages : false ,
@@ -178,6 +194,9 @@ pub struct MachineConfigUpdate {
178194 /// The memory size in MiB.
179195 #[ serde( default ) ]
180196 pub mem_size_mib : Option < usize > ,
197+ /// The memory configuration
198+ #[ serde( default ) ]
199+ pub mem_config : Option < MemoryConfig > ,
181200 /// Enables or disabled SMT.
182201 #[ serde( default ) ]
183202 pub smt : Option < bool > ,
@@ -210,6 +229,7 @@ impl From<MachineConfig> for MachineConfigUpdate {
210229 MachineConfigUpdate {
211230 vcpu_count : Some ( cfg. vcpu_count ) ,
212231 mem_size_mib : Some ( cfg. mem_size_mib ) ,
232+ mem_config : Some ( cfg. mem_config ) ,
213233 smt : Some ( cfg. smt ) ,
214234 cpu_template : cfg. static_template ( ) ,
215235 track_dirty_pages : Some ( cfg. track_dirty_pages ) ,
@@ -263,11 +283,19 @@ impl MachineConfig {
263283
264284 let mem_size_mib = update. mem_size_mib . unwrap_or ( self . mem_size_mib ) ;
265285 let page_config = update. huge_pages . unwrap_or ( self . huge_pages ) ;
286+ let mem_config = update. mem_config . unwrap_or ( self . mem_config ) ;
266287
267288 if mem_size_mib == 0 || !page_config. is_valid_mem_size ( mem_size_mib) {
268289 return Err ( MachineConfigError :: InvalidMemorySize ) ;
269290 }
270291
292+ #[ cfg( target_arch = "aarch64" ) ]
293+ if mem_config. initial_swiotlb_size >= mem_size_mib
294+ || !page_config. is_valid_mem_size ( mem_config. initial_swiotlb_size )
295+ {
296+ return Err ( MachineConfigError :: InvalidSwiotlbRegionSize ) ;
297+ }
298+
271299 let cpu_template = match update. cpu_template {
272300 None => self . cpu_template . clone ( ) ,
273301 Some ( StaticCpuTemplate :: None ) => None ,
@@ -277,6 +305,7 @@ impl MachineConfig {
277305 Ok ( MachineConfig {
278306 vcpu_count,
279307 mem_size_mib,
308+ mem_config,
280309 smt,
281310 cpu_template,
282311 track_dirty_pages : update. track_dirty_pages . unwrap_or ( self . track_dirty_pages ) ,
0 commit comments