blob: 71773eb0f59bb747507412b7f2d20ff3d5523fd2
1 | /* |
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 | */ |
32 | int 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 | |
87 | err_ashmem: |
88 | if ( hnd->share_attr_fd >= 0 ) |
89 | { |
90 | close( hnd->share_attr_fd ); |
91 | hnd->share_attr_fd = -1; |
92 | } |
93 | |
94 | out: |
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 | */ |
104 | int 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 | |
127 | out: |
128 | return rval; |
129 | } |
130 |