@@ -65,57 +65,6 @@ pub(crate) fn compact_page_frame_numbers(v: &mut [u32]) -> Vec<(u32, u32)> {
6565 result
6666}
6767
68- pub ( crate ) fn remove_range (
69- guest_memory : & GuestMemoryMmap ,
70- range : ( GuestAddress , u64 ) ,
71- restored_from_file : bool ,
72- ) -> Result < ( ) , RemoveRegionError > {
73- let ( guest_address, range_len) = range;
74-
75- if let Some ( region) = guest_memory. find_region ( guest_address) {
76- if guest_address. 0 + range_len > region. start_addr ( ) . 0 + region. len ( ) {
77- return Err ( RemoveRegionError :: MalformedRange ) ;
78- }
79- let phys_address = guest_memory
80- . get_host_address ( guest_address)
81- . map_err ( |_| RemoveRegionError :: AddressTranslation ) ?;
82-
83- // Mmap a new anonymous region over the present one in order to create a hole.
84- // This workaround is (only) needed after resuming from a snapshot because the guest memory
85- // is mmaped from file as private and there is no `madvise` flag that works for this case.
86- if restored_from_file {
87- // SAFETY: The address and length are known to be valid.
88- let ret = unsafe {
89- libc:: mmap (
90- phys_address. cast ( ) ,
91- u64_to_usize ( range_len) ,
92- libc:: PROT_READ | libc:: PROT_WRITE ,
93- libc:: MAP_FIXED | libc:: MAP_ANONYMOUS | libc:: MAP_PRIVATE ,
94- -1 ,
95- 0 ,
96- )
97- } ;
98- if ret == libc:: MAP_FAILED {
99- return Err ( RemoveRegionError :: MmapFail ( io:: Error :: last_os_error ( ) ) ) ;
100- }
101- } ;
102-
103- // Madvise the region in order to mark it as not used.
104- // SAFETY: The address and length are known to be valid.
105- let ret = unsafe {
106- let range_len = u64_to_usize ( range_len) ;
107- libc:: madvise ( phys_address. cast ( ) , range_len, libc:: MADV_DONTNEED )
108- } ;
109- if ret < 0 {
110- return Err ( RemoveRegionError :: MadviseFail ( io:: Error :: last_os_error ( ) ) ) ;
111- }
112-
113- Ok ( ( ) )
114- } else {
115- Err ( RemoveRegionError :: RegionNotFound )
116- }
117- }
118-
11968#[ cfg( test) ]
12069mod tests {
12170 use std:: fmt:: Debug ;
@@ -174,88 +123,6 @@ mod tests {
174123 ) ;
175124 }
176125
177- #[ test]
178- fn test_remove_range ( ) {
179- let page_size: usize = 0x1000 ;
180- let mem = single_region_mem ( 2 * page_size) ;
181-
182- // Fill the memory with ones.
183- let ones = vec ! [ 1u8 ; 2 * page_size] ;
184- mem. write ( & ones[ ..] , GuestAddress ( 0 ) ) . unwrap ( ) ;
185-
186- // Remove the first page.
187- remove_range ( & mem, ( GuestAddress ( 0 ) , page_size as u64 ) , false ) . unwrap ( ) ;
188-
189- // Check that the first page is zeroed.
190- let mut actual_page = vec ! [ 0u8 ; page_size] ;
191- mem. read ( actual_page. as_mut_slice ( ) , GuestAddress ( 0 ) )
192- . unwrap ( ) ;
193- assert_eq ! ( vec![ 0u8 ; page_size] , actual_page) ;
194- // Check that the second page still contains ones.
195- mem. read ( actual_page. as_mut_slice ( ) , GuestAddress ( page_size as u64 ) )
196- . unwrap ( ) ;
197- assert_eq ! ( vec![ 1u8 ; page_size] , actual_page) ;
198-
199- // Malformed range: the len is too big.
200- assert_match ! (
201- remove_range( & mem, ( GuestAddress ( 0 ) , 0x10000 ) , false ) . unwrap_err( ) ,
202- RemoveRegionError :: MalformedRange
203- ) ;
204-
205- // Region not mapped.
206- assert_match ! (
207- remove_range( & mem, ( GuestAddress ( 0x10000 ) , 0x10 ) , false ) . unwrap_err( ) ,
208- RemoveRegionError :: RegionNotFound
209- ) ;
210-
211- // Madvise fail: the guest address is not aligned to the page size.
212- assert_match ! (
213- remove_range( & mem, ( GuestAddress ( 0x20 ) , page_size as u64 ) , false ) . unwrap_err( ) ,
214- RemoveRegionError :: MadviseFail ( _)
215- ) ;
216- }
217-
218- #[ test]
219- fn test_remove_range_on_restored ( ) {
220- let page_size: usize = 0x1000 ;
221- let mem = single_region_mem ( 2 * page_size) ;
222-
223- // Fill the memory with ones.
224- let ones = vec ! [ 1u8 ; 2 * page_size] ;
225- mem. write ( & ones[ ..] , GuestAddress ( 0 ) ) . unwrap ( ) ;
226-
227- // Remove the first page.
228- remove_range ( & mem, ( GuestAddress ( 0 ) , page_size as u64 ) , true ) . unwrap ( ) ;
229-
230- // Check that the first page is zeroed.
231- let mut actual_page = vec ! [ 0u8 ; page_size] ;
232- mem. read ( actual_page. as_mut_slice ( ) , GuestAddress ( 0 ) )
233- . unwrap ( ) ;
234- assert_eq ! ( vec![ 0u8 ; page_size] , actual_page) ;
235- // Check that the second page still contains ones.
236- mem. read ( actual_page. as_mut_slice ( ) , GuestAddress ( page_size as u64 ) )
237- . unwrap ( ) ;
238- assert_eq ! ( vec![ 1u8 ; page_size] , actual_page) ;
239-
240- // Malformed range: the len is too big.
241- assert_match ! (
242- remove_range( & mem, ( GuestAddress ( 0 ) , 0x10000 ) , true ) . unwrap_err( ) ,
243- RemoveRegionError :: MalformedRange
244- ) ;
245-
246- // Region not mapped.
247- assert_match ! (
248- remove_range( & mem, ( GuestAddress ( 0x10000 ) , 0x10 ) , true ) . unwrap_err( ) ,
249- RemoveRegionError :: RegionNotFound
250- ) ;
251-
252- // Mmap fail: the guest address is not aligned to the page size.
253- assert_match ! (
254- remove_range( & mem, ( GuestAddress ( 0x20 ) , page_size as u64 ) , true ) . unwrap_err( ) ,
255- RemoveRegionError :: MmapFail ( _)
256- ) ;
257- }
258-
259126 /// -------------------------------------
260127 /// BEGIN PROPERTY BASED TESTING
261128 use proptest:: prelude:: * ;
0 commit comments