Merge "ion: system_secure_heap: Support ION_IOC_DRAIN"

This commit is contained in:
Linux Build Service Account 2016-08-18 12:04:32 -07:00 committed by Gerrit - the friendly Code Review server
commit cb715cde3a
3 changed files with 54 additions and 4 deletions

View file

@ -36,6 +36,7 @@ struct prefetch_info {
struct list_head list;
int vmid;
size_t size;
bool shrink;
};
static bool is_cp_flag_present(unsigned long flags)
@ -161,6 +162,31 @@ out:
sys_heap->ops->free(&buffer);
}
static void process_one_shrink(struct ion_heap *sys_heap,
struct prefetch_info *info)
{
struct ion_buffer buffer;
size_t pool_size, size;
int ret;
buffer.heap = sys_heap;
buffer.flags = info->vmid;
pool_size = ion_system_heap_secure_page_pool_total(sys_heap,
info->vmid);
size = min(pool_size, info->size);
ret = sys_heap->ops->allocate(sys_heap, &buffer, size, PAGE_SIZE,
buffer.flags);
if (ret) {
pr_debug("%s: Failed to shrink 0x%zx, ret = %d\n",
__func__, info->size, ret);
return;
}
buffer.private_flags = ION_PRIV_FLAG_SHRINKER_FREE;
sys_heap->ops->free(&buffer);
}
static void ion_system_secure_heap_prefetch_work(struct work_struct *work)
{
struct ion_system_secure_heap *secure_heap = container_of(work,
@ -176,7 +202,10 @@ static void ion_system_secure_heap_prefetch_work(struct work_struct *work)
list_del(&info->list);
spin_unlock_irqrestore(&secure_heap->work_lock, flags);
process_one_prefetch(sys_heap, info);
if (info->shrink)
process_one_shrink(sys_heap, info);
else
process_one_prefetch(sys_heap, info);
kfree(info);
spin_lock_irqsave(&secure_heap->work_lock, flags);
@ -186,7 +215,7 @@ static void ion_system_secure_heap_prefetch_work(struct work_struct *work)
static int alloc_prefetch_info(
struct ion_prefetch_regions __user *user_regions,
struct list_head *items)
bool shrink, struct list_head *items)
{
struct prefetch_info *info;
size_t __user *user_sizes;
@ -215,6 +244,7 @@ static int alloc_prefetch_info(
goto out_free;
info->vmid = vmid;
info->shrink = shrink;
INIT_LIST_HEAD(&info->list);
list_add_tail(&info->list, items);
}
@ -224,7 +254,8 @@ out_free:
return err;
}
int ion_system_secure_heap_prefetch(struct ion_heap *heap, void *ptr)
static int __ion_system_secure_heap_resize(struct ion_heap *heap, void *ptr,
bool shrink)
{
struct ion_system_secure_heap *secure_heap = container_of(heap,
struct ion_system_secure_heap,
@ -242,7 +273,7 @@ int ion_system_secure_heap_prefetch(struct ion_heap *heap, void *ptr)
return -EINVAL;
for (i = 0; i < data->nr_regions; i++) {
ret = alloc_prefetch_info(&data->regions[i], &items);
ret = alloc_prefetch_info(&data->regions[i], shrink, &items);
if (ret)
goto out_free;
}
@ -266,6 +297,16 @@ out_free:
return ret;
}
int ion_system_secure_heap_prefetch(struct ion_heap *heap, void *ptr)
{
return __ion_system_secure_heap_resize(heap, ptr, false);
}
int ion_system_secure_heap_drain(struct ion_heap *heap, void *ptr)
{
return __ion_system_secure_heap_resize(heap, ptr, true);
}
static struct sg_table *ion_system_secure_heap_map_dma(struct ion_heap *heap,
struct ion_buffer *buffer)
{

View file

@ -766,6 +766,14 @@ long msm_ion_custom_ioctl(struct ion_client *client,
(void *)data.prefetch_data.len,
ion_secure_cma_drain_pool);
if (ret)
return ret;
ret = ion_walk_heaps(client, data.prefetch_data.heap_id,
ION_HEAP_TYPE_SYSTEM_SECURE,
(void *)&data.prefetch_data,
ion_system_secure_heap_drain);
if (ret)
return ret;
break;

View file

@ -52,6 +52,7 @@ 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 *);
int ion_system_secure_heap_prefetch(struct ion_heap *heap, void *data);
int ion_system_secure_heap_drain(struct ion_heap *heap, void *data);
struct ion_heap *ion_cma_secure_heap_create(struct ion_platform_heap *);
void ion_cma_secure_heap_destroy(struct ion_heap *);