Skip to content

Commit 8b97dc4

Browse files
committed
Support ARM CCA feature
Enable to build confidential guests using ARM CCA (Confidential Computing Architecture). This work relies on v7 series for Linux and v5 series for KVM. This has been tested only on the corresponding FVP model simulator. For testing, you require specific kvm-ioctls and kvm-bindings crates. Signed-off-by: Matias Ezequiel Vara Larsen <[email protected]>
1 parent 8affa13 commit 8b97dc4

File tree

16 files changed

+388
-40
lines changed

16 files changed

+388
-40
lines changed

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ ifeq ($(SEV),1)
2727
INIT_SRC += $(SNP_INIT_SRC)
2828
BUILD_INIT = 0
2929
endif
30+
ifeq ($(CCA), 1)
31+
FEATURE_FLAGS := --features cca
32+
endif
3033
ifeq ($(GPU),1)
3134
FEATURE_FLAGS += --features gpu
3235
endif

src/arch/Cargo.toml

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ authors = ["The Chromium OS Authors"]
55
edition = "2021"
66

77
[features]
8+
default = ["cca"]
9+
cca = []
810
tee = []
911
amd-sev = [ "tee" ]
1012
efi = []
@@ -18,8 +20,8 @@ smbios = { path = "../smbios" }
1820
utils = { path = "../utils" }
1921

2022
[target.'cfg(target_os = "linux")'.dependencies]
21-
kvm-bindings = { version = ">=0.8", features = ["fam-wrappers"] }
22-
kvm-ioctls = ">=0.17"
23+
kvm-bindings = { version = ">=0.8", features = ["fam-wrappers"] , git = "https://github.com/virtee/kvm-bindings", branch = "add_bindings_for_realms" }
24+
kvm-ioctls = { version = ">=0.17", git = "https://github.com/virtee/kvm-ioctls", branch = "cca" }
2325

2426
[target.'cfg(target_arch = "aarch64")'.dependencies]
2527
vm-fdt = ">= 0.2.0"

src/arch/src/aarch64/fdt.rs

+3
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,10 @@ fn create_psci_node(fdt: &mut FdtWriter) -> Result<()> {
285285
// Two methods available: hvc and smc.
286286
// As per documentation, PSCI calls between a guest and hypervisor may use the HVC conduit instead of SMC.
287287
// So, since we are using kvm, we need to use hvc.
288+
#[cfg(not(feature = "cca"))]
288289
fdt.property_string("method", "hvc")?;
290+
#[cfg(feature = "cca")]
291+
fdt.property_string("method", "smc")?;
289292
fdt.end_node(node)?;
290293

291294
Ok(())

src/arch/src/aarch64/linux/regs.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,10 @@ arm64_sys_reg!(MPIDR_EL1, 3, 0, 0, 0, 5);
125125
/// * `boot_ip` - Starting instruction pointer.
126126
/// * `mem` - Reserved DRAM for current VM.
127127
pub fn setup_regs(vcpu: &VcpuFd, cpu_id: u8, boot_ip: u64, mem: &GuestMemoryMmap) -> Result<()> {
128-
// Get the register index of the PSTATE (Processor State) register.
128+
// PSTATE cannot be accesed from the host in CCA
129+
#[cfg(not(feature = "cca"))]
129130
#[allow(deref_nullptr)]
131+
// Get the register index of the PSTATE (Processor State) register.
130132
vcpu.set_one_reg(arm64_core_reg!(pstate), &PSTATE_FAULT_BITS_64.to_le_bytes())
131133
.map_err(Error::SetCoreRegister)?;
132134

src/cpuid/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ edition = "2021"
88
vmm-sys-util = ">=0.11"
99

1010
[target.'cfg(target_os = "linux")'.dependencies]
11-
kvm-bindings = { version = ">=0.8", features = ["fam-wrappers"] }
12-
kvm-ioctls = ">=0.17"
11+
kvm-bindings = { version = ">=0.8", features = ["fam-wrappers"] , git = "https://github.com/virtee/kvm-bindings", branch = "add_bindings_for_realms" }
12+
kvm-ioctls = { version = ">=0.17", git = "https://github.com/virtee/kvm-ioctls", branch = "cca" }

src/devices/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ authors = ["The Chromium OS Authors"]
55
edition = "2021"
66

77
[features]
8+
default = ["cca"]
89
tee = []
10+
cca = []
911
amd-sev = ["blk", "tee"]
1012
net = []
1113
blk = []

src/devices/src/virtio/console/device.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,18 @@ use crate::virtio::{PortDescription, VmmExitObserver};
3030
pub(crate) const CONTROL_RXQ_INDEX: usize = 2;
3131
pub(crate) const CONTROL_TXQ_INDEX: usize = 3;
3232

33-
pub(crate) const AVAIL_FEATURES: u64 = 1 << uapi::VIRTIO_CONSOLE_F_SIZE as u64
34-
| 1 << uapi::VIRTIO_CONSOLE_F_MULTIPORT as u64
35-
| 1 << uapi::VIRTIO_F_VERSION_1 as u64;
33+
// CCA requires VIRTIO_F_ACCESS_PLATFORM to ensure DMA-APIs
34+
// are triggered for virtio in Linux
35+
pub(crate) const AVAIL_FEATURES: u64 = if cfg!(feature = "cca") {
36+
1 << uapi::VIRTIO_CONSOLE_F_SIZE as u64
37+
| 1 << uapi::VIRTIO_CONSOLE_F_MULTIPORT as u64
38+
| 1 << uapi::VIRTIO_F_VERSION_1 as u64
39+
| 1 << uapi::VIRTIO_F_ACCESS_PLATFORM as u64
40+
} else {
41+
1 << uapi::VIRTIO_CONSOLE_F_SIZE as u64
42+
| 1 << uapi::VIRTIO_CONSOLE_F_MULTIPORT as u64
43+
| 1 << uapi::VIRTIO_F_VERSION_1 as u64
44+
};
3645

3746
#[repr(C)]
3847
#[derive(Default)]

src/devices/src/virtio/console/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ mod defs {
2222
pub const VIRTIO_CONSOLE_F_MULTIPORT: u32 = 1;
2323
pub const VIRTIO_F_VERSION_1: u32 = 32;
2424
pub const VIRTIO_ID_CONSOLE: u32 = 3;
25+
pub const VIRTIO_F_ACCESS_PLATFORM: u32 = 33;
2526
}
2627

2728
#[allow(dead_code)]

src/devices/src/virtio/fs/device.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ use std::thread::JoinHandle;
99
#[cfg(target_os = "macos")]
1010
use hvf::MemoryMapping;
1111
use utils::eventfd::{EventFd, EFD_NONBLOCK};
12-
use virtio_bindings::{virtio_config::VIRTIO_F_VERSION_1, virtio_ring::VIRTIO_RING_F_EVENT_IDX};
12+
use virtio_bindings::{
13+
virtio_config::VIRTIO_F_ACCESS_PLATFORM, virtio_config::VIRTIO_F_VERSION_1,
14+
virtio_ring::VIRTIO_RING_F_EVENT_IDX,
15+
};
1316
use vm_memory::{ByteValued, GuestMemoryMmap};
1417

1518
use super::super::{
@@ -70,7 +73,13 @@ impl Fs {
7073
.push(EventFd::new(utils::eventfd::EFD_NONBLOCK).map_err(FsError::EventFd)?);
7174
}
7275

73-
let avail_features = (1u64 << VIRTIO_F_VERSION_1) | (1u64 << VIRTIO_RING_F_EVENT_IDX);
76+
let avail_features = if cfg!(feature = "cca") {
77+
(1u64 << VIRTIO_F_VERSION_1)
78+
| (1u64 << VIRTIO_RING_F_EVENT_IDX)
79+
| (1 << VIRTIO_F_ACCESS_PLATFORM as u64)
80+
} else {
81+
(1u64 << VIRTIO_F_VERSION_1) | (1u64 << VIRTIO_RING_F_EVENT_IDX)
82+
};
7483

7584
let tag = fs_id.into_bytes();
7685
let mut config = VirtioFsConfig::default();

src/devices/src/virtio/rng/device.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,17 @@ use super::super::{
1313
use super::{defs, defs::uapi};
1414
use crate::legacy::GicV3;
1515
use crate::Error as DeviceError;
16+
use virtio_bindings::virtio_config::VIRTIO_F_ACCESS_PLATFORM;
1617

1718
// Request queue.
1819
pub(crate) const REQ_INDEX: usize = 0;
1920

2021
// Supported features.
21-
pub(crate) const AVAIL_FEATURES: u64 = 1 << uapi::VIRTIO_F_VERSION_1 as u64;
22+
pub(crate) const AVAIL_FEATURES: u64 = if cfg!(feature = "cca") {
23+
1 << uapi::VIRTIO_F_VERSION_1 as u64 | 1 << VIRTIO_F_ACCESS_PLATFORM as u64
24+
} else {
25+
1 << uapi::VIRTIO_F_VERSION_1 as u64
26+
};
2227

2328
#[derive(Copy, Clone, Debug, Default)]
2429
#[repr(C, packed)]

src/libkrun/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ snd = []
1616
virgl_resource_map2 = []
1717

1818
[dependencies]
19+
vm-memory = { version = ">=0.13", features = ["backend-mmap"] }
1920
crossbeam-channel = "0.5"
2021
env_logger = "0.9.0"
2122
libc = ">=0.2.39"
2223
log = "0.4.0"
2324
once_cell = "1.4.1"
2425

26+
kvm-bindings = { version = ">=0.8", features = ["fam-wrappers"] , git = "https://github.com/virtee/kvm-bindings", branch = "add_bindings_for_realms" }
2527
devices = { path = "../devices" }
2628
polly = { path = "../polly" }
2729
utils = { path = "../utils" }

src/libkrun/src/lib.rs

+68
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
#[macro_use]
22
extern crate log;
33

4+
use crossbeam_channel::unbounded;
5+
use kvm_bindings::kvm_memory_attributes;
6+
use libc::fallocate;
7+
use libc::madvise;
8+
use libc::FALLOC_FL_KEEP_SIZE;
9+
use libc::FALLOC_FL_PUNCH_HOLE;
10+
use libc::MADV_DONTNEED;
411
use std::collections::hash_map::Entry;
512
use std::collections::HashMap;
613
use std::convert::TryInto;
@@ -11,10 +18,13 @@ use std::ffi::CString;
1118
#[cfg(target_os = "linux")]
1219
use std::os::fd::AsRawFd;
1320
use std::os::fd::RawFd;
21+
use std::os::raw::c_void;
1422
use std::path::PathBuf;
1523
use std::slice;
1624
use std::sync::atomic::{AtomicI32, Ordering};
1725
use std::sync::Mutex;
26+
use vm_memory::GuestMemoryRegion;
27+
use vm_memory::{Address, GuestMemory};
1828

1929
#[cfg(target_os = "macos")]
2030
use crossbeam_channel::unbounded;
@@ -1225,9 +1235,12 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
12251235
#[cfg(target_os = "macos")]
12261236
let (sender, receiver) = unbounded();
12271237

1238+
let (io_sender, receiver) = unbounded();
1239+
12281240
let _vmm = match vmm::builder::build_microvm(
12291241
&ctx_cfg.vmr,
12301242
&mut event_manager,
1243+
io_sender,
12311244
ctx_cfg.shutdown_efd,
12321245
#[cfg(target_os = "macos")]
12331246
sender,
@@ -1242,6 +1255,61 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
12421255
#[cfg(target_os = "macos")]
12431256
let mapper_vmm = _vmm.clone();
12441257

1258+
let vm = _vmm.lock().unwrap().kvm_vm().fd.clone();
1259+
let guest_mem = _vmm.lock().unwrap().guest_memory().clone();
1260+
let guest_memfd = _vmm.lock().unwrap().guest_memfd_vec.clone();
1261+
1262+
std::thread::spawn(move || loop {
1263+
match receiver.recv() {
1264+
Err(e) => error!("Error in receiver: {:?}", e),
1265+
Ok(m) => {
1266+
let _ret = vm
1267+
.lock()
1268+
.unwrap()
1269+
.set_memory_attributes(kvm_memory_attributes {
1270+
address: m.addr,
1271+
size: m.size,
1272+
attributes: m.attributes as u64,
1273+
flags: 0,
1274+
});
1275+
1276+
// from private to shared
1277+
if m.attributes == 0 {
1278+
for (index, region) in guest_mem.iter().enumerate() {
1279+
// this supposes that m.addr + m.size < region.start + region.size
1280+
// which may be false
1281+
if (region.start_addr().raw_value() + region.size() as u64) > m.addr {
1282+
let offset = m.addr - region.start_addr().raw_value();
1283+
unsafe {
1284+
let _ret = fallocate(
1285+
*guest_memfd.get(index).unwrap(),
1286+
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
1287+
offset as i64,
1288+
m.size as i64,
1289+
);
1290+
}
1291+
}
1292+
}
1293+
// from shared to private
1294+
} else {
1295+
for (_index, region) in guest_mem.iter().enumerate() {
1296+
if (region.start_addr().raw_value() + region.size() as u64) > m.addr {
1297+
let offset = m.addr - region.start_addr().raw_value();
1298+
let host_startaddr = m.addr + offset;
1299+
unsafe {
1300+
let _ret = madvise(
1301+
host_startaddr as *mut c_void,
1302+
m.size.try_into().unwrap(),
1303+
MADV_DONTNEED,
1304+
);
1305+
}
1306+
}
1307+
}
1308+
}
1309+
}
1310+
}
1311+
});
1312+
12451313
#[cfg(target_os = "macos")]
12461314
std::thread::Builder::new()
12471315
.name("mapping worker".into())

src/vmm/Cargo.toml

+6-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ authors = ["Amazon Firecracker team <[email protected]>"]
55
edition = "2021"
66

77
[features]
8+
default = ["cca"]
89
tee = []
910
amd-sev = [ "blk", "tee", "codicon", "kbs-types", "procfs", "rdrand", "serde", "serde_json", "sev", "curl" ]
11+
cca = []
1012
net = []
1113
blk = []
1214
efi = [ "blk", "net" ]
@@ -37,12 +39,14 @@ sev = { version = "4.0.0", features = ["openssl"], optional = true }
3739
curl = { version = "0.4", optional = true }
3840
nix = "0.24.1"
3941

42+
cca = { git = "https://github.com/virtee/cca" }
43+
4044
[target.'cfg(target_arch = "x86_64")'.dependencies]
4145
cpuid = { path = "../cpuid" }
4246

4347
[target.'cfg(target_os = "linux")'.dependencies]
44-
kvm-bindings = { version = ">=0.10", features = ["fam-wrappers"] }
45-
kvm-ioctls = ">=0.17"
48+
kvm-bindings = { version = ">=0.8", features = ["fam-wrappers"] , git = "https://github.com/virtee/kvm-bindings", branch = "add_bindings_for_realms" }
49+
kvm-ioctls = { version = ">=0.17", git = "https://github.com/virtee/kvm-ioctls", branch = "cca" }
4650

4751
[target.'cfg(target_os = "macos")'.dependencies]
4852
hvf = { path = "../hvf" }

0 commit comments

Comments
 (0)