source: mainline/kernel/generic/src/cap/cap.c@ 9e87562

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 9e87562 was 9e87562, checked in by Jakub Jermar <jakub@…>, 8 years ago

Make all accesses to capabilites exclusive

This commit makes sure that all accesses to the capabilities array and other
metadata are protected by a mutex. This is necessary for future resizing of the
capabilities array.

Group task's capabilities by type so that it is possible to visit all
capabilities of the given type effectively.

Provide cap_publish() and cap_unpublish() to automate steps that make the
capability visible/invisible to userspace and insert/remove the capability from
the respective type list.

  • Property mode set to 100644
File size: 4.4 KB
RevLine 
[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]42void 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]50void 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]56void 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]67void caps_task_free(task_t *task)
[e7ac23d0]68{
[9e87562]69 free(task->cap_info->caps);
70 free(task->cap_info);
71}
72
73bool caps_apply_to_all(task_t *task, cap_type_t type,
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
90void caps_lock(task_t *task)
91{
92 mutex_lock(&task->cap_info->lock);
93}
94
95void caps_unlock(task_t *task)
96{
97 mutex_unlock(&task->cap_info->lock);
[e7ac23d0]98}
99
[3f74275]100cap_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]111int 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]133void 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
144cap_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]159void 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 */
Note: See TracBrowser for help on using the repository browser.