Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4c7d1bd1 authored by Neeti Desai's avatar Neeti Desai Committed by Liam Mark
Browse files

msm: Update the assign api to secure buffers



The assign call apis have been updated by TZ to
include more usecases. Update the secure_buffer
api files with the same. The system secure heap
needs to be updated to reflect the change in
the api calls.

Change-Id: Idc784ddac222e6ad9f5defafc422e6e3fb88aa0c
Signed-off-by: default avatarNeeti Desai <neetid@codeaurora.org>
Signed-off-by: default avatarPatrick Daly <pdaly@codeaurora.org>
parent 95d5d878
Loading
Loading
Loading
Loading
+111 −14
Original line number Diff line number Diff line
@@ -53,6 +53,18 @@ struct info_list {
#define V2_CHUNK_SIZE		SZ_1M
#define FEATURE_ID_CP 12

struct dest_vm_and_perm_info {
	u32 vm;
	u32 perm;
	u32 *ctx;
	u32 ctx_size;
};

struct dest_info_list {
	struct dest_vm_and_perm_info *dest_info;
	u64 list_size;
};

static int secure_buffer_change_chunk(u32 chunks,
				u32 nchunks,
				u32 chunk_size,
@@ -184,7 +196,38 @@ int msm_unsecure_table(struct sg_table *table)

}

static struct info_list *get_info_list(struct sg_table *table)
static struct dest_info_list *populate_dest_info(int *dest_vmids, int nelements,
								int *dest_perms)
{
	struct dest_vm_and_perm_info *dest_info;
	struct dest_info_list *list;
	int i;

	dest_info = kmalloc_array(nelements,
			(sizeof(struct dest_vm_and_perm_info)),
				GFP_KERNEL | __GFP_ZERO);
	if (!dest_info)
		return NULL;

	for (i = 0; i < nelements; i++) {
		dest_info[i].vm = dest_vmids[i];
		dest_info[i].perm = dest_perms[i];
		dest_info[i].ctx = NULL;
		dest_info[i].ctx_size = 0;
	}
	list = kzalloc(sizeof(struct dest_info_list), GFP_KERNEL);
	if (!list) {
		kfree(dest_info);
		return NULL;
	}

	list->dest_info = dest_info;
	list->list_size = nelements * sizeof(struct dest_vm_and_perm_info);

	return list;
}

static struct info_list *get_info_list_from_table(struct sg_table *table)
{
	int i;
	struct scatterlist *sg;
@@ -218,42 +261,96 @@ static void destroy_info_list(struct info_list *info_list)
	kfree(info_list);
}

int msm_ion_hyp_assign_call(struct sg_table *table,
			u32 *source_vm_list, u32 source_list_size,
			u32 *dest_vm_list, u32 dest_list_size)
static void destroy_dest_info_list(struct dest_info_list *dest_list)
{
	kfree(dest_list->dest_info);
	kfree(dest_list);
}

int hyp_assign_table(struct sg_table *table,
			u32 *source_vm_list, int source_nelems,
			int *dest_vmids, int *dest_perms,
			int dest_nelems)
{
	struct info_list *info_list = NULL;
	int ret;
	struct info_list *info_list = NULL;
	struct dest_info_list *dest_info_list = NULL;
	struct scm_desc desc = {0};

	info_list = get_info_list(table);
	info_list = get_info_list_from_table(table);
	if (!info_list)
		return -ENOMEM;

	dest_info_list = populate_dest_info(dest_vmids, dest_nelems,
							dest_perms);
	if (!dest_info_list) {
		ret = -ENOMEM;
		goto err1;
	}

	desc.args[0] = virt_to_phys(info_list->list_head);
	desc.args[1] = info_list->list_size;
	desc.args[2] = virt_to_phys(source_vm_list);
	desc.args[3] = source_list_size;
	desc.args[4] = virt_to_phys(dest_vm_list);
	desc.args[5] = dest_list_size;
	desc.args[3] = sizeof(*source_vm_list) * source_nelems;
	desc.args[4] = virt_to_phys(dest_info_list->dest_info);
	desc.args[5] = dest_info_list->list_size;
	desc.args[6] = 0;

	desc.arginfo = SCM_ARGS(7, SCM_RO, SCM_VAL, SCM_RO, SCM_VAL, SCM_RO,
				SCM_VAL, SCM_VAL);

	dmac_flush_range(source_vm_list, source_vm_list + source_nelems);
	dmac_flush_range(info_list->list_head, info_list->list_head +
		(info_list->list_size / sizeof(*info_list->list_head)));
	dmac_flush_range(source_vm_list, source_vm_list +
				(source_list_size / sizeof(*source_vm_list)));
	dmac_flush_range(dest_vm_list, dest_vm_list +
				(dest_list_size / sizeof(*dest_vm_list)));
	dmac_flush_range(dest_info_list->dest_info, dest_info_list->dest_info +
		(dest_info_list->list_size /
				sizeof(*dest_info_list->dest_info)));

	ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP,
			MEM_PROT_ASSIGN_ID), &desc);
	if (ret)
		pr_info("%s: Failed to assign memory protection, ret = %d\n",
			__func__, ret);

	destroy_dest_info_list(dest_info_list);

err1:
	destroy_info_list(info_list);
	return ret;
}

int hyp_assign_phys(phys_addr_t addr, u64 size,
			int *dest_vmids, int *dest_perms,
			int dest_nelems)
{
	struct sg_table *table;
	u32 source_vm;
	int ret;

	table = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
	if (!table)
		return -ENOMEM;
	ret = sg_alloc_table(table, 1, GFP_KERNEL);
	if (ret)
		goto err1;

	sg_set_page(table->sgl, phys_to_page(addr), size, 0);

	source_vm = VMID_HLOS;

	ret = hyp_assign_table(table, &source_vm, 1, dest_vmids,
						dest_perms, dest_nelems);
	if (ret)
		goto err2;

	return ret;
err2:
	sg_free_table(table);
err1:
	kfree(table);
	return ret;
}

#define MAKE_CP_VERSION(major, minor, patch) \
	(((major & 0x3FF) << 22) | ((minor & 0x3FF) << 12) | (patch & 0xFFF))

+30 −7
Original line number Diff line number Diff line
@@ -16,14 +16,30 @@
#define __QCOM_SECURE_BUFFER_H__


#define VMID_HLOS 0x3
#define VMID_CP_TOUCH 0x8
#define VMID_CP_BITSTREAM 0x9
#define VMID_CP_PIXEL 0xA
#define VMID_CP_NON_PIXEL 0xB
#define VMID_CP_CAMERA 0xD
#define VMID_HLOS_FREE 0xE
#define VMID_MSS_NONMSA 0x10
#define VMID_INVAL -1

#define PERM_READ                       0x4
#define PERM_WRITE                      0x2

#ifdef CONFIG_QCOM_SECURE_BUFFER
int msm_secure_table(struct sg_table *table);
int msm_unsecure_table(struct sg_table *table);
int msm_ion_hyp_assign_call(struct sg_table *table,
		u32 *source_vm_list, u32 source_list_size,
		u32 *dest_vm_list, u32 dest_list_size);
int hyp_assign_table(struct sg_table *table,
			u32 *source_vm_list, int source_nelems,
			int *dest_vmids, int *dest_perms,
			int dest_nelems);
int hyp_assign_phys(phys_addr_t addr, u64 size,
			int *dest_vmids, int *dest_perms,
			int dest_nelems);
bool msm_secure_v2_is_supported(void);

#else
static inline int msm_secure_table(struct sg_table *table)
{
@@ -33,9 +49,16 @@ static inline int msm_unsecure_table(struct sg_table *table)
{
	return -EINVAL;
}
static inline int hyp_assign_call(struct sg_table *table,
		u32 *source_vm_list, u32 source_list_size,
		u32 *dest_vm_list, u32 dest_list_size);
int hyp_assign_table(struct sg_table *table,
			u32 *source_vm_list, int source_nelems,
			int *dest_vmids, int *dest_perms,
			int dest_nelems)
{
	return -EINVAL;
}
int hyp_assign_phys(phys_addr_t addr, u64 size,
			int *dest_vmids, int *dest_perms,
			int dest_nelems)
{
	return -EINVAL;
}