Skip to content

Commit fb2c14a

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 81322ae commit fb2c14a

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
@@ -119,3 +119,15 @@ int32_t pmp_init_kernel(pmp_config_t *config);
119119
* Returns 0 on successful recovery, negative error code on failure.
120120
*/
121121
int32_t pmp_handle_access_fault(uint32_t fault_addr, uint8_t is_write);
122+
123+
/* Switches PMP configuration during task context switch.
124+
*
125+
* Evicts the old task's dynamic regions from hardware and loads the new
126+
* task's regions into available PMP slots. Kernel regions marked as locked
127+
* are preserved across all context switches.
128+
*
129+
* @old_mspace : Memory space of task being switched out (can be NULL)
130+
* @new_mspace : Memory space of task being switched in (can be NULL)
131+
* Returns 0 on success, negative error code on failure.
132+
*/
133+
int32_t pmp_switch_context(memspace_t *old_mspace, memspace_t *new_mspace);

0 commit comments

Comments
 (0)