android: ion: add support for HPA exception area
authorCho KyongHo <pullip.cho@samsung.com>
Thu, 3 May 2018 08:14:01 +0000 (17:14 +0900)
committerhyesoo.yu <hyesoo.yu@samsung.com>
Tue, 29 May 2018 06:31:41 +0000 (15:31 +0900)
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 <pullip.cho@samsung.com>
drivers/staging/android/ion/ion_exynos.h
drivers/staging/android/ion/ion_fdt_exynos.c
drivers/staging/android/ion/ion_hpa_heap.c

index 5a454c1f4761aaf6e3ddf09fae2aacfd101524b9..c22c5770dabf604a95fad7e9a36e8d07779693a8 100644 (file)
@@ -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)
index 04983a3275158677b014a05adf4427c33080bcc1..949705df119b3edea2a4d6d203b42f20c0dea40e 100644 (file)
@@ -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);
index ee03932103afa0ba6d1494d3f8f53215a22308b7..aad0234eaf456eebe119af392b2ae1a2bd91abe5 100644 (file)
@@ -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;
 }