@@ -24,7 +24,7 @@ use crate::address::Address;
2424use crate :: guest_memory:: {
2525 self , FileOffset , GuestAddress , GuestMemory , GuestMemoryRegion , GuestUsize , MemoryRegionAddress ,
2626} ;
27- use crate :: volatile_memory:: VolatileMemory ;
27+ use crate :: volatile_memory:: { VolatileMemory , VolatileSlice } ;
2828use crate :: Bytes ;
2929
3030#[ cfg( unix) ]
@@ -165,6 +165,7 @@ impl Bytes<MemoryRegionAddress> for GuestRegionMmap {
165165 fn write ( & self , buf : & [ u8 ] , addr : MemoryRegionAddress ) -> guest_memory:: Result < usize > {
166166 let maddr = addr. raw_value ( ) as usize ;
167167 self . as_volatile_slice ( )
168+ . unwrap ( )
168169 . write ( buf, maddr)
169170 . map_err ( Into :: into)
170171 }
@@ -183,20 +184,23 @@ impl Bytes<MemoryRegionAddress> for GuestRegionMmap {
183184 fn read ( & self , buf : & mut [ u8 ] , addr : MemoryRegionAddress ) -> guest_memory:: Result < usize > {
184185 let maddr = addr. raw_value ( ) as usize ;
185186 self . as_volatile_slice ( )
187+ . unwrap ( )
186188 . read ( buf, maddr)
187189 . map_err ( Into :: into)
188190 }
189191
190192 fn write_slice ( & self , buf : & [ u8 ] , addr : MemoryRegionAddress ) -> guest_memory:: Result < ( ) > {
191193 let maddr = addr. raw_value ( ) as usize ;
192194 self . as_volatile_slice ( )
195+ . unwrap ( )
193196 . write_slice ( buf, maddr)
194197 . map_err ( Into :: into)
195198 }
196199
197200 fn read_slice ( & self , buf : & mut [ u8 ] , addr : MemoryRegionAddress ) -> guest_memory:: Result < ( ) > {
198201 let maddr = addr. raw_value ( ) as usize ;
199202 self . as_volatile_slice ( )
203+ . unwrap ( )
200204 . read_slice ( buf, maddr)
201205 . map_err ( Into :: into)
202206 }
@@ -232,6 +236,7 @@ impl Bytes<MemoryRegionAddress> for GuestRegionMmap {
232236 {
233237 let maddr = addr. raw_value ( ) as usize ;
234238 self . as_volatile_slice ( )
239+ . unwrap ( )
235240 . read_from :: < F > ( maddr, src, count)
236241 . map_err ( Into :: into)
237242 }
@@ -267,6 +272,7 @@ impl Bytes<MemoryRegionAddress> for GuestRegionMmap {
267272 {
268273 let maddr = addr. raw_value ( ) as usize ;
269274 self . as_volatile_slice ( )
275+ . unwrap ( )
270276 . read_exact_from :: < F > ( maddr, src, count)
271277 . map_err ( Into :: into)
272278 }
@@ -299,6 +305,7 @@ impl Bytes<MemoryRegionAddress> for GuestRegionMmap {
299305 {
300306 let maddr = addr. raw_value ( ) as usize ;
301307 self . as_volatile_slice ( )
308+ . unwrap ( )
302309 . write_to :: < F > ( maddr, dst, count)
303310 . map_err ( Into :: into)
304311 }
@@ -331,6 +338,7 @@ impl Bytes<MemoryRegionAddress> for GuestRegionMmap {
331338 {
332339 let maddr = addr. raw_value ( ) as usize ;
333340 self . as_volatile_slice ( )
341+ . unwrap ( )
334342 . write_all_to :: < F > ( maddr, dst, count)
335343 . map_err ( Into :: into)
336344 }
@@ -364,6 +372,15 @@ impl GuestMemoryRegion for GuestRegionMmap {
364372 . ok_or ( guest_memory:: Error :: InvalidBackendAddress )
365373 . map ( |addr| self . as_ptr ( ) . wrapping_offset ( addr. raw_value ( ) as isize ) )
366374 }
375+
376+ fn get_slice (
377+ & self ,
378+ offset : MemoryRegionAddress ,
379+ count : usize ,
380+ ) -> guest_memory:: Result < VolatileSlice > {
381+ let slice = self . mapping . get_slice ( offset. raw_value ( ) as usize , count) ?;
382+ Ok ( slice)
383+ }
367384}
368385
369386/// [`GuestMemory`](trait.GuestMemory.html) implementation that mmaps the guest's memory
@@ -972,7 +989,8 @@ mod tests {
972989 let slice = guest_mem
973990 . find_region ( GuestAddress ( 0 ) )
974991 . unwrap ( )
975- . as_volatile_slice ( ) ;
992+ . as_volatile_slice ( )
993+ . unwrap ( ) ;
976994
977995 let buf = & mut [ 0 , 0 , 0 , 0 , 0 ] ;
978996 assert_eq ! ( slice. read( buf, 0 ) . unwrap( ) , 5 ) ;
@@ -1301,4 +1319,79 @@ mod tests {
13011319 assert_eq ! ( gm. regions[ 0 ] . start_addr( ) , GuestAddress ( 0x0000 ) ) ;
13021320 assert_eq ! ( region. start_addr( ) , GuestAddress ( 0x10_0000 ) ) ;
13031321 }
1322+
1323+ #[ test]
1324+ fn test_guest_memory_mmap_get_slice ( ) {
1325+ let region_addr = GuestAddress ( 0 ) ;
1326+ let region_size = 0x400 ;
1327+ let region =
1328+ GuestRegionMmap :: new ( MmapRegion :: new ( region_size) . unwrap ( ) , region_addr) . unwrap ( ) ;
1329+
1330+ // Normal case.
1331+ let slice_addr = MemoryRegionAddress ( 0x100 ) ;
1332+ let slice_size = 0x200 ;
1333+ let slice = region. get_slice ( slice_addr, slice_size) . unwrap ( ) ;
1334+ assert_eq ! ( slice. len( ) , slice_size) ;
1335+
1336+ // Empty slice.
1337+ let slice_addr = MemoryRegionAddress ( 0x200 ) ;
1338+ let slice_size = 0x0 ;
1339+ let slice = region. get_slice ( slice_addr, slice_size) . unwrap ( ) ;
1340+ assert ! ( slice. is_empty( ) ) ;
1341+
1342+ // Error case when slice_size is beyond the boundary.
1343+ let slice_addr = MemoryRegionAddress ( 0x300 ) ;
1344+ let slice_size = 0x200 ;
1345+ assert ! ( region. get_slice( slice_addr, slice_size) . is_err( ) ) ;
1346+ }
1347+
1348+ #[ test]
1349+ fn test_guest_memory_mmap_as_volatile_slice ( ) {
1350+ let region_addr = GuestAddress ( 0 ) ;
1351+ let region_size = 0x400 ;
1352+ let region =
1353+ GuestRegionMmap :: new ( MmapRegion :: new ( region_size) . unwrap ( ) , region_addr) . unwrap ( ) ;
1354+
1355+ // Test slice length.
1356+ let slice = region. as_volatile_slice ( ) . unwrap ( ) ;
1357+ assert_eq ! ( slice. len( ) , region_size) ;
1358+
1359+ // Test slice data.
1360+ let v = 0x1234_5678u32 ;
1361+ let r = slice. get_ref :: < u32 > ( 0x200 ) . unwrap ( ) ;
1362+ r. store ( v) ;
1363+ assert_eq ! ( r. load( ) , v) ;
1364+ }
1365+
1366+ #[ test]
1367+ fn test_guest_memory_get_slice ( ) {
1368+ let start_addr1 = GuestAddress ( 0 ) ;
1369+ let start_addr2 = GuestAddress ( 0x800 ) ;
1370+ let guest_mem =
1371+ GuestMemoryMmap :: from_ranges ( & [ ( start_addr1, 0x400 ) , ( start_addr2, 0x400 ) ] ) . unwrap ( ) ;
1372+
1373+ // Normal cases.
1374+ let slice_size = 0x200 ;
1375+ let slice = guest_mem
1376+ . get_slice ( GuestAddress ( 0x100 ) , slice_size)
1377+ . unwrap ( ) ;
1378+ assert_eq ! ( slice. len( ) , slice_size) ;
1379+
1380+ let slice_size = 0x400 ;
1381+ let slice = guest_mem
1382+ . get_slice ( GuestAddress ( 0x800 ) , slice_size)
1383+ . unwrap ( ) ;
1384+ assert_eq ! ( slice. len( ) , slice_size) ;
1385+
1386+ // Empty slice.
1387+ assert ! ( guest_mem
1388+ . get_slice( GuestAddress ( 0x900 ) , 0 )
1389+ . unwrap( )
1390+ . is_empty( ) ) ;
1391+
1392+ // Error cases, wrong size or base address.
1393+ assert ! ( guest_mem. get_slice( GuestAddress ( 0 ) , 0x500 ) . is_err( ) ) ;
1394+ assert ! ( guest_mem. get_slice( GuestAddress ( 0x600 ) , 0x100 ) . is_err( ) ) ;
1395+ assert ! ( guest_mem. get_slice( GuestAddress ( 0xc00 ) , 0x100 ) . is_err( ) ) ;
1396+ }
13041397}
0 commit comments