@@ -269,6 +269,15 @@ static void mem_region_broadcast(struct addr_space* as, struct mp_region* mpr, u
269269 }
270270}
271271
272+ static bool mem_broadcast (struct addr_space * as , struct mp_region * mpr , bool broadcast )
273+ {
274+ if (as -> type == AS_HYP && mpr -> as_sec == SEC_HYP_PRIVATE ) {
275+ return false;
276+ }
277+
278+ return broadcast ;
279+ }
280+
272281static bool mem_vmpu_insert_region (struct addr_space * as , mpid_t mpid , struct mp_region * mpr ,
273282 bool broadcast , bool locked )
274283{
@@ -278,7 +287,7 @@ static bool mem_vmpu_insert_region(struct addr_space* as, mpid_t mpid, struct mp
278287
279288 if (mpu_map (as , mpr , locked )) {
280289 mem_vmpu_set_entry (as , mpid , mpr , locked );
281- if (broadcast ) {
290+ if (mem_broadcast ( as , mpr , broadcast ) ) {
282291 mem_region_broadcast (as , mpr , MEM_INSERT_REGION , locked );
283292 }
284293 return true;
@@ -292,14 +301,15 @@ static bool mem_vmpu_update_region(struct addr_space* as, mpid_t mpid, struct mp
292301{
293302 bool merged = false;
294303
295- if (mpu_update (as , & merge_reg )) {
304+ if (mpu_update (as , & merge_reg )) {
296305 struct mpe * mpe = mem_vmpu_get_entry (as , mpid );
297306 mpe -> region = merge_reg ;
298- if (broadcast ) {
307+ if (mem_broadcast ( as , & mpe -> region , broadcast ) ) {
299308 mem_region_broadcast (as , & mpe -> region , MEM_UPDATE_REGION , locked );
300309 }
301310 merged = true;
302311 }
312+ return merged ;
303313}
304314
305315static bool mem_vmpu_remove_region (struct addr_space * as , mpid_t mpid , bool broadcast )
@@ -309,7 +319,7 @@ static bool mem_vmpu_remove_region(struct addr_space* as, mpid_t mpid, bool broa
309319 struct mpe * mpe = mem_vmpu_get_entry (as , mpid );
310320
311321 if ((mpe != NULL ) && (mpe -> state == MPE_S_VALID )) {
312- if (broadcast ) {
322+ if (mem_broadcast ( as , & mpe -> region , broadcast ) ) {
313323 mem_region_broadcast (as , & mpe -> region , MEM_REMOVE_REGION , mpe -> lock );
314324 }
315325 mpu_unmap (as , & mpe -> region );
@@ -338,12 +348,11 @@ static void mem_handle_broadcast_remove(struct addr_space* as, struct mp_region*
338348 }
339349}
340350
341- static void mem_handle_broadcast_update (struct addr_space * as , struct mp_region * mpr )
351+ static void mem_handle_broadcast_update (struct addr_space * as , struct mp_region * mpr , bool locked )
342352{
343- //TODO:ARMV8M - check if this makes sense
353+ // TODO:ARMV8M - check if this makes sense
344354 if (as -> type == AS_HYP ) {
345- mem_unmap_range (& cpu ()-> as , mpr -> base , mpr -> size , false);
346- mem_map (& cpu ()-> as , mpr , false, false);
355+ mem_update (& cpu ()-> as , mpr , false, locked );
347356 } else {
348357 mpu_update (as , mpr );
349358 }
@@ -373,7 +382,7 @@ void mem_handle_broadcast_region(uint32_t event, uint64_t data)
373382 mem_handle_broadcast_remove (as , & sh_reg -> region );
374383 break ;
375384 case MEM_UPDATE_REGION :
376- mem_handle_broadcast_update (as , & sh_reg -> region );
385+ mem_handle_broadcast_update (as , & sh_reg -> region , sh_reg -> lock );
377386 break ;
378387 default :
379388 ERROR ("unknown mem broadcast msg" );
@@ -437,7 +446,7 @@ void mem_vmpu_coalesce_contiguous(struct addr_space* as, bool broadcast, bool lo
437446 .size = prev_reg -> region .size + cur_reg -> region .size ,
438447 .mem_flags = cur_reg -> region .mem_flags ,
439448 };
440- if (mem_vmpu_update_region (as , prev_mpid , merged_reg , broadcast , locked )) {
449+ if (mem_vmpu_update_region (as , prev_mpid , merged_reg , broadcast , locked )) {
441450 mem_vmpu_remove_region (as , cur_mpid , broadcast );
442451 }
443452 } else {
@@ -446,6 +455,21 @@ void mem_vmpu_coalesce_contiguous(struct addr_space* as, bool broadcast, bool lo
446455 }
447456}
448457
458+ bool mem_update (struct addr_space * as , struct mp_region * mpr , bool broadcast , bool locked )
459+ {
460+ mpid_t update_mpid = INVALID_MPID ;
461+ list_foreach (as -> vmpu .ordered_list , struct mpe , cur ) {
462+ if (cur -> region .base == mpr -> base && cur -> region .size != mpr -> size ) {
463+ update_mpid = cur -> mpid ;
464+ break ;
465+ }
466+ }
467+ if (update_mpid != INVALID_MPID ) {
468+ return mem_vmpu_update_region (as , update_mpid , * mpr , broadcast , locked );
469+ }
470+ return false;
471+ }
472+
449473bool mem_map (struct addr_space * as , struct mp_region * mpr , bool broadcast , bool locked )
450474{
451475 bool mapped = false;
@@ -511,21 +535,21 @@ bool mem_unmap_range(struct addr_space* as, vaddr_t vaddr, size_t size, bool bro
511535 size_t top_size = limit >= r_limit ? 0 : r_limit - limit ;
512536 size_t bottom_size = vaddr <= r_base ? 0 : vaddr - r_base ;
513537
514- mem_vmpu_remove_region (as , mpid , true );
538+ mem_vmpu_remove_region (as , mpid , broadcast );
515539
516540 if (top_size > 0 ) {
517541 struct mp_region top = reg ;
518542 top .base = limit ;
519543 top .size = top_size ;
520544 mpid_t top_mpid = mem_vmpu_allocate_entry (as );
521- mem_vmpu_insert_region (as , top_mpid , & top , true , locked );
545+ mem_vmpu_insert_region (as , top_mpid , & top , broadcast , locked );
522546 }
523547
524548 if (bottom_size > 0 ) {
525549 struct mp_region bottom = reg ;
526550 bottom .size = bottom_size ;
527551 mpid_t bottom_mpid = mem_vmpu_allocate_entry (as );
528- mem_vmpu_insert_region (as , bottom_mpid , & bottom , true , locked );
552+ mem_vmpu_insert_region (as , bottom_mpid , & bottom , broadcast , locked );
529553 }
530554
531555 size_t overlap_size = reg .size - top_size - bottom_size ;
0 commit comments