Skip to content

Commit 425fd41

Browse files
fix(broadcast): Fix update broadcast
1 parent 46aeeb0 commit 425fd41

File tree

1 file changed

+37
-13
lines changed

1 file changed

+37
-13
lines changed

src/core/mpu/mem.c

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
292301
static 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

325335
static 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+
469493
bool 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

Comments
 (0)