feat(mm): add `get_mode_partial`
Add the `get_mode_partial` function for querying the mode of a range of
pages, and returning the longest subrange of pages that have the same
mode. This is needed for the new behaviour of `FFA_MEM_PERM_GET` added
in v1.3.
Change-Id: I9bdfd7f76c45faec7793dd0023e70409ce5bea0f
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/src/mm.c b/src/mm.c
index 74002c5..f53cfeb 100644
--- a/src/mm.c
+++ b/src/mm.c
@@ -1142,6 +1142,26 @@
return success;
}
+bool mm_vm_get_mode_partial(const struct mm_ptable *ptable, ipaddr_t begin,
+ ipaddr_t end, mm_mode_t *mode, ipaddr_t *end_ret)
+{
+ struct mm_get_attrs_state ret;
+ bool success;
+
+ ret = mm_get_attrs(ptable, ipa_addr(begin), ipa_addr(end));
+ success = ret.got_attrs;
+
+ if (success && mode != NULL) {
+ *mode = arch_mm_stage2_attrs_to_mode(ret.attrs);
+ }
+
+ if (success && end_ret != NULL) {
+ *end_ret = ret.mismatch ? ipa_init(ret.mismatch) : end;
+ }
+
+ return success;
+}
+
/**
* Gets the mode of the given range of virtual addresses if they
* are mapped with the same mode.
@@ -1166,6 +1186,28 @@
return success;
}
+bool mm_get_mode_partial(const struct mm_ptable *ptable, vaddr_t begin,
+ vaddr_t end, mm_mode_t *mode, vaddr_t *end_ret)
+{
+ struct mm_get_attrs_state ret;
+ bool success;
+
+ assert(ptable->stage1);
+
+ ret = mm_get_attrs(ptable, va_addr(begin), va_addr(end));
+ success = ret.got_attrs;
+
+ if (success && mode != NULL) {
+ *mode = arch_mm_stage1_attrs_to_mode(ret.attrs);
+ }
+
+ if (success && end_ret != NULL) {
+ *end_ret = ret.mismatch ? va_init(ret.mismatch) : end;
+ }
+
+ return success;
+}
+
static struct mm_stage1_locked mm_stage1_lock_unsafe(void)
{
return (struct mm_stage1_locked){.ptable = &ptable};