arch/arm64/kvm/hyp/nvhe/ffa.c

Source file repositories/reference/linux-study-clean/arch/arm64/kvm/hyp/nvhe/ffa.c

File Facts

System
Linux kernel
Corpus path
arch/arm64/kvm/hyp/nvhe/ffa.c
Extension
.c
Size
25208 bytes
Lines
994
Domain
Architecture Layer
Bucket
arch/arm64
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct kvm_ffa_descriptor_buffer {
	void	*buf;
	size_t	len;
};

static struct kvm_ffa_descriptor_buffer ffa_desc_buf;

struct kvm_ffa_buffers {
	hyp_spinlock_t lock;
	void *tx;
	void *rx;
};

/*
 * 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 hyp_buffers;
static struct kvm_ffa_buffers host_buffers;
static u32 hyp_ffa_version;
static bool has_version_negotiated;
static hyp_spinlock_t version_lock;

static void ffa_to_smccc_error(struct arm_smccc_1_2_regs *res, u64 ffa_errno)
{
	*res = (struct arm_smccc_1_2_regs) {
		.a0	= FFA_ERROR,
		.a2	= ffa_errno,
	};
}

static void ffa_to_smccc_res_prop(struct arm_smccc_1_2_regs *res, int ret, u64 prop)
{
	if (ret == FFA_RET_SUCCESS) {
		*res = (struct arm_smccc_1_2_regs) { .a0 = FFA_SUCCESS,
						      .a2 = prop };
	} else {
		ffa_to_smccc_error(res, ret);
	}
}

static void ffa_to_smccc_res(struct arm_smccc_1_2_regs *res, int ret)
{
	ffa_to_smccc_res_prop(res, ret, 0);
}

static void ffa_set_retval(struct kvm_cpu_context *ctxt,
			   struct arm_smccc_1_2_regs *res)
{
	cpu_reg(ctxt, 0) = res->a0;
	cpu_reg(ctxt, 1) = res->a1;
	cpu_reg(ctxt, 2) = res->a2;
	cpu_reg(ctxt, 3) = res->a3;
	cpu_reg(ctxt, 4) = res->a4;
	cpu_reg(ctxt, 5) = res->a5;
	cpu_reg(ctxt, 6) = res->a6;
	cpu_reg(ctxt, 7) = res->a7;

	/*
	 * DEN0028C 2.6: SMC32/HVC32 call from aarch64 must preserve x8-x30.
	 *
	 * In FF-A 1.2, we cannot rely on the function ID sent by the caller to
	 * detect 32-bit calls because the CPU cycle management interfaces (e.g.
	 * FFA_MSG_WAIT, FFA_RUN) are 32-bit only but can have 64-bit responses.
	 *
	 * FFA-1.3 introduces 64-bit variants of the CPU cycle management
	 * interfaces. Moreover, FF-A 1.3 clarifies that SMC32 direct requests
	 * complete with SMC32 direct responses which *should* allow us use the
	 * function ID sent by the caller to determine whether to return x8-x17.
	 *
	 * Note that we also cannot rely on function IDs in the response.
	 *
	 * Given the above, assume SMC64 and send back x0-x17 unconditionally
	 * as the passthrough code (__kvm_hyp_host_forward_smc) does the same.
	 */
	cpu_reg(ctxt, 8) = res->a8;
	cpu_reg(ctxt, 9) = res->a9;
	cpu_reg(ctxt, 10) = res->a10;
	cpu_reg(ctxt, 11) = res->a11;
	cpu_reg(ctxt, 12) = res->a12;
	cpu_reg(ctxt, 13) = res->a13;
	cpu_reg(ctxt, 14) = res->a14;
	cpu_reg(ctxt, 15) = res->a15;
	cpu_reg(ctxt, 16) = res->a16;
	cpu_reg(ctxt, 17) = res->a17;
}

static bool is_ffa_call(u64 func_id)
{

Annotation

Implementation Notes