From: Cho KyongHo Date: Thu, 3 May 2018 08:14:01 +0000 (+0900) Subject: android: ion: add support for HPA exception area X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=18f921b409a77bd32ca464ee7a771a2751a4dafb;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git android: ion: add support for HPA exception area ION HPA Heap allocates pages for Secure DRM from HPA. But some memory areas are not allowed to protect for Secure DRM. The areas are declared in the property 'ion,hpa_alloc_exception' under a device tree node 'ion-hpa-heap'. It should be found by ION during heap initialization and passed to HPA when allocating Secure DRM buffers. Change-Id: I47585bad0a5b11dec140994714788f7aa918ccc1 Signed-off-by: Cho KyongHo --- diff --git a/drivers/staging/android/ion/ion_exynos.h b/drivers/staging/android/ion/ion_exynos.h index 5a454c1f4761..c22c5770dabf 100644 --- a/drivers/staging/android/ion/ion_exynos.h +++ b/drivers/staging/android/ion/ion_exynos.h @@ -71,9 +71,11 @@ extern struct ion_heap *ion_cma_heap_create(struct cma *cma, #endif #if defined(CONFIG_ION_HPA_HEAP) -extern struct ion_heap *ion_hpa_heap_create(struct ion_platform_heap *pheap); +extern struct ion_heap *ion_hpa_heap_create(struct ion_platform_heap *pheap, + phys_addr_t except_areas[][2], + int n_except_areas); #else -#define ion_hpa_heap_create(p) ERR_PTR(-ENODEV) +#define ion_hpa_heap_create(p, areas, n_areas) ERR_PTR(-ENODEV) #endif #if defined(CONFIG_EXYNOS_CONTENT_PATH_PROTECTION) && defined(CONFIG_ION_EXYNOS) diff --git a/drivers/staging/android/ion/ion_fdt_exynos.c b/drivers/staging/android/ion/ion_fdt_exynos.c index 04983a327515..949705df119b 100644 --- a/drivers/staging/android/ion/ion_fdt_exynos.c +++ b/drivers/staging/android/ion/ion_fdt_exynos.c @@ -110,6 +110,11 @@ static int __init exynos_ion_reserved_mem_setup(struct reserved_mem *rmem) RESERVEDMEM_OF_DECLARE(ion, "exynos9820-ion", exynos_ion_reserved_mem_setup); +#define MAX_HPA_EXCEPTION_AREAS 4 + +static int hpa_num_exception_areas; +static phys_addr_t hpa_alloc_exceptions[MAX_HPA_EXCEPTION_AREAS][2]; + static bool __init register_hpa_heap(struct device_node *np, unsigned int prot_id_map) { @@ -151,8 +156,8 @@ static bool __init register_hpa_heap(struct device_node *np, pheap.align = SZ_64K; pheap.type = ION_HEAP_TYPE_HPA; - heap = ion_hpa_heap_create(&pheap); - + heap = ion_hpa_heap_create(&pheap, hpa_alloc_exceptions, + hpa_num_exception_areas); if (IS_ERR(heap)) { pr_err("%s: failed to register '%s' heap\n", __func__, pheap.name); @@ -171,10 +176,49 @@ static bool __init exynos_ion_register_hpa_heaps(unsigned int prot_id_map) struct device_node *np, *child; bool secure = false; - for_each_node_by_name(np, "ion-hpa-heap") + for_each_node_by_name(np, "ion-hpa-heap") { + const __be32 *range; + int len; + + range = of_get_property(np, "ion,hpa_alloc_exception", &len); + if (range && (len > 0)) { + int n_addr = of_n_addr_cells(np); + int n_size = of_n_size_cells(np); + int n_area = len / (sizeof(*range) * (n_size + n_addr)); + const void *prop; + phys_addr_t base, size; + int i; + + /* + * If 'ion-hpa-heap' node defines its own range properties, + * override the range properties defined by its parent. + */ + prop = of_get_property(np, "#address-cells", NULL); + if (prop) + n_addr = be32_to_cpup(prop); + + prop = of_get_property(np, "#size-cells", NULL); + if (prop) + n_size = be32_to_cpup(prop); + + for (i = hpa_num_exception_areas; + i < min(n_area, MAX_HPA_EXCEPTION_AREAS) ; i++) { + base = (phys_addr_t)of_read_number(range, n_addr); + range += n_addr; + size = (phys_addr_t)of_read_number(range, n_size); + range += n_size; + + hpa_alloc_exceptions[i][0] = base; + hpa_alloc_exceptions[i][1] = base + size - 1; + } + + hpa_num_exception_areas = i; + } + for_each_child_of_node(np, child) if (of_device_is_compatible(child, "exynos9820-ion")) secure |= register_hpa_heap(child, prot_id_map); + } return secure; } @@ -246,4 +290,4 @@ static int __init exynos_ion_register_heaps(void) return 0; } -device_initcall(exynos_ion_register_heaps); +subsys_initcall(exynos_ion_register_heaps); diff --git a/drivers/staging/android/ion/ion_hpa_heap.c b/drivers/staging/android/ion/ion_hpa_heap.c index ee03932103af..aad0234eaf45 100644 --- a/drivers/staging/android/ion/ion_hpa_heap.c +++ b/drivers/staging/android/ion/ion_hpa_heap.c @@ -34,6 +34,8 @@ struct ion_hpa_heap { struct ion_heap heap; unsigned int order; unsigned int protection_id; + phys_addr_t (*exception_areas)[2]; + int exception_count; bool secure; }; @@ -85,7 +87,9 @@ static int ion_hpa_allocate(struct ion_heap *heap, if (ret) goto err_sg; - ret = alloc_pages_highorder(hpa_heap->order, pages, count); + i = protected ? hpa_heap->exception_count : 0; + ret = alloc_pages_highorder_except(hpa_heap->order, pages, count, + hpa_heap->exception_areas, i); if (ret) goto err_pages; @@ -177,7 +181,9 @@ static struct ion_heap_ops ion_hpa_ops = { .query_heap = hpa_heap_query, }; -struct ion_heap *ion_hpa_heap_create(struct ion_platform_heap *data) +struct ion_heap *ion_hpa_heap_create(struct ion_platform_heap *data, + phys_addr_t except_areas[][2], + int n_except_areas) { struct ion_hpa_heap *heap; @@ -192,7 +198,8 @@ struct ion_heap *ion_hpa_heap_create(struct ion_platform_heap *data) heap->order = get_order(data->align); heap->protection_id = data->id; heap->secure = data->secure; - + heap->exception_areas = except_areas; + heap->exception_count = n_except_areas; return &heap->heap; }