[7e3826d9] | 1 | /*
|
---|
| 2 | * Copyright (c) 2017 Jakub Jermar
|
---|
| 3 | * All rights reserved.
|
---|
| 4 | *
|
---|
| 5 | * Redistribution and use in source and binary forms, with or without
|
---|
| 6 | * modification, are permitted provided that the following conditions
|
---|
| 7 | * are met:
|
---|
| 8 | *
|
---|
| 9 | * - Redistributions of source code must retain the above copyright
|
---|
| 10 | * notice, this list of conditions and the following disclaimer.
|
---|
| 11 | * - Redistributions in binary form must reproduce the above copyright
|
---|
| 12 | * notice, this list of conditions and the following disclaimer in the
|
---|
| 13 | * documentation and/or other materials provided with the distribution.
|
---|
| 14 | * - The name of the author may not be used to endorse or promote products
|
---|
| 15 | * derived from this software without specific prior written permission.
|
---|
| 16 | *
|
---|
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
---|
| 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
---|
| 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
---|
| 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
---|
| 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
---|
| 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
---|
| 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
---|
| 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
---|
| 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
---|
| 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
---|
| 27 | */
|
---|
| 28 |
|
---|
| 29 | /** @addtogroup generic
|
---|
| 30 | * @{
|
---|
| 31 | */
|
---|
| 32 | /** @file
|
---|
| 33 | */
|
---|
| 34 |
|
---|
[3f74275] | 35 | #include <cap/cap.h>
|
---|
[7e3826d9] | 36 | #include <proc/task.h>
|
---|
[9e87562] | 37 | #include <synch/mutex.h>
|
---|
[e9d15d9] | 38 | #include <abi/errno.h>
|
---|
[e7ac23d0] | 39 | #include <mm/slab.h>
|
---|
[9e87562] | 40 | #include <adt/list.h>
|
---|
[7e3826d9] | 41 |
|
---|
[e68765e] | 42 | void cap_initialize(cap_t *cap, int handle)
|
---|
[05ffb41] | 43 | {
|
---|
[3f74275] | 44 | cap->type = CAP_TYPE_INVALID;
|
---|
[e68765e] | 45 | cap->handle = handle;
|
---|
[3f74275] | 46 | cap->can_reclaim = NULL;
|
---|
[9e87562] | 47 | link_initialize(&cap->link);
|
---|
[05ffb41] | 48 | }
|
---|
| 49 |
|
---|
[3f74275] | 50 | void caps_task_alloc(task_t *task)
|
---|
[e7ac23d0] | 51 | {
|
---|
[9e87562] | 52 | task->cap_info = (cap_info_t *) malloc(sizeof(cap_info_t), 0);
|
---|
| 53 | task->cap_info->caps = malloc(sizeof(cap_t) * MAX_CAPS, 0);
|
---|
[e7ac23d0] | 54 | }
|
---|
| 55 |
|
---|
[3f74275] | 56 | void caps_task_init(task_t *task)
|
---|
[e7ac23d0] | 57 | {
|
---|
[9e87562] | 58 | mutex_initialize(&task->cap_info->lock, MUTEX_PASSIVE);
|
---|
| 59 |
|
---|
| 60 | for (int i = 0; i < CAP_TYPE_MAX; i++)
|
---|
| 61 | list_initialize(&task->cap_info->type_list[i]);
|
---|
| 62 |
|
---|
[3f74275] | 63 | for (int i = 0; i < MAX_CAPS; i++)
|
---|
[9e87562] | 64 | cap_initialize(&task->cap_info->caps[i], i);
|
---|
[e7ac23d0] | 65 | }
|
---|
| 66 |
|
---|
[3f74275] | 67 | void caps_task_free(task_t *task)
|
---|
[e7ac23d0] | 68 | {
|
---|
[9e87562] | 69 | free(task->cap_info->caps);
|
---|
| 70 | free(task->cap_info);
|
---|
| 71 | }
|
---|
| 72 |
|
---|
[6abfd250] | 73 | bool caps_apply_to_type(task_t *task, cap_type_t type,
|
---|
[9e87562] | 74 | bool (*cb)(cap_t *, void *), void *arg)
|
---|
| 75 | {
|
---|
| 76 | bool done = true;
|
---|
| 77 |
|
---|
| 78 | mutex_lock(&task->cap_info->lock);
|
---|
| 79 | list_foreach_safe(task->cap_info->type_list[type], cur, next) {
|
---|
| 80 | cap_t *cap = list_get_instance(cur, cap_t, link);
|
---|
| 81 | done = cb(cap, arg);
|
---|
| 82 | if (!done)
|
---|
| 83 | break;
|
---|
| 84 | }
|
---|
| 85 | mutex_unlock(&task->cap_info->lock);
|
---|
| 86 |
|
---|
| 87 | return done;
|
---|
| 88 | }
|
---|
| 89 |
|
---|
| 90 | void caps_lock(task_t *task)
|
---|
| 91 | {
|
---|
| 92 | mutex_lock(&task->cap_info->lock);
|
---|
| 93 | }
|
---|
| 94 |
|
---|
| 95 | void caps_unlock(task_t *task)
|
---|
| 96 | {
|
---|
| 97 | mutex_unlock(&task->cap_info->lock);
|
---|
[e7ac23d0] | 98 | }
|
---|
| 99 |
|
---|
[3f74275] | 100 | cap_t *cap_get(task_t *task, int handle, cap_type_t type)
|
---|
[7e3826d9] | 101 | {
|
---|
[9e87562] | 102 | assert(mutex_locked(&task->cap_info->lock));
|
---|
| 103 |
|
---|
[3f74275] | 104 | if ((handle < 0) || (handle >= MAX_CAPS))
|
---|
[7e3826d9] | 105 | return NULL;
|
---|
[9e87562] | 106 | if (task->cap_info->caps[handle].type != type)
|
---|
[7e3826d9] | 107 | return NULL;
|
---|
[9e87562] | 108 | return &task->cap_info->caps[handle];
|
---|
[7e3826d9] | 109 | }
|
---|
| 110 |
|
---|
[3f74275] | 111 | int cap_alloc(task_t *task)
|
---|
[7e3826d9] | 112 | {
|
---|
[3f74275] | 113 | int handle;
|
---|
[7e3826d9] | 114 |
|
---|
[9e87562] | 115 | mutex_lock(&task->cap_info->lock);
|
---|
[3f74275] | 116 | for (handle = 0; handle < MAX_CAPS; handle++) {
|
---|
[9e87562] | 117 | cap_t *cap = &task->cap_info->caps[handle];
|
---|
[3f74275] | 118 | if (cap->type > CAP_TYPE_ALLOCATED) {
|
---|
| 119 | if (cap->can_reclaim && cap->can_reclaim(cap))
|
---|
[e68765e] | 120 | cap_initialize(cap, handle);
|
---|
[05ffb41] | 121 | }
|
---|
[3f74275] | 122 | if (cap->type == CAP_TYPE_INVALID) {
|
---|
| 123 | cap->type = CAP_TYPE_ALLOCATED;
|
---|
[9e87562] | 124 | mutex_unlock(&task->cap_info->lock);
|
---|
[3f74275] | 125 | return handle;
|
---|
[7e3826d9] | 126 | }
|
---|
| 127 | }
|
---|
[9e87562] | 128 | mutex_unlock(&task->cap_info->lock);
|
---|
[7e3826d9] | 129 |
|
---|
[e9d15d9] | 130 | return ELIMIT;
|
---|
[7e3826d9] | 131 | }
|
---|
| 132 |
|
---|
[9e87562] | 133 | void cap_publish(task_t *task, int handle, cap_type_t type, void *kobject)
|
---|
| 134 | {
|
---|
| 135 | mutex_lock(&task->cap_info->lock);
|
---|
| 136 | cap_t *cap = cap_get(task, handle, CAP_TYPE_ALLOCATED);
|
---|
| 137 | assert(cap);
|
---|
| 138 | cap->type = type;
|
---|
| 139 | cap->kobject = kobject;
|
---|
| 140 | list_append(&cap->link, &task->cap_info->type_list[type]);
|
---|
| 141 | mutex_unlock(&task->cap_info->lock);
|
---|
| 142 | }
|
---|
| 143 |
|
---|
| 144 | cap_t *cap_unpublish(task_t *task, int handle, cap_type_t type)
|
---|
| 145 | {
|
---|
| 146 | cap_t *cap;
|
---|
| 147 |
|
---|
| 148 | mutex_lock(&task->cap_info->lock);
|
---|
| 149 | cap = cap_get(task, handle, type);
|
---|
| 150 | if (cap) {
|
---|
| 151 | list_remove(&cap->link);
|
---|
| 152 | cap->type = CAP_TYPE_ALLOCATED;
|
---|
| 153 | }
|
---|
| 154 | mutex_unlock(&task->cap_info->lock);
|
---|
| 155 |
|
---|
| 156 | return cap;
|
---|
| 157 | }
|
---|
| 158 |
|
---|
[3f74275] | 159 | void cap_free(task_t *task, int handle)
|
---|
[7e3826d9] | 160 | {
|
---|
[3f74275] | 161 | assert(handle >= 0);
|
---|
| 162 | assert(handle < MAX_CAPS);
|
---|
[9e87562] | 163 | assert(task->cap_info->caps[handle].type == CAP_TYPE_ALLOCATED);
|
---|
[7e3826d9] | 164 |
|
---|
[9e87562] | 165 | mutex_lock(&task->cap_info->lock);
|
---|
| 166 | cap_initialize(&task->cap_info->caps[handle], handle);
|
---|
| 167 | mutex_unlock(&task->cap_info->lock);
|
---|
[7e3826d9] | 168 | }
|
---|
| 169 |
|
---|
| 170 | /** @}
|
---|
| 171 | */
|
---|