blob: a35703082070cd2cfeaa15d35f63988b06ff0caa [file] [log] [blame]
John Stultz16100f62017-05-03 11:12:18 -07001/*
2 * Copyright (C) 2014 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 <cutils/log.h>
21#include <sys/mman.h>
22#include "gralloc_priv.h"
23#include "gralloc_buffer_priv.h"
24
25
26/*
27 * Allocate shared memory for attribute storage. Only to be
28 * used by gralloc internally.
29 *
30 * Return 0 on success.
31 */
32int gralloc_buffer_attr_allocate( private_handle_t *hnd )
33{
34 int rval = -1;
35
36 if( !hnd )
37 goto out;
38
39 if( hnd->share_attr_fd >= 0 )
40 {
41 ALOGW("Warning share attribute fd already exists during create. Closing.");
42 close( hnd->share_attr_fd );
43 }
44
45 hnd->share_attr_fd = ashmem_create_region( "gralloc_shared_attr", PAGE_SIZE );
46 if(hnd->share_attr_fd < 0)
47 {
48 ALOGE("Failed to allocate page for shared attribute region");
49 goto err_ashmem;
50 }
51
52 /*
53 * Default protection on the shm region is PROT_EXEC | PROT_READ | PROT_WRITE.
54 *
55 * Personality flag READ_IMPLIES_EXEC which is used by some processes, namely gdbserver,
56 * causes a mmap with PROT_READ to be translated to PROT_READ | PROT_EXEC.
57 *
58 * If we were to drop PROT_EXEC here with a call to ashmem_set_prot_region()
59 * this can potentially cause clients to fail importing this gralloc attribute buffer
60 * with EPERM error since PROT_EXEC is not allowed.
61 *
62 * Because of this we keep the PROT_EXEC flag.
63 */
64
65 hnd->attr_base = mmap( NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, hnd->share_attr_fd, 0 );
66 if(hnd->attr_base != MAP_FAILED)
67 {
68 /* The attribute region contains signed integers only.
69 * The reason for this is because we can set a value less than 0 for
70 * not-initialized values.
71 */
72 attr_region *region = (attr_region *) hnd->attr_base;
73
74 memset(hnd->attr_base, 0xff, PAGE_SIZE);
75 munmap( hnd->attr_base, PAGE_SIZE );
76 hnd->attr_base = MAP_FAILED;
77 }
78 else
79 {
80 ALOGE("Failed to mmap shared attribute region");
81 goto err_ashmem;
82 }
83
84 rval = 0;
85 goto out;
86
87err_ashmem:
88 if( hnd->share_attr_fd >= 0 )
89 {
90 close( hnd->share_attr_fd );
91 hnd->share_attr_fd = -1;
92 }
93
94out:
95 return rval;
96}
97
98/*
99 * Frees the shared memory allocated for attribute storage.
100 * Only to be used by gralloc internally.
101
102 * Return 0 on success.
103 */
104int gralloc_buffer_attr_free( private_handle_t *hnd )
105{
106 int rval = -1;
107
108 if( !hnd )
109 goto out;
110
111 if( hnd->share_attr_fd < 0 )
112 {
113 ALOGE("Shared attribute region not avail to free");
114 goto out;
115 }
116 if( hnd->attr_base != MAP_FAILED )
117 {
118 ALOGW("Warning shared attribute region mapped at free. Unmapping");
119 munmap( hnd->attr_base, PAGE_SIZE );
120 hnd->attr_base = MAP_FAILED;
121 }
122
123 close( hnd->share_attr_fd );
124 hnd->share_attr_fd = -1;
125 rval = 0;
126
127out:
128 return rval;
129}