@@ -138,6 +138,21 @@ pub(crate) enum MemoryRegionType {
138138 MappedFile ,
139139}
140140
141+ #[ cfg( target_os = "windows" ) ]
142+ impl MemoryRegionType {
143+ /// Derives the [`SurrogateMapping`] from this region type.
144+ ///
145+ /// `MappedFile` regions use read-only file-backed mappings with no
146+ /// guard pages; all other region types use the standard sandbox
147+ /// shared memory mapping with guard pages.
148+ pub ( crate ) fn surrogate_mapping ( & self ) -> SurrogateMapping {
149+ match self {
150+ MemoryRegionType :: MappedFile => SurrogateMapping :: ReadOnlyFile ,
151+ _ => SurrogateMapping :: SandboxMemory ,
152+ }
153+ }
154+ }
155+
141156/// A trait that distinguishes between different kinds of memory region representations.
142157///
143158/// This trait is used to parameterize [`MemoryRegion_`]
@@ -202,9 +217,6 @@ pub struct HostRegionBase {
202217 /// The offset into file mapping region where this
203218 /// [`HostRegionBase`] is pointing.
204219 pub offset : usize ,
205- /// How this region should be mapped through the surrogate process.
206- /// Controls page protection and guard page behaviour.
207- pub ( crate ) surrogate_mapping : SurrogateMapping ,
208220}
209221#[ cfg( target_os = "windows" ) ]
210222impl std:: hash:: Hash for HostRegionBase {
@@ -216,7 +228,6 @@ impl std::hash::Hash for HostRegionBase {
216228 self . handle_base . hash ( state) ;
217229 self . handle_size . hash ( state) ;
218230 self . offset . hash ( state) ;
219- self . surrogate_mapping . hash ( state) ;
220231 }
221232}
222233#[ cfg( target_os = "windows" ) ]
@@ -242,7 +253,6 @@ impl MemoryRegionKind for HostGuestMemoryRegion {
242253 handle_base : base. handle_base ,
243254 handle_size : base. handle_size ,
244255 offset : base. offset + size,
245- surrogate_mapping : base. surrogate_mapping ,
246256 }
247257 }
248258}
@@ -442,161 +452,3 @@ impl From<&MemoryRegion> for kvm_bindings::kvm_userspace_memory_region {
442452 }
443453 }
444454}
445-
446- #[ cfg( test) ]
447- mod tests {
448- use super :: * ;
449-
450- #[ test]
451- fn memory_region_flags_display ( ) {
452- assert_eq ! ( format!( "{}" , MemoryRegionFlags :: NONE ) , "NONE" ) ;
453- assert_eq ! ( format!( "{}" , MemoryRegionFlags :: READ ) , "READ" ) ;
454- assert_eq ! (
455- format!( "{}" , MemoryRegionFlags :: READ | MemoryRegionFlags :: WRITE ) ,
456- "READ | WRITE"
457- ) ;
458- assert_eq ! (
459- format!(
460- "{}" ,
461- MemoryRegionFlags :: READ | MemoryRegionFlags :: WRITE | MemoryRegionFlags :: EXECUTE
462- ) ,
463- "READ | WRITE | EXECUTE"
464- ) ;
465- }
466-
467- #[ cfg( target_os = "windows" ) ]
468- mod windows_tests {
469- use std:: collections:: HashSet ;
470- use std:: hash:: { DefaultHasher , Hash , Hasher } ;
471-
472- use super :: * ;
473-
474- /// Helper to create a `HostRegionBase` with the given `SurrogateMapping`.
475- fn make_host_region_base ( mapping : SurrogateMapping ) -> HostRegionBase {
476- HostRegionBase {
477- from_handle : windows:: Win32 :: Foundation :: INVALID_HANDLE_VALUE . into ( ) ,
478- handle_base : 0x1000 ,
479- handle_size : 0x2000 ,
480- offset : 0x100 ,
481- surrogate_mapping : mapping,
482- }
483- }
484-
485- fn hash_of ( val : & impl Hash ) -> u64 {
486- let mut hasher = DefaultHasher :: new ( ) ;
487- val. hash ( & mut hasher) ;
488- hasher. finish ( )
489- }
490-
491- #[ test]
492- fn surrogate_mapping_equality ( ) {
493- assert_eq ! (
494- SurrogateMapping :: SandboxMemory ,
495- SurrogateMapping :: SandboxMemory
496- ) ;
497- assert_eq ! (
498- SurrogateMapping :: ReadOnlyFile ,
499- SurrogateMapping :: ReadOnlyFile
500- ) ;
501- assert_ne ! (
502- SurrogateMapping :: SandboxMemory ,
503- SurrogateMapping :: ReadOnlyFile
504- ) ;
505- }
506-
507- #[ test]
508- fn surrogate_mapping_variants_are_distinct ( ) {
509- // Verify the two variants are distinct values that can be
510- // used to key different behaviour in the surrogate pipeline
511- let sandbox = SurrogateMapping :: SandboxMemory ;
512- let readonly = SurrogateMapping :: ReadOnlyFile ;
513- assert_ne ! ( sandbox, readonly) ;
514-
515- // Verify Copy semantics work (enum is Copy + Eq)
516- let copy = sandbox;
517- assert_eq ! ( sandbox, copy) ;
518- }
519-
520- #[ test]
521- fn host_region_base_different_surrogate_mapping_not_equal ( ) {
522- let sandbox = make_host_region_base ( SurrogateMapping :: SandboxMemory ) ;
523- let readonly = make_host_region_base ( SurrogateMapping :: ReadOnlyFile ) ;
524- assert_ne ! ( sandbox, readonly) ;
525- }
526-
527- #[ test]
528- fn host_region_base_different_surrogate_mapping_different_hash ( ) {
529- let sandbox = make_host_region_base ( SurrogateMapping :: SandboxMemory ) ;
530- let readonly = make_host_region_base ( SurrogateMapping :: ReadOnlyFile ) ;
531- assert_ne ! ( hash_of( & sandbox) , hash_of( & readonly) ) ;
532- }
533-
534- #[ test]
535- fn host_region_base_same_surrogate_mapping_equal_and_same_hash ( ) {
536- let a = make_host_region_base ( SurrogateMapping :: SandboxMemory ) ;
537- let b = make_host_region_base ( SurrogateMapping :: SandboxMemory ) ;
538- assert_eq ! ( a, b) ;
539- assert_eq ! ( hash_of( & a) , hash_of( & b) ) ;
540- }
541-
542- #[ test]
543- fn host_region_base_into_usize ( ) {
544- let hrb = make_host_region_base ( SurrogateMapping :: SandboxMemory ) ;
545- let addr: usize = hrb. into ( ) ;
546- assert_eq ! ( addr, 0x1000 + 0x100 ) ; // handle_base + offset
547- }
548-
549- #[ test]
550- fn memory_region_kind_add_preserves_surrogate_mapping ( ) {
551- let base = make_host_region_base ( SurrogateMapping :: ReadOnlyFile ) ;
552- let result = <HostGuestMemoryRegion as MemoryRegionKind >:: add ( base, 0x400 ) ;
553-
554- assert_eq ! ( result. from_handle, base. from_handle) ;
555- assert_eq ! ( result. handle_base, base. handle_base) ;
556- assert_eq ! ( result. handle_size, base. handle_size) ;
557- assert_eq ! ( result. offset, base. offset + 0x400 ) ;
558- assert_eq ! ( result. surrogate_mapping, SurrogateMapping :: ReadOnlyFile ) ;
559- }
560-
561- #[ test]
562- fn host_region_base_works_in_hashset ( ) {
563- let sandbox = make_host_region_base ( SurrogateMapping :: SandboxMemory ) ;
564- let readonly = make_host_region_base ( SurrogateMapping :: ReadOnlyFile ) ;
565-
566- let mut set = HashSet :: new ( ) ;
567- set. insert ( sandbox) ;
568- set. insert ( readonly) ;
569- // Both should be present since they differ by surrogate_mapping
570- assert_eq ! ( set. len( ) , 2 ) ;
571-
572- // Inserting a duplicate should not increase the count
573- set. insert ( make_host_region_base ( SurrogateMapping :: SandboxMemory ) ) ;
574- assert_eq ! ( set. len( ) , 2 ) ;
575- }
576-
577- #[ test]
578- fn memory_region_with_surrogate_mapping_equality ( ) {
579- let base_sandbox = make_host_region_base ( SurrogateMapping :: SandboxMemory ) ;
580- let base_readonly = make_host_region_base ( SurrogateMapping :: ReadOnlyFile ) ;
581-
582- let region_sandbox = MemoryRegion {
583- guest_region : 0x0 ..0x2000 ,
584- host_region : base_sandbox
585- ..<HostGuestMemoryRegion as MemoryRegionKind >:: add ( base_sandbox, 0x2000 ) ,
586- flags : MemoryRegionFlags :: READ ,
587- region_type : MemoryRegionType :: Code ,
588- } ;
589-
590- let region_readonly = MemoryRegion {
591- guest_region : 0x0 ..0x2000 ,
592- host_region : base_readonly
593- ..<HostGuestMemoryRegion as MemoryRegionKind >:: add ( base_readonly, 0x2000 ) ,
594- flags : MemoryRegionFlags :: READ ,
595- region_type : MemoryRegionType :: Code ,
596- } ;
597-
598- // Regions with different surrogate_mapping should not be equal
599- assert_ne ! ( region_sandbox, region_readonly) ;
600- }
601- }
602- }
0 commit comments