mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 05:35:20 +00:00
hypervisor: mshv: Update mshv crates to v0.3.0
And modify to code to use the updated interfaces. Arguments for map_guest_memory, get_dirty_bitmap, vp.run(), import_isolated_pages, modify_gpa_host_access have changed. Update these to use the new interfaces, including new MSHV_* definitions, and remove some redundant arguments. Update seccomp IOCTLs to reflect interface changes. Fix irq-related definitions naming. Bump vfio-ioctls to support mshv v0.3.0. Signed-off-by: Nuno Das Neves <nudasnev@microsoft.com>
This commit is contained in:
parent
d9ee760f3b
commit
9f08aa6dc2
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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)]
|
||||
|
@ -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<mshv_user_mem_region> 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<ClockData> for MshvClockData {
|
||||
|
||||
impl From<UserMemoryRegion> 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<UserMemoryRegion> for mshv_user_mem_region {
|
||||
size: region.memory_size,
|
||||
userspace_addr: region.userspace_addr,
|
||||
flags,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -182,13 +168,13 @@ impl From<crate::StandardRegisters> for mshv_bindings::StandardRegisters {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<mshv_msi_routing_entry> for IrqRoutingEntry {
|
||||
fn from(s: mshv_msi_routing_entry) -> Self {
|
||||
impl From<mshv_user_irq_entry> for IrqRoutingEntry {
|
||||
fn from(s: mshv_user_irq_entry) -> Self {
|
||||
IrqRoutingEntry::Mshv(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<IrqRoutingEntry> for mshv_msi_routing_entry {
|
||||
impl From<IrqRoutingEntry> 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<cpu::VmExit, cpu::HypervisorCpuError> {
|
||||
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::<mshv_modify_gpa_host_access, u64>(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::<mshv_msi_routing, mshv_msi_routing_entry>(entries.len());
|
||||
vec_with_array_field::<mshv_user_irq_table, mshv_user_irq_entry>(entries.len());
|
||||
msi_routing[0].nr = entries.len() as u32;
|
||||
|
||||
let entries: Vec<mshv_msi_routing_entry> = entries
|
||||
let entries: Vec<mshv_user_irq_entry> = 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::<mshv_import_isolated_pages, u64>(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::<mshv_modify_gpa_host_access, u64>(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());
|
||||
}
|
||||
|
||||
|
@ -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" }
|
||||
|
@ -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 }
|
||||
|
@ -159,8 +159,13 @@ use hypervisor::mshv::mshv_ioctls::*;
|
||||
fn create_vmm_ioctl_seccomp_rule_common_mshv() -> Result<Vec<SeccompRule>, 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<Vec<SeccompRule>, 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<Vec<SeccompRule>, 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(
|
||||
|
Loading…
Reference in New Issue
Block a user