22// SPDX-License-Identifier: Apache-2.0
33use std:: fmt:: Debug ;
44
5- use serde:: { de , Deserialize , Serialize } ;
5+ use serde:: { Deserialize , Serialize } ;
66
77use crate :: cpu_config:: templates:: { CpuTemplateType , CustomCpuTemplate , StaticCpuTemplate } ;
88
@@ -20,23 +20,25 @@ pub enum VmConfigError {
2020 IncompatibleBalloonSize ,
2121 /// The memory size (MiB) is invalid.
2222 InvalidMemorySize ,
23- /// The vCPU number is invalid! The vCPU number can only be 1 or an even number when SMT is enabled.
23+ /// 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.
2424 InvalidVcpuCount ,
2525 /// Could not get the configuration of the previously installed balloon device to validate the memory size.
2626 InvalidVmState ,
27+ /// Enabling simultaneous multithreading is not supported on aarch64.
28+ #[ cfg( target_arch = "aarch64" ) ]
29+ SmtNotSupported ,
2730}
2831
2932/// Struct used in PUT `/machine-config` API call.
3033#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
3134#[ serde( deny_unknown_fields) ]
3235pub struct MachineConfig {
3336 /// Number of vcpu to start.
34- #[ serde( deserialize_with = "deserialize_vcpu_num" ) ]
3537 pub vcpu_count : u8 ,
3638 /// The memory size in MiB.
3739 pub mem_size_mib : usize ,
3840 /// Enables or disabled SMT.
39- #[ serde( default , deserialize_with = "deserialize_smt" ) ]
41+ #[ serde( default ) ]
4042 pub smt : bool ,
4143 /// A CPU template that it is used to filter the CPU features exposed to the guest.
4244 #[ serde( default , skip_serializing_if = "Option::is_none" ) ]
@@ -62,21 +64,13 @@ impl Default for MachineConfig {
6264#[ serde( deny_unknown_fields) ]
6365pub struct MachineConfigUpdate {
6466 /// Number of vcpu to start.
65- #[ serde(
66- default ,
67- skip_serializing_if = "Option::is_none" ,
68- deserialize_with = "deserialize_vcpu_num"
69- ) ]
67+ #[ serde( default , skip_serializing_if = "Option::is_none" ) ]
7068 pub vcpu_count : Option < u8 > ,
7169 /// The memory size in MiB.
7270 #[ serde( skip_serializing_if = "Option::is_none" ) ]
7371 pub mem_size_mib : Option < usize > ,
7472 /// Enables or disabled SMT.
75- #[ serde(
76- default ,
77- skip_serializing_if = "Option::is_none" ,
78- deserialize_with = "deserialize_smt"
79- ) ]
73+ #[ serde( default , skip_serializing_if = "Option::is_none" ) ]
8074 pub smt : Option < bool > ,
8175 /// A CPU template that it is used to filter the CPU features exposed to the guest.
8276 #[ serde( default , skip_serializing_if = "Option::is_none" ) ]
@@ -146,7 +140,12 @@ impl VmConfig {
146140
147141 let smt = update. smt . unwrap_or ( self . smt ) ;
148142
149- if vcpu_count == 0 {
143+ #[ cfg( target_arch = "aarch64" ) ]
144+ if smt {
145+ return Err ( VmConfigError :: SmtNotSupported ) ;
146+ }
147+
148+ if vcpu_count == 0 || vcpu_count > MAX_SUPPORTED_VCPUS {
150149 return Err ( VmConfigError :: InvalidVcpuCount ) ;
151150 }
152151
@@ -205,53 +204,3 @@ impl From<&VmConfig> for MachineConfig {
205204 }
206205 }
207206}
208-
209- /// Deserialization function for the `vcpu_num` field in `MachineConfig` and `MachineConfigUpdate`.
210- /// This is called only when `vcpu_num` is present in the JSON configuration.
211- /// `T` can be either `u8` or `Option<u8>` which both support ordering if `vcpu_num` is
212- /// present in the JSON.
213- fn deserialize_vcpu_num < ' de , D , T > ( d : D ) -> Result < T , D :: Error >
214- where
215- D : de:: Deserializer < ' de > ,
216- T : Deserialize < ' de > + PartialOrd + From < u8 > + Debug ,
217- {
218- let val = T :: deserialize ( d) ?;
219-
220- if val > T :: from ( MAX_SUPPORTED_VCPUS ) {
221- return Err ( de:: Error :: invalid_value (
222- de:: Unexpected :: Other ( "vcpu_num" ) ,
223- & "number of vCPUs exceeds the maximum limitation" ,
224- ) ) ;
225- }
226- if val < T :: from ( 1 ) {
227- return Err ( de:: Error :: invalid_value (
228- de:: Unexpected :: Other ( "vcpu_num" ) ,
229- & "number of vCPUs should be larger than 0" ,
230- ) ) ;
231- }
232-
233- Ok ( val)
234- }
235-
236- /// Deserialization function for the `smt` field in `MachineConfig` and `MachineConfigUpdate`.
237- /// This is called only when `smt` is present in the JSON configuration.
238- fn deserialize_smt < ' de , D , T > ( d : D ) -> Result < T , D :: Error >
239- where
240- D : de:: Deserializer < ' de > ,
241- T : Deserialize < ' de > + PartialEq + From < bool > + Debug ,
242- {
243- let val = T :: deserialize ( d) ?;
244-
245- // If this function was called it means that `smt` was specified in
246- // the JSON. On aarch64 the only accepted value is `false` so throw an
247- // error if `true` was specified.
248- #[ cfg( target_arch = "aarch64" ) ]
249- if val == T :: from ( true ) {
250- return Err ( de:: Error :: invalid_value (
251- de:: Unexpected :: Other ( "smt" ) ,
252- & "Enabling simultaneous multithreading is not supported on aarch64" ,
253- ) ) ;
254- }
255-
256- Ok ( val)
257- }
0 commit comments