@@ -295,13 +295,20 @@ impl VmAddressRegion {
295295 let mut guard = self . inner . lock ( ) ;
296296 let inner = guard. as_mut ( ) . ok_or ( ZxError :: BAD_STATE ) ?;
297297 let end_addr = addr + len;
298- // TODO: Partially protect a mapping
298+ // check if there are overlapping subregion
299+ if inner
300+ . children
301+ . iter ( )
302+ . any ( |child| child. end_addr ( ) >= addr && child. addr ( ) <= end_addr)
303+ {
304+ return Err ( ZxError :: INVALID_ARGS ) ;
305+ }
299306 let length: usize = inner
300307 . mappings
301308 . iter ( )
302309 . filter_map ( |map| {
303- if map. addr ( ) >= addr && map. end_addr ( ) <= end_addr {
304- Some ( map. size ( ) )
310+ if map. end_addr ( ) >= addr && map. addr ( ) <= end_addr {
311+ Some ( end_addr . min ( map. end_addr ( ) ) - addr . max ( map . addr ( ) ) )
305312 } else {
306313 None
307314 }
@@ -310,21 +317,23 @@ impl VmAddressRegion {
310317 if length != len {
311318 return Err ( ZxError :: NOT_FOUND ) ;
312319 }
320+ // check if protect flags is valid
313321 if inner
314322 . mappings
315323 . iter ( )
316- . filter ( |map| map. addr ( ) >= addr && map. end_addr ( ) <= end_addr) // get mappings in range: [addr, end_addr]
324+ . filter ( |map| map. end_addr ( ) >= addr && map. addr ( ) <= end_addr) // get mappings in range: [addr, end_addr]
317325 . any ( |map| !map. is_valid_mapping_flags ( flags) )
318- // check if protect flags is valid
319326 {
320327 return Err ( ZxError :: ACCESS_DENIED ) ;
321328 }
322329 inner
323330 . mappings
324331 . iter ( )
325- . filter ( |map| map. addr ( ) >= addr && map. end_addr ( ) <= end_addr)
332+ . filter ( |map| map. end_addr ( ) >= addr && map. addr ( ) <= end_addr)
326333 . for_each ( |map| {
327- map. protect ( flags) ;
334+ let start_index = pages ( addr. max ( map. addr ( ) ) - map. addr ( ) ) ;
335+ let end_index = pages ( end_addr. min ( map. end_addr ( ) ) - map. addr ( ) ) ;
336+ map. protect ( flags, start_index, end_index) ;
328337 } ) ;
329338 Ok ( ( ) )
330339 }
@@ -834,10 +843,10 @@ impl VmMapping {
834843 self . permissions . contains ( flags & MMUFlags :: RXW )
835844 }
836845
837- fn protect ( & self , flags : MMUFlags ) {
846+ fn protect ( & self , flags : MMUFlags , start_index : usize , end_index : usize ) {
838847 let mut inner = self . inner . lock ( ) ;
839848 let mut pg_table = self . page_table . lock ( ) ;
840- for i in 0 .. pages ( inner . size ) {
849+ for i in start_index..end_index {
841850 let mut new_flags = inner. flags [ i] ;
842851 new_flags. remove ( MMUFlags :: RXW ) ;
843852 new_flags. insert ( flags & MMUFlags :: RXW ) ;
0 commit comments