Commit 634d90cf authored by Will Deacon's avatar Will Deacon Committed by Oliver Upton
Browse files

KVM: arm64: Handle FFA_MEM_LEND calls from the host



Handle FFA_MEM_LEND calls from the host by treating them identically to
FFA_MEM_SHARE calls for the purposes of the host stage-2 page-table, but
forwarding on the original request to EL3.

Signed-off-by: default avatarWill Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20230523101828.7328-9-will@kernel.org


Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
parent 0e3bcb49
Loading
Loading
Loading
Loading
+15 −7
Original line number Diff line number Diff line
@@ -116,10 +116,10 @@ static int ffa_unmap_hyp_buffers(void)
	return res.a0 == FFA_SUCCESS ? FFA_RET_SUCCESS : res.a2;
}

static void ffa_mem_share(struct arm_smccc_res *res, u32 len, u32 fraglen)
static void ffa_mem_xfer(struct arm_smccc_res *res, u64 func_id, u32 len,
			  u32 fraglen)
{
	arm_smccc_1_1_smc(FFA_FN64_MEM_SHARE,
			  len, fraglen,
	arm_smccc_1_1_smc(func_id, len, fraglen,
			  0, 0, 0, 0, 0,
			  res);
}
@@ -321,7 +321,8 @@ static int ffa_host_unshare_ranges(struct ffa_mem_region_addr_range *ranges,
	return ret;
}

static void do_ffa_mem_share(struct arm_smccc_res *res,
static __always_inline void do_ffa_mem_xfer(const u64 func_id,
					    struct arm_smccc_res *res,
					    struct kvm_cpu_context *ctxt)
{
	DECLARE_REG(u32, len, ctxt, 1);
@@ -333,6 +334,9 @@ static void do_ffa_mem_share(struct arm_smccc_res *res,
	int ret = 0;
	u32 offset;

	BUILD_BUG_ON(func_id != FFA_FN64_MEM_SHARE &&
		     func_id != FFA_FN64_MEM_LEND);

	if (addr_mbz || npages_mbz || fraglen > len ||
	    fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE) {
		ret = FFA_RET_INVALID_PARAMETERS;
@@ -382,7 +386,7 @@ static void do_ffa_mem_share(struct arm_smccc_res *res,
	if (ret)
		goto out_unlock;

	ffa_mem_share(res, len, fraglen);
	ffa_mem_xfer(res, func_id, len, fraglen);
	if (res->a0 != FFA_SUCCESS) {
		WARN_ON(ffa_host_unshare_ranges(reg->constituents,
						reg->addr_range_cnt));
@@ -519,11 +523,15 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt)
		goto out_handled;
	case FFA_MEM_SHARE:
	case FFA_FN64_MEM_SHARE:
		do_ffa_mem_share(&res, host_ctxt);
		do_ffa_mem_xfer(FFA_FN64_MEM_SHARE, &res, host_ctxt);
		goto out_handled;
	case FFA_MEM_RECLAIM:
		do_ffa_mem_reclaim(&res, host_ctxt);
		goto out_handled;
	case FFA_MEM_LEND:
	case FFA_FN64_MEM_LEND:
		do_ffa_mem_xfer(FFA_FN64_MEM_LEND, &res, host_ctxt);
		goto out_handled;
	}

	if (ffa_call_supported(func_id))