ANDROID: KVM: arm64: Allocate pages for hypervisor FF-A mailboxes

The FF-A proxy code needs to allocate its own buffer pair for
communication with EL3 and for forwarding calls from the host at EL1.

Reserve a couple of pages for this purpose and use them to initialise
the hypervisor's FF-A buffer structure.

Co-developed-by: Will Deacon <willdeacon@google.com>
Signed-off-by: Andrew Walbran <qwandor@google.com>
Bug: 171706629
Signed-off-by: Will Deacon <willdeacon@google.com>
Change-Id: Id72cd7f59be20eb6d1faa6f1c5e64ecc8debf929
This commit is contained in:
Andrew Walbran
2021-12-01 13:46:30 +00:00
committed by Will Deacon
parent a3a8448f92
commit 6c5af2e050
5 changed files with 40 additions and 3 deletions

View File

@@ -322,4 +322,12 @@ static inline unsigned long host_s2_pgtable_pages(void)
return res;
}
#define KVM_FFA_MBOX_NR_PAGES 1
static inline unsigned long hyp_ffa_proxy_pages(void)
{
/* A page each for the hypervisor's RX and TX mailboxes. */
return 2 * KVM_FFA_MBOX_NR_PAGES;
}
#endif /* __ARM64_KVM_PKVM_H__ */

View File

@@ -7,11 +7,18 @@
#define __KVM_HYP_FFA_H
#include <asm/kvm_host.h>
#include <nvhe/spinlock.h>
#define FFA_MIN_FUNC_NUM 0x60
#define FFA_MAX_FUNC_NUM 0x7F
int hyp_ffa_init(void);
struct kvm_ffa_buffers {
hyp_spinlock_t lock;
void *tx;
void *rx;
};
int hyp_ffa_init(void *pages);
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt);
#endif /* __KVM_HYP_FFA_H */

View File

@@ -28,6 +28,8 @@
#include <linux/arm-smccc.h>
#include <linux/arm_ffa.h>
#include <asm/kvm_pkvm.h>
#include <nvhe/ffa.h>
#include <nvhe/trap_handler.h>
@@ -37,6 +39,13 @@
*/
#define HOST_FFA_ID 0
/*
* Note that we don't currently lock these buffers explicitly, instead
* relying on the locking of the host FFA buffers as we only have one
* client.
*/
static struct kvm_ffa_buffers ffa_buffers;
static void ffa_to_smccc_error(struct arm_smccc_res *res, u64 ffa_errno)
{
*res = (struct arm_smccc_res) {
@@ -162,7 +171,7 @@ out_handled:
return true;
}
int hyp_ffa_init(void)
int hyp_ffa_init(void *pages)
{
struct arm_smccc_res res;
@@ -183,5 +192,11 @@ int hyp_ffa_init(void)
if (res.a2 != HOST_FFA_ID)
return -EINVAL;
ffa_buffers = (struct kvm_ffa_buffers) {
.lock = __HYP_SPIN_LOCK_UNLOCKED,
.tx = pages,
.rx = pages + (KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE),
};
return 0;
}

View File

@@ -31,6 +31,7 @@ phys_addr_t pvmfw_size;
static void *vmemmap_base;
static void *hyp_pgt_base;
static void *host_s2_pgt_base;
static void *ffa_proxy_pages;
static struct kvm_pgtable_mm_ops pkvm_pgtable_mm_ops;
static struct hyp_pool hpool;
@@ -60,6 +61,11 @@ static int divide_memory_pool(void *virt, unsigned long size)
if (!host_s2_pgt_base)
return -ENOMEM;
nr_pages = hyp_ffa_proxy_pages();
ffa_proxy_pages = hyp_early_alloc_contig(nr_pages);
if (!ffa_proxy_pages)
return -ENOMEM;
return 0;
}
@@ -332,7 +338,7 @@ void __noreturn __pkvm_init_finalise(void)
if (ret)
goto out;
ret = hyp_ffa_init();
ret = hyp_ffa_init(ffa_proxy_pages);
if (ret)
goto out;
out:

View File

@@ -82,6 +82,7 @@ void __init kvm_hyp_reserve(void)
hyp_mem_pages += host_s2_pgtable_pages();
hyp_mem_pages += hyp_shadow_table_pages(KVM_SHADOW_VM_SIZE);
hyp_mem_pages += hyp_vmemmap_pages(STRUCT_HYP_PAGE_SIZE);
hyp_mem_pages += hyp_ffa_proxy_pages();
/*
* Try to allocate a PMD-aligned region to reduce TLB pressure once