Skip to content

Commit 414152b

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 8460ff7 commit 414152b

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

arch/riscv/pmp.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,3 +508,39 @@ int32_t pmp_handle_access_fault(uint32_t fault_addr, uint8_t is_write)
508508
int32_t ret = pmp_evict_fpage(victim);
509509
return (ret == 0) ? pmp_load_fpage(target_fpage, victim->pmp_id) : ret;
510510
}
511+
512+
int32_t pmp_switch_context(memspace_t *old_mspace, memspace_t *new_mspace)
513+
{
514+
if (old_mspace == new_mspace)
515+
return 0;
516+
517+
pmp_config_t *config = pmp_get_config();
518+
if (!config)
519+
return -1;
520+
521+
/* Evict old task's dynamic regions */
522+
if (old_mspace) {
523+
for (fpage_t *fp = old_mspace->pmp_first; fp; fp = fp->pmp_next) {
524+
uint8_t region_id = fp->pmp_id;
525+
if (region_id != 0 && !config->regions[region_id].locked) {
526+
pmp_disable_region(config, region_id);
527+
fp->pmp_id = 0;
528+
}
529+
}
530+
}
531+
532+
/* Load new task's regions into available slots */
533+
if (new_mspace) {
534+
uint8_t available_slots = PMP_MAX_REGIONS - config->region_count;
535+
uint8_t loaded_count = 0;
536+
537+
for (fpage_t *fp = new_mspace->first;
538+
fp && loaded_count < available_slots; fp = fp->as_next) {
539+
uint8_t region_idx = config->region_count + loaded_count;
540+
if (pmp_load_fpage(fp, region_idx) == 0)
541+
loaded_count++;
542+
}
543+
}
544+
545+
return 0;
546+
}

arch/riscv/pmp.h

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

0 commit comments

Comments
 (0)