int handle_map_shmem()

in amdtee/call.c [286:349]


int handle_map_shmem(u32 count, struct shmem_desc *start, u32 *buf_id)
{
	struct tee_cmd_map_shared_mem *cmd;
	phys_addr_t paddr;
	int ret, i;
	u32 status;

	if (!count || !start || !buf_id)
		return -EINVAL;

	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	if (!cmd)
		return -ENOMEM;

	/* Size must be page aligned */
	for (i = 0; i < count ; i++) {
		if (!start[i].kaddr || (start[i].size & (PAGE_SIZE - 1))) {
			ret = -EINVAL;
			goto free_cmd;
		}

		if ((u64)start[i].kaddr & (PAGE_SIZE - 1)) {
			pr_err("map shared memory: page unaligned. addr 0x%llx",
			       (u64)start[i].kaddr);
			ret = -EINVAL;
			goto free_cmd;
		}
	}

	cmd->sg_list.count = count;

	/* Create buffer list */
	for (i = 0; i < count ; i++) {
		paddr = __psp_pa(start[i].kaddr);
		cmd->sg_list.buf[i].hi_addr = upper_32_bits(paddr);
		cmd->sg_list.buf[i].low_addr = lower_32_bits(paddr);
		cmd->sg_list.buf[i].size = start[i].size;
		cmd->sg_list.size += cmd->sg_list.buf[i].size;

		pr_debug("buf[%d]:hi addr = 0x%x\n", i,
			 cmd->sg_list.buf[i].hi_addr);
		pr_debug("buf[%d]:low addr = 0x%x\n", i,
			 cmd->sg_list.buf[i].low_addr);
		pr_debug("buf[%d]:size = 0x%x\n", i, cmd->sg_list.buf[i].size);
		pr_debug("list size = 0x%x\n", cmd->sg_list.size);
	}

	*buf_id = 0;

	ret = psp_tee_process_cmd(TEE_CMD_ID_MAP_SHARED_MEM, (void *)cmd,
				  sizeof(*cmd), &status);
	if (!ret && !status) {
		*buf_id = cmd->buf_id;
		pr_debug("mapped buffer ID = 0x%x\n", *buf_id);
	} else {
		pr_err("map shared memory: status = 0x%x\n", status);
		ret = -ENOMEM;
	}

free_cmd:
	kfree(cmd);

	return ret;
}