membacking/lib.rs
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! This implements HvLite's memory manager.
5//!
6//! Externally, this is managed by the [`GuestMemoryManager`] object.
7//!
8//! Internally, guest memory is made up of a set of _regions_, each of which has
9//! a fixed length and can be dynamically mapped and unmapped into guest
10//! physical address space. Regions have priority--if a higher priority region
11//! overlaps a lower priority one, the higher priority region will be mapped
12//! into the VM.
13//!
14//! Each region contains a set of _mappings_, which specify the mapping of
15//! portion of an OS mappable object (file descriptor on Unix, section handle on
16//! Windows) to an offset within the region. Many regions will have exactly one
17//! mapping, but some may have a dynamic set of mappings; for example, virtiofs
18//! dynamically maps and unmaps files into a pre-allocated MMIO region to
19//! support DAX.
20//!
21//! The regions and their mappings are maintained by the region manager
22//! (`RegionManager`). Its job is to determine the currently active set of
23//! mappings, which it sends to the mapping manager (`MappingManager`).
24//!
25//! The mapping manager tracks the virtual address space mappers (`VaMapper`),
26//! which are used to maintain a linear virtual address space for guest memory
27//! access by VMM processes. The mapping manager is responsible for keeping
28//! track of which VA mappers have which mappings, to send mappings to the
29//! mappers upon request, and to send requests to tear down those mappings when
30//! the set of active mappings changes.
31//!
32//! The VA mappers implement the
33//! [`GuestMemoryAccess`](guestmem::GuestMemoryAccess) trait and can be
34//! used to back [`GuestMemory`](guestmem::GuestMemory).
35//!
36//! The region manager also keeps a list of partition memory mappers. These are
37//! used to map and unmap regions from GPA space. The partitions do not care
38//! about the individual mappings but instead just reference the linear virtual
39//! address space maintained by a VA mapper.
40//!
41//! Currently, there are some holes in this implementation:
42//!
43//! * Guest VSM (multiple VTLs) is not supported. There is some basic support
44//! for mapping memory into both a VTL0 and a VTL2 partition, and for mapping
45//! a VTL0 alias map into VTL2, but there is no support for page protections
46//! or per-VTL [`GuestMemory`](guestmem::GuestMemory) objects.
47//!
48//! Supporting this could be implemented via separate VA spaces for VTL0 and
49//! VTL2 memory. However, eventually we will use the hypervisor's
50//! implementation of a combined partition for VTL0 and VTL2 (and VTL1), which
51//! will require handling this very differently.
52//!
53//! * There is no support for locking memory. We obviously have to "support"
54//! this because the lock APIs exist on `GuestMemory`, but currently we can
55//! tear down mappings while they are locked. This has two side effects:
56//!
57//! 1. We can segfault in normal Rust code if the guest does something to
58//! unmap some memory that is locked. E.g., it can cause us to segfault in
59//! vmbus code accessing a ring buffer. This is not a memory safety issue
60//! but it is certainly undesirable.
61//!
62//! 2. The guest might be able to access or mutate memory after the VMM has
63//! torn it down, e.g. by issuing a storage IO to it concurrently with
64//! unmapping it. The exact implications of this are not easy to reason
65//! about.
66
67mod mapping_manager;
68mod memory_manager;
69mod partition_mapper;
70mod region_manager;
71
72#[cfg(windows)]
73mod sys {
74 pub type RemoteProcess = Box<dyn 'static + std::os::windows::io::AsHandle + Send + Sync>;
75}
76
77#[cfg(unix)]
78mod sys {
79 pub enum RemoteProcess {}
80}
81
82/// A remote process handle.
83///
84/// This is used when specifying the process to use for mapping memory into a
85/// partition. This is necessary because on Windows, it is not possible to map
86/// memory from a single process into multiple partitions.
87///
88/// On Unix, this is an empty (uninhabitable) enum.
89pub type RemoteProcess = sys::RemoteProcess;
90
91pub use memory_manager::DeviceMemoryMapper;
92pub use memory_manager::GuestMemoryBuilder;
93pub use memory_manager::GuestMemoryClient;
94pub use memory_manager::GuestMemoryManager;
95pub use memory_manager::MemoryBuildError;
96pub use memory_manager::PartitionAttachError;
97pub use memory_manager::RamVisibility;
98pub use memory_manager::RamVisibilityControl;
99pub use memory_manager::SharedMemoryBacking;