Creates a guest physical memory region. # Safety `userspace_addr` must point to `memory_size` bytes of memory that will stay mapped until a successful call to `remove_user_memory_region().` Freeing them with `munmap()` before then will cause undefined guest behavior but at least should not cause undefined behavior in the host. In theory, at least.
(
&self,
slot: u32,
guest_phys_addr: u64,
memory_size: usize,
userspace_addr: *mut u8,
readonly: bool,
log_dirty_pages: bool,
)
| 1006 | /// should not cause undefined behavior in the host. In theory, |
| 1007 | /// at least. |
| 1008 | unsafe fn create_user_memory_region( |
| 1009 | &self, |
| 1010 | slot: u32, |
| 1011 | guest_phys_addr: u64, |
| 1012 | memory_size: usize, |
| 1013 | userspace_addr: *mut u8, |
| 1014 | readonly: bool, |
| 1015 | log_dirty_pages: bool, |
| 1016 | ) -> vm::Result<()> { |
| 1017 | let mut flags = 0; |
| 1018 | if readonly { |
| 1019 | flags |= KVM_MEM_READONLY; |
| 1020 | } |
| 1021 | if log_dirty_pages { |
| 1022 | flags |= KVM_MEM_LOG_DIRTY_PAGES; |
| 1023 | } |
| 1024 | |
| 1025 | const _: () = assert!(core::mem::size_of::<usize>() <= core::mem::size_of::<u64>()); |
| 1026 | |
| 1027 | // Create a per-region guest_memfd when supported. |
| 1028 | // Each region gets its own fd sized exactly to memory_size |
| 1029 | #[cfg(feature = "sev_snp")] |
| 1030 | let guest_memfd = if let Some(slots) = &self.memory_slots { |
| 1031 | // SAFETY: Safe because guest regions are guaranteed not to overlap. |
| 1032 | let fd = unsafe { |
| 1033 | OwnedFd::from_raw_fd( |
| 1034 | self.fd |
| 1035 | .create_guest_memfd(kvm_create_guest_memfd { |
| 1036 | size: memory_size as u64, |
| 1037 | ..Default::default() |
| 1038 | }) |
| 1039 | .map_err(|e| vm::HypervisorVmError::CreateUserMemory(e.into()))?, |
| 1040 | ) |
| 1041 | }; |
| 1042 | let raw_fd = fd.as_raw_fd() as u32; |
| 1043 | slots.write().unwrap().insert( |
| 1044 | slot, |
| 1045 | KvmMemorySlot { |
| 1046 | guest_memfd: fd, |
| 1047 | guest_phys_addr, |
| 1048 | memory_size: memory_size as u64, |
| 1049 | }, |
| 1050 | ); |
| 1051 | raw_fd |
| 1052 | } else { |
| 1053 | 0 |
| 1054 | }; |
| 1055 | #[cfg(not(feature = "sev_snp"))] |
| 1056 | let guest_memfd = 0; |
| 1057 | |
| 1058 | let mut region = kvm_userspace_memory_region2 { |
| 1059 | slot, |
| 1060 | flags: self.get_kvm_userspace_memory_region_flag(flags), |
| 1061 | guest_phys_addr, |
| 1062 | memory_size: memory_size as u64, |
| 1063 | userspace_addr: userspace_addr as usize as u64, |
| 1064 | #[cfg(not(target_arch = "riscv64"))] |
| 1065 | guest_memfd, |