Skip to content

Commit 48149d4

Browse files
committed
Implement PMP context switching for task isolation
Add per-task memory space switching during context transitions. Evicts old task's dynamic regions and loads new task's regions into available hardware slots while preserving locked kernel regions.
1 parent 70be3d9 commit 48149d4

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

arch/riscv/pmp.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,3 +425,38 @@ int32_t pmp_handle_access_fault(uint32_t fault_addr, uint8_t is_write)
425425
int32_t ret = pmp_evict_fpage(victim);
426426
return (ret == 0) ? pmp_load_fpage(target_fpage, victim->pmp_id) : ret;
427427
}
428+
429+
int32_t pmp_switch_context(memspace_t *old_mspace, memspace_t *new_mspace)
430+
{
431+
if (old_mspace == new_mspace)
432+
return 0;
433+
434+
pmp_config_t *config = pmp_get_config();
435+
if (!config)
436+
return -1;
437+
438+
/* Evict old task's dynamic regions */
439+
if (old_mspace) {
440+
for (fpage_t *fp = old_mspace->pmp_first; fp; fp = fp->pmp_next) {
441+
uint8_t region_id = fp->pmp_id;
442+
if (region_id != 0 && !config->regions[region_id].locked) {
443+
pmp_disable_region(config, region_id);
444+
fp->pmp_id = 0;
445+
}
446+
}
447+
}
448+
449+
/* Load new task's regions into available slots */
450+
if (new_mspace) {
451+
uint8_t available_slots = PMP_MAX_REGIONS - config->region_count;
452+
uint8_t loaded_count = 0;
453+
454+
for (fpage_t *fp = new_mspace->first; fp && loaded_count < available_slots; fp = fp->as_next) {
455+
uint8_t region_idx = config->region_count + loaded_count;
456+
if (pmp_load_fpage(fp, region_idx) == 0)
457+
loaded_count++;
458+
}
459+
}
460+
461+
return 0;
462+
}

arch/riscv/pmp.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,15 @@ int32_t pmp_init_kernel(pmp_config_t *config);
121121
* Returns 0 on successful recovery, negative error code on failure.
122122
*/
123123
int32_t pmp_handle_access_fault(uint32_t fault_addr, uint8_t is_write);
124+
125+
/* Switches PMP configuration during task context switch.
126+
*
127+
* Evicts the old task's dynamic regions from hardware and loads the new
128+
* task's regions into available PMP slots. Kernel regions marked as locked
129+
* are preserved across all context switches.
130+
*
131+
* @old_mspace : Memory space of task being switched out (can be NULL)
132+
* @new_mspace : Memory space of task being switched in (can be NULL)
133+
* Returns 0 on success, negative error code on failure.
134+
*/
135+
int32_t pmp_switch_context(memspace_t *old_mspace, memspace_t *new_mspace);

0 commit comments

Comments
 (0)