source: mainline/kernel/generic/src/cap/cap.c@ 6abfd250

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

Rename caps_apply_to_all to caps_apply_to_type

  • 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
[6abfd250]73bool 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
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.