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