diff --git a/Cargo.lock b/Cargo.lock index a0d655b40..cefd31966 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1254,8 +1254,8 @@ checksum = "9bec4598fddb13cc7b528819e697852653252b760f1228b7642679bf2ff2cd07" [[package]] name = "mshv-bindings" -version = "0.2.0" -source = "git+https://github.com/rust-vmm/mshv?tag=v0.2.0#dd0a9f5ab9c32673e88d6de200af788dbfca6a72" +version = "0.3.0" +source = "git+https://github.com/rust-vmm/mshv?tag=v0.3.0#fda05380ea4c68b807996299d5ffb2854ca6d01d" dependencies = [ "libc", "num_enum", @@ -1267,8 +1267,8 @@ dependencies = [ [[package]] name = "mshv-ioctls" -version = "0.2.0" -source = "git+https://github.com/rust-vmm/mshv?tag=v0.2.0#dd0a9f5ab9c32673e88d6de200af788dbfca6a72" +version = "0.3.0" +source = "git+https://github.com/rust-vmm/mshv?tag=v0.3.0#fda05380ea4c68b807996299d5ffb2854ca6d01d" dependencies = [ "libc", "mshv-bindings", @@ -2225,7 +2225,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "vfio-bindings" version = "0.4.0" -source = "git+https://github.com/rust-vmm/vfio?branch=main#94bec9fa2a94a29e11d83766a992cb85496fcb7c" +source = "git+https://github.com/rust-vmm/vfio?branch=main#09c6b193d6b5a339f6a3ec3f44095046c519baaa" dependencies = [ "vmm-sys-util", ] @@ -2233,7 +2233,7 @@ dependencies = [ [[package]] name = "vfio-ioctls" version = "0.2.0" -source = "git+https://github.com/rust-vmm/vfio?branch=main#94bec9fa2a94a29e11d83766a992cb85496fcb7c" +source = "git+https://github.com/rust-vmm/vfio?branch=main#09c6b193d6b5a339f6a3ec3f44095046c519baaa" dependencies = [ "byteorder", "kvm-bindings", diff --git a/hypervisor/Cargo.toml b/hypervisor/Cargo.toml index 518b5a798..dc3e2c910 100644 --- a/hypervisor/Cargo.toml +++ b/hypervisor/Cargo.toml @@ -22,11 +22,11 @@ kvm-bindings = { version = "0.9.1", optional = true, features = ["serde"] } kvm-ioctls = { version = "0.18.0", optional = true } libc = "0.2.158" log = "0.4.22" -mshv-bindings = { git = "https://github.com/rust-vmm/mshv", tag = "v0.2.0", features = [ +mshv-bindings = { git = "https://github.com/rust-vmm/mshv", tag = "v0.3.0", features = [ "fam-wrappers", "with-serde", ], optional = true } -mshv-ioctls = { git = "https://github.com/rust-vmm/mshv", tag = "v0.2.0", optional = true } +mshv-ioctls = { git = "https://github.com/rust-vmm/mshv", tag = "v0.3.0", optional = true } serde = { version = "1.0.208", features = ["derive", "rc"] } serde_with = { version = "3.9.0", default-features = false, features = [ "macros", diff --git a/hypervisor/src/lib.rs b/hypervisor/src/lib.rs index d83eeabca..b4e578e5f 100644 --- a/hypervisor/src/lib.rs +++ b/hypervisor/src/lib.rs @@ -186,7 +186,7 @@ pub enum IrqRoutingEntry { #[cfg(feature = "kvm")] Kvm(kvm_bindings::kvm_irq_routing_entry), #[cfg(feature = "mshv")] - Mshv(mshv_bindings::mshv_msi_routing_entry), + Mshv(mshv_bindings::mshv_user_irq_entry), } #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 6000513d9..ada404391 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -46,9 +46,6 @@ pub use x86_64::*; #[cfg(target_arch = "x86_64")] pub use x86_64::{emulator, VcpuMshvState}; -const DIRTY_BITMAP_CLEAR_DIRTY: u64 = 0x4; -const DIRTY_BITMAP_SET_DIRTY: u64 = 0x8; - /// /// Export generically-named wrappers of mshv-bindings for Unix-based platforms /// @@ -61,19 +58,13 @@ pub const PAGE_SHIFT: usize = 12; impl From for UserMemoryRegion { fn from(region: mshv_user_mem_region) -> Self { - let mut flags: u32 = 0; - if region.flags & HV_MAP_GPA_READABLE != 0 { - flags |= USER_MEMORY_REGION_READ; - } - if region.flags & HV_MAP_GPA_WRITABLE != 0 { + let mut flags: u32 = USER_MEMORY_REGION_READ | USER_MEMORY_REGION_ADJUSTABLE; + if region.flags & (1 << MSHV_SET_MEM_BIT_WRITABLE) != 0 { flags |= USER_MEMORY_REGION_WRITE; } - if region.flags & HV_MAP_GPA_EXECUTABLE != 0 { + if region.flags & (1 << MSHV_SET_MEM_BIT_EXECUTABLE) != 0 { flags |= USER_MEMORY_REGION_EXECUTE; } - if region.flags & HV_MAP_GPA_ADJUSTABLE != 0 { - flags |= USER_MEMORY_REGION_ADJUSTABLE; - } UserMemoryRegion { guest_phys_addr: (region.guest_pfn << PAGE_SHIFT as u64) @@ -107,18 +98,12 @@ impl From for MshvClockData { impl From for mshv_user_mem_region { fn from(region: UserMemoryRegion) -> Self { - let mut flags: u32 = 0; - if region.flags & USER_MEMORY_REGION_READ != 0 { - flags |= HV_MAP_GPA_READABLE; - } + let mut flags: u8 = 0; if region.flags & USER_MEMORY_REGION_WRITE != 0 { - flags |= HV_MAP_GPA_WRITABLE; + flags |= 1 << MSHV_SET_MEM_BIT_WRITABLE; } if region.flags & USER_MEMORY_REGION_EXECUTE != 0 { - flags |= HV_MAP_GPA_EXECUTABLE; - } - if region.flags & USER_MEMORY_REGION_ADJUSTABLE != 0 { - flags |= HV_MAP_GPA_ADJUSTABLE; + flags |= 1 << MSHV_SET_MEM_BIT_EXECUTABLE; } mshv_user_mem_region { @@ -126,6 +111,7 @@ impl From for mshv_user_mem_region { size: region.memory_size, userspace_addr: region.userspace_addr, flags, + ..Default::default() } } } @@ -182,13 +168,13 @@ impl From for mshv_bindings::StandardRegisters { } } -impl From for IrqRoutingEntry { - fn from(s: mshv_msi_routing_entry) -> Self { +impl From for IrqRoutingEntry { + fn from(s: mshv_user_irq_entry) -> Self { IrqRoutingEntry::Mshv(s) } } -impl From for mshv_msi_routing_entry { +impl From for mshv_user_irq_entry { fn from(e: IrqRoutingEntry) -> Self { match e { IrqRoutingEntry::Mshv(e) => e, @@ -556,8 +542,7 @@ impl cpu::Vcpu for MshvVcpu { #[allow(non_upper_case_globals)] fn run(&self) -> std::result::Result { - let hv_message: hv_message = hv_message::default(); - match self.fd.run(hv_message) { + match self.fd.run() { Ok(x) => match x.header.message_type { hv_message_type_HVMSG_X64_HALT => { debug!("HALT"); @@ -724,16 +709,21 @@ impl cpu::Vcpu for MshvVcpu { let mut gpa_list = vec_with_array_field::(gpas.len()); - gpa_list[0].gpa_list_size = gpas.len() as u64; - gpa_list[0].host_access = host_vis; - gpa_list[0].acquire = 0; + gpa_list[0].page_count = gpas.len() as u64; gpa_list[0].flags = 0; + if host_vis & HV_MAP_GPA_READABLE != 0 { + gpa_list[0].flags |= 1 << MSHV_GPA_HOST_ACCESS_BIT_READABLE; + } + if host_vis & HV_MAP_GPA_WRITABLE != 0 { + gpa_list[0].flags |= 1 << MSHV_GPA_HOST_ACCESS_BIT_WRITABLE; + } // SAFETY: gpa_list initialized with gpas.len() and now it is being turned into // gpas_slice with gpas.len() again. It is guaranteed to be large enough to hold // everything from gpas. unsafe { - let gpas_slice: &mut [u64] = gpa_list[0].gpa_list.as_mut_slice(gpas.len()); + let gpas_slice: &mut [u64] = + gpa_list[0].guest_pfns.as_mut_slice(gpas.len()); gpas_slice.copy_from_slice(gpas.as_slice()); } @@ -1777,9 +1767,9 @@ impl vm::Vm for MshvVm { readonly: bool, _log_dirty_pages: bool, ) -> UserMemoryRegion { - let mut flags = HV_MAP_GPA_READABLE | HV_MAP_GPA_EXECUTABLE | HV_MAP_GPA_ADJUSTABLE; + let mut flags = 1 << MSHV_SET_MEM_BIT_EXECUTABLE; if !readonly { - flags |= HV_MAP_GPA_WRITABLE; + flags |= 1 << MSHV_SET_MEM_BIT_WRITABLE; } mshv_user_mem_region { @@ -1787,6 +1777,7 @@ impl vm::Vm for MshvVm { guest_pfn: guest_phys_addr >> PAGE_SHIFT, size: memory_size, userspace_addr, + ..Default::default() } .into() } @@ -1807,7 +1798,7 @@ impl vm::Vm for MshvVm { /// fn make_routing_entry(&self, gsi: u32, config: &InterruptSourceConfig) -> IrqRoutingEntry { match config { - InterruptSourceConfig::MsiIrq(cfg) => mshv_msi_routing_entry { + InterruptSourceConfig::MsiIrq(cfg) => mshv_user_irq_entry { gsi, address_lo: cfg.low_addr, address_hi: cfg.high_addr, @@ -1822,10 +1813,10 @@ impl vm::Vm for MshvVm { fn set_gsi_routing(&self, entries: &[IrqRoutingEntry]) -> vm::Result<()> { let mut msi_routing = - vec_with_array_field::(entries.len()); + vec_with_array_field::(entries.len()); msi_routing[0].nr = entries.len() as u32; - let entries: Vec = entries + let entries: Vec = entries .iter() .map(|entry| match entry { IrqRoutingEntry::Mshv(e) => *e, @@ -1838,7 +1829,7 @@ impl vm::Vm for MshvVm { // entries_slice with entries.len() again. It is guaranteed to be large enough to hold // everything from entries. unsafe { - let entries_slice: &mut [mshv_msi_routing_entry] = + let entries_slice: &mut [mshv_user_irq_entry] = msi_routing[0].entries.as_mut_slice(entries.len()); entries_slice.copy_from_slice(&entries); } @@ -1867,7 +1858,11 @@ impl vm::Vm for MshvVm { // This is a requirement from Microsoft Hypervisor for (_, s) in dirty_log_slots.iter() { self.fd - .get_dirty_log(s.guest_pfn, s.memory_size as usize, DIRTY_BITMAP_SET_DIRTY) + .get_dirty_log( + s.guest_pfn, + s.memory_size as usize, + MSHV_GPAP_ACCESS_OP_SET as u8, + ) .map_err(|e| vm::HypervisorVmError::StartDirtyLog(e.into()))?; } self.fd @@ -1884,7 +1879,7 @@ impl vm::Vm for MshvVm { .get_dirty_log( base_gpa >> PAGE_SHIFT, memory_size as usize, - DIRTY_BITMAP_CLEAR_DIRTY, + MSHV_GPAP_ACCESS_OP_CLEAR as u8, ) .map_err(|e| vm::HypervisorVmError::GetDirtyLog(e.into())) } @@ -1937,20 +1932,20 @@ impl vm::Vm for MshvVm { page_size: u32, pages: &[u64], ) -> vm::Result<()> { + debug_assert!(page_size == hv_isolated_page_size_HV_ISOLATED_PAGE_SIZE_4KB); if pages.is_empty() { return Ok(()); } let mut isolated_pages = vec_with_array_field::(pages.len()); - isolated_pages[0].num_pages = pages.len() as u64; - isolated_pages[0].page_type = page_type; - isolated_pages[0].page_size = page_size; + isolated_pages[0].page_type = page_type as u8; + isolated_pages[0].page_count = pages.len() as u64; // SAFETY: isolated_pages initialized with pages.len() and now it is being turned into // pages_slice with pages.len() again. It is guaranteed to be large enough to hold // everything from pages. unsafe { - let pages_slice: &mut [u64] = isolated_pages[0].page_number.as_mut_slice(pages.len()); + let pages_slice: &mut [u64] = isolated_pages[0].guest_pfns.as_mut_slice(pages.len()); pages_slice.copy_from_slice(pages); } self.fd @@ -2054,6 +2049,8 @@ impl vm::Vm for MshvVm { #[cfg(feature = "sev_snp")] fn gain_page_access(&self, gpa: u64, size: u32) -> vm::Result<()> { + use mshv_ioctls::set_bits; + if !self.sev_snp_enabled { return Ok(()); } @@ -2065,16 +2062,19 @@ impl vm::Vm for MshvVm { if !gpas.is_empty() { let mut gpa_list = vec_with_array_field::(gpas.len()); - gpa_list[0].gpa_list_size = gpas.len() as u64; - gpa_list[0].host_access = HV_MAP_GPA_READABLE | HV_MAP_GPA_WRITABLE; - gpa_list[0].acquire = 1; - gpa_list[0].flags = 0; + gpa_list[0].page_count = gpas.len() as u64; + gpa_list[0].flags = set_bits!( + u8, + MSHV_GPA_HOST_ACCESS_BIT_ACQUIRE, + MSHV_GPA_HOST_ACCESS_BIT_READABLE, + MSHV_GPA_HOST_ACCESS_BIT_WRITABLE + ); // SAFETY: gpa_list initialized with gpas.len() and now it is being turned into // gpas_slice with gpas.len() again. It is guaranteed to be large enough to hold // everything from gpas. unsafe { - let gpas_slice: &mut [u64] = gpa_list[0].gpa_list.as_mut_slice(gpas.len()); + let gpas_slice: &mut [u64] = gpa_list[0].guest_pfns.as_mut_slice(gpas.len()); gpas_slice.copy_from_slice(gpas.as_slice()); } diff --git a/virtio-devices/Cargo.toml b/virtio-devices/Cargo.toml index 0ef52e60b..6f31403f1 100644 --- a/virtio-devices/Cargo.toml +++ b/virtio-devices/Cargo.toml @@ -17,7 +17,7 @@ epoll = "4.3.3" event_monitor = { path = "../event_monitor" } libc = "0.2.158" log = "0.4.22" -mshv-ioctls = { git = "https://github.com/rust-vmm/mshv", tag = "v0.2.0", optional = true } +mshv-ioctls = { git = "https://github.com/rust-vmm/mshv", tag = "v0.3.0", optional = true } net_gen = { path = "../net_gen" } net_util = { path = "../net_util" } pci = { path = "../pci" } diff --git a/vmm/Cargo.toml b/vmm/Cargo.toml index 389a40a5e..b92e71b80 100644 --- a/vmm/Cargo.toml +++ b/vmm/Cargo.toml @@ -51,7 +51,7 @@ libc = "0.2.158" linux-loader = { version = "0.11.0", features = ["bzimage", "elf", "pe"] } log = "0.4.22" micro_http = { git = "https://github.com/firecracker-microvm/micro-http", branch = "main" } -mshv-bindings = { git = "https://github.com/rust-vmm/mshv", tag = "v0.2.0", features = [ +mshv-bindings = { git = "https://github.com/rust-vmm/mshv", tag = "v0.3.0", features = [ "fam-wrappers", "with-serde", ], optional = true } diff --git a/vmm/src/seccomp_filters.rs b/vmm/src/seccomp_filters.rs index 32bce4cc0..3879c927a 100644 --- a/vmm/src/seccomp_filters.rs +++ b/vmm/src/seccomp_filters.rs @@ -159,8 +159,13 @@ use hypervisor::mshv::mshv_ioctls::*; fn create_vmm_ioctl_seccomp_rule_common_mshv() -> Result, BackendError> { Ok(or![ and![Cond::new(1, ArgLen::Dword, Eq, MSHV_CREATE_PARTITION())?], - and![Cond::new(1, ArgLen::Dword, Eq, MSHV_MAP_GUEST_MEMORY())?], - and![Cond::new(1, ArgLen::Dword, Eq, MSHV_UNMAP_GUEST_MEMORY())?], + and![Cond::new( + 1, + ArgLen::Dword, + Eq, + MSHV_INITIALIZE_PARTITION() + )?], + and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SET_GUEST_MEMORY())?], and![Cond::new(1, ArgLen::Dword, Eq, MSHV_CREATE_VP())?], and![Cond::new(1, ArgLen::Dword, Eq, MSHV_IRQFD())?], and![Cond::new(1, ArgLen::Dword, Eq, MSHV_IOEVENTFD())?], @@ -186,7 +191,7 @@ fn create_vmm_ioctl_seccomp_rule_common_mshv() -> Result, Backe 1, ArgLen::Dword, Eq, - MSHV_GET_GPA_ACCESS_STATES() + MSHV_GET_GPAP_ACCESS_BITMAP() )?], and![Cond::new(1, ArgLen::Dword, Eq, MSHV_VP_TRANSLATE_GVA())?], and![Cond::new( @@ -700,8 +705,7 @@ fn create_vcpu_ioctl_seccomp_rule_mshv() -> Result, BackendErro and![Cond::new(1, ArgLen::Dword, Eq, MSHV_RUN_VP())?], and![Cond::new(1, ArgLen::Dword, Eq, MSHV_GET_VP_REGISTERS())?], and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SET_VP_REGISTERS())?], - and![Cond::new(1, ArgLen::Dword, Eq, MSHV_MAP_GUEST_MEMORY())?], - and![Cond::new(1, ArgLen::Dword, Eq, MSHV_UNMAP_GUEST_MEMORY())?], + and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SET_GUEST_MEMORY())?], and![Cond::new(1, ArgLen::Dword, Eq, MSHV_VP_TRANSLATE_GVA())?], and![Cond::new(1, ArgLen::Dword, Eq, MSHV_GET_VP_CPUID_VALUES())?], and![Cond::new(