Skip to content

Commit 2077cfc

Browse files
committed
Add CCA feature
This is WIP Signed-off-by: Matias Ezequiel Vara Larsen <[email protected]>
1 parent 86f75cd commit 2077cfc

File tree

15 files changed

+389
-50
lines changed

15 files changed

+389
-50
lines changed

Makefile

Lines changed: 3 additions & 0 deletions
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/src/aarch64/fdt.rs

Lines changed: 3 additions & 0 deletions
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

Lines changed: 3 additions & 1 deletion
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/arch/src/aarch64/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub fn arch_memory_regions(size: usize) -> (ArchMemoryInfo, Vec<(GuestAddress, u
6969
} else {
7070
vec![
7171
(GuestAddress(layout::DRAM_MEM_START), dram_size),
72-
(GuestAddress(shm_start_addr), MMIO_SHM_SIZE as usize),
72+
//(GuestAddress(shm_start_addr), MMIO_SHM_SIZE as usize),
7373
]
7474
};
7575

src/devices/Cargo.toml

Lines changed: 2 additions & 0 deletions
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

Lines changed: 12 additions & 3 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ use std::sync::{Arc, Mutex};
55
use std::thread::JoinHandle;
66

77
use utils::eventfd::{EventFd, EFD_NONBLOCK};
8-
use virtio_bindings::{virtio_config::VIRTIO_F_VERSION_1, virtio_ring::VIRTIO_RING_F_EVENT_IDX};
8+
use virtio_bindings::{
9+
virtio_config::VIRTIO_F_ACCESS_PLATFORM, virtio_config::VIRTIO_F_VERSION_1,
10+
virtio_ring::VIRTIO_RING_F_EVENT_IDX,
11+
};
912
use vm_memory::{ByteValued, GuestMemoryMmap};
1013

1114
use super::super::{
@@ -63,7 +66,13 @@ impl Fs {
6366
.push(EventFd::new(utils::eventfd::EFD_NONBLOCK).map_err(FsError::EventFd)?);
6467
}
6568

66-
let avail_features = (1u64 << VIRTIO_F_VERSION_1) | (1u64 << VIRTIO_RING_F_EVENT_IDX);
69+
let avail_features = if cfg!(feature = "cca") {
70+
(1u64 << VIRTIO_F_VERSION_1)
71+
| (1u64 << VIRTIO_RING_F_EVENT_IDX)
72+
| (1 << VIRTIO_F_ACCESS_PLATFORM as u64)
73+
} else {
74+
(1u64 << VIRTIO_F_VERSION_1) | (1u64 << VIRTIO_RING_F_EVENT_IDX)
75+
};
6776

6877
let tag = fs_id.into_bytes();
6978
let mut config = VirtioFsConfig::default();

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

Lines changed: 6 additions & 1 deletion
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::Gic;
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/src/lib.rs

Lines changed: 68 additions & 0 deletions
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;
@@ -1077,9 +1087,12 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
10771087
#[cfg(target_os = "macos")]
10781088
let (sender, receiver) = unbounded();
10791089

1090+
let (io_sender, receiver) = unbounded();
1091+
10801092
let _vmm = match vmm::builder::build_microvm(
10811093
&ctx_cfg.vmr,
10821094
&mut event_manager,
1095+
io_sender,
10831096
ctx_cfg.shutdown_efd,
10841097
#[cfg(target_os = "macos")]
10851098
sender,
@@ -1094,6 +1107,61 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
10941107
#[cfg(target_os = "macos")]
10951108
let mapper_vmm = _vmm.clone();
10961109

1110+
let vm = _vmm.lock().unwrap().kvm_vm().fd.clone();
1111+
let guest_mem = _vmm.lock().unwrap().guest_memory().clone();
1112+
let guest_memfd = _vmm.lock().unwrap().guest_memfd_vec.clone();
1113+
1114+
std::thread::spawn(move || loop {
1115+
match receiver.recv() {
1116+
Err(e) => error!("Error in receiver: {:?}", e),
1117+
Ok(m) => {
1118+
let _ret = vm
1119+
.lock()
1120+
.unwrap()
1121+
.set_memory_attributes(kvm_memory_attributes {
1122+
address: m.addr,
1123+
size: m.size,
1124+
attributes: m.attributes as u64,
1125+
flags: 0,
1126+
});
1127+
1128+
// from private to shared
1129+
if m.attributes == 0 {
1130+
for (index, region) in guest_mem.iter().enumerate() {
1131+
// this supposes that m.addr + m.size < region.start + region.size
1132+
// which may be false
1133+
if (region.start_addr().raw_value() + region.size() as u64) > m.addr {
1134+
let offset = m.addr - region.start_addr().raw_value();
1135+
unsafe {
1136+
let _ret = fallocate(
1137+
*guest_memfd.get(index).unwrap(),
1138+
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
1139+
offset as i64,
1140+
m.size as i64,
1141+
);
1142+
}
1143+
}
1144+
}
1145+
// from shared to private
1146+
} else {
1147+
for (_index, region) in guest_mem.iter().enumerate() {
1148+
if (region.start_addr().raw_value() + region.size() as u64) > m.addr {
1149+
let offset = m.addr - region.start_addr().raw_value();
1150+
let host_startaddr = m.addr + offset;
1151+
unsafe {
1152+
let _ret = madvise(
1153+
host_startaddr as *mut c_void,
1154+
m.size.try_into().unwrap(),
1155+
MADV_DONTNEED,
1156+
);
1157+
}
1158+
}
1159+
}
1160+
}
1161+
}
1162+
}
1163+
});
1164+
10971165
#[cfg(target_os = "macos")]
10981166
std::thread::spawn(move || loop {
10991167
match receiver.recv() {

0 commit comments

Comments
 (0)