msm: ion: Add secure cma heap

Add the infrastructure to support a secure cma heap
needed for secure usecases. The new heap uses
the existing cma heap infrastructure, along with adding
the assign call to assign the correct VM to the buffers
during allocation and free.

Change-Id: I0c959f46ffa6eb67128b6794e9e60c470a3d292e
Signed-off-by: Neeti Desai <neetid@codeaurora.org>
This commit is contained in:
Neeti Desai 2015-06-24 15:41:54 -07:00 committed by David Keitel
parent 4cbd8a0f84
commit 3eac23bf1a
6 changed files with 147 additions and 17 deletions

View file

@ -23,6 +23,7 @@
#include <linux/msm_ion.h>
#include <asm/cacheflush.h>
#include <soc/qcom/secure_buffer.h>
#include "ion.h"
#include "ion_priv.h"
@ -233,3 +234,105 @@ void ion_cma_heap_destroy(struct ion_heap *heap)
{
kfree(heap);
}
static void ion_secure_cma_free(struct ion_buffer *buffer)
{
int ret = 0;
u32 source_vm;
int dest_vmid;
int dest_perms;
struct ion_cma_buffer_info *info = buffer->priv_virt;
source_vm = get_secure_vmid(buffer->flags);
if (source_vm < 0) {
pr_err("%s: Failed to get secure vmid\n", __func__);
return;
}
dest_vmid = VMID_HLOS;
dest_perms = PERM_READ | PERM_WRITE | PERM_EXEC;
ret = hyp_assign_table(info->table, &source_vm, 1,
&dest_vmid, &dest_perms, 1);
if (ret) {
pr_err("%s: Not freeing memory since assign failed\n",
__func__);
return;
}
ion_cma_free(buffer);
}
static int ion_secure_cma_allocate(struct ion_heap *heap,
struct ion_buffer *buffer, unsigned long len,
unsigned long align, unsigned long flags)
{
int ret = 0;
int source_vm;
int dest_vm;
int dest_perms;
struct ion_cma_buffer_info *info;
source_vm = VMID_HLOS;
dest_vm = get_secure_vmid(flags);
if (dest_vm < 0) {
pr_err("%s: Failed to get secure vmid\n", __func__);
return -EINVAL;
}
dest_perms = PERM_READ | PERM_WRITE;
ret = ion_cma_allocate(heap, buffer, len, align, flags);
if (ret) {
dev_err(heap->priv, "Unable to allocate cma buffer");
return ret;
}
info = buffer->priv_virt;
ret = hyp_assign_table(info->table, &source_vm, 1,
&dest_vm, &dest_perms, 1);
if (ret) {
pr_err("%s: Assign call failed\n", __func__);
goto err;
}
return ret;
err:
ion_secure_cma_free(buffer);
return ret;
}
static struct ion_heap_ops ion_secure_cma_ops = {
.allocate = ion_secure_cma_allocate,
.free = ion_secure_cma_free,
.map_dma = ion_cma_heap_map_dma,
.unmap_dma = ion_cma_heap_unmap_dma,
.phys = ion_cma_phys,
.map_user = ion_cma_mmap,
.map_kernel = ion_cma_map_kernel,
.unmap_kernel = ion_cma_unmap_kernel,
.print_debug = ion_cma_print_debug,
};
struct ion_heap *ion_cma_secure_heap_create(struct ion_platform_heap *data)
{
struct ion_heap *heap;
heap = kzalloc(sizeof(struct ion_heap), GFP_KERNEL);
if (!heap)
return ERR_PTR(-ENOMEM);
heap->ops = &ion_secure_cma_ops;
/*
* set device as private heaps data, later it will be
* used to make the link with reserved CMA memory
*/
heap->priv = data->priv;
heap->type = ION_HEAP_TYPE_HYP_CMA;
cma_heap_has_outer_cache = data->has_outer_cache;
return heap;
}
void ion_cma_secure_heap_destroy(struct ion_heap *heap)
{
kfree(heap);
}

View file

@ -33,22 +33,6 @@ static bool is_cp_flag_present(unsigned long flags)
ION_FLAG_CP_CAMERA);
}
static int get_secure_vmid(unsigned long flags)
{
if (flags & ION_FLAG_CP_TOUCH)
return VMID_CP_TOUCH;
if (flags & ION_FLAG_CP_BITSTREAM)
return VMID_CP_BITSTREAM;
if (flags & ION_FLAG_CP_PIXEL)
return VMID_CP_PIXEL;
if (flags & ION_FLAG_CP_NON_PIXEL)
return VMID_CP_NON_PIXEL;
if (flags & ION_FLAG_CP_CAMERA)
return VMID_CP_CAMERA;
return -EINVAL;
}
static void ion_system_secure_heap_free(struct ion_buffer *buffer)
{
int ret = 0;

View file

@ -35,6 +35,7 @@
#include "../ion_priv.h"
#include "ion_cp_common.h"
#include "compat_msm_ion.h"
#include <soc/qcom/secure_buffer.h>
#define ION_COMPAT_STR "qcom,msm-ion"
@ -109,6 +110,10 @@ static struct ion_heap_desc ion_heap_meta[] = {
{
.id = ION_ADSP_HEAP_ID,
.name = ION_ADSP_HEAP_NAME,
},
{
.id = ION_SECURE_DISPLAY_HEAP_ID,
.name = ION_SECURE_DISPLAY_HEAP_NAME,
}
};
#endif
@ -372,6 +377,7 @@ static struct heap_types_info {
MAKE_HEAP_TYPE_MAPPING(DMA),
MAKE_HEAP_TYPE_MAPPING(SECURE_DMA),
MAKE_HEAP_TYPE_MAPPING(SYSTEM_SECURE),
MAKE_HEAP_TYPE_MAPPING(HYP_CMA),
};
static int msm_ion_get_heap_type_from_dt_node(struct device_node *node,
@ -573,6 +579,24 @@ int ion_heap_allow_heap_secure(enum ion_heap_type type)
return false;
}
int get_secure_vmid(unsigned long flags)
{
if (flags & ION_FLAG_CP_TOUCH)
return VMID_CP_TOUCH;
if (flags & ION_FLAG_CP_BITSTREAM)
return VMID_CP_BITSTREAM;
if (flags & ION_FLAG_CP_PIXEL)
return VMID_CP_PIXEL;
if (flags & ION_FLAG_CP_NON_PIXEL)
return VMID_CP_NON_PIXEL;
if (flags & ION_FLAG_CP_CAMERA)
return VMID_CP_CAMERA;
if (flags & ION_FLAG_CP_SEC_DISPLAY)
return VMID_CP_SEC_DISPLAY;
if (flags & ION_FLAG_CP_APP)
return VMID_CP_APP;
return -EINVAL;
}
/* fix up the cases where the ioctl direction bits are incorrect */
static unsigned int msm_ion_ioctl_dir(unsigned int cmd)
{
@ -823,6 +847,9 @@ static struct ion_heap *msm_ion_heap_create(struct ion_platform_heap *heap_data)
case ION_HEAP_TYPE_SYSTEM_SECURE:
heap = ion_system_secure_heap_create(heap_data);
break;
case ION_HEAP_TYPE_HYP_CMA:
heap = ion_cma_secure_heap_create(heap_data);
break;
default:
heap = ion_heap_create(heap_data);
}
@ -854,6 +881,10 @@ static void msm_ion_heap_destroy(struct ion_heap *heap)
case ION_HEAP_TYPE_SYSTEM_SECURE:
ion_system_secure_heap_destroy(heap);
break;
case ION_HEAP_TYPE_HYP_CMA:
ion_cma_secure_heap_destroy(heap);
break;
default:
ion_heap_destroy(heap);
}

View file

@ -2,7 +2,7 @@
* drivers/staging/android/ion/msm_ion_priv.h
*
* Copyright (C) 2011 Google, Inc.
* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@ -52,6 +52,9 @@ void ion_cp_heap_destroy(struct ion_heap *);
struct ion_heap *ion_system_secure_heap_create(struct ion_platform_heap *);
void ion_system_secure_heap_destroy(struct ion_heap *);
struct ion_heap *ion_cma_secure_heap_create(struct ion_platform_heap *);
void ion_cma_secure_heap_destroy(struct ion_heap *);
long msm_ion_custom_ioctl(struct ion_client *client,
unsigned int cmd,
unsigned long arg);
@ -117,6 +120,8 @@ int ion_heap_allow_heap_secure(enum ion_heap_type type);
int ion_heap_allow_handle_secure(enum ion_heap_type type);
int get_secure_vmid(unsigned long);
/**
* ion_create_chunked_sg_table - helper function to create sg table
* with specified chunk size

View file

@ -7,6 +7,7 @@ enum msm_ion_heap_types {
ION_HEAP_TYPE_MSM_START = ION_HEAP_TYPE_CUSTOM + 1,
ION_HEAP_TYPE_SECURE_DMA = ION_HEAP_TYPE_MSM_START,
ION_HEAP_TYPE_SYSTEM_SECURE,
ION_HEAP_TYPE_HYP_CMA,
/*
* if you add a heap type here you should also add it to
* heap_types_info[] in msm_ion.c
@ -26,6 +27,7 @@ enum ion_heap_ids {
INVALID_HEAP_ID = -1,
ION_CP_MM_HEAP_ID = 8,
ION_SECURE_HEAP_ID = 9,
ION_SECURE_DISPLAY_HEAP_ID = 10,
ION_CP_MFC_HEAP_ID = 12,
ION_CP_WB_HEAP_ID = 16, /* 8660 only */
ION_CAMERA_HEAP_ID = 20, /* 8660 only */
@ -78,6 +80,8 @@ enum cp_mem_usage {
#define ION_FLAG_CP_CAMERA (1 << 21)
#define ION_FLAG_CP_HLOS (1 << 22)
#define ION_FLAG_CP_HLOS_FREE (1 << 23)
#define ION_FLAG_CP_SEC_DISPLAY (1 << 25)
#define ION_FLAG_CP_APP (1 << 26)
/**
* Flag to allow non continguous allocation of memory from secure
@ -130,6 +134,7 @@ enum cp_mem_usage {
#define ION_PIL2_HEAP_NAME "pil_2"
#define ION_QSECOM_HEAP_NAME "qsecom"
#define ION_SECURE_HEAP_NAME "secure_heap"
#define ION_SECURE_DISPLAY_HEAP_NAME "secure_display"
#define ION_SET_CACHED(__cache) (__cache | ION_FLAG_CACHED)
#define ION_SET_UNCACHED(__cache) (__cache & ~ION_FLAG_CACHED)

View file

@ -24,6 +24,8 @@
#define VMID_CP_CAMERA 0xD
#define VMID_HLOS_FREE 0xE
#define VMID_MSS_NONMSA 0x10
#define VMID_CP_SEC_DISPLAY 0x11
#define VMID_CP_APP 0x12
#define VMID_INVAL -1
#define PERM_READ 0x4