Skip to content

Commit ce1a02d

Browse files
committed
Verify memory access permissions in PMP regions
Checks if a memory access falls within a configured region by comparing the requested address and size against the region boundaries. When a matching region is found, validates that the region's permissions match the requested operation type.
1 parent 920d586 commit ce1a02d

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

arch/riscv/pmp.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,3 +344,41 @@ int32_t pmp_get_region(const pmp_config_t *config, uint8_t region_idx,
344344

345345
return ERR_OK;
346346
}
347+
348+
int32_t pmp_check_access(const pmp_config_t *config, uint32_t addr,
349+
uint32_t size, uint8_t is_write, uint8_t is_execute)
350+
{
351+
if (!config)
352+
return ERR_PMP_INVALID_REGION;
353+
354+
uint32_t access_end = addr + size;
355+
356+
/* In TOR mode, check all regions in priority order */
357+
for (uint8_t i = 0; i < config->region_count; i++) {
358+
const pmp_region_t *region = &config->regions[i];
359+
360+
/* Skip disabled regions */
361+
if (region->addr_start == 0 && region->addr_end == 0)
362+
continue;
363+
364+
/* Check if access falls within this region */
365+
if (addr >= region->addr_start && access_end <= region->addr_end) {
366+
/* Verify permissions match access type */
367+
uint8_t required_perm = 0;
368+
if (is_write)
369+
required_perm |= PMPCFG_W;
370+
if (is_execute)
371+
required_perm |= PMPCFG_X;
372+
if (!is_write && !is_execute)
373+
required_perm = PMPCFG_R;
374+
375+
if ((region->permissions & required_perm) == required_perm)
376+
return 1; /* Access allowed */
377+
else
378+
return 0; /* Access denied */
379+
}
380+
}
381+
382+
/* Access not covered by any region */
383+
return 0;
384+
}

0 commit comments

Comments
 (0)