@@ -1429,4 +1429,98 @@ mod tests {
14291429 drop ( sbox) ;
14301430 }
14311431 }
1432+
1433+ /// Helper: create a MultiUseSandbox from the simple guest with default config.
1434+ #[ cfg( feature = "trace_guest" ) ]
1435+ fn sandbox_for_gva_tests ( ) -> MultiUseSandbox {
1436+ let path = simple_guest_as_string ( ) . unwrap ( ) ;
1437+ UninitializedSandbox :: new ( GuestBinary :: FilePath ( path) , None )
1438+ . unwrap ( )
1439+ . evolve ( )
1440+ . unwrap ( )
1441+ }
1442+
1443+ /// Helper: read memory at `gva` of length `len` from the guest side via
1444+ /// `ReadMappedBuffer(gva, len, false)` and from the host side via
1445+ /// `read_guest_memory_by_gva`, then assert both views are identical.
1446+ #[ cfg( feature = "trace_guest" ) ]
1447+ fn assert_gva_read_matches ( sbox : & mut MultiUseSandbox , gva : u64 , len : usize ) {
1448+ // Guest reads via its own page tables
1449+ let expected: Vec < u8 > = sbox
1450+ . call ( "ReadMappedBuffer" , ( gva, len as u64 , true ) )
1451+ . unwrap ( ) ;
1452+ assert_eq ! ( expected. len( ) , len) ;
1453+
1454+ // Host reads by walking the same page tables
1455+ let root_pt = sbox. vm . get_root_pt ( ) . unwrap ( ) ;
1456+ let actual = sbox
1457+ . mem_mgr
1458+ . read_guest_memory_by_gva ( gva, len, root_pt)
1459+ . unwrap ( ) ;
1460+
1461+ assert_eq ! (
1462+ actual, expected,
1463+ "read_guest_memory_by_gva at GVA {:#x} (len {}) differs from guest ReadMappedBuffer" ,
1464+ gva, len,
1465+ ) ;
1466+ }
1467+
1468+ /// Test reading a small buffer (< 1 page) from guest memory via GVA.
1469+ /// Uses the guest code section which is already identity-mapped.
1470+ #[ test]
1471+ #[ cfg( feature = "trace_guest" ) ]
1472+ fn read_guest_memory_by_gva_single_page ( ) {
1473+ let mut sbox = sandbox_for_gva_tests ( ) ;
1474+ let code_gva = sbox. mem_mgr . layout . get_guest_code_address ( ) as u64 ;
1475+ assert_gva_read_matches ( & mut sbox, code_gva, 128 ) ;
1476+ }
1477+
1478+ /// Test reading exactly one full page (4096 bytes) from guest memory.
1479+ /// Uses the guest code section
1480+ #[ test]
1481+ #[ cfg( feature = "trace_guest" ) ]
1482+ fn read_guest_memory_by_gva_full_page ( ) {
1483+ let mut sbox = sandbox_for_gva_tests ( ) ;
1484+ let code_gva = sbox. mem_mgr . layout . get_guest_code_address ( ) as u64 ;
1485+ assert_gva_read_matches ( & mut sbox, code_gva, 4096 ) ;
1486+ }
1487+
1488+ /// Test that a read starting at an odd (non-page-aligned) address and
1489+ /// spanning two page boundaries returns correct data.
1490+ #[ test]
1491+ #[ cfg( feature = "trace_guest" ) ]
1492+ fn read_guest_memory_by_gva_unaligned_cross_page ( ) {
1493+ let mut sbox = sandbox_for_gva_tests ( ) ;
1494+ let code_gva = sbox. mem_mgr . layout . get_guest_code_address ( ) as u64 ;
1495+ // Start 1 byte before the second page boundary and read 4097 bytes
1496+ // (spans 2 full page boundaries).
1497+ let start = code_gva + 4096 - 1 ;
1498+ println ! (
1499+ "Testing unaligned cross-page read starting at {:#x} spanning 4097 bytes" ,
1500+ start
1501+ ) ;
1502+ assert_gva_read_matches ( & mut sbox, start, 4097 ) ;
1503+ }
1504+
1505+ /// Test reading exactly two full pages (8192 bytes) from guest memory.
1506+ #[ test]
1507+ #[ cfg( feature = "trace_guest" ) ]
1508+ fn read_guest_memory_by_gva_two_full_pages ( ) {
1509+ let mut sbox = sandbox_for_gva_tests ( ) ;
1510+ let code_gva = sbox. mem_mgr . layout . get_guest_code_address ( ) as u64 ;
1511+ assert_gva_read_matches ( & mut sbox, code_gva, 4096 * 2 ) ;
1512+ }
1513+
1514+ /// Test reading a region that spans across a page boundary: starts
1515+ /// 100 bytes before the end of the first page and reads 200 bytes
1516+ /// into the second page.
1517+ #[ test]
1518+ #[ cfg( feature = "trace_guest" ) ]
1519+ fn read_guest_memory_by_gva_cross_page_boundary ( ) {
1520+ let mut sbox = sandbox_for_gva_tests ( ) ;
1521+ let code_gva = sbox. mem_mgr . layout . get_guest_code_address ( ) as u64 ;
1522+ // Start 100 bytes before the first page boundary, read across it.
1523+ let start = code_gva + 4096 - 100 ;
1524+ assert_gva_read_matches ( & mut sbox, start, 200 ) ;
1525+ }
14321526}
0 commit comments