Skip to content

Commit 0f8c912

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 87e4f18 commit 0f8c912

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
@@ -749,6 +749,8 @@ pub fn build_microvm(
749749
mmio_device_manager,
750750
#[cfg(target_arch = "x86_64")]
751751
pio_device_manager,
752+
#[cfg(feature = "tee")]
753+
guest_memfd_vec: guest_memfd,
752754
};
753755

754756
#[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: 80 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ use kvm_bindings::{
4040
KVM_CLOCK_TSC_STABLE, KVM_IRQCHIP_IOAPIC, KVM_IRQCHIP_PIC_MASTER, KVM_IRQCHIP_PIC_SLAVE,
4141
KVM_MAX_CPUID_ENTRIES,
4242
};
43+
#[cfg(feature = "tee")]
44+
use kvm_bindings::{
45+
kvm_create_guest_memfd, kvm_memory_attributes, kvm_userspace_memory_region2, KVM_API_VERSION,
46+
KVM_MEMORY_ATTRIBUTE_PRIVATE, KVM_MEM_GUEST_MEMFD,
47+
};
48+
#[cfg(not(feature = "tee"))]
4349
use kvm_bindings::{kvm_userspace_memory_region, KVM_API_VERSION};
4450
use kvm_ioctls::*;
4551
use utils::eventfd::EventFd;
@@ -101,6 +107,12 @@ pub enum Error {
101107
SetUserMemoryRegion(kvm_ioctls::Error),
102108
/// Error creating memory map for SHM region.
103109
ShmMmap(io::Error),
110+
#[cfg(feature = "tee")]
111+
/// Cannot set the memory regions.
112+
SetUserMemoryRegion2(kvm_ioctls::Error),
113+
#[cfg(feature = "tee")]
114+
/// Cannot create guest memfd.
115+
CreateGuestMemfd(kvm_ioctls::Error),
104116
#[cfg(feature = "amd-sev")]
105117
/// Error initializing the Secure Virtualization Backend (SNP).
106118
SnpSecVirtInit(SnpError),
@@ -253,6 +265,10 @@ impl Display for Error {
253265
SetUserMemoryRegion(e) => write!(f, "Cannot set the memory regions: {e}"),
254266
ShmMmap(e) => write!(f, "Error creating memory map for SHM region: {e}"),
255267
#[cfg(feature = "tee")]
268+
SetUserMemoryRegion2(e) => write!(f, "Cannot set the memory regions: {e}"),
269+
#[cfg(feature = "tee")]
270+
CreateGuestMemfd(e) => write!(f, "Cannot create guest memfd: {e}"),
271+
#[cfg(feature = "tee")]
256272
SnpSecVirtInit(e) => write!(
257273
f,
258274
"Error initializing the Secure Virtualization Backend (SEV): {e:?}"
@@ -503,6 +519,7 @@ impl Vm {
503519
pub fn memory_init(
504520
&mut self,
505521
guest_mem: &GuestMemoryMmap,
522+
#[cfg(feature = "tee")] guest_memfd: &mut Vec<RawFd>,
506523
kvm_max_memslots: usize,
507524
) -> Result<()> {
508525
if guest_mem.num_regions() > kvm_max_memslots {
@@ -511,20 +528,69 @@ impl Vm {
511528
for region in guest_mem.iter() {
512529
// It's safe to unwrap because the guest address is valid.
513530
let host_addr = guest_mem.get_host_address(region.start_addr()).unwrap();
514-
debug!("Guest memory starts at {:x?}", host_addr);
515-
let memory_region = kvm_userspace_memory_region {
516-
slot: self.next_mem_slot,
517-
guest_phys_addr: region.start_addr().raw_value(),
518-
memory_size: region.len(),
519-
userspace_addr: host_addr as u64,
520-
flags: 0,
521-
};
522-
// Safe because we mapped the memory region, we made sure that the regions
523-
// are not overlapping.
524-
unsafe {
525-
self.fd
526-
.set_user_memory_region(memory_region)
527-
.map_err(Error::SetUserMemoryRegion)?;
531+
info!("Guest memory starts at {:x?}", host_addr);
532+
533+
#[cfg(feature = "tee")]
534+
{
535+
let gmem = kvm_create_guest_memfd {
536+
size: region.len(),
537+
flags: 0,
538+
reserved: [0; 6],
539+
};
540+
541+
let id: RawFd = self
542+
.fd
543+
.create_guest_memfd(gmem)
544+
.map_err(Error::CreateGuestMemfd)?;
545+
546+
guest_memfd.push(id);
547+
548+
let memory_region = kvm_userspace_memory_region2 {
549+
slot: self.next_mem_slot as u32,
550+
flags: KVM_MEM_GUEST_MEMFD,
551+
guest_phys_addr: region.start_addr().raw_value(),
552+
memory_size: region.len(),
553+
userspace_addr: host_addr as u64,
554+
guest_memfd_offset: 0,
555+
guest_memfd: id as u32,
556+
pad1: 0,
557+
pad2: [0; 14],
558+
};
559+
560+
// Safe because we mapped the memory region, we made sure that the regions
561+
// are not overlapping.
562+
unsafe {
563+
self.fd
564+
.set_user_memory_region2(memory_region)
565+
.map_err(Error::SetUserMemoryRegion2)?;
566+
};
567+
568+
// set private by default when using guestmemfd
569+
// this imitates QEMU behavior
570+
let attr = kvm_memory_attributes {
571+
address: region.start_addr().raw_value(),
572+
size: region.len(),
573+
attributes: KVM_MEMORY_ATTRIBUTE_PRIVATE as u64,
574+
flags: 0,
575+
};
576+
self.fd.set_memory_attributes(attr).unwrap();
577+
}
578+
#[cfg(not(feature = "tee"))]
579+
{
580+
let memory_region = kvm_userspace_memory_region {
581+
slot: self.next_mem_slot as u32,
582+
guest_phys_addr: region.start_addr().raw_value(),
583+
memory_size: region.len(),
584+
userspace_addr: host_addr as u64,
585+
flags: 0,
586+
};
587+
// Safe because we mapped the memory region, we made sure that the regions
588+
// are not overlapping.
589+
unsafe {
590+
self.fd
591+
.set_user_memory_region(memory_region)
592+
.map_err(Error::SetUserMemoryRegion)?;
593+
};
528594
};
529595
self.next_mem_slot += 1;
530596
}

0 commit comments

Comments
 (0)