Changeset d24e987 in mainline
- Timestamp:
- 2018-10-16T18:03:43Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2d93763a, e344422
- Parents:
- c0cef6f9
- git-author:
- Jakub Jermar <jakub@…> (2018-10-16 17:55:57)
- git-committer:
- Jakub Jermar <jakub@…> (2018-10-16 18:03:43)
- Location:
- kernel/generic
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/cap/cap.h
rc0cef6f9 rd24e987 69 69 70 70 /* 71 * Everything in kobject_t except for the atomic reference count is imutable. 71 * Everything in kobject_t except for the atomic reference count, the capability 72 * list and its lock is imutable. 72 73 */ 73 74 typedef struct kobject { 74 75 kobject_type_t type; 75 76 atomic_t refcnt; 77 78 /** Mutex protecting caps_list */ 79 mutex_t caps_list_lock; 80 /** List of published capabilities associated with the kobject */ 81 list_t caps_list; 76 82 77 83 kobject_ops_t *ops; … … 93 99 struct task *task; 94 100 cap_handle_t handle; 101 102 /** Link to the kobject's list of capabilities. */ 103 link_t kobj_link; 95 104 96 105 /* Link to the task's capabilities of the same kobject type. */ … … 122 131 extern void cap_publish(struct task *, cap_handle_t, kobject_t *); 123 132 extern kobject_t *cap_unpublish(struct task *, cap_handle_t, kobject_type_t); 133 extern void cap_revoke(kobject_t *); 124 134 extern void cap_free(struct task *, cap_handle_t); 125 135 -
kernel/generic/src/cap/cap.c
rc0cef6f9 rd24e987 63 63 * kobject_add_ref() or as a result of unpublishing a capability and 64 64 * disassociating it from its kobject_t using cap_unpublish(). 65 * 66 * A holder of an explicit reference to a kernel object may revoke access to it 67 * from all capabilities that point to it by calling cap_revoke(). 65 68 * 66 69 * As kernel objects are reference-counted, they get automatically destroyed … … 208 211 cap->task = task; 209 212 cap->handle = handle; 213 link_initialize(&cap->kobj_link); 210 214 link_initialize(&cap->type_link); 211 215 } … … 281 285 cap_publish(task_t *task, cap_handle_t handle, kobject_t *kobj) 282 286 { 287 mutex_lock(&kobj->caps_list_lock); 283 288 mutex_lock(&task->cap_info->lock); 284 289 cap_t *cap = cap_get(task, handle, CAP_STATE_ALLOCATED); … … 287 292 /* Hand over kobj's reference to cap */ 288 293 cap->kobject = kobj; 294 list_append(&cap->kobj_link, &kobj->caps_list); 289 295 list_append(&cap->type_link, &task->cap_info->type_list[kobj->type]); 290 296 mutex_unlock(&task->cap_info->lock); 297 mutex_unlock(&kobj->caps_list_lock); 298 } 299 300 static void cap_unpublish_unsafe(cap_t *cap) 301 { 302 cap->kobject = NULL; 303 list_remove(&cap->kobj_link); 304 list_remove(&cap->type_link); 305 cap->state = CAP_STATE_ALLOCATED; 291 306 } 292 307 … … 302 317 * @param type Kernel object type of the object associated with the 303 318 * capability. 319 * 320 * @return Pointer and explicit reference to the kobject that was associated 321 * with the capability. 304 322 */ 305 323 kobject_t *cap_unpublish(task_t *task, cap_handle_t handle, kobject_type_t type) … … 307 325 kobject_t *kobj = NULL; 308 326 327 restart: 309 328 mutex_lock(&task->cap_info->lock); 310 329 cap_t *cap = cap_get(task, handle, CAP_STATE_PUBLISHED); … … 313 332 /* Hand over cap's reference to kobj */ 314 333 kobj = cap->kobject; 315 cap->kobject = NULL; 316 list_remove(&cap->type_link); 317 cap->state = CAP_STATE_ALLOCATED; 334 if (!mutex_trylock(&kobj->caps_list_lock)) { 335 mutex_unlock(&task->cap_info->lock); 336 kobj = NULL; 337 goto restart; 338 } 339 cap_unpublish_unsafe(cap); 340 mutex_unlock(&kobj->caps_list_lock); 318 341 } 319 342 } … … 321 344 322 345 return kobj; 346 } 347 348 /** Revoke access to kobject from all existing capabilities 349 * 350 * All published capabilities associated with the kobject are unpublished (i.e. 351 * their new state is set to CAP_STATE_ALLOCATED) and no longer point to the 352 * kobject. Kobject's reference count is decreased accordingly. 353 * 354 * Note that the caller is supposed to hold an explicit reference to the kobject 355 * so that the kobject is guaranteed to exist when this function returns. 356 * 357 * @param kobj Pointer and explicit reference to the kobject capabilities of 358 * which are about to be unpublished. 359 */ 360 void cap_revoke(kobject_t *kobj) 361 { 362 mutex_lock(&kobj->caps_list_lock); 363 list_foreach_safe(kobj->caps_list, cur, hlp) { 364 cap_t *cap = list_get_instance(cur, cap_t, kobj_link); 365 mutex_lock(&cap->task->cap_info->lock); 366 cap_unpublish_unsafe(cap); 367 /* Drop the reference for the unpublished capability */ 368 kobject_put(kobj); 369 mutex_unlock(&cap->task->cap_info->lock); 370 } 371 mutex_unlock(&kobj->caps_list_lock); 323 372 } 324 373 … … 355 404 { 356 405 atomic_store(&kobj->refcnt, 1); 406 407 mutex_initialize(&kobj->caps_list_lock, MUTEX_PASSIVE); 408 list_initialize(&kobj->caps_list); 409 357 410 kobj->type = type; 358 411 kobj->raw = raw;
Note:
See TracChangeset
for help on using the changeset viewer.