Skip to content

Commit 4f71574

Browse files
committed
api: forbid ht_enabled=true on ARM
Signed-off-by: alindima <[email protected]>
1 parent ebc0dc3 commit 4f71574

File tree

6 files changed

+80
-21
lines changed

6 files changed

+80
-21
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
interfaces. Specifying interfaces that allow forwarding requests to MMDS is done
5858
by adding the network interface's ID to the `network_interfaces` field of PUT
5959
`/mmds/config` request's body.
60+
- Configuring `ht_enabled: true` on aarch64 via the API is forbidden.
6061

6162
### Fixed
6263

src/api_server/src/parsed_request.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,7 @@ pub(crate) mod tests {
789789
let body = "{ \
790790
\"vcpu_count\": 0, \
791791
\"mem_size_mib\": 0, \
792-
\"ht_enabled\": true \
792+
\"ht_enabled\": false \
793793
}";
794794
sender
795795
.write_all(http_request("PUT", "/machine-config", Some(&body)).as_bytes())
@@ -1010,7 +1010,7 @@ pub(crate) mod tests {
10101010
let body = "{ \
10111011
\"vcpu_count\": 0, \
10121012
\"mem_size_mib\": 0, \
1013-
\"ht_enabled\": true \
1013+
\"ht_enabled\": false \
10141014
}";
10151015
sender
10161016
.write_all(http_request("PATCH", "/machine-config", Some(&body)).as_bytes())
@@ -1021,7 +1021,7 @@ pub(crate) mod tests {
10211021
let body = "{ \
10221022
\"vcpu_count\": 0, \
10231023
\"mem_size_mib\": 0, \
1024-
\"ht_enabled\": true, \
1024+
\"ht_enabled\": false, \
10251025
\"cpu_template\": \"C3\" \
10261026
}";
10271027
sender

src/api_server/src/request/machine_configuration.rs

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub(crate) fn parse_put_machine_config(body: &Body) -> Result<ParsedRequest, Err
1919
Error::SerdeJson(e)
2020
})?;
2121

22+
#[cfg(target_arch = "aarch64")]
2223
check_unsupported_fields(&vm_config)?;
2324

2425
if vm_config.vcpu_count.is_none()
@@ -43,6 +44,7 @@ pub(crate) fn parse_patch_machine_config(body: &Body) -> Result<ParsedRequest, E
4344
Error::SerdeJson(e)
4445
})?;
4546

47+
#[cfg(target_arch = "aarch64")]
4648
check_unsupported_fields(&vm_config)?;
4749

4850
if vm_config.vcpu_count.is_none()
@@ -57,17 +59,24 @@ pub(crate) fn parse_patch_machine_config(body: &Body) -> Result<ParsedRequest, E
5759
)))
5860
}
5961

60-
fn check_unsupported_fields(_vm_config: &VmConfig) -> Result<(), Error> {
61-
#[cfg(target_arch = "aarch64")]
62-
{
63-
if _vm_config.cpu_template.is_some() {
64-
// cpu_template is not supported on aarch64
65-
return Err(Error::Generic(
66-
StatusCode::BadRequest,
67-
"CPU templates are not supported on aarch64".to_string(),
68-
));
69-
}
62+
#[cfg(target_arch = "aarch64")]
63+
fn check_unsupported_fields(vm_config: &VmConfig) -> Result<(), Error> {
64+
if vm_config.cpu_template.is_some() {
65+
// cpu_template is not supported on aarch64
66+
return Err(Error::Generic(
67+
StatusCode::BadRequest,
68+
"CPU templates are not supported on aarch64".to_string(),
69+
));
70+
}
71+
72+
if let Some(true) = vm_config.ht_enabled {
73+
// ht_enabled: true is not supported on aarch64
74+
return Err(Error::Generic(
75+
StatusCode::BadRequest,
76+
"Enabling HyperThreading is not supported on aarch64".to_string(),
77+
));
7078
}
79+
7180
Ok(())
7281
}
7382

@@ -91,13 +100,13 @@ mod tests {
91100
// 2. Test case for mandatory fields.
92101
let body = r#"{
93102
"mem_size_mib": 1024,
94-
"ht_enabled": true
103+
"ht_enabled": false
95104
}"#;
96105
assert!(parse_put_machine_config(&Body::new(body)).is_err());
97106

98107
let body = r#"{
99108
"vcpu_count": 8,
100-
"ht_enabled": true
109+
"ht_enabled": false
101110
}"#;
102111
assert!(parse_put_machine_config(&Body::new(body)).is_err());
103112

@@ -111,13 +120,13 @@ mod tests {
111120
let body = r#"{
112121
"vcpu_count": 8,
113122
"mem_size_mib": 1024,
114-
"ht_enabled": true,
123+
"ht_enabled": false,
115124
"track_dirty_pages": true
116125
}"#;
117126
let expected_config = VmConfig {
118127
vcpu_count: Some(8),
119128
mem_size_mib: Some(1024),
120-
ht_enabled: Some(true),
129+
ht_enabled: Some(false),
121130
cpu_template: None,
122131
track_dirty_pages: true,
123132
};
@@ -131,7 +140,7 @@ mod tests {
131140
let body = r#"{
132141
"vcpu_count": 8,
133142
"mem_size_mib": 1024,
134-
"ht_enabled": true,
143+
"ht_enabled": false,
135144
"cpu_template": "T2",
136145
"track_dirty_pages": true
137146
}"#;
@@ -142,7 +151,7 @@ mod tests {
142151
let expected_config = VmConfig {
143152
vcpu_count: Some(8),
144153
mem_size_mib: Some(1024),
145-
ht_enabled: Some(true),
154+
ht_enabled: Some(false),
146155
cpu_template: Some(CpuFeaturesTemplate::T2),
147156
track_dirty_pages: true,
148157
};
@@ -157,6 +166,35 @@ mod tests {
157166
{
158167
assert!(parse_put_machine_config(&Body::new(body)).is_err());
159168
}
169+
170+
// 5. Test that setting `ht_enabled: true` is successful on x86_64 while on aarch64, it is not.
171+
let body = r#"{
172+
"vcpu_count": 8,
173+
"mem_size_mib": 1024,
174+
"ht_enabled": true,
175+
"track_dirty_pages": true
176+
}"#;
177+
178+
#[cfg(target_arch = "x86_64")]
179+
{
180+
let expected_config = VmConfig {
181+
vcpu_count: Some(8),
182+
mem_size_mib: Some(1024),
183+
ht_enabled: Some(true),
184+
cpu_template: None,
185+
track_dirty_pages: true,
186+
};
187+
188+
match vmm_action_from_request(parse_put_machine_config(&Body::new(body)).unwrap()) {
189+
VmmAction::SetVmConfiguration(config) => assert_eq!(config, expected_config),
190+
_ => panic!("Test failed."),
191+
}
192+
}
193+
194+
#[cfg(target_arch = "aarch64")]
195+
{
196+
assert!(parse_put_machine_config(&Body::new(body)).is_err());
197+
}
160198
}
161199

162200
#[test]

src/api_server/swagger/firecracker.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,7 @@ definitions:
774774
description:
775775
The CPU Template defines a set of flags to be disabled from the microvm so that
776776
the features exposed to the guest are the same as in the selected instance type.
777+
Works only on Intel.
777778
enum:
778779
- C3
779780
- T2
@@ -935,7 +936,7 @@ definitions:
935936
$ref: "#/definitions/CpuTemplate"
936937
ht_enabled:
937938
type: boolean
938-
description: Flag for enabling/disabling Hyperthreading
939+
description: Flag for enabling/disabling Hyperthreading. x86-only.
939940
mem_size_mib:
940941
type: integer
941942
description: Memory size of VM

tests/integration_tests/functional/test_api.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ def test_api_put_update_pre_boot(test_microvm_with_api):
181181
# The machine configuration has a default value, so all PUTs are updates.
182182
microvm_config_json = {
183183
'vcpu_count': 4,
184-
'ht_enabled': True,
184+
'ht_enabled': not platform.machine() == 'aarch64',
185185
'mem_size_mib': 256,
186186
'track_dirty_pages': True
187187
}
@@ -393,6 +393,7 @@ def test_api_mmds_config(test_microvm_with_api):
393393
)['mmds-config']['version'] == "V2"
394394

395395

396+
# pylint: disable=too-many-statements
396397
def test_api_machine_config(test_microvm_with_api):
397398
"""
398399
Test /machine_config PUT/PATCH scenarios that unit tests can't cover.
@@ -425,6 +426,22 @@ def test_api_machine_config(test_microvm_with_api):
425426
)
426427
assert test_microvm.api_session.is_status_bad_request(response.status_code)
427428

429+
# Test that ht_enabled=True errors on ARM.
430+
response = test_microvm.machine_cfg.patch(
431+
ht_enabled=True
432+
)
433+
if platform.machine() == "x86_64":
434+
assert test_microvm.api_session.is_status_no_content(
435+
response.status_code
436+
)
437+
else:
438+
assert test_microvm.api_session.is_status_bad_request(
439+
response.status_code
440+
)
441+
assert "Enabling HyperThreading is not supported on aarch64" in\
442+
response.text
443+
444+
# Test that CPU template errors on ARM.
428445
response = test_microvm.machine_cfg.patch(
429446
cpu_template='C3'
430447
)

tests/integration_tests/functional/test_topology.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ def test_cache_topology(test_microvm_with_api, network_config, num_vcpus, htt):
152152
153153
@type: functional
154154
"""
155+
if htt and PLATFORM == 'aarch64':
156+
pytest.skip("HyperThreading is configurable only on x86.")
155157
vm = test_microvm_with_api
156158
vm.spawn()
157159
vm.basic_config(vcpu_count=num_vcpus, ht_enabled=htt)

0 commit comments

Comments
 (0)