@@ -289,6 +289,15 @@ static void mem_region_broadcast(struct addr_space* as, struct mp_region* mpr, u
289289 }
290290}
291291
292+ static bool mem_broadcast (struct addr_space * as , struct mp_region * mpr , bool broadcast )
293+ {
294+ if (as -> type == AS_HYP && mpr -> as_sec == SEC_HYP_PRIVATE ) {
295+ return false;
296+ }
297+
298+ return broadcast ;
299+ }
300+
292301static bool mem_vmpu_insert_region (struct addr_space * as , mpid_t mpid , struct mp_region * mpr ,
293302 bool broadcast , bool locked )
294303{
@@ -298,7 +307,7 @@ static bool mem_vmpu_insert_region(struct addr_space* as, mpid_t mpid, struct mp
298307
299308 if (mpu_map (as , mpr , locked )) {
300309 mem_vmpu_set_entry (as , mpid , mpr , locked );
301- if (broadcast ) {
310+ if (mem_broadcast ( as , mpr , broadcast ) ) {
302311 mem_region_broadcast (as , mpr , MEM_INSERT_REGION , locked );
303312 }
304313 return true;
@@ -312,14 +321,15 @@ static bool mem_vmpu_update_region(struct addr_space* as, mpid_t mpid, struct mp
312321{
313322 bool merged = false;
314323
315- if (mpu_update (as , & merge_reg )) {
324+ if (mpu_update (as , & merge_reg )) {
316325 struct mpe * mpe = mem_vmpu_get_entry (as , mpid );
317326 mpe -> region = merge_reg ;
318- if (broadcast ) {
327+ if (mem_broadcast ( as , & mpe -> region , broadcast ) ) {
319328 mem_region_broadcast (as , & mpe -> region , MEM_UPDATE_REGION , locked );
320329 }
321330 merged = true;
322331 }
332+ return merged ;
323333}
324334
325335static bool mem_vmpu_remove_region (struct addr_space * as , mpid_t mpid , bool broadcast )
@@ -329,7 +339,7 @@ static bool mem_vmpu_remove_region(struct addr_space* as, mpid_t mpid, bool broa
329339 struct mpe * mpe = mem_vmpu_get_entry (as , mpid );
330340
331341 if ((mpe != NULL ) && (mpe -> state == MPE_S_VALID )) {
332- if (broadcast ) {
342+ if (mem_broadcast ( as , & mpe -> region , broadcast ) ) {
333343 mem_region_broadcast (as , & mpe -> region , MEM_REMOVE_REGION , mpe -> lock );
334344 }
335345 mpu_unmap (as , & mpe -> region );
@@ -358,12 +368,11 @@ static void mem_handle_broadcast_remove(struct addr_space* as, struct mp_region*
358368 }
359369}
360370
361- static void mem_handle_broadcast_update (struct addr_space * as , struct mp_region * mpr )
371+ static void mem_handle_broadcast_update (struct addr_space * as , struct mp_region * mpr , bool locked )
362372{
363- //TODO:ARMV8M - check if this makes sense
373+ // TODO:ARMV8M - check if this makes sense
364374 if (as -> type == AS_HYP ) {
365- mem_unmap_range (& cpu ()-> as , mpr -> base , mpr -> size , false);
366- mem_map (& cpu ()-> as , mpr , false, false);
375+ mem_update (& cpu ()-> as , mpr , false, locked );
367376 } else {
368377 mpu_update (as , mpr );
369378 }
@@ -393,7 +402,7 @@ void mem_handle_broadcast_region(uint32_t event, uint64_t data)
393402 mem_handle_broadcast_remove (as , & sh_reg -> region );
394403 break ;
395404 case MEM_UPDATE_REGION :
396- mem_handle_broadcast_update (as , & sh_reg -> region );
405+ mem_handle_broadcast_update (as , & sh_reg -> region , sh_reg -> lock );
397406 break ;
398407 default :
399408 ERROR ("unknown mem broadcast msg" );
@@ -457,7 +466,7 @@ void mem_vmpu_coalesce_contiguous(struct addr_space* as, bool broadcast, bool lo
457466 .size = prev_reg -> region .size + cur_reg -> region .size ,
458467 .mem_flags = cur_reg -> region .mem_flags ,
459468 };
460- if (mem_vmpu_update_region (as , prev_mpid , merged_reg , broadcast , locked )) {
469+ if (mem_vmpu_update_region (as , prev_mpid , merged_reg , broadcast , locked )) {
461470 mem_vmpu_remove_region (as , cur_mpid , broadcast );
462471 }
463472 } else {
@@ -466,6 +475,21 @@ void mem_vmpu_coalesce_contiguous(struct addr_space* as, bool broadcast, bool lo
466475 }
467476}
468477
478+ bool mem_update (struct addr_space * as , struct mp_region * mpr , bool broadcast , bool locked )
479+ {
480+ mpid_t update_mpid = INVALID_MPID ;
481+ list_foreach (as -> vmpu .ordered_list , struct mpe , cur ) {
482+ if (cur -> region .base == mpr -> base && cur -> region .size != mpr -> size ) {
483+ update_mpid = cur -> mpid ;
484+ break ;
485+ }
486+ }
487+ if (update_mpid != INVALID_MPID ) {
488+ return mem_vmpu_update_region (as , update_mpid , * mpr , broadcast , locked );
489+ }
490+ return false;
491+ }
492+
469493bool mem_map (struct addr_space * as , struct mp_region * mpr , bool broadcast , bool locked )
470494{
471495 bool mapped = false;
@@ -531,21 +555,21 @@ bool mem_unmap_range(struct addr_space* as, vaddr_t vaddr, size_t size, bool bro
531555 size_t top_size = limit >= r_limit ? 0 : r_limit - limit ;
532556 size_t bottom_size = vaddr <= r_base ? 0 : vaddr - r_base ;
533557
534- mem_vmpu_remove_region (as , mpid , true );
558+ mem_vmpu_remove_region (as , mpid , broadcast );
535559
536560 if (top_size > 0 ) {
537561 struct mp_region top = reg ;
538562 top .base = limit ;
539563 top .size = top_size ;
540564 mpid_t top_mpid = mem_vmpu_allocate_entry (as );
541- mem_vmpu_insert_region (as , top_mpid , & top , true , locked );
565+ mem_vmpu_insert_region (as , top_mpid , & top , broadcast , locked );
542566 }
543567
544568 if (bottom_size > 0 ) {
545569 struct mp_region bottom = reg ;
546570 bottom .size = bottom_size ;
547571 mpid_t bottom_mpid = mem_vmpu_allocate_entry (as );
548- mem_vmpu_insert_region (as , bottom_mpid , & bottom , true , locked );
572+ mem_vmpu_insert_region (as , bottom_mpid , & bottom , broadcast , locked );
549573 }
550574
551575 size_t overlap_size = reg .size - top_size - bottom_size ;
0 commit comments