use std::str::FromStr;
use std::sync::Arc;
use vm_memory::{GuestAddressSpace, GuestMemoryAtomic, GuestMemoryLoadGuard, GuestMemoryMmap};
mod raw_region;
pub use raw_region::GuestRegionRaw;
mod hybrid;
pub use hybrid::{GuestMemoryHybrid, GuestRegionHybrid};
#[derive(Debug, Eq, PartialEq)]
pub enum MemorySourceType {
FileOnHugeTlbFs,
MmapAnonymous,
MmapAnonymousHugeTlbFs,
MemFdShared,
MemFdOnHugeTlbFs,
}
impl MemorySourceType {
pub fn is_hugepage(&self) -> bool {
*self == Self::FileOnHugeTlbFs
|| *self == Self::MmapAnonymousHugeTlbFs
|| *self == Self::MemFdOnHugeTlbFs
}
pub fn is_mmap_anonymous(&self) -> bool {
*self == Self::MmapAnonymous || *self == Self::MmapAnonymousHugeTlbFs
}
}
impl FromStr for MemorySourceType {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"hugetlbfs" => Ok(MemorySourceType::FileOnHugeTlbFs),
"memfd" => Ok(MemorySourceType::MemFdShared),
"shmem" => Ok(MemorySourceType::MemFdShared),
"hugememfd" => Ok(MemorySourceType::MemFdOnHugeTlbFs),
"hugeshmem" => Ok(MemorySourceType::MemFdOnHugeTlbFs),
"anon" => Ok(MemorySourceType::MmapAnonymous),
"mmap" => Ok(MemorySourceType::MmapAnonymous),
"hugeanon" => Ok(MemorySourceType::MmapAnonymousHugeTlbFs),
"hugemmap" => Ok(MemorySourceType::MmapAnonymousHugeTlbFs),
_ => Err(format!("unknown memory source type {s}")),
}
}
}
#[derive(Debug, Default)]
struct GuestMemoryHotplugManager {}
#[allow(unused)]
#[derive(Debug, Clone)]
pub struct GuestMemoryManager {
default: GuestMemoryAtomic<GuestMemoryHybrid>,
hybrid: GuestMemoryAtomic<GuestMemoryHybrid>,
iommu: GuestMemoryAtomic<GuestMemoryHybrid>,
normal: GuestMemoryAtomic<GuestMemoryMmap>,
hotplug: Arc<GuestMemoryHotplugManager>,
}
impl GuestMemoryManager {
pub fn new() -> Self {
Self::default()
}
pub fn get_normal_guest_memory(&self) -> &GuestMemoryAtomic<GuestMemoryMmap> {
&self.normal
}
pub fn to_manager<AS: GuestAddressSpace>(_m: &AS) -> Option<&Self> {
None
}
}
impl Default for GuestMemoryManager {
fn default() -> Self {
let hybrid = GuestMemoryAtomic::new(GuestMemoryHybrid::new());
let iommu = GuestMemoryAtomic::new(GuestMemoryHybrid::new());
let normal = GuestMemoryAtomic::new(GuestMemoryMmap::new());
let default = hybrid.clone();
GuestMemoryManager {
default,
hybrid,
iommu,
normal,
hotplug: Arc::new(GuestMemoryHotplugManager::default()),
}
}
}
impl GuestAddressSpace for GuestMemoryManager {
type M = GuestMemoryHybrid;
type T = GuestMemoryLoadGuard<GuestMemoryHybrid>;
fn memory(&self) -> Self::T {
self.default.memory()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_memory_source_type() {
assert_eq!(
MemorySourceType::from_str("hugetlbfs").unwrap(),
MemorySourceType::FileOnHugeTlbFs
);
assert_eq!(
MemorySourceType::from_str("memfd").unwrap(),
MemorySourceType::MemFdShared
);
assert_eq!(
MemorySourceType::from_str("shmem").unwrap(),
MemorySourceType::MemFdShared
);
assert_eq!(
MemorySourceType::from_str("hugememfd").unwrap(),
MemorySourceType::MemFdOnHugeTlbFs
);
assert_eq!(
MemorySourceType::from_str("hugeshmem").unwrap(),
MemorySourceType::MemFdOnHugeTlbFs
);
assert_eq!(
MemorySourceType::from_str("anon").unwrap(),
MemorySourceType::MmapAnonymous
);
assert_eq!(
MemorySourceType::from_str("mmap").unwrap(),
MemorySourceType::MmapAnonymous
);
assert_eq!(
MemorySourceType::from_str("hugeanon").unwrap(),
MemorySourceType::MmapAnonymousHugeTlbFs
);
assert_eq!(
MemorySourceType::from_str("hugemmap").unwrap(),
MemorySourceType::MmapAnonymousHugeTlbFs
);
assert!(MemorySourceType::from_str("test").is_err());
}
#[ignore]
#[test]
fn test_to_manager() {
let manager = GuestMemoryManager::new();
let mgr = GuestMemoryManager::to_manager(&manager).unwrap();
assert_eq!(&manager as *const _, mgr as *const _);
}
}