1 /*
2  * Copyright (C) 2014-2018 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 #if GRALLOC_USE_ASHMEM_METADATA == 1
20 #include <cutils/ashmem.h>
21 #else
22 #include "mali_gralloc_ion.h"
23 #endif
24 
25 #include <log/log.h>
26 #include <sys/mman.h>
27 
28 #if GRALLOC_VERSION_MAJOR == 1
29 #include <hardware/gralloc1.h>
30 #elif GRALLOC_VERSION_MAJOR == 0
31 #include <hardware/gralloc.h>
32 #endif
33 
34 #include "mali_gralloc_module.h"
35 #include "mali_gralloc_private_interface_types.h"
36 #include "mali_gralloc_buffer.h"
37 #include "gralloc_buffer_priv.h"
38 
39 /*
40  * Allocate shared memory for attribute storage. Only to be
41  * used by gralloc internally.
42  *
43  * Return 0 on success.
44  */
gralloc_buffer_attr_allocate(private_handle_t * hnd)45 int gralloc_buffer_attr_allocate(private_handle_t *hnd)
46 {
47 	int rval = -1;
48 	int share_attr_fd = -1;
49 
50 	if (!hnd)
51 	{
52 		goto out;
53 	}
54 
55 	share_attr_fd = hnd->get_share_attr_fd();
56 	if (share_attr_fd >= 0)
57 	{
58 		ALOGW("Warning share attribute fd already exists during create. Closing.");
59 		close(share_attr_fd);
60 	}
61 
62 #if GRALLOC_USE_ASHMEM_METADATA == 1
63 	share_attr_fd = ashmem_create_region("gralloc_shared_attr", PAGE_SIZE);
64 #else
65 	share_attr_fd = alloc_metadata();
66 #endif
67 
68 	if (share_attr_fd < 0)
69 	{
70 		ALOGE("Failed to allocate page for shared attribute region");
71 		goto err_ashmem;
72 	}
73 
74 	/*
75 	 * Default protection on the shm region is PROT_EXEC | PROT_READ | PROT_WRITE.
76 	 *
77 	 * Personality flag READ_IMPLIES_EXEC which is used by some processes, namely gdbserver,
78 	 * causes a mmap with PROT_READ to be translated to PROT_READ | PROT_EXEC.
79 	 *
80 	 * If we were to drop PROT_EXEC here with a call to ashmem_set_prot_region()
81 	 * this can potentially cause clients to fail importing this gralloc attribute buffer
82 	 * with EPERM error since PROT_EXEC is not allowed.
83 	 *
84 	 * Because of this we keep the PROT_EXEC flag.
85 	 */
86 
87 	hnd->attr_base = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, share_attr_fd, 0);
88 
89 	if (hnd->attr_base != MAP_FAILED)
90 	{
91 		memset(hnd->attr_base, 0xff, PAGE_SIZE);
92 		munmap(hnd->attr_base, PAGE_SIZE);
93 		hnd->attr_base = MAP_FAILED;
94 	}
95 	else
96 	{
97 		ALOGE("Failed to mmap shared attribute region");
98 		goto err_ashmem;
99 	}
100 
101 	hnd->set_share_attr_fd(share_attr_fd);
102 
103 	rval = 0;
104 	goto out;
105 
106 err_ashmem:
107 
108 	if (share_attr_fd >= 0)
109 	{
110 		close(share_attr_fd);
111 		hnd->set_share_attr_fd(-1);
112 	}
113 
114 out:
115 	return rval;
116 }
117 
118 /*
119  * Frees the shared memory allocated for attribute storage.
120  * Only to be used by gralloc internally.
121 
122  * Return 0 on success.
123  */
gralloc_buffer_attr_free(private_handle_t * hnd)124 int gralloc_buffer_attr_free(private_handle_t *hnd)
125 {
126 	int rval = -1;
127 	int share_attr_fd = -1;
128 
129 	if (!hnd)
130 	{
131 		goto out;
132 	}
133 
134 	share_attr_fd = hnd->get_share_attr_fd();
135 	if (share_attr_fd < 0)
136 	{
137 		ALOGE("Shared attribute region not avail to free");
138 		goto out;
139 	}
140 
141 	if (hnd->attr_base != MAP_FAILED)
142 	{
143 		AWAR("Warning shared attribute region mapped at free. Unmapping on pid(%d) tid(%d)", getpid(), gettid());
144 		hnd->dump(__FUNCTION__);
145 		munmap(hnd->attr_base, PAGE_SIZE);
146 		hnd->attr_base = MAP_FAILED;
147 	}
148 
149 	close(share_attr_fd);
150 	hnd->set_share_attr_fd(-1);
151 	rval = 0;
152 
153 out:
154 	return rval;
155 }
156