Skip to content

Commit 731f5d5

Browse files
fix(broadcast): Fix update broadcast
Signed-off-by: Miguel Silva <[email protected]>
1 parent c3bce24 commit 731f5d5

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
@@ -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+
272281
static 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

305315
static 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+
449473
bool 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

Comments
 (0)