Skip to content

Commit 72ac94b

Browse files
committed
feat(aarch64): ability to work with wide registers
- Updated `kvm-bindings` to 1.4 which changes `get/set_one_reg` methods. - Updated internal representation of aarch64 registers Now we are able to work with register wider then 128 bits. All registers are stored in the `Aarch64RegisterVec` in one byte array. This way registers of different sizes can be efficiently stored and iterated on. Supported sizes are: 8, 16, 32, 64, 128, 256, 512, 1024, 2048 bits (all sizes supported by KVM). Register size is determined by the ID of the register. Interactions with registers are happening using `Aarch64RegisterRef` or `Aarch64RegisterRefMut`. Signed-off-by: Egor Lazarchuk <[email protected]>
1 parent b1ba5e6 commit 72ac94b

File tree

13 files changed

+1085
-351
lines changed

13 files changed

+1085
-351
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cpu-template-helper/src/template/dump/aarch64.rs

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4+
use vmm::arch::aarch64::regs::RegSize;
45
use vmm::cpu_config::aarch64::custom_cpu_template::RegisterModifier;
56
use vmm::cpu_config::templates::{CpuConfiguration, CustomCpuTemplate, RegisterValueFilter};
67

@@ -10,7 +11,18 @@ pub fn config_to_template(cpu_config: &CpuConfiguration) -> CustomCpuTemplate {
1011
let mut reg_modifiers: Vec<RegisterModifier> = cpu_config
1112
.regs
1213
.iter()
13-
.map(|reg| reg_modifier!(reg.id, reg.value))
14+
.map(|reg| match reg.size() {
15+
RegSize::U32 => {
16+
reg_modifier!(reg.id, u128::from(reg.value::<u32, 4>()))
17+
}
18+
RegSize::U64 => {
19+
reg_modifier!(reg.id, u128::from(reg.value::<u64, 8>()))
20+
}
21+
RegSize::U128 => {
22+
reg_modifier!(reg.id, reg.value::<u128, 16>())
23+
}
24+
_ => unreachable!("Only 32, 64 and 128 bit wide registers are supported"),
25+
})
1426
.collect();
1527
reg_modifiers.sort_by_key(|modifier| modifier.addr);
1628

@@ -19,41 +31,38 @@ pub fn config_to_template(cpu_config: &CpuConfiguration) -> CustomCpuTemplate {
1931

2032
#[cfg(test)]
2133
mod tests {
22-
use vmm::arch::aarch64::regs::Aarch64Register;
34+
use vmm::arch::aarch64::regs::{Aarch64RegisterRef, Aarch64RegisterVec};
2335

2436
use super::*;
2537

26-
fn build_sample_regs() -> Vec<Aarch64Register> {
27-
vec![
28-
Aarch64Register {
29-
id: 0x0,
30-
value: 0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff,
31-
},
32-
Aarch64Register {
33-
id: 0xffff_ffff_ffff_ffff,
34-
value: 0x0000_ffff_0000_ffff_0000_ffff_0000_ffff,
35-
},
36-
Aarch64Register {
37-
id: 0x1,
38-
value: 0x0000_ffff_0000_ffff_0000_ffff_0000_ffff,
39-
},
40-
]
38+
// These are used as IDs to satisfy requirenments
39+
// of `Aarch64RegisterRef::new`
40+
const KVM_REG_SIZE_U32: u64 = 0x0020000000000000;
41+
const KVM_REG_SIZE_U64: u64 = 0x0030000000000000;
42+
const KVM_REG_SIZE_U128: u64 = 0x0040000000000000;
43+
44+
fn build_sample_regs() -> Aarch64RegisterVec {
45+
let mut v = Aarch64RegisterVec::default();
46+
v.push(Aarch64RegisterRef::new(
47+
KVM_REG_SIZE_U128,
48+
&0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff_u128.to_le_bytes(),
49+
));
50+
v.push(Aarch64RegisterRef::new(
51+
KVM_REG_SIZE_U32,
52+
&0x0000_ffff_u32.to_le_bytes(),
53+
));
54+
v.push(Aarch64RegisterRef::new(
55+
KVM_REG_SIZE_U64,
56+
&0x0000_ffff_0000_ffff_u64.to_le_bytes(),
57+
));
58+
v
4159
}
4260

4361
fn build_expected_reg_modifiers() -> Vec<RegisterModifier> {
4462
vec![
45-
reg_modifier!(
46-
0x0000_0000_0000_0000,
47-
0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff
48-
),
49-
reg_modifier!(
50-
0x0000_0000_0000_0001,
51-
0x0000_ffff_0000_ffff_0000_ffff_0000_ffff
52-
),
53-
reg_modifier!(
54-
0xffff_ffff_ffff_ffff,
55-
0x0000_ffff_0000_ffff_0000_ffff_0000_ffff
56-
),
63+
reg_modifier!(KVM_REG_SIZE_U32, 0x0000_ffff),
64+
reg_modifier!(KVM_REG_SIZE_U64, 0x0000_ffff_0000_ffff),
65+
reg_modifier!(KVM_REG_SIZE_U128, 0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff),
5766
]
5867
}
5968

src/vmm/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ bitflags = "2.0.2"
1414
derive_more = { version = "0.99.17", default-features = false, features = ["from", "display"] }
1515
event-manager = "0.3.0"
1616
kvm-bindings = { version = "0.6.0", features = ["fam-wrappers"] }
17-
kvm-ioctls = "0.12.0"
17+
kvm-ioctls = "0.14.0"
1818
lazy_static = "1.4.0"
1919
libc = "0.2.117"
2020
linux-loader = "0.9.0"

src/vmm/src/arch/aarch64/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ pub mod gic;
99
pub mod layout;
1010
/// Logic for configuring aarch64 registers.
1111
pub mod regs;
12+
/// Helper methods for VcpuFd.
13+
pub mod vcpu;
1214

1315
use std::cmp::min;
1416
use std::collections::HashMap;

0 commit comments

Comments
 (0)