feat(api): add page count param/return to `FFA_MEM_PERM_GET`
The v1.3 specification adds a new "page count" argument and return value
to the `FFA_MEM_PERM_GET` ABI. Update `api_ffa_mem_perm_get` and
`ffa_mem_perm_get` accordingly.
Change-Id: I21a068bce2275caf5b9278ac891d686e76615560
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/src/api.c b/src/api.c
index 381cc42..8b09306 100644
--- a/src/api.c
+++ b/src/api.c
@@ -15,6 +15,7 @@
#include "hf/arch/other_world.h"
#include "hf/arch/timer.h"
+#include "hf/addr.h"
#include "hf/bits.h"
#include "hf/check.h"
#include "hf/dlog.h"
@@ -4569,13 +4570,23 @@
return result;
}
-struct ffa_value api_ffa_mem_perm_get(vaddr_t base_addr, struct vcpu *current)
+struct ffa_value api_ffa_mem_perm_get(vaddr_t base_addr, uint32_t page_count,
+ struct vcpu *current)
{
struct vm_locked vm_locked;
struct ffa_value ret;
bool mode_ret;
uint32_t mode;
- vaddr_t end_addr = va_add(base_addr, PAGE_SIZE);
+ vaddr_t end_addr;
+
+ /**
+ * The size of the memory region is calculated as (page_count + 1) *
+ * granule size to ensure backwards compatability: v1.2 or earlier
+ * callers, who leave `arg2` as 0, will get the correct behaviour
+ * (querying a single page).
+ */
+ page_count += 1;
+ end_addr = va_add(base_addr, page_count * PAGE_SIZE);
if (!ffa_memory_is_mem_perm_get_valid(current)) {
dlog_error("FFA_MEM_PERM_GET: not allowed\n");
@@ -4605,8 +4616,10 @@
mode_ret =
mm_get_mode(&vm_locked.vm->ptable, base_addr, end_addr, &mode);
if (!mode_ret || (mode & MM_MODE_INVALID)) {
- dlog_error("FFA_MEM_PERM_GET: cannot find page at %#016lx\n",
- va_addr(base_addr));
+ dlog_error(
+ "FFA_MEM_PERM_GET: cannot find permission for range "
+ "%#016lx - %#016lx\n",
+ va_addr(base_addr), va_addr(end_addr));
ret = ffa_error(FFA_INVALID_PARAMETERS);
goto out;
}
@@ -4624,7 +4637,8 @@
ret = (struct ffa_value){
.func = FFA_SUCCESS_32,
- .arg3 = 1,
+ /* Same logic as for the input page count. */
+ .arg3 = page_count - 1,
};
if (mode & MM_MODE_W) {