Skip to content

Commit 5dad6eb

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 3269b17 commit 5dad6eb

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

arch/riscv/pmp.h

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

0 commit comments

Comments
 (0)