int handle_load_ta()

in amdtee/call.c [399:447]


int handle_load_ta(void *data, u32 size, struct tee_ioctl_open_session_arg *arg)
{
	struct tee_cmd_unload_ta unload_cmd = {};
	struct tee_cmd_load_ta load_cmd = {};
	phys_addr_t blob;
	int ret;

	if (size == 0 || !data || !arg)
		return -EINVAL;

	blob = __psp_pa(data);
	if (blob & (PAGE_SIZE - 1)) {
		pr_err("load TA: page unaligned. blob 0x%llx", blob);
		return -EINVAL;
	}

	load_cmd.hi_addr = upper_32_bits(blob);
	load_cmd.low_addr = lower_32_bits(blob);
	load_cmd.size = size;

	mutex_lock(&ta_refcount_mutex);

	ret = psp_tee_process_cmd(TEE_CMD_ID_LOAD_TA, (void *)&load_cmd,
				  sizeof(load_cmd), &arg->ret);
	if (ret) {
		arg->ret_origin = TEEC_ORIGIN_COMMS;
		arg->ret = TEEC_ERROR_COMMUNICATION;
	} else if (arg->ret == TEEC_SUCCESS) {
		ret = get_ta_refcount(load_cmd.ta_handle);
		if (!ret) {
			arg->ret_origin = TEEC_ORIGIN_COMMS;
			arg->ret = TEEC_ERROR_OUT_OF_MEMORY;

			/* Unload the TA on error */
			unload_cmd.ta_handle = load_cmd.ta_handle;
			psp_tee_process_cmd(TEE_CMD_ID_UNLOAD_TA,
					    (void *)&unload_cmd,
					    sizeof(unload_cmd), &ret);
		} else {
			set_session_id(load_cmd.ta_handle, 0, &arg->session);
		}
	}
	mutex_unlock(&ta_refcount_mutex);

	pr_debug("load TA: TA handle = 0x%x, RO = 0x%x, ret = 0x%x\n",
		 load_cmd.ta_handle, arg->ret_origin, arg->ret);

	return 0;
}