Changeset c1f68b0 in mainline for kernel/generic/src/cap/cap.c


Ignore:
Timestamp:
2017-10-28T11:40:41Z (6 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
eca820c
Parents:
15d9fe6
Message:

Use recursive mutex to protect task_t::cap_info

This makes it possible to use the mutex-protected capability APIs even
inside caps_apply_to_kobject_type() callbacks. Now there is no need to
provide eg. cap_unpublish_locked() and cap_free_locked(). Likewise,
ipc_irq_unsubscribe() can be used when the task's cap_info is already
locked by the current thread inside of a callback.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/cap/cap.c

    r15d9fe6 rc1f68b0  
    148148void caps_task_init(task_t *task)
    149149{
    150         mutex_initialize(&task->cap_info->lock, MUTEX_PASSIVE);
     150        mutex_initialize(&task->cap_info->lock, MUTEX_RECURSIVE);
    151151
    152152        for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++)
     
    238238        if (cap->state == CAP_STATE_PUBLISHED && cap->kobject->ops->reclaim &&
    239239            cap->kobject->ops->reclaim(cap->kobject)) {
    240                 kobject_t *kobj = cap_unpublish_locked(cap->task, cap->handle,
     240                kobject_t *kobj = cap_unpublish(cap->task, cap->handle,
    241241                    cap->kobject->type);
    242242                kobject_put(kobj);
     
    318318}
    319319
    320 /** @copydoc cap_unpublish()
    321  *
    322  * Can only be called internally by the capability subsytem or from a
    323  * caps_apply_to_kobject_type() callback.
    324  */
    325 kobject_t *
    326 cap_unpublish_locked(task_t *task, cap_handle_t handle, kobject_type_t type)
     320/** Unpublish published capability
     321 *
     322 * The kernel object is moved out of the capability. In other words, the
     323 * capability's reference to the objects is handed over to the kernel object
     324 * pointer returned by this function. Once unpublished, the capability does not
     325 * refer to any kernel object anymore.
     326 *
     327 * @param task    Task in which to unpublish the capability.
     328 * @param handle  Capability handle.
     329 * @param type    Kernel object type of the object associated with the
     330 *                capability.
     331 */
     332kobject_t *cap_unpublish(task_t *task, cap_handle_t handle, kobject_type_t type)
    327333{
    328334        kobject_t *kobj = NULL;
    329335
     336        mutex_lock(&task->cap_info->lock);
    330337        cap_t *cap = cap_get(task, handle, CAP_STATE_PUBLISHED);
    331338        if (cap) {
     
    338345                }
    339346        }
     347        mutex_unlock(&task->cap_info->lock);
    340348
    341349        return kobj;
    342350}
    343351
    344 /** Unpublish published capability
    345  *
    346  * The kernel object is moved out of the capability. In other words, the
    347  * capability's reference to the objects is handed over to the kernel object
    348  * pointer returned by this function. Once unpublished, the capability does not
    349  * refer to any kernel object anymore.
    350  *
    351  * @param task    Task in which to unpublish the capability.
     352/** Free allocated capability
     353 *
     354 * @param task    Task in which to free the capability.
    352355 * @param handle  Capability handle.
    353  * @param type    Kernel object type of the object associated with the
    354  *                capability.
    355  */
    356 kobject_t *cap_unpublish(task_t *task, cap_handle_t handle, kobject_type_t type)
    357 {
    358 
    359         mutex_lock(&task->cap_info->lock);
    360         kobject_t *kobj = cap_unpublish_locked(task, handle, type);
    361         mutex_unlock(&task->cap_info->lock);
    362 
    363         return kobj;
    364 }
    365 
    366 /** @copydoc cap_free()
    367  *
    368  * Can only be called internally by the capability subsytem or from a
    369  * caps_apply_to_kobject_type() callback.
    370  */
    371 void cap_free_locked(task_t *task, cap_handle_t handle)
     356 */
     357void cap_free(task_t *task, cap_handle_t handle)
    372358{
    373359        assert(handle >= 0);
    374360        assert(handle < MAX_CAPS);
    375361
     362        mutex_lock(&task->cap_info->lock);
    376363        cap_t *cap = cap_get(task, handle, CAP_STATE_ALLOCATED);
    377364
     
    381368        ra_free(task->cap_info->handles, handle, 1);
    382369        slab_free(cap_slab, cap);
    383 }
    384 
    385 /** Free allocated capability
    386  *
    387  * @param task    Task in which to free the capability.
    388  * @param handle  Capability handle.
    389  */
    390 void cap_free(task_t *task, cap_handle_t handle)
    391 {
    392         mutex_lock(&task->cap_info->lock);
    393         cap_free_locked(task, handle);
    394370        mutex_unlock(&task->cap_info->lock);
    395371}
Note: See TracChangeset for help on using the changeset viewer.