Skip to content

Commit 6cebf95

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

File tree

15 files changed

+361
-47
lines changed

15 files changed

+361
-47
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/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/arch/src/aarch64/mod.rs

+1-1
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

+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
@@ -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

+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::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

+54
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
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::FALLOC_FL_KEEP_SIZE;
8+
use libc::FALLOC_FL_PUNCH_HOLE;
49
use std::collections::hash_map::Entry;
510
use std::collections::HashMap;
611
use std::convert::TryInto;
@@ -15,6 +20,8 @@ use std::path::PathBuf;
1520
use std::slice;
1621
use std::sync::atomic::{AtomicI32, Ordering};
1722
use std::sync::Mutex;
23+
use vm_memory::GuestMemoryRegion;
24+
use vm_memory::{Address, GuestMemory};
1825

1926
#[cfg(target_os = "macos")]
2027
use crossbeam_channel::unbounded;
@@ -1077,9 +1084,12 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
10771084
#[cfg(target_os = "macos")]
10781085
let (sender, receiver) = unbounded();
10791086

1087+
let (io_sender, receiver) = unbounded();
1088+
10801089
let _vmm = match vmm::builder::build_microvm(
10811090
&ctx_cfg.vmr,
10821091
&mut event_manager,
1092+
io_sender,
10831093
ctx_cfg.shutdown_efd,
10841094
#[cfg(target_os = "macos")]
10851095
sender,
@@ -1094,6 +1104,50 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
10941104
#[cfg(target_os = "macos")]
10951105
let mapper_vmm = _vmm.clone();
10961106

1107+
let vm = _vmm.lock().unwrap().kvm_vm().fd.clone();
1108+
let guest_mem = _vmm.lock().unwrap().guest_memory().clone();
1109+
let guest_memfd = _vmm.lock().unwrap().guest_memfd_vec.clone();
1110+
1111+
std::thread::spawn(move || loop {
1112+
match receiver.recv() {
1113+
Err(e) => error!("Error in receiver: {:?}", e),
1114+
Ok(m) => {
1115+
let _ret = vm
1116+
.lock()
1117+
.unwrap()
1118+
.set_memory_attributes(kvm_memory_attributes {
1119+
address: m.addr,
1120+
size: m.size,
1121+
attributes: m.attributes as u64,
1122+
flags: 0,
1123+
});
1124+
1125+
// from private to shared
1126+
// e.g., ram_block_discard_guest_memfd_range
1127+
if m.attributes == 0 {
1128+
for (index, region) in guest_mem.iter().enumerate() {
1129+
if (region.start_addr().raw_value() + region.size() as u64) > m.addr {
1130+
// offset es function de la posicion de mapeo
1131+
let offset = m.addr - region.start_addr().raw_value();
1132+
unsafe {
1133+
let _ret = fallocate(
1134+
*guest_memfd.get(index).unwrap(),
1135+
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
1136+
offset as i64,
1137+
m.size as i64,
1138+
);
1139+
}
1140+
}
1141+
}
1142+
// from shared to private
1143+
// e.g., ram_block_discard_range
1144+
} else {
1145+
// do something
1146+
}
1147+
}
1148+
}
1149+
});
1150+
10971151
#[cfg(target_os = "macos")]
10981152
std::thread::spawn(move || loop {
10991153
match receiver.recv() {

0 commit comments

Comments
 (0)