• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define TLOG_TAG "coverage-common-shm"
18 
19 #include <assert.h>
20 #include <lib/coverage/common/cov_shm.h>
21 #include <lk/macros.h>
22 #include <stdlib.h>
23 #include <sys/auxv.h>
24 #include <sys/mman.h>
25 #include <trusty/memref.h>
26 #include <trusty_log.h>
27 #include <uapi/err.h>
28 
29 #define PAGE_SIZE getauxval(AT_PAGESZ)
30 #define MMAP_FLAG_PROT_RW (MMAP_FLAG_PROT_READ | MMAP_FLAG_PROT_WRITE)
31 
cov_shm_alloc(struct cov_shm * shm,size_t len)32 int cov_shm_alloc(struct cov_shm* shm, size_t len) {
33     int rc;
34     void* base;
35     size_t shm_len;
36 
37     shm_len = round_up(len, PAGE_SIZE);
38     base = memalign(PAGE_SIZE, shm_len);
39     if (!base) {
40         TLOGE("failed to allocate %zu bytes of shared memory\n", shm_len);
41         return ERR_NO_MEMORY;
42     }
43 
44     rc = memref_create(base, shm_len, MMAP_FLAG_PROT_RW);
45     if (rc < 0) {
46         TLOGE("failed (%d) to create memref\n", rc);
47         free(shm);
48         return rc;
49     }
50 
51     shm->memref = (handle_t)rc;
52     shm->base = base;
53     shm->len = shm_len;
54 
55     cov_shm_clear(shm);
56     return NO_ERROR;
57 }
58 
cov_shm_free(struct cov_shm * shm)59 void cov_shm_free(struct cov_shm* shm) {
60     /*
61      * TODO: HACK: No way to safely deallocate memory that has already been
62      * shared, but works in practice.
63      */
64     free(shm->base);
65     close(shm->memref);
66     shm->memref = INVALID_IPC_HANDLE;
67     shm->base = NULL;
68     shm->len = 0;
69 }
70 
cov_shm_mmap(struct cov_shm * shm,handle_t memref,size_t len)71 int cov_shm_mmap(struct cov_shm* shm, handle_t memref, size_t len) {
72     void* base = mmap(0, len, MMAP_FLAG_PROT_RW, 0, memref, 0);
73     if (base == MAP_FAILED) {
74         TLOGE("failed to mmap() shared memory\n");
75         return ERR_BAD_HANDLE;
76     }
77 
78     shm->memref = memref;
79     shm->base = base;
80     shm->len = len;
81     return NO_ERROR;
82 }
83 
cov_shm_munmap(struct cov_shm * shm)84 void cov_shm_munmap(struct cov_shm* shm) {
85     assert(cov_shm_is_mapped(shm));
86 
87     munmap(shm->base, shm->len);
88     close(shm->memref);
89     shm->memref = INVALID_IPC_HANDLE;
90     shm->base = NULL;
91     shm->len = 0;
92 }
93 
cov_shm_clear(struct cov_shm * shm)94 void cov_shm_clear(struct cov_shm* shm) {
95     assert(cov_shm_is_mapped(shm));
96 
97     for (size_t i = 0; i < shm->len; i++) {
98         WRITE_ONCE(*((uint8_t*)(shm->base) + i), 0);
99     }
100 }
101