Changeset 48bcf49 in mainline for kernel/generic/src/cap/cap.c
- Timestamp:
- 2017-09-28T22:08:15Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6636fb19
- Parents:
- dd20cbb
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/cap/cap.c
rdd20cbb r48bcf49 40 40 #include <adt/list.h> 41 41 42 void cap_initialize(cap_t *cap, int handle) 43 { 44 cap->type = CAP_TYPE_INVALID; 42 static kobject_t *cap_unpublish_locked(task_t *, cap_handle_t, kobject_type_t); 43 44 void cap_initialize(cap_t *cap, cap_handle_t handle) 45 { 46 cap->state = CAP_STATE_FREE; 45 47 cap->handle = handle; 46 cap->can_reclaim = NULL;47 48 link_initialize(&cap->link); 48 49 } … … 58 59 mutex_initialize(&task->cap_info->lock, MUTEX_PASSIVE); 59 60 60 for ( int i = 0; i < CAP_TYPE_MAX; i++)61 list_initialize(&task->cap_info->type_list[ i]);62 63 for ( int i = 0; i < MAX_CAPS; i++)64 cap_initialize(&task->cap_info->caps[ i], i);61 for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++) 62 list_initialize(&task->cap_info->type_list[t]); 63 64 for (cap_handle_t h = 0; h < MAX_CAPS; h++) 65 cap_initialize(&task->cap_info->caps[h], h); 65 66 } 66 67 … … 71 72 } 72 73 73 bool caps_apply_to_ type(task_t *task, cap_type_t type,74 bool caps_apply_to_kobject_type(task_t *task, kobject_type_t type, 74 75 bool (*cb)(cap_t *, void *), void *arg) 75 76 { … … 88 89 } 89 90 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); 98 } 99 100 cap_t *cap_get(task_t *task, int handle, cap_type_t type) 91 static cap_t *cap_get(task_t *task, cap_handle_t handle, cap_state_t state) 101 92 { 102 93 assert(mutex_locked(&task->cap_info->lock)); … … 104 95 if ((handle < 0) || (handle >= MAX_CAPS)) 105 96 return NULL; 106 if (task->cap_info->caps[handle]. type != type)97 if (task->cap_info->caps[handle].state != state) 107 98 return NULL; 108 99 return &task->cap_info->caps[handle]; 109 100 } 110 101 111 int cap_alloc(task_t *task) 112 { 113 int handle; 114 115 mutex_lock(&task->cap_info->lock); 116 for (handle = 0; handle < MAX_CAPS; handle++) { 102 cap_handle_t cap_alloc(task_t *task) 103 { 104 mutex_lock(&task->cap_info->lock); 105 for (cap_handle_t handle = 0; handle < MAX_CAPS; handle++) { 117 106 cap_t *cap = &task->cap_info->caps[handle]; 118 if (cap->type > CAP_TYPE_ALLOCATED) { 119 if (cap->can_reclaim && cap->can_reclaim(cap)) { 120 list_remove(&cap->link); 121 cap_initialize(cap, handle); 122 } 123 } 124 if (cap->type == CAP_TYPE_INVALID) { 125 cap->type = CAP_TYPE_ALLOCATED; 107 /* See if the capability should be garbage-collected */ 108 if (cap->state == CAP_STATE_PUBLISHED && 109 cap->kobject->ops->reclaim && 110 cap->kobject->ops->reclaim(cap->kobject)) { 111 kobject_t *kobj = cap_unpublish_locked(task, handle, 112 cap->kobject->type); 113 kobject_put(kobj); 114 cap_initialize(&task->cap_info->caps[handle], handle); 115 } 116 if (cap->state == CAP_STATE_FREE) { 117 cap->state = CAP_STATE_ALLOCATED; 126 118 mutex_unlock(&task->cap_info->lock); 127 119 return handle; … … 133 125 } 134 126 135 void cap_publish(task_t *task, int handle, cap_type_t type, void *kobject) 136 { 137 mutex_lock(&task->cap_info->lock); 138 cap_t *cap = cap_get(task, handle, CAP_TYPE_ALLOCATED); 127 void 128 cap_publish(task_t *task, cap_handle_t handle, kobject_t *kobj) 129 { 130 mutex_lock(&task->cap_info->lock); 131 cap_t *cap = cap_get(task, handle, CAP_STATE_ALLOCATED); 139 132 assert(cap); 140 cap->type = type; 141 cap->kobject = kobject; 142 list_append(&cap->link, &task->cap_info->type_list[type]); 143 mutex_unlock(&task->cap_info->lock); 144 } 145 146 cap_t *cap_unpublish(task_t *task, int handle, cap_type_t type) 147 { 148 cap_t *cap; 149 150 mutex_lock(&task->cap_info->lock); 151 cap = cap_get(task, handle, type); 133 cap->state = CAP_STATE_PUBLISHED; 134 /* Hand over kobj's reference to cap */ 135 cap->kobject = kobj; 136 list_append(&cap->link, &task->cap_info->type_list[kobj->type]); 137 mutex_unlock(&task->cap_info->lock); 138 } 139 140 static kobject_t * 141 cap_unpublish_locked(task_t *task, cap_handle_t handle, kobject_type_t type) 142 { 143 kobject_t *kobj = NULL; 144 145 cap_t *cap = cap_get(task, handle, CAP_STATE_PUBLISHED); 152 146 if (cap) { 153 list_remove(&cap->link); 154 cap->type = CAP_TYPE_ALLOCATED; 155 } 156 mutex_unlock(&task->cap_info->lock); 157 158 return cap; 159 } 160 161 void cap_free(task_t *task, int handle) 147 if (cap->kobject->type == type) { 148 /* Hand over cap's reference to kobj */ 149 kobj = cap->kobject; 150 cap->kobject = NULL; 151 list_remove(&cap->link); 152 cap->state = CAP_STATE_ALLOCATED; 153 } 154 } 155 156 return kobj; 157 } 158 kobject_t *cap_unpublish(task_t *task, cap_handle_t handle, kobject_type_t type) 159 { 160 161 mutex_lock(&task->cap_info->lock); 162 kobject_t *kobj = cap_unpublish_locked(task, handle, type); 163 mutex_unlock(&task->cap_info->lock); 164 165 return kobj; 166 } 167 168 void cap_free(task_t *task, cap_handle_t handle) 162 169 { 163 170 assert(handle >= 0); 164 171 assert(handle < MAX_CAPS); 165 assert(task->cap_info->caps[handle]. type == CAP_TYPE_ALLOCATED);172 assert(task->cap_info->caps[handle].state == CAP_STATE_ALLOCATED); 166 173 167 174 mutex_lock(&task->cap_info->lock); … … 170 177 } 171 178 179 void kobject_initialize(kobject_t *kobj, kobject_type_t type, void *raw, 180 kobject_ops_t *ops) 181 { 182 atomic_set(&kobj->refcnt, 1); 183 kobj->type = type; 184 kobj->raw = raw; 185 kobj->ops = ops; 186 } 187 188 kobject_t * 189 kobject_get(struct task *task, cap_handle_t handle, kobject_type_t type) 190 { 191 kobject_t *kobj = NULL; 192 193 mutex_lock(&task->cap_info->lock); 194 cap_t *cap = cap_get(task, handle, CAP_STATE_PUBLISHED); 195 if (cap) { 196 if (cap->kobject->type == type) { 197 kobj = cap->kobject; 198 atomic_inc(&kobj->refcnt); 199 } 200 } 201 mutex_unlock(&task->cap_info->lock); 202 203 return kobj; 204 } 205 206 void kobject_put(kobject_t *kobj) 207 { 208 if (atomic_postdec(&kobj->refcnt) == 1) { 209 kobj->ops->destroy(kobj->raw); 210 free(kobj); 211 } 212 } 213 172 214 /** @} 173 215 */
Note:
See TracChangeset
for help on using the changeset viewer.