diff --git a/src/arch/src/aarch64/mod.rs b/src/arch/src/aarch64/mod.rs index 9450b94d..c76d99a9 100644 --- a/src/arch/src/aarch64/mod.rs +++ b/src/arch/src/aarch64/mod.rs @@ -16,12 +16,11 @@ pub mod macos; #[cfg(target_os = "macos")] pub use self::macos::*; -use std::cmp::min; use std::collections::HashMap; use std::fmt::Debug; use self::gic::GICDevice; -use crate::ArchMemoryInfo; +use crate::{round_up, ArchMemoryInfo}; use vm_memory::{Address, GuestAddress, GuestMemory, GuestMemoryMmap}; #[cfg(feature = "efi")] @@ -42,8 +41,6 @@ pub enum Error { /// The start of the memory area reserved for MMIO devices. pub const MMIO_MEM_START: u64 = layout::MAPPED_IO_START; -/// The size of the MMIO shared memory area used by virtio-fs DAX. -pub const MMIO_SHM_SIZE: u64 = 1 << 33; pub use self::fdt::DeviceInfoForFDT; use crate::DeviceType; @@ -51,26 +48,24 @@ use crate::DeviceType; /// Returns a Vec of the valid memory addresses for aarch64. /// See [`layout`](layout) module for a drawing of the specific memory model for this platform. pub fn arch_memory_regions(size: usize) -> (ArchMemoryInfo, Vec<(GuestAddress, usize)>) { - let dram_size = min(size as u64, layout::DRAM_MEM_MAX_SIZE) as usize; + let page_size: usize = unsafe { libc::sysconf(libc::_SC_PAGESIZE).try_into().unwrap() }; + let dram_size = round_up(size, page_size); let ram_last_addr = layout::DRAM_MEM_START + (dram_size as u64); let shm_start_addr = ((ram_last_addr / 0x4000_0000) + 1) * 0x4000_0000; + let info = ArchMemoryInfo { ram_last_addr, shm_start_addr, - shm_size: MMIO_SHM_SIZE, + page_size, }; let regions = if cfg!(feature = "efi") { vec![ // Space for loading EDK2 and its variables (GuestAddress(0u64), 0x800_0000), (GuestAddress(layout::DRAM_MEM_START), dram_size), - (GuestAddress(shm_start_addr), MMIO_SHM_SIZE as usize), ] } else { - vec![ - (GuestAddress(layout::DRAM_MEM_START), dram_size), - (GuestAddress(shm_start_addr), MMIO_SHM_SIZE as usize), - ] + vec![(GuestAddress(layout::DRAM_MEM_START), dram_size)] }; (info, regions) diff --git a/src/arch/src/lib.rs b/src/arch/src/lib.rs index f09be292..7e8e24dc 100644 --- a/src/arch/src/lib.rs +++ b/src/arch/src/lib.rs @@ -11,9 +11,12 @@ use std::result; pub struct ArchMemoryInfo { pub ram_last_addr: u64, pub shm_start_addr: u64, - pub shm_size: u64, + pub page_size: usize, } +pub mod shm; +pub use shm::*; + /// Module for aarch64 related functionality. #[cfg(target_arch = "aarch64")] pub mod aarch64; @@ -22,7 +25,6 @@ pub mod aarch64; pub use aarch64::{ arch_memory_regions, configure_system, get_kernel_start, initrd_load_addr, layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE, layout::IRQ_MAX, Error, MMIO_MEM_START, - MMIO_SHM_SIZE, }; /// Module for x86_64 related functionality. @@ -33,7 +35,7 @@ pub mod x86_64; pub use crate::x86_64::{ arch_memory_regions, configure_system, get_kernel_start, initrd_load_addr, layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE, layout::IRQ_MAX, Error, BIOS_SIZE, BIOS_START, - MMIO_MEM_START, MMIO_SHM_SIZE, RESET_VECTOR, + MMIO_MEM_START, RESET_VECTOR, }; /// Type for returning public functions outcome. @@ -66,6 +68,15 @@ pub struct InitrdConfig { /// Default (smallest) memory page size for the supported architectures. pub const PAGE_SIZE: usize = 4096; +pub fn round_up(size: usize, align: usize) -> usize { + let page_mask = align - 1; + (size + page_mask) & !page_mask +} +pub fn round_down(size: usize, align: usize) -> usize { + let page_mask = !(align - 1); + size & page_mask +} + impl fmt::Display for DeviceType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{self:?}") diff --git a/src/arch/src/shm.rs b/src/arch/src/shm.rs new file mode 100644 index 00000000..e1f14061 --- /dev/null +++ b/src/arch/src/shm.rs @@ -0,0 +1,43 @@ +use crate::round_up; + +use super::ArchMemoryInfo; +#[derive(Debug)] +pub enum Error { + OutOfSpace, +} + +#[derive(Clone)] +pub struct ShmRegion { + pub guest_addr: u64, + pub size: usize, +} + +pub struct ShmManager { + next_guest_addr: u64, + page_size: usize, +} + +impl ShmManager { + pub fn new(info: &ArchMemoryInfo) -> ShmManager { + Self { + next_guest_addr: info.shm_start_addr, + page_size: info.page_size, + } + } + + pub fn get_region(&mut self, size: usize) -> Result { + let size = round_up(size, self.page_size); + + let region = ShmRegion { + guest_addr: self.next_guest_addr, + size, + }; + + if let Some(addr) = self.next_guest_addr.checked_add(size as u64) { + self.next_guest_addr = addr; + Ok(region) + } else { + Err(Error::OutOfSpace) + } + } +} diff --git a/src/arch/src/x86_64/mod.rs b/src/arch/src/x86_64/mod.rs index 64dc6113..e31046e8 100644 --- a/src/arch/src/x86_64/mod.rs +++ b/src/arch/src/x86_64/mod.rs @@ -17,8 +17,7 @@ pub mod msr; /// Logic for configuring x86_64 registers. pub mod regs; -use crate::ArchMemoryInfo; -use crate::InitrdConfig; +use crate::{round_up, ArchMemoryInfo, InitrdConfig}; use arch_gen::x86::bootparam::{boot_params, E820_RAM}; use vm_memory::Bytes; use vm_memory::{ @@ -60,8 +59,6 @@ const FIRST_ADDR_PAST_32BITS: u64 = 1 << 32; const MEM_32BIT_GAP_SIZE: u64 = 768 << 20; /// The start of the memory area reserved for MMIO devices. pub const MMIO_MEM_START: u64 = FIRST_ADDR_PAST_32BITS - MEM_32BIT_GAP_SIZE; -/// The size of the MMIO shared memory area used by virtio-fs DAX. -pub const MMIO_SHM_SIZE: u64 = 1 << 33; /// Returns a Vec of the valid memory addresses. /// These should be used to configure the GuestMemoryMmap structure for the platform. @@ -73,6 +70,9 @@ pub fn arch_memory_regions( kernel_load_addr: u64, kernel_size: usize, ) -> (ArchMemoryInfo, Vec<(GuestAddress, usize)>) { + let page_size: usize = unsafe { libc::sysconf(libc::_SC_PAGESIZE).try_into().unwrap() }; + + let size = round_up(size, page_size); if size < (kernel_load_addr + kernel_size as u64) as usize { panic!("Kernel doesn't fit in RAM"); } @@ -90,7 +90,6 @@ pub fn arch_memory_regions( vec![ (GuestAddress(0), kernel_load_addr as usize), (GuestAddress(kernel_load_addr + kernel_size as u64), size), - (GuestAddress(FIRST_ADDR_PAST_32BITS), MMIO_SHM_SIZE as usize), ], ) } @@ -108,7 +107,6 @@ pub fn arch_memory_regions( (MMIO_MEM_START - (kernel_load_addr + kernel_size as u64)) as usize, ), (GuestAddress(FIRST_ADDR_PAST_32BITS), remaining), - (GuestAddress(shm_start_addr), MMIO_SHM_SIZE as usize), ], ) } @@ -116,7 +114,7 @@ pub fn arch_memory_regions( let info = ArchMemoryInfo { ram_last_addr, shm_start_addr, - shm_size: MMIO_SHM_SIZE, + page_size, }; (info, regions) } @@ -132,6 +130,9 @@ pub fn arch_memory_regions( kernel_load_addr: u64, kernel_size: usize, ) -> (ArchMemoryInfo, Vec<(GuestAddress, usize)>) { + let page_size: usize = unsafe { libc::sysconf(libc::_SC_PAGESIZE).try_into().unwrap() }; + + let size = round_up(size, page_size); if size < (kernel_load_addr + kernel_size as u64) as usize { panic!("Kernel doesn't fit in RAM"); } @@ -170,7 +171,7 @@ pub fn arch_memory_regions( let info = ArchMemoryInfo { ram_last_addr, shm_start_addr, - shm_size: 0, + page_size, }; (info, regions) } @@ -319,7 +320,7 @@ mod tests { #[test] fn regions_lt_4gb() { let (_info, regions) = arch_memory_regions(1usize << 29, KERNEL_LOAD_ADDR, KERNEL_SIZE); - assert_eq!(3, regions.len()); + assert_eq!(2, regions.len()); assert_eq!(GuestAddress(0), regions[0].0); assert_eq!(KERNEL_LOAD_ADDR as usize, regions[0].1); assert_eq!( @@ -333,7 +334,7 @@ mod tests { fn regions_gt_4gb() { let (_info, regions) = arch_memory_regions((1usize << 32) + 0x8000, KERNEL_LOAD_ADDR, KERNEL_SIZE); - assert_eq!(4, regions.len()); + assert_eq!(3, regions.len()); assert_eq!(GuestAddress(0), regions[0].0); assert_eq!(KERNEL_LOAD_ADDR as usize, regions[0].1); assert_eq!( diff --git a/src/devices/src/virtio/device.rs b/src/devices/src/virtio/device.rs index 242ba83a..8eb90b6d 100644 --- a/src/devices/src/virtio/device.rs +++ b/src/devices/src/virtio/device.rs @@ -21,6 +21,7 @@ pub enum DeviceState { #[derive(Clone)] pub struct VirtioShmRegion { + #[cfg(target_os = "linux")] pub host_addr: u64, pub guest_addr: u64, pub size: usize, diff --git a/src/devices/src/virtio/fs/server.rs b/src/devices/src/virtio/fs/server.rs index 8f91e693..b97f6641 100644 --- a/src/devices/src/virtio/fs/server.rs +++ b/src/devices/src/virtio/fs/server.rs @@ -137,11 +137,19 @@ impl Server { x if x == Opcode::CopyFileRange as u32 => self.copyfilerange(in_header, r, w), x if (x == Opcode::SetupMapping as u32) && shm_region.is_some() => { let shm = shm_region.unwrap(); - self.setupmapping(in_header, r, w, shm.host_addr, shm.size as u64) + #[cfg(target_os = "linux")] + let shm_base_addr = shm.host_addr; + #[cfg(target_os = "macos")] + let shm_base_addr = shm.guest_addr; + self.setupmapping(in_header, r, w, shm_base_addr, shm.size as u64) } x if (x == Opcode::RemoveMapping as u32) && shm_region.is_some() => { let shm = shm_region.unwrap(); - self.removemapping(in_header, r, w, shm.host_addr, shm.size as u64) + #[cfg(target_os = "linux")] + let shm_base_addr = shm.host_addr; + #[cfg(target_os = "macos")] + let shm_base_addr = shm.guest_addr; + self.removemapping(in_header, r, w, shm_base_addr, shm.size as u64) } _ => reply_error( linux_error(io::Error::from_raw_os_error(libc::ENOSYS)), diff --git a/src/devices/src/virtio/gpu/worker.rs b/src/devices/src/virtio/gpu/worker.rs index 5597d055..16c15ca2 100644 --- a/src/devices/src/virtio/gpu/worker.rs +++ b/src/devices/src/virtio/gpu/worker.rs @@ -16,7 +16,7 @@ use utils::eventfd::EventFd; use vm_memory::{GuestAddress, GuestMemoryMmap}; use super::super::descriptor_utils::{Reader, Writer}; -use super::super::{GpuError, Queue as VirtQueue, VirtioShmRegion, VIRTIO_MMIO_INT_VRING}; +use super::super::{GpuError, Queue as VirtQueue, VIRTIO_MMIO_INT_VRING}; use super::protocol::{ virtio_gpu_ctrl_hdr, virtio_gpu_mem_entry, GpuCommand, GpuResponse, VirtioGpuResult, }; @@ -24,6 +24,7 @@ use super::virtio_gpu::VirtioGpu; use crate::legacy::Gic; use crate::virtio::gpu::protocol::{VIRTIO_GPU_FLAG_FENCE, VIRTIO_GPU_FLAG_INFO_RING_IDX}; use crate::virtio::gpu::virtio_gpu::VirtioGpuRing; +use crate::virtio::VirtioShmRegion; use crate::Error as DeviceError; pub struct Worker { diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index 1f5d993e..c8ca3ef6 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -23,8 +23,6 @@ use devices::legacy::VcpuList; use devices::legacy::{Gic, Serial}; #[cfg(feature = "net")] use devices::virtio::Net; -#[cfg(not(feature = "tee"))] -use devices::virtio::VirtioShmRegion; use devices::virtio::{port_io, MmioTransport, PortDescription, Vsock}; #[cfg(target_os = "macos")] use hvf::MemoryMapping; @@ -55,6 +53,8 @@ use crate::vstate::{Error as VstateError, Vcpu, VcpuConfig, Vm}; use arch::ArchMemoryInfo; #[cfg(feature = "tee")] use arch::InitrdConfig; +#[cfg(not(feature = "tee"))] +use arch::ShmManager; #[cfg(feature = "tee")] use kvm_bindings::KVM_MAX_CPUID_ENTRIES; use libc::{STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO}; @@ -67,6 +67,7 @@ use vm_memory::mmap::GuestRegionMmap; use vm_memory::mmap::MmapRegion; #[cfg(any(target_arch = "aarch64", feature = "tee"))] use vm_memory::Bytes; +#[cfg(feature = "tee")] use vm_memory::GuestMemory; use vm_memory::{GuestAddress, GuestMemoryMmap}; @@ -131,7 +132,10 @@ pub enum StartMicrovmError { SecureVirtAttest(VstateError), /// Cannot initialize the Secure Virtualization backend. SecureVirtPrepare(VstateError), - + /// Error adding an SHM region. + ShmAdd(VstateError), + /// Error configuring an SHM region. + ShmCreate(arch::shm::Error), /// The TEE specified is not supported. InvalidTee, } @@ -295,6 +299,18 @@ impl Display for StartMicrovmError { "Cannot initialize the Secure Virtualization backend. {err_msg}" ) } + ShmAdd(ref err) => { + let mut err_msg = format!("{:?}", err); + err_msg = err_msg.replace('\"', ""); + + write!(f, "Error while adding an SHM region. {err_msg}") + } + ShmCreate(ref err) => { + let mut err_msg = format!("{:?}", err); + err_msg = err_msg.replace('\"', ""); + + write!(f, "Error while creating an SHM region. {err_msg}") + } InvalidTee => { write!(f, "TEE selected is not currently supported") } @@ -560,13 +576,7 @@ pub fn build_microvm( } #[cfg(not(feature = "tee"))] - let _shm_region = Some(VirtioShmRegion { - host_addr: guest_memory - .get_host_address(GuestAddress(arch_memory_info.shm_start_addr)) - .unwrap() as u64, - guest_addr: arch_memory_info.shm_start_addr, - size: arch_memory_info.shm_size as usize, - }); + let mut shm_manager = ShmManager::new(&arch_memory_info); let mut vmm = Vmm { guest_memory, @@ -596,7 +606,7 @@ pub fn build_microvm( attach_gpu_device( &mut vmm, event_manager, - _shm_region, + &mut shm_manager, intc.clone(), virgl_flags, #[cfg(target_os = "macos")] @@ -604,7 +614,7 @@ pub fn build_microvm( )?; } #[cfg(not(feature = "tee"))] - attach_fs_devices(&mut vmm, &vm_resources.fs, None, intc.clone())?; + attach_fs_devices(&mut vmm, &vm_resources.fs, &mut shm_manager, intc.clone())?; #[cfg(feature = "blk")] attach_block_devices(&mut vmm, &vm_resources.block, intc.clone())?; if let Some(vsock) = vm_resources.vsock.get() { @@ -1111,7 +1121,7 @@ fn attach_mmio_device( fn attach_fs_devices( vmm: &mut Vmm, fs_devs: &FsBuilder, - shm_region: Option, + shm_manager: &mut ShmManager, intc: Option>>, ) -> std::result::Result<(), StartMicrovmError> { use self::StartMicrovmError::*; @@ -1123,9 +1133,13 @@ fn attach_fs_devices( fs.lock().unwrap().set_intc(intc.clone()); } - if let Some(ref shm) = shm_region { - fs.lock().unwrap().set_shm_region(shm.clone()); - } + let shm_region = shm_manager + .get_region(1 << 30) + .map_err(StartMicrovmError::ShmCreate)?; + let virtio_shm_region = vmm + .add_shm_region(shm_region) + .map_err(StartMicrovmError::ShmAdd)?; + fs.lock().unwrap().set_shm_region(virtio_shm_region); // The device mutex mustn't be locked here otherwise it will deadlock. attach_mmio_device( @@ -1379,7 +1393,7 @@ fn attach_rng_device( fn attach_gpu_device( vmm: &mut Vmm, event_manager: &mut EventManager, - shm_region: Option, + shm_manager: &mut ShmManager, intc: Option>>, virgl_flags: u32, #[cfg(target_os = "macos")] map_sender: Sender, @@ -1405,9 +1419,13 @@ fn attach_gpu_device( gpu.lock().unwrap().set_intc(intc); } - if let Some(ref shm) = shm_region { - gpu.lock().unwrap().set_shm_region(shm.clone()); - } + let shm_region = shm_manager + .get_region(1 << 33) + .map_err(StartMicrovmError::ShmCreate)?; + let virtio_shm_region = vmm + .add_shm_region(shm_region) + .map_err(StartMicrovmError::ShmAdd)?; + gpu.lock().unwrap().set_shm_region(virtio_shm_region); // The device mutex mustn't be locked here otherwise it will deadlock. attach_mmio_device(vmm, id, MmioTransport::new(vmm.guest_memory().clone(), gpu)) @@ -1487,7 +1505,7 @@ pub mod tests { #[test] #[cfg(target_arch = "aarch64")] fn test_create_vcpus_aarch64() { - let guest_memory = create_guest_memory(128).unwrap(); + let (guest_memory, _info) = default_guest_memory(128).unwrap(); let vm = setup_vm(&guest_memory).unwrap(); let vcpu_count = 2; diff --git a/src/vmm/src/lib.rs b/src/vmm/src/lib.rs index ea3fdb38..fe3194dd 100644 --- a/src/vmm/src/lib.rs +++ b/src/vmm/src/lib.rs @@ -52,12 +52,10 @@ use crate::terminal::term_set_canonical_mode; use crate::vstate::VcpuEvent; use crate::vstate::{Vcpu, VcpuHandle, VcpuResponse, Vm}; -use arch::ArchMemoryInfo; -use arch::DeviceType; -use arch::InitrdConfig; +use arch::{ArchMemoryInfo, DeviceType, InitrdConfig, ShmRegion}; #[cfg(target_os = "macos")] use crossbeam_channel::Sender; -use devices::virtio::VmmExitObserver; +use devices::virtio::{VirtioShmRegion, VmmExitObserver}; use devices::BusDevice; use kernel::cmdline::Cmdline as KernelCmdline; use polly::event_manager::{self, EventManager, Subscriber}; @@ -362,6 +360,13 @@ impl Vmm { &self.vm } + pub fn add_shm_region( + &mut self, + region: ShmRegion, + ) -> std::result::Result { + self.vm.add_shm_region(region) + } + #[cfg(target_os = "macos")] pub fn add_mapping( &self, diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index 8a64740f..564ad9b8 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -6,6 +6,7 @@ // found in the THIRD-PARTY file. use crossbeam_channel::{unbounded, Receiver, Sender, TryRecvError}; +use devices::virtio::VirtioShmRegion; use libc::{c_int, c_void, siginfo_t}; use std::cell::Cell; use std::fmt::{Display, Formatter}; @@ -34,9 +35,9 @@ use kbs_types::Tee; #[cfg(feature = "tee")] use crate::resources::TeeConfig; use crate::vmm_config::machine_config::CpuFeaturesTemplate; -use arch; #[cfg(target_arch = "aarch64")] use arch::aarch64::gic::GICDevice; +use arch::{self, ShmRegion}; #[cfg(target_arch = "x86_64")] use cpuid::{c3, filter_cpuid, t2, VmSpec}; #[cfg(target_arch = "x86_64")] @@ -111,6 +112,8 @@ pub enum Error { SetupGIC(arch::aarch64::gic::Error), /// Cannot set the memory regions. SetUserMemoryRegion(kvm_ioctls::Error), + /// Error creating memory map for SHM region. + ShmMmap(io::Error), #[cfg(feature = "amd-sev")] /// Error initializing the Secure Virtualization Backend (SEV). SevSecVirtInit(SevError), @@ -270,6 +273,7 @@ impl Display for Error { "Cannot set the local interruption due to bad configuration: {e:?}" ), SetUserMemoryRegion(e) => write!(f, "Cannot set the memory regions: {e}"), + ShmMmap(e) => write!(f, "Error creating memory map for SHM region: {e}"), #[cfg(feature = "tee")] SevSecVirtInit(e) => { write!( @@ -453,6 +457,7 @@ impl KvmContext { /// A wrapper around creating and using a VM. pub struct Vm { fd: VmFd, + next_mem_slot: u32, // X86 specific fields. #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] @@ -492,6 +497,7 @@ impl Vm { Ok(Vm { fd: vm_fd, + next_mem_slot: 0, #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] supported_cpuid, #[cfg(target_arch = "x86_64")] @@ -524,6 +530,7 @@ impl Vm { Ok(Vm { fd: vm_fd, + next_mem_slot: 0, supported_cpuid, supported_msrs, sev, @@ -553,12 +560,12 @@ impl Vm { if guest_mem.num_regions() > kvm_max_memslots { return Err(Error::NotEnoughMemorySlots); } - for (index, region) in guest_mem.iter().enumerate() { + for region in guest_mem.iter() { // It's safe to unwrap because the guest address is valid. let host_addr = guest_mem.get_host_address(region.start_addr()).unwrap(); - info!("Guest memory starts at {:x?}", host_addr); + debug!("Guest memory starts at {:x?}", host_addr); let memory_region = kvm_userspace_memory_region { - slot: index as u32, + slot: self.next_mem_slot, guest_phys_addr: region.start_addr().raw_value(), memory_size: region.len(), userspace_addr: host_addr as u64, @@ -571,6 +578,7 @@ impl Vm { .set_user_memory_region(memory_region) .map_err(Error::SetUserMemoryRegion)?; }; + self.next_mem_slot += 1; } #[cfg(target_arch = "x86_64")] @@ -581,6 +589,42 @@ impl Vm { Ok(()) } + pub fn add_shm_region(&mut self, region: ShmRegion) -> Result { + let host_addr = unsafe { + libc::mmap( + std::ptr::null_mut(), + region.size, + libc::PROT_READ | libc::PROT_WRITE, + libc::MAP_SHARED | libc::MAP_ANONYMOUS, + -1, + 0 as libc::off_t, + ) + }; + if host_addr == libc::MAP_FAILED { + return Err(Error::ShmMmap(io::Error::last_os_error())); + } + let memory_region = kvm_userspace_memory_region { + slot: self.next_mem_slot, + guest_phys_addr: region.guest_addr, + memory_size: region.size as u64, + userspace_addr: host_addr as u64, + flags: 0, + }; + // Safe because we mapped the memory region, we made sure that the regions + // are not overlapping. + unsafe { + self.fd + .set_user_memory_region(memory_region) + .map_err(Error::SetUserMemoryRegion)?; + }; + self.next_mem_slot += 1; + Ok(VirtioShmRegion { + host_addr: host_addr as u64, + guest_addr: region.guest_addr, + size: region.size, + }) + } + #[cfg(feature = "amd-sev")] pub fn sev_secure_virt_prepare( &mut self, diff --git a/src/vmm/src/macos/vstate.rs b/src/vmm/src/macos/vstate.rs index 3e89621e..0b725511 100644 --- a/src/vmm/src/macos/vstate.rs +++ b/src/vmm/src/macos/vstate.rs @@ -17,10 +17,11 @@ use std::time::Duration; use super::super::{FC_EXIT_CODE_GENERIC_ERROR, FC_EXIT_CODE_OK}; use crate::vmm_config::machine_config::CpuFeaturesTemplate; -use arch; use arch::aarch64::gic::GICDevice; +use arch::{self, ShmRegion}; use crossbeam_channel::{unbounded, Receiver, RecvTimeoutError, Sender}; use devices::legacy::{Gic, VcpuList}; +use devices::virtio::VirtioShmRegion; use hvf::{HvfVcpu, HvfVm, VcpuExit}; use utils::eventfd::EventFd; use vm_memory::{ @@ -151,6 +152,17 @@ impl Vm { self.irqchip_handle.as_ref().unwrap() } + pub fn add_shm_region(&mut self, region: ShmRegion) -> Result { + // While on Linux we create a large mmap for the ShmRegion, register it with KVM + // and then add submapping on top of it, on macOS we need to map and register + // each SHM window independently. As a consequence, we don't need to mmap and + // register the whole SHM region. + Ok(VirtioShmRegion { + guest_addr: region.guest_addr, + size: region.size, + }) + } + pub fn add_mapping( &self, reply_sender: Sender,