Skip to content

Commit 7afe3b7

Browse files
MatiasVaratylerfanelli
authored andcommitted
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 f207298 commit 7afe3b7

File tree

3 files changed

+84
-14
lines changed

3 files changed

+84
-14
lines changed

src/vmm/src/builder.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,8 @@ pub fn build_microvm(
765765
mmio_device_manager,
766766
#[cfg(target_arch = "x86_64")]
767767
pio_device_manager,
768+
#[cfg(feature = "tee")]
769+
guest_memfd_vec: guest_memfd,
768770
};
769771

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

src/vmm/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ pub struct Vmm {
207207
mmio_device_manager: MMIODeviceManager,
208208
#[cfg(target_arch = "x86_64")]
209209
pio_device_manager: PortIODeviceManager,
210+
211+
#[cfg(feature = "tee")]
212+
pub guest_memfd_vec: Vec<RawFd>,
210213
}
211214

212215
impl Vmm {

src/vmm/src/linux/vstate.rs

Lines changed: 79 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ use kvm_bindings::{
4343
use kvm_bindings::{
4444
kvm_userspace_memory_region, KVM_API_VERSION, KVM_SYSTEM_EVENT_RESET, KVM_SYSTEM_EVENT_SHUTDOWN,
4545
};
46+
#[cfg(feature = "tee")]
47+
use kvm_bindings::{
48+
kvm_create_guest_memfd, kvm_memory_attributes, kvm_userspace_memory_region2, KVM_API_VERSION,
49+
KVM_MEMORY_ATTRIBUTE_PRIVATE, KVM_MEM_GUEST_MEMFD,
50+
};
4651
use kvm_ioctls::*;
4752
use utils::eventfd::EventFd;
4853
use utils::signal::{register_signal_handler, sigrtmin, Killable};
@@ -103,6 +108,12 @@ pub enum Error {
103108
SetUserMemoryRegion(kvm_ioctls::Error),
104109
/// Error creating memory map for SHM region.
105110
ShmMmap(io::Error),
111+
#[cfg(feature = "tee")]
112+
/// Cannot set the memory regions.
113+
SetUserMemoryRegion2(kvm_ioctls::Error),
114+
#[cfg(feature = "tee")]
115+
/// Cannot create guest memfd.
116+
CreateGuestMemfd(kvm_ioctls::Error),
106117
#[cfg(feature = "amd-sev")]
107118
/// Error initializing the Secure Virtualization Backend (SNP).
108119
SnpSecVirtInit(SnpError),
@@ -255,6 +266,10 @@ impl Display for Error {
255266
SetUserMemoryRegion(e) => write!(f, "Cannot set the memory regions: {e}"),
256267
ShmMmap(e) => write!(f, "Error creating memory map for SHM region: {e}"),
257268
#[cfg(feature = "tee")]
269+
SetUserMemoryRegion2(e) => write!(f, "Cannot set the memory regions: {e}"),
270+
#[cfg(feature = "tee")]
271+
CreateGuestMemfd(e) => write!(f, "Cannot create guest memfd: {e}"),
272+
#[cfg(feature = "tee")]
258273
SnpSecVirtInit(e) => write!(
259274
f,
260275
"Error initializing the Secure Virtualization Backend (SEV): {e:?}"
@@ -505,6 +520,7 @@ impl Vm {
505520
pub fn memory_init(
506521
&mut self,
507522
guest_mem: &GuestMemoryMmap,
523+
#[cfg(feature = "tee")] guest_memfd: &mut Vec<RawFd>,
508524
kvm_max_memslots: usize,
509525
) -> Result<()> {
510526
if guest_mem.num_regions() > kvm_max_memslots {
@@ -513,20 +529,69 @@ impl Vm {
513529
for region in guest_mem.iter() {
514530
// It's safe to unwrap because the guest address is valid.
515531
let host_addr = guest_mem.get_host_address(region.start_addr()).unwrap();
516-
debug!("Guest memory starts at {:x?}", host_addr);
517-
let memory_region = kvm_userspace_memory_region {
518-
slot: self.next_mem_slot,
519-
guest_phys_addr: region.start_addr().raw_value(),
520-
memory_size: region.len(),
521-
userspace_addr: host_addr as u64,
522-
flags: 0,
523-
};
524-
// Safe because we mapped the memory region, we made sure that the regions
525-
// are not overlapping.
526-
unsafe {
527-
self.fd
528-
.set_user_memory_region(memory_region)
529-
.map_err(Error::SetUserMemoryRegion)?;
532+
info!("Guest memory starts at {:x?}", host_addr);
533+
534+
#[cfg(feature = "tee")]
535+
{
536+
let gmem = kvm_create_guest_memfd {
537+
size: region.len(),
538+
flags: 0,
539+
reserved: [0; 6],
540+
};
541+
542+
let id: RawFd = self
543+
.fd
544+
.create_guest_memfd(gmem)
545+
.map_err(Error::CreateGuestMemfd)?;
546+
547+
guest_memfd.push(id);
548+
549+
let memory_region = kvm_userspace_memory_region2 {
550+
slot: self.next_mem_slot as u32,
551+
flags: KVM_MEM_GUEST_MEMFD,
552+
guest_phys_addr: region.start_addr().raw_value(),
553+
memory_size: region.len(),
554+
userspace_addr: host_addr as u64,
555+
guest_memfd_offset: 0,
556+
guest_memfd: id as u32,
557+
pad1: 0,
558+
pad2: [0; 14],
559+
};
560+
561+
// Safe because we mapped the memory region, we made sure that the regions
562+
// are not overlapping.
563+
unsafe {
564+
self.fd
565+
.set_user_memory_region2(memory_region)
566+
.map_err(Error::SetUserMemoryRegion2)?;
567+
};
568+
569+
// set private by default when using guestmemfd
570+
// this imitates QEMU behavior
571+
let attr = kvm_memory_attributes {
572+
address: region.start_addr().raw_value(),
573+
size: region.len(),
574+
attributes: KVM_MEMORY_ATTRIBUTE_PRIVATE as u64,
575+
flags: 0,
576+
};
577+
self.fd.set_memory_attributes(attr).unwrap();
578+
}
579+
#[cfg(not(feature = "tee"))]
580+
{
581+
let memory_region = kvm_userspace_memory_region {
582+
slot: self.next_mem_slot as u32,
583+
guest_phys_addr: region.start_addr().raw_value(),
584+
memory_size: region.len(),
585+
userspace_addr: host_addr as u64,
586+
flags: 0,
587+
};
588+
// Safe because we mapped the memory region, we made sure that the regions
589+
// are not overlapping.
590+
unsafe {
591+
self.fd
592+
.set_user_memory_region(memory_region)
593+
.map_err(Error::SetUserMemoryRegion)?;
594+
};
530595
};
531596
self.next_mem_slot += 1;
532597
}

0 commit comments

Comments
 (0)