Skip to content

Commit 15ac9fc

Browse files
committed
Use create_guest_memfd() and set_user_memory_region2()
When tee feature is enabled, use create_guest_memfd() and set_user_memory_region2(). The created regions are marked as private by using set_memory_attributes() thus imitating QEMU behavior. Signed-off-by: Matias Ezequiel Vara Larsen <[email protected]>
1 parent 8046252 commit 15ac9fc

File tree

3 files changed

+85
-14
lines changed

3 files changed

+85
-14
lines changed

src/vmm/src/builder.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,8 @@ pub fn build_microvm(
624624
mmio_device_manager,
625625
#[cfg(target_arch = "x86_64")]
626626
pio_device_manager,
627+
#[cfg(feature = "tee")]
628+
guest_memfd_vec: guest_memfd,
627629
};
628630

629631
#[cfg(not(feature = "tee"))]

src/vmm/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ pub struct Vmm {
199199
mmio_device_manager: MMIODeviceManager,
200200
#[cfg(target_arch = "x86_64")]
201201
pio_device_manager: PortIODeviceManager,
202+
203+
#[cfg(feature = "tee")]
204+
pub guest_memfd_vec: Vec<RawFd>,
202205
}
203206

204207
impl Vmm {

src/vmm/src/linux/vstate.rs

Lines changed: 80 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ use kvm_bindings::{
4545
Msrs, KVM_CLOCK_TSC_STABLE, KVM_IRQCHIP_IOAPIC, KVM_IRQCHIP_PIC_MASTER, KVM_IRQCHIP_PIC_SLAVE,
4646
KVM_MAX_CPUID_ENTRIES, KVM_PIT_SPEAKER_DUMMY,
4747
};
48+
#[cfg(feature = "tee")]
49+
use kvm_bindings::{
50+
kvm_create_guest_memfd, kvm_memory_attributes, kvm_userspace_memory_region2, KVM_API_VERSION,
51+
KVM_MEMORY_ATTRIBUTE_PRIVATE, KVM_MEM_GUEST_MEMFD,
52+
};
53+
#[cfg(not(feature = "tee"))]
4854
use kvm_bindings::{kvm_userspace_memory_region, KVM_API_VERSION};
4955
use kvm_ioctls::*;
5056
use utils::eventfd::EventFd;
@@ -112,6 +118,12 @@ pub enum Error {
112118
SetUserMemoryRegion(kvm_ioctls::Error),
113119
/// Error creating memory map for SHM region.
114120
ShmMmap(io::Error),
121+
#[cfg(feature = "tee")]
122+
/// Cannot set the memory regions.
123+
SetUserMemoryRegion2(kvm_ioctls::Error),
124+
#[cfg(feature = "tee")]
125+
/// Cannot create guest memfd.
126+
CreateGuestMemfd(kvm_ioctls::Error),
115127
#[cfg(feature = "amd-sev")]
116128
/// Error initializing the Secure Virtualization Backend (SEV).
117129
SevSecVirtInit(SevError),
@@ -273,6 +285,10 @@ impl Display for Error {
273285
SetUserMemoryRegion(e) => write!(f, "Cannot set the memory regions: {e}"),
274286
ShmMmap(e) => write!(f, "Error creating memory map for SHM region: {e}"),
275287
#[cfg(feature = "tee")]
288+
SetUserMemoryRegion2(e) => write!(f, "Cannot set the memory regions: {e}"),
289+
#[cfg(feature = "tee")]
290+
CreateGuestMemfd(e) => write!(f, "Cannot create guest memfd: {e}"),
291+
#[cfg(feature = "tee")]
276292
SevSecVirtInit(e) => {
277293
write!(
278294
f,
@@ -553,6 +569,7 @@ impl Vm {
553569
pub fn memory_init(
554570
&mut self,
555571
guest_mem: &GuestMemoryMmap,
572+
#[cfg(feature = "tee")] guest_memfd: &mut Vec<RawFd>,
556573
kvm_max_memslots: usize,
557574
) -> Result<()> {
558575
if guest_mem.num_regions() > kvm_max_memslots {
@@ -561,20 +578,69 @@ impl Vm {
561578
for region in guest_mem.iter() {
562579
// It's safe to unwrap because the guest address is valid.
563580
let host_addr = guest_mem.get_host_address(region.start_addr()).unwrap();
564-
debug!("Guest memory starts at {:x?}", host_addr);
565-
let memory_region = kvm_userspace_memory_region {
566-
slot: self.next_mem_slot,
567-
guest_phys_addr: region.start_addr().raw_value(),
568-
memory_size: region.len(),
569-
userspace_addr: host_addr as u64,
570-
flags: 0,
571-
};
572-
// Safe because we mapped the memory region, we made sure that the regions
573-
// are not overlapping.
574-
unsafe {
575-
self.fd
576-
.set_user_memory_region(memory_region)
577-
.map_err(Error::SetUserMemoryRegion)?;
581+
info!("Guest memory starts at {:x?}", host_addr);
582+
583+
#[cfg(feature = "tee")]
584+
{
585+
let gmem = kvm_create_guest_memfd {
586+
size: region.len(),
587+
flags: 0,
588+
reserved: [0; 6],
589+
};
590+
591+
let id: RawFd = self
592+
.fd
593+
.create_guest_memfd(gmem)
594+
.map_err(Error::CreateGuestMemfd)?;
595+
596+
guest_memfd.push(id);
597+
598+
let memory_region = kvm_userspace_memory_region2 {
599+
slot: self.next_mem_slot as u32,
600+
flags: KVM_MEM_GUEST_MEMFD,
601+
guest_phys_addr: region.start_addr().raw_value(),
602+
memory_size: region.len(),
603+
userspace_addr: host_addr as u64,
604+
guest_memfd_offset: 0,
605+
guest_memfd: id as u32,
606+
pad1: 0,
607+
pad2: [0; 14],
608+
};
609+
610+
// Safe because we mapped the memory region, we made sure that the regions
611+
// are not overlapping.
612+
unsafe {
613+
self.fd
614+
.set_user_memory_region2(memory_region)
615+
.map_err(Error::SetUserMemoryRegion2)?;
616+
};
617+
618+
// set private by default when using guestmemfd
619+
// this imitates QEMU behavior
620+
let attr = kvm_memory_attributes {
621+
address: region.start_addr().raw_value(),
622+
size: region.len(),
623+
attributes: KVM_MEMORY_ATTRIBUTE_PRIVATE as u64,
624+
flags: 0,
625+
};
626+
self.fd.set_memory_attributes(attr).unwrap();
627+
}
628+
#[cfg(not(feature = "tee"))]
629+
{
630+
let memory_region = kvm_userspace_memory_region {
631+
slot: self.next_mem_slot as u32,
632+
guest_phys_addr: region.start_addr().raw_value(),
633+
memory_size: region.len(),
634+
userspace_addr: host_addr as u64,
635+
flags: 0,
636+
};
637+
// Safe because we mapped the memory region, we made sure that the regions
638+
// are not overlapping.
639+
unsafe {
640+
self.fd
641+
.set_user_memory_region(memory_region)
642+
.map_err(Error::SetUserMemoryRegion)?;
643+
};
578644
};
579645
self.next_mem_slot += 1;
580646
}

0 commit comments

Comments
 (0)