Merge "ion: Ensure non-HLOS memory cannot be mapped by CPU"

This commit is contained in:
Linux Build Service Account 2018-10-04 14:58:31 -07:00 committed by Gerrit - the friendly Code Review server
commit d750db225f
5 changed files with 66 additions and 7 deletions

View file

@ -313,14 +313,37 @@ err:
return ret; return ret;
} }
static void *ion_secure_cma_map_kernel(struct ion_heap *heap,
struct ion_buffer *buffer)
{
if (!is_buffer_hlos_assigned(buffer)) {
pr_info("%s: Mapping non-HLOS accessible buffer disallowed\n",
__func__);
return NULL;
}
return ion_cma_map_kernel(heap, buffer);
}
static int ion_secure_cma_map_user(struct ion_heap *mapper,
struct ion_buffer *buffer,
struct vm_area_struct *vma)
{
if (!is_buffer_hlos_assigned(buffer)) {
pr_info("%s: Mapping non-HLOS accessible buffer disallowed\n",
__func__);
return -EINVAL;
}
return ion_cma_mmap(mapper, buffer, vma);
}
static struct ion_heap_ops ion_secure_cma_ops = { static struct ion_heap_ops ion_secure_cma_ops = {
.allocate = ion_secure_cma_allocate, .allocate = ion_secure_cma_allocate,
.free = ion_secure_cma_free, .free = ion_secure_cma_free,
.map_dma = ion_cma_heap_map_dma, .map_dma = ion_cma_heap_map_dma,
.unmap_dma = ion_cma_heap_unmap_dma, .unmap_dma = ion_cma_heap_unmap_dma,
.phys = ion_cma_phys, .phys = ion_cma_phys,
.map_user = ion_cma_mmap, .map_user = ion_secure_cma_map_user,
.map_kernel = ion_cma_map_kernel, .map_kernel = ion_secure_cma_map_kernel,
.unmap_kernel = ion_cma_unmap_kernel, .unmap_kernel = ion_cma_unmap_kernel,
.print_debug = ion_cma_print_debug, .print_debug = ion_cma_print_debug,
}; };

View file

@ -99,6 +99,11 @@ size_t ion_system_heap_secure_page_pool_total(struct ion_heap *heap,
return total << PAGE_SHIFT; return total << PAGE_SHIFT;
} }
static int ion_heap_is_system_heap_type(enum ion_heap_type type)
{
return type == ((enum ion_heap_type)ION_HEAP_TYPE_SYSTEM);
}
static struct page *alloc_buffer_page(struct ion_system_heap *heap, static struct page *alloc_buffer_page(struct ion_system_heap *heap,
struct ion_buffer *buffer, struct ion_buffer *buffer,
unsigned long order, unsigned long order,
@ -352,6 +357,13 @@ static int ion_system_heap_allocate(struct ion_heap *heap,
int vmid = get_secure_vmid(buffer->flags); int vmid = get_secure_vmid(buffer->flags);
struct device *dev = heap->priv; struct device *dev = heap->priv;
if (ion_heap_is_system_heap_type(buffer->heap->type) &&
is_secure_vmid_valid(vmid)) {
pr_info("%s: System heap doesn't support secure allocations\n",
__func__);
return -EINVAL;
}
if (align > PAGE_SIZE) if (align > PAGE_SIZE)
return -EINVAL; return -EINVAL;

View file

@ -1,6 +1,6 @@
/* /*
* *
* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@ -170,14 +170,15 @@ out:
sys_heap->ops->free(&buffer); sys_heap->ops->free(&buffer);
} }
static void process_one_shrink(struct ion_heap *sys_heap, static void process_one_shrink(struct ion_system_secure_heap *secure_heap,
struct ion_heap *sys_heap,
struct prefetch_info *info) struct prefetch_info *info)
{ {
struct ion_buffer buffer; struct ion_buffer buffer;
size_t pool_size, size; size_t pool_size, size;
int ret; int ret;
buffer.heap = sys_heap; buffer.heap = &secure_heap->heap;
buffer.flags = info->vmid; buffer.flags = info->vmid;
pool_size = ion_system_heap_secure_page_pool_total(sys_heap, pool_size = ion_system_heap_secure_page_pool_total(sys_heap,
@ -192,6 +193,7 @@ static void process_one_shrink(struct ion_heap *sys_heap,
} }
buffer.private_flags = ION_PRIV_FLAG_SHRINKER_FREE; buffer.private_flags = ION_PRIV_FLAG_SHRINKER_FREE;
buffer.heap = sys_heap;
sys_heap->ops->free(&buffer); sys_heap->ops->free(&buffer);
} }
@ -211,7 +213,7 @@ static void ion_system_secure_heap_prefetch_work(struct work_struct *work)
spin_unlock_irqrestore(&secure_heap->work_lock, flags); spin_unlock_irqrestore(&secure_heap->work_lock, flags);
if (info->shrink) if (info->shrink)
process_one_shrink(sys_heap, info); process_one_shrink(secure_heap, sys_heap, info);
else else
process_one_prefetch(sys_heap, info); process_one_prefetch(sys_heap, info);

View file

@ -678,6 +678,21 @@ int get_secure_vmid(unsigned long flags)
return VMID_CP_SPSS_SP_SHARED; return VMID_CP_SPSS_SP_SHARED;
return -EINVAL; return -EINVAL;
} }
bool is_buffer_hlos_assigned(struct ion_buffer *buffer)
{
bool is_hlos = false;
if (buffer->heap->type == (enum ion_heap_type)ION_HEAP_TYPE_HYP_CMA &&
(buffer->flags & ION_FLAG_CP_HLOS))
is_hlos = true;
if (get_secure_vmid(buffer->flags) <= 0)
is_hlos = true;
return is_hlos;
}
/* fix up the cases where the ioctl direction bits are incorrect */ /* fix up the cases where the ioctl direction bits are incorrect */
static unsigned int msm_ion_ioctl_dir(unsigned int cmd) static unsigned int msm_ion_ioctl_dir(unsigned int cmd)
{ {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, The Linux Foundation. All rights reserved. * Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@ -175,6 +175,8 @@ int msm_ion_do_cache_offset_op(
void *vaddr, unsigned int offset, unsigned long len, void *vaddr, unsigned int offset, unsigned long len,
unsigned int cmd); unsigned int cmd);
bool is_buffer_hlos_assigned(struct ion_buffer *buffer);
#else #else
static inline struct ion_client *msm_ion_client_create(const char *name) static inline struct ion_client *msm_ion_client_create(const char *name)
{ {
@ -202,6 +204,11 @@ int msm_ion_do_cache_offset_op(
return -ENODEV; return -ENODEV;
} }
static bool is_buffer_hlos_assigned(struct ion_buffer *buffer)
{
return true;
}
#endif /* CONFIG_ION */ #endif /* CONFIG_ION */
#endif #endif