@@ -24,7 +24,7 @@ use crate::address::Address;
24
24
use crate :: guest_memory:: {
25
25
self , FileOffset , GuestAddress , GuestMemory , GuestMemoryRegion , GuestUsize , MemoryRegionAddress ,
26
26
} ;
27
- use crate :: volatile_memory:: VolatileMemory ;
27
+ use crate :: volatile_memory:: { VolatileMemory , VolatileSlice } ;
28
28
use crate :: Bytes ;
29
29
30
30
#[ cfg( unix) ]
@@ -165,6 +165,7 @@ impl Bytes<MemoryRegionAddress> for GuestRegionMmap {
165
165
fn write ( & self , buf : & [ u8 ] , addr : MemoryRegionAddress ) -> guest_memory:: Result < usize > {
166
166
let maddr = addr. raw_value ( ) as usize ;
167
167
self . as_volatile_slice ( )
168
+ . unwrap ( )
168
169
. write ( buf, maddr)
169
170
. map_err ( Into :: into)
170
171
}
@@ -183,20 +184,23 @@ impl Bytes<MemoryRegionAddress> for GuestRegionMmap {
183
184
fn read ( & self , buf : & mut [ u8 ] , addr : MemoryRegionAddress ) -> guest_memory:: Result < usize > {
184
185
let maddr = addr. raw_value ( ) as usize ;
185
186
self . as_volatile_slice ( )
187
+ . unwrap ( )
186
188
. read ( buf, maddr)
187
189
. map_err ( Into :: into)
188
190
}
189
191
190
192
fn write_slice ( & self , buf : & [ u8 ] , addr : MemoryRegionAddress ) -> guest_memory:: Result < ( ) > {
191
193
let maddr = addr. raw_value ( ) as usize ;
192
194
self . as_volatile_slice ( )
195
+ . unwrap ( )
193
196
. write_slice ( buf, maddr)
194
197
. map_err ( Into :: into)
195
198
}
196
199
197
200
fn read_slice ( & self , buf : & mut [ u8 ] , addr : MemoryRegionAddress ) -> guest_memory:: Result < ( ) > {
198
201
let maddr = addr. raw_value ( ) as usize ;
199
202
self . as_volatile_slice ( )
203
+ . unwrap ( )
200
204
. read_slice ( buf, maddr)
201
205
. map_err ( Into :: into)
202
206
}
@@ -232,6 +236,7 @@ impl Bytes<MemoryRegionAddress> for GuestRegionMmap {
232
236
{
233
237
let maddr = addr. raw_value ( ) as usize ;
234
238
self . as_volatile_slice ( )
239
+ . unwrap ( )
235
240
. read_from :: < F > ( maddr, src, count)
236
241
. map_err ( Into :: into)
237
242
}
@@ -267,6 +272,7 @@ impl Bytes<MemoryRegionAddress> for GuestRegionMmap {
267
272
{
268
273
let maddr = addr. raw_value ( ) as usize ;
269
274
self . as_volatile_slice ( )
275
+ . unwrap ( )
270
276
. read_exact_from :: < F > ( maddr, src, count)
271
277
. map_err ( Into :: into)
272
278
}
@@ -299,6 +305,7 @@ impl Bytes<MemoryRegionAddress> for GuestRegionMmap {
299
305
{
300
306
let maddr = addr. raw_value ( ) as usize ;
301
307
self . as_volatile_slice ( )
308
+ . unwrap ( )
302
309
. write_to :: < F > ( maddr, dst, count)
303
310
. map_err ( Into :: into)
304
311
}
@@ -331,6 +338,7 @@ impl Bytes<MemoryRegionAddress> for GuestRegionMmap {
331
338
{
332
339
let maddr = addr. raw_value ( ) as usize ;
333
340
self . as_volatile_slice ( )
341
+ . unwrap ( )
334
342
. write_all_to :: < F > ( maddr, dst, count)
335
343
. map_err ( Into :: into)
336
344
}
@@ -364,6 +372,15 @@ impl GuestMemoryRegion for GuestRegionMmap {
364
372
. ok_or ( guest_memory:: Error :: InvalidBackendAddress )
365
373
. map ( |addr| self . as_ptr ( ) . wrapping_offset ( addr. raw_value ( ) as isize ) )
366
374
}
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
+ }
367
384
}
368
385
369
386
/// [`GuestMemory`](trait.GuestMemory.html) implementation that mmaps the guest's memory
@@ -972,7 +989,8 @@ mod tests {
972
989
let slice = guest_mem
973
990
. find_region ( GuestAddress ( 0 ) )
974
991
. unwrap ( )
975
- . as_volatile_slice ( ) ;
992
+ . as_volatile_slice ( )
993
+ . unwrap ( ) ;
976
994
977
995
let buf = & mut [ 0 , 0 , 0 , 0 , 0 ] ;
978
996
assert_eq ! ( slice. read( buf, 0 ) . unwrap( ) , 5 ) ;
@@ -1301,4 +1319,79 @@ mod tests {
1301
1319
assert_eq ! ( gm. regions[ 0 ] . start_addr( ) , GuestAddress ( 0x0000 ) ) ;
1302
1320
assert_eq ! ( region. start_addr( ) , GuestAddress ( 0x10_0000 ) ) ;
1303
1321
}
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
+ }
1304
1397
}
0 commit comments