@@ -242,7 +242,8 @@ fn inspect_mappings(mappings: &Vec<Mapping>) -> impl '_ + Inspect {
242242 req. respond ( )
243243 . field ( "writable" , mapping. params . writable )
244244 . field ( "mapping_type" , mapping. params . mapping_type )
245- . hex ( "file_offset" , mapping. params . file_offset ) ;
245+ . field ( "backed_by_fd" , mapping. params . backing . mappable ( ) . is_some ( ) )
246+ . hex ( "file_offset" , mapping. params . backing . file_offset ( ) ) ;
246247 } ) ,
247248 ) ;
248249 }
@@ -254,15 +255,66 @@ struct Mapping {
254255 active_mappers : Vec < MapperId > ,
255256}
256257
258+ /// How a guest memory mapping is backed by host memory.
259+ #[ derive( Debug , MeshPayload , Clone ) ]
260+ pub enum MappingBacking {
261+ /// Backed by a mappable OS object (shared memory or file). The mapping
262+ /// manager mmaps `mappable` at `file_offset` into each VA mapper, so the
263+ /// same physical pages are shared across all mappers (and shareable with
264+ /// other processes via `GuestMemorySharing`).
265+ File {
266+ /// The OS object to map.
267+ mappable : Mappable ,
268+ /// The file offset into `mappable`.
269+ file_offset : u64 ,
270+ } ,
271+ /// Backed by private anonymous memory committed directly by the mapping
272+ /// manager. There is no backing fd, so the memory cannot be shared with
273+ /// other processes or programmed into DMA targets that require an fd; it is
274+ /// exposed to DMA targets purely by host VA.
275+ ///
276+ /// Private memory is only valid with a single local eager mapper: lazy
277+ /// mappers and remote mappers are rejected when any range is private (see
278+ /// [`MappingManagerClient::new_mapper`] and
279+ /// [`MappingManagerClient::new_remote_mapper`]). Committing anonymous pages
280+ /// into multiple independent mappers would not share storage.
281+ ///
282+ /// Unlike file-backed memory, the storage *is* the VA mapping: there is no
283+ /// fd holding the pages. Tearing the mapping down (via the region manager's
284+ /// `remove_mappings`) decommits and zeroes the pages, so a private region
285+ /// must not be transiently disabled and re-enabled — doing so would lose
286+ /// guest memory. The region manager asserts against this.
287+ Private {
288+ /// Whether the range is eligible for Transparent Huge Pages (Linux).
289+ transparent_hugepages : bool ,
290+ } ,
291+ }
292+
293+ impl MappingBacking {
294+ /// Returns the backing object, if this mapping is file-backed.
295+ pub fn mappable ( & self ) -> Option < & Mappable > {
296+ match self {
297+ MappingBacking :: File { mappable, .. } => Some ( mappable) ,
298+ MappingBacking :: Private { .. } => None ,
299+ }
300+ }
301+
302+ /// Returns the offset within the backing object, or 0 if there is none.
303+ pub fn file_offset ( & self ) -> u64 {
304+ match self {
305+ MappingBacking :: File { file_offset, .. } => * file_offset,
306+ MappingBacking :: Private { .. } => 0 ,
307+ }
308+ }
309+ }
310+
257311/// The mapping parameters.
258312#[ derive( Debug , MeshPayload , Clone ) ]
259313pub struct MappingParams {
260314 /// The memory range for the mapping.
261315 pub range : MemoryRange ,
262- /// The OS object to map.
263- pub mappable : Mappable ,
264- /// The file offset into `mappable`.
265- pub file_offset : u64 ,
316+ /// How the mapping is backed by host memory.
317+ pub backing : MappingBacking ,
266318 /// Whether to map the memory as writable.
267319 pub writable : bool ,
268320 /// The type of memory being mapped.
@@ -593,7 +645,11 @@ impl MappingManagerTask {
593645 fn get_dma_target_mappings ( & self ) -> Vec < MappingParams > {
594646 self . mappings
595647 . iter ( )
596- . filter ( |m| m. params . mapping_type == MappingType :: Ram )
648+ // Only file-backed RAM can be shared with other processes;
649+ // private/anonymous RAM has no fd to hand out.
650+ . filter ( |m| {
651+ m. params . mapping_type == MappingType :: Ram && m. params . backing . mappable ( ) . is_some ( )
652+ } )
597653 . map ( |m| m. params . clone ( ) )
598654 . collect ( )
599655 }
@@ -653,11 +709,14 @@ impl ProvideShareableRegions for DmaRegionProvider {
653709
654710 Ok ( mappings
655711 . into_iter ( )
656- . map ( |m| ShareableRegion {
657- guest_address : m. range . start ( ) ,
658- size : m. range . len ( ) ,
659- file : m. mappable . inner_arc ( ) ,
660- file_offset : m. file_offset ,
712+ . filter_map ( |m| {
713+ let mappable = m. backing . mappable ( ) ?;
714+ Some ( ShareableRegion {
715+ guest_address : m. range . start ( ) ,
716+ size : m. range . len ( ) ,
717+ file : mappable. inner_arc ( ) ,
718+ file_offset : m. backing . file_offset ( ) ,
719+ } )
661720 } )
662721 . collect ( ) )
663722 }
@@ -686,8 +745,10 @@ mod tests {
686745 client
687746 . add_mapping ( MappingParams {
688747 range : MemoryRange :: new ( 0 ..0x100000 ) ,
689- mappable : ram,
690- file_offset : 0 ,
748+ backing : MappingBacking :: File {
749+ mappable : ram,
750+ file_offset : 0 ,
751+ } ,
691752 writable : true ,
692753 mapping_type : MappingType :: Ram ,
693754 numa_node : None ,
@@ -698,8 +759,10 @@ mod tests {
698759 client
699760 . add_mapping ( MappingParams {
700761 range : MemoryRange :: new ( 0x100000 ..0x101000 ) ,
701- mappable : device,
702- file_offset : 0 ,
762+ backing : MappingBacking :: File {
763+ mappable : device,
764+ file_offset : 0 ,
765+ } ,
703766 writable : true ,
704767 mapping_type : MappingType :: Device ,
705768 numa_node : None ,
@@ -731,8 +794,10 @@ mod tests {
731794 client
732795 . add_mapping ( MappingParams {
733796 range : MemoryRange :: new ( 0 ..0x1000 ) ,
734- mappable,
735- file_offset : 0 ,
797+ backing : MappingBacking :: File {
798+ mappable,
799+ file_offset : 0 ,
800+ } ,
736801 writable : true ,
737802 mapping_type : MappingType :: Device ,
738803 numa_node : None ,
@@ -755,8 +820,10 @@ mod tests {
755820 . into ( ) ;
756821 let params = MappingParams {
757822 range : MemoryRange :: new ( 0 ..0x10000 ) ,
758- mappable,
759- file_offset : 0 ,
823+ backing : MappingBacking :: File {
824+ mappable,
825+ file_offset : 0 ,
826+ } ,
760827 writable : true ,
761828 mapping_type : MappingType :: Ram ,
762829 numa_node : None ,
@@ -829,8 +896,10 @@ mod tests {
829896 . into ( ) ;
830897 let params = MappingParams {
831898 range : MemoryRange :: new ( 0 ..0x1000 ) ,
832- mappable,
833- file_offset : 0 ,
899+ backing : MappingBacking :: File {
900+ mappable,
901+ file_offset : 0 ,
902+ } ,
834903 writable : true ,
835904 mapping_type : MappingType :: Device ,
836905 numa_node : None ,
@@ -942,8 +1011,10 @@ mod tests {
9421011 . into ( ) ;
9431012 let params = MappingParams {
9441013 range : MemoryRange :: new ( 0 ..0x1000 ) ,
945- mappable,
946- file_offset : 0 ,
1014+ backing : MappingBacking :: File {
1015+ mappable,
1016+ file_offset : 0 ,
1017+ } ,
9471018 writable : true ,
9481019 mapping_type : MappingType :: Device ,
9491020 numa_node : None ,
@@ -1060,8 +1131,10 @@ mod tests {
10601131 . into ( ) ;
10611132 task. add_mapping ( MappingParams {
10621133 range : MemoryRange :: new ( start..end) ,
1063- mappable,
1064- file_offset : 0 ,
1134+ backing : MappingBacking :: File {
1135+ mappable,
1136+ file_offset : 0 ,
1137+ } ,
10651138 writable : true ,
10661139 mapping_type : MappingType :: Ram ,
10671140 numa_node : None ,
@@ -1148,8 +1221,10 @@ mod tests {
11481221 . into ( ) ;
11491222 let params = MappingParams {
11501223 range : MemoryRange :: new ( 0 ..0x1000 ) ,
1151- mappable,
1152- file_offset : 0 ,
1224+ backing : MappingBacking :: File {
1225+ mappable,
1226+ file_offset : 0 ,
1227+ } ,
11531228 writable : true ,
11541229 mapping_type : MappingType :: Device ,
11551230 numa_node : None ,
@@ -1255,8 +1330,10 @@ mod tests {
12551330 . into ( ) ;
12561331 task. add_mapping ( MappingParams {
12571332 range : MemoryRange :: new ( 0x20000 ..0x21000 ) ,
1258- mappable,
1259- file_offset : 0 ,
1333+ backing : MappingBacking :: File {
1334+ mappable,
1335+ file_offset : 0 ,
1336+ } ,
12601337 writable : true ,
12611338 mapping_type : MappingType :: Device ,
12621339 numa_node : None ,
@@ -1362,8 +1439,10 @@ mod tests {
13621439 client
13631440 . add_mapping ( MappingParams {
13641441 range : MemoryRange :: new ( 0 ..0x10000 ) ,
1365- mappable,
1366- file_offset : 0 ,
1442+ backing : MappingBacking :: File {
1443+ mappable,
1444+ file_offset : 0 ,
1445+ } ,
13671446 writable : true ,
13681447 mapping_type : MappingType :: Device ,
13691448 numa_node : None ,
@@ -1410,8 +1489,10 @@ mod tests {
14101489 client
14111490 . add_mapping ( MappingParams {
14121491 range : MemoryRange :: new ( 0 ..0x10000 ) ,
1413- mappable,
1414- file_offset : 0 ,
1492+ backing : MappingBacking :: File {
1493+ mappable,
1494+ file_offset : 0 ,
1495+ } ,
14151496 writable : true ,
14161497 mapping_type : MappingType :: Ram ,
14171498 numa_node : None ,
@@ -1446,8 +1527,10 @@ mod tests {
14461527 client
14471528 . add_mapping ( MappingParams {
14481529 range : MemoryRange :: new ( 0 ..0x10000 ) ,
1449- mappable,
1450- file_offset : 0 ,
1530+ backing : MappingBacking :: File {
1531+ mappable,
1532+ file_offset : 0 ,
1533+ } ,
14511534 writable : true ,
14521535 mapping_type : MappingType :: Device ,
14531536 numa_node : None ,
@@ -1475,8 +1558,10 @@ mod tests {
14751558 client
14761559 . add_mapping ( MappingParams {
14771560 range : MemoryRange :: new ( 0x10000 ..0x11000 ) ,
1478- mappable,
1479- file_offset : 0 ,
1561+ backing : MappingBacking :: File {
1562+ mappable,
1563+ file_offset : 0 ,
1564+ } ,
14801565 writable : true ,
14811566 mapping_type : MappingType :: Device ,
14821567 numa_node : None ,
0 commit comments