Home | History | Annotate | Download | only in gralloc960
      1 /*
      2  * Copyright (C) 2014-2017 ARM Limited. All rights reserved.
      3  *
      4  * Copyright (C) 2008 The Android Open Source Project
      5  *
      6  * Licensed under the Apache License, Version 2.0 (the "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *      http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  */
     18 
     19 #include <cutils/ashmem.h>
     20 #include <log/log.h>
     21 #include <sys/mman.h>
     22 
     23 #if GRALLOC_USE_GRALLOC1_API == 1
     24 #include <hardware/gralloc1.h>
     25 #else
     26 #include <hardware/gralloc.h>
     27 #endif
     28 
     29 #include "mali_gralloc_module.h"
     30 #include "mali_gralloc_private_interface_types.h"
     31 #include "mali_gralloc_buffer.h"
     32 #include "gralloc_buffer_priv.h"
     33 
     34 /*
     35  * Allocate shared memory for attribute storage. Only to be
     36  * used by gralloc internally.
     37  *
     38  * Return 0 on success.
     39  */
     40 int gralloc_buffer_attr_allocate(private_handle_t *hnd)
     41 {
     42 	int rval = -1;
     43 
     44 	if (!hnd)
     45 	{
     46 		goto out;
     47 	}
     48 
     49 	if (hnd->share_attr_fd >= 0)
     50 	{
     51 		ALOGW("Warning share attribute fd already exists during create. Closing.");
     52 		close(hnd->share_attr_fd);
     53 	}
     54 
     55 	hnd->share_attr_fd = ashmem_create_region("gralloc_shared_attr", PAGE_SIZE);
     56 
     57 	if (hnd->share_attr_fd < 0)
     58 	{
     59 		ALOGE("Failed to allocate page for shared attribute region");
     60 		goto err_ashmem;
     61 	}
     62 
     63 	/*
     64 	 * Default protection on the shm region is PROT_EXEC | PROT_READ | PROT_WRITE.
     65 	 *
     66 	 * Personality flag READ_IMPLIES_EXEC which is used by some processes, namely gdbserver,
     67 	 * causes a mmap with PROT_READ to be translated to PROT_READ | PROT_EXEC.
     68 	 *
     69 	 * If we were to drop PROT_EXEC here with a call to ashmem_set_prot_region()
     70 	 * this can potentially cause clients to fail importing this gralloc attribute buffer
     71 	 * with EPERM error since PROT_EXEC is not allowed.
     72 	 *
     73 	 * Because of this we keep the PROT_EXEC flag.
     74 	 */
     75 
     76 	hnd->attr_base = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, hnd->share_attr_fd, 0);
     77 
     78 	if (hnd->attr_base != MAP_FAILED)
     79 	{
     80 		/* The attribute region contains signed integers only.
     81 		 * The reason for this is because we can set a value less than 0 for
     82 		 * not-initialized values.
     83 		 */
     84 		attr_region *region = (attr_region *)hnd->attr_base;
     85 
     86 		memset(hnd->attr_base, 0xff, PAGE_SIZE);
     87 		munmap(hnd->attr_base, PAGE_SIZE);
     88 		hnd->attr_base = MAP_FAILED;
     89 	}
     90 	else
     91 	{
     92 		ALOGE("Failed to mmap shared attribute region");
     93 		goto err_ashmem;
     94 	}
     95 
     96 	rval = 0;
     97 	goto out;
     98 
     99 err_ashmem:
    100 
    101 	if (hnd->share_attr_fd >= 0)
    102 	{
    103 		close(hnd->share_attr_fd);
    104 		hnd->share_attr_fd = -1;
    105 	}
    106 
    107 out:
    108 	return rval;
    109 }
    110 
    111 /*
    112  * Frees the shared memory allocated for attribute storage.
    113  * Only to be used by gralloc internally.
    114 
    115  * Return 0 on success.
    116  */
    117 int gralloc_buffer_attr_free(private_handle_t *hnd)
    118 {
    119 	int rval = -1;
    120 
    121 	if (!hnd)
    122 	{
    123 		goto out;
    124 	}
    125 
    126 	if (hnd->share_attr_fd < 0)
    127 	{
    128 		ALOGE("Shared attribute region not avail to free");
    129 		goto out;
    130 	}
    131 
    132 	if (hnd->attr_base != MAP_FAILED)
    133 	{
    134 		ALOGW("Warning shared attribute region mapped at free. Unmapping");
    135 		munmap(hnd->attr_base, PAGE_SIZE);
    136 		hnd->attr_base = MAP_FAILED;
    137 	}
    138 
    139 	close(hnd->share_attr_fd);
    140 	hnd->share_attr_fd = -1;
    141 	rval = 0;
    142 
    143 out:
    144 	return rval;
    145 }
    146