mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
arm/mpu: Find MPU region by range
Implement a function to find the index of a MPU region in the xen_mpumap MPU region array. This function will be used in future commits to implement creating and destroying MPU regions. Signed-off-by: Luca Fancellu <luca.fancellu@arm.com> Signed-off-by: Hari Limaye <hari.limaye@arm.com> Reviewed-by: Michal Orzel <michal.orzel@amd.com>
This commit is contained in:
1 parent
2dee23ad96
commit
01acbb5384
2 files changed
+84
No files matched your search
@@ -10,6 +10,13 @@
|
||||
#include <asm/mm.h>
|
||||
#include <asm/mpu.h>
|
||||
|
||||
#define MPUMAP_REGION_OVERLAP -1
|
||||
#define MPUMAP_REGION_NOTFOUND 0
|
||||
#define MPUMAP_REGION_FOUND 1
|
||||
#define MPUMAP_REGION_INCLUSIVE 2
|
||||
|
||||
#define INVALID_REGION_IDX 0xFFU
|
||||
|
||||
extern struct page_info *frame_table;
|
||||
|
||||
extern uint8_t max_mpu_regions;
|
||||
@@ -75,6 +82,28 @@ void write_protection_region(const pr_t *pr_write, uint8_t sel);
|
||||
*/
|
||||
pr_t pr_of_addr(paddr_t base, paddr_t limit, unsigned int flags);
|
||||
|
||||
/*
|
||||
* Checks whether a given memory range is present in the provided table of
|
||||
* MPU protection regions.
|
||||
*
|
||||
* @param table Array of pr_t protection regions.
|
||||
* @param r_regions Number of elements in `table`.
|
||||
* @param base Start of the memory region to be checked (inclusive).
|
||||
* @param limit End of the memory region to be checked (exclusive).
|
||||
* @param index Set to the index of the region if an exact or inclusive
|
||||
* match is found, and INVALID_REGION otherwise.
|
||||
* @return: Return code indicating the result of the search:
|
||||
* MPUMAP_REGION_NOTFOUND: no part of the range is present in `table`
|
||||
* MPUMAP_REGION_FOUND: found an exact match in `table`
|
||||
* MPUMAP_REGION_INCLUSIVE: found an inclusive match in `table`
|
||||
* MPUMAP_REGION_OVERLAP: found an overlap with a mapping in `table`
|
||||
*
|
||||
* Note: make sure that the range [`base`, `limit`) refers to the memory region
|
||||
* inclusive of `base` and exclusive of `limit`.
|
||||
*/
|
||||
int mpumap_contains_region(pr_t *table, uint8_t nr_regions, paddr_t base,
|
||||
paddr_t limit, uint8_t *index);
|
||||
|
||||
#endif /* __ARM_MPU_MM_H__ */
|
||||
|
||||
/*
|
||||
|
||||
@@ -110,6 +110,61 @@ pr_t pr_of_addr(paddr_t base, paddr_t limit, unsigned int flags)
|
||||
return region;
|
||||
}
|
||||
|
||||
int mpumap_contains_region(pr_t *table, uint8_t nr_regions, paddr_t base,
|
||||
paddr_t limit, uint8_t *index)
|
||||
{
|
||||
ASSERT(index);
|
||||
*index = INVALID_REGION_IDX;
|
||||
|
||||
/*
|
||||
* The caller supplies a half-open interval [base, limit), i.e. limit is the
|
||||
* first byte *after* the region. Require limit strictly greater than base,
|
||||
* which is necessarily a non-empty region.
|
||||
*/
|
||||
ASSERT(base < limit);
|
||||
|
||||
/*
|
||||
* Internally we use inclusive bounds, so convert range to [base, limit-1].
|
||||
* The prior assertion guarantees the subtraction will not underflow.
|
||||
*/
|
||||
limit = limit - 1;
|
||||
|
||||
for ( uint8_t i = 0; i < nr_regions; i++ )
|
||||
{
|
||||
paddr_t iter_base = pr_get_base(&table[i]);
|
||||
paddr_t iter_limit = pr_get_limit(&table[i]);
|
||||
|
||||
/* Skip invalid (disabled) regions */
|
||||
if ( !region_is_valid(&table[i]) )
|
||||
continue;
|
||||
|
||||
/* No match */
|
||||
if ( (iter_limit < base) || (iter_base > limit) )
|
||||
continue;
|
||||
|
||||
/* Exact match */
|
||||
if ( (iter_base == base) && (iter_limit == limit) )
|
||||
{
|
||||
*index = i;
|
||||
return MPUMAP_REGION_FOUND;
|
||||
}
|
||||
|
||||
/* Inclusive match */
|
||||
if ( (base >= iter_base) && (limit <= iter_limit) )
|
||||
{
|
||||
*index = i;
|
||||
return MPUMAP_REGION_INCLUSIVE;
|
||||
}
|
||||
|
||||
/* Overlap */
|
||||
printk("Range %#"PRIpaddr" - %#"PRIpaddr" overlaps with the existing region %#"PRIpaddr" - %#"PRIpaddr"\n",
|
||||
base, limit + 1, iter_base, iter_limit + 1);
|
||||
return MPUMAP_REGION_OVERLAP;
|
||||
}
|
||||
|
||||
return MPUMAP_REGION_NOTFOUND;
|
||||
}
|
||||
|
||||
void __init setup_mm(void)
|
||||
{
|
||||
BUG_ON("unimplemented");
|
||||
|
||||