Commit 89437638 authored by Sebastian Ene's avatar Sebastian Ene Committed by Oliver Upton
Browse files

KVM: arm64: Add support for FFA_PARTITION_INFO_GET



Handle the FFA_PARTITION_INFO_GET host call inside the pKVM hypervisor
and copy the response message back to the host buffers.

Signed-off-by: default avatarSebastian Ene <sebastianene@google.com>
Reviewed-by: default avatarSudeep Holla <sudeep.holla@arm.com>
Tested-by: default avatarSudeep Holla <sudeep.holla@arm.com>
Acked-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20240613132035.1070360-3-sebastianene@google.com


Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
parent c9c01262
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -719,6 +719,55 @@ static void do_ffa_version(struct arm_smccc_res *res,
	hyp_spin_unlock(&version_lock);
}

static void do_ffa_part_get(struct arm_smccc_res *res,
			    struct kvm_cpu_context *ctxt)
{
	DECLARE_REG(u32, uuid0, ctxt, 1);
	DECLARE_REG(u32, uuid1, ctxt, 2);
	DECLARE_REG(u32, uuid2, ctxt, 3);
	DECLARE_REG(u32, uuid3, ctxt, 4);
	DECLARE_REG(u32, flags, ctxt, 5);
	u32 count, partition_sz, copy_sz;

	hyp_spin_lock(&host_buffers.lock);
	if (!host_buffers.rx) {
		ffa_to_smccc_res(res, FFA_RET_BUSY);
		goto out_unlock;
	}

	arm_smccc_1_1_smc(FFA_PARTITION_INFO_GET, uuid0, uuid1,
			  uuid2, uuid3, flags, 0, 0,
			  res);

	if (res->a0 != FFA_SUCCESS)
		goto out_unlock;

	count = res->a2;
	if (!count)
		goto out_unlock;

	if (hyp_ffa_version > FFA_VERSION_1_0) {
		/* Get the number of partitions deployed in the system */
		if (flags & 0x1)
			goto out_unlock;

		partition_sz  = res->a3;
	} else {
		/* FFA_VERSION_1_0 lacks the size in the response */
		partition_sz = FFA_1_0_PARTITON_INFO_SZ;
	}

	copy_sz = partition_sz * count;
	if (copy_sz > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE) {
		ffa_to_smccc_res(res, FFA_RET_ABORTED);
		goto out_unlock;
	}

	memcpy(host_buffers.rx, hyp_buffers.rx, copy_sz);
out_unlock:
	hyp_spin_unlock(&host_buffers.lock);
}

bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
	struct arm_smccc_res res;
@@ -773,6 +822,9 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
	case FFA_VERSION:
		do_ffa_version(&res, host_ctxt);
		goto out_handled;
	case FFA_PARTITION_INFO_GET:
		do_ffa_part_get(&res, host_ctxt);
		goto out_handled;
	}

	if (ffa_call_supported(func_id))
+3 −0
Original line number Diff line number Diff line
@@ -212,6 +212,9 @@ bool ffa_device_is_valid(struct ffa_device *ffa_dev) { return false; }

extern const struct bus_type ffa_bus_type;

/* The FF-A 1.0 partition structure lacks the uuid[4] */
#define FFA_1_0_PARTITON_INFO_SZ	(8)

/* FFA transport related */
struct ffa_partition_info {
	u16 id;