Changeset 6caf5fb in mainline for kernel/generic/src/cap/cap.c


Ignore:
Timestamp:
2025-01-16T21:42:15Z (20 hours ago)
Author:
GitHub <noreply@…>
Parents:
e0e2264 (diff), 455241b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2025-01-16 21:42:15)
git-committer:
GitHub <noreply@…> (2025-01-16 21:42:15)
Message:

Merge 455241b37bedd3719ed3b5b025fdf26f44fd565b into e0e22648f5799cc98671695e153b0b00037daeb9

File:
1 edited

Legend:

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

    re0e2264 r6caf5fb  
    9393
    9494#define CAPS_START      ((intptr_t) CAP_NIL + 1)
    95 #define CAPS_SIZE       (INT_MAX - (int) CAPS_START)
    96 #define CAPS_LAST       (CAPS_SIZE - 1)
     95#define CAPS_LAST       ((intptr_t) INT_MAX - 1)
     96#define CAPS_SIZE       (CAPS_LAST - CAPS_START + 1)
    9797
    9898static slab_cache_t *cap_cache;
    99 static slab_cache_t *kobject_cache;
    10099
    101100kobject_ops_t *kobject_ops[KOBJECT_TYPE_MAX] = {
     
    125124}
    126125
     126static void caps_remove_callback(ht_link_t *item)
     127{
     128        cap_t *cap = hash_table_get_inst(item, cap_t, caps_link);
     129
     130        if (cap->kobject) {
     131                kobject_t *kobj = cap->kobject;
     132
     133                mutex_lock(&kobj->caps_list_lock);
     134                cap->kobject = NULL;
     135                list_remove(&cap->kobj_link);
     136                mutex_unlock(&kobj->caps_list_lock);
     137
     138                kobject_put(kobj);
     139        }
     140
     141        list_remove(&cap->type_link);
     142
     143        slab_free(cap_cache, cap);
     144}
     145
    127146static const hash_table_ops_t caps_ops = {
    128147        .hash = caps_hash,
    129148        .key_hash = caps_key_hash,
    130         .key_equal = caps_key_equal
     149        .key_equal = caps_key_equal,
     150        .remove_callback = caps_remove_callback,
    131151};
    132152
     
    135155        cap_cache = slab_cache_create("cap_t", sizeof(cap_t), 0, NULL,
    136156            NULL, 0);
    137         kobject_cache = slab_cache_create("kobject_t", sizeof(kobject_t), 0,
    138             NULL, NULL, 0);
    139157}
    140158
     
    148166        if (!task->cap_info)
    149167                return ENOMEM;
     168
     169        if (!hash_table_create(&task->cap_info->caps, 0, 0, &caps_ops)) {
     170                free(task->cap_info);
     171                return ENOMEM;
     172        }
     173
     174        mutex_initialize(&task->cap_info->lock, MUTEX_RECURSIVE);
     175
     176        task->cap_info->handles = NULL;
     177
     178        for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++)
     179                list_initialize(&task->cap_info->type_list[t]);
     180
     181        return EOK;
     182}
     183
     184/** Initialize the capability info structure
     185 *
     186 * @param task  Task for which to initialize the info structure.
     187 */
     188errno_t caps_task_init(task_t *task)
     189{
     190        assert(task->cap_info);
     191        assert(!task->cap_info->handles);
     192
    150193        task->cap_info->handles = ra_arena_create();
    151194        if (!task->cap_info->handles)
    152                 goto error_handles;
    153         if (!ra_span_add(task->cap_info->handles, CAPS_START, CAPS_SIZE))
    154                 goto error_span;
    155         if (!hash_table_create(&task->cap_info->caps, 0, 0, &caps_ops))
    156                 goto error_span;
     195                return ENOMEM;
     196
     197        if (!ra_span_add(task->cap_info->handles, CAPS_START, CAPS_SIZE)) {
     198                ra_arena_destroy(task->cap_info->handles);
     199                return ENOMEM;
     200        }
     201
    157202        return EOK;
    158 
    159 error_span:
    160         ra_arena_destroy(task->cap_info->handles);
    161 error_handles:
    162         free(task->cap_info);
    163         return ENOMEM;
    164 }
    165 
    166 /** Initialize the capability info structure
    167  *
    168  * @param task  Task for which to initialize the info structure.
    169  */
    170 void caps_task_init(task_t *task)
    171 {
    172         mutex_initialize(&task->cap_info->lock, MUTEX_RECURSIVE);
     203}
     204
     205void caps_task_clear(task_t *task)
     206{
     207        mutex_lock(&task->cap_info->lock);
     208
     209        hash_table_clear(&task->cap_info->caps);
     210
     211        if (task->cap_info->handles) {
     212                ra_arena_destroy(task->cap_info->handles);
     213                task->cap_info->handles = NULL;
     214        }
    173215
    174216        for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++)
    175217                list_initialize(&task->cap_info->type_list[t]);
     218
     219        mutex_unlock(&task->cap_info->lock);
    176220}
    177221
     
    183227{
    184228        hash_table_destroy(&task->cap_info->caps);
    185         ra_arena_destroy(task->cap_info->handles);
     229
     230        if (task->cap_info->handles)
     231                ra_arena_destroy(task->cap_info->handles);
     232
    186233        free(task->cap_info);
    187234}
     
    300347cap_publish(task_t *task, cap_handle_t handle, kobject_t *kobj)
    301348{
     349        mutex_lock(&task->cap_info->lock);
    302350        mutex_lock(&kobj->caps_list_lock);
    303         mutex_lock(&task->cap_info->lock);
    304351        cap_t *cap = cap_get(task, handle, CAP_STATE_ALLOCATED);
    305352        assert(cap);
     
    309356        list_append(&cap->kobj_link, &kobj->caps_list);
    310357        list_append(&cap->type_link, &task->cap_info->type_list[kobj->type]);
    311         mutex_unlock(&task->cap_info->lock);
    312358        mutex_unlock(&kobj->caps_list_lock);
     359        mutex_unlock(&task->cap_info->lock);
    313360}
    314361
     
    340387        kobject_t *kobj = NULL;
    341388
    342 restart:
    343389        mutex_lock(&task->cap_info->lock);
    344390        cap_t *cap = cap_get(task, handle, CAP_STATE_PUBLISHED);
     
    347393                        /* Hand over cap's reference to kobj */
    348394                        kobj = cap->kobject;
    349                         if (mutex_trylock(&kobj->caps_list_lock) != EOK) {
    350                                 mutex_unlock(&task->cap_info->lock);
    351                                 kobj = NULL;
    352                                 goto restart;
    353                         }
     395
     396                        mutex_lock(&kobj->caps_list_lock);
    354397                        cap_unpublish_unsafe(cap);
    355398                        mutex_unlock(&kobj->caps_list_lock);
     
    376419{
    377420        mutex_lock(&kobj->caps_list_lock);
    378         list_foreach_safe(kobj->caps_list, cur, hlp) {
    379                 cap_t *cap = list_get_instance(cur, cap_t, kobj_link);
    380                 mutex_lock(&cap->task->cap_info->lock);
     421
     422        while (!list_empty(&kobj->caps_list)) {
     423                cap_t *cap = list_get_instance(list_first(&kobj->caps_list), cap_t, kobj_link);
     424
     425                /* We're trying to acquire the two locks in reverse order. */
     426                if (mutex_trylock(&cap->task->cap_info->lock) != EOK) {
     427                        mutex_unlock(&kobj->caps_list_lock);
     428                        mutex_lock(&kobj->caps_list_lock);
     429                        continue;
     430                }
     431
    381432                cap_unpublish_unsafe(cap);
    382433                /* Drop the reference for the unpublished capability */
    383434                kobject_put(kobj);
     435
    384436                mutex_unlock(&cap->task->cap_info->lock);
    385437        }
     438
    386439        mutex_unlock(&kobj->caps_list_lock);
    387440}
     
    404457        hash_table_remove_item(&task->cap_info->caps, &cap->caps_link);
    405458        ra_free(task->cap_info->handles, cap_handle_raw(handle), 1);
    406         slab_free(cap_cache, cap);
    407         mutex_unlock(&task->cap_info->lock);
    408 }
    409 
    410 kobject_t *kobject_alloc(unsigned int flags)
    411 {
    412         return slab_alloc(kobject_cache, flags);
    413 }
    414 
    415 void kobject_free(kobject_t *kobj)
    416 {
    417         slab_free(kobject_cache, kobj);
     459        mutex_unlock(&task->cap_info->lock);
    418460}
    419461
     
    422464 * @param kobj  Kernel object to initialize.
    423465 * @param type  Type of the kernel object.
    424  * @param raw   Raw pointer to the encapsulated object.
    425  */
    426 void kobject_initialize(kobject_t *kobj, kobject_type_t type, void *raw)
    427 {
    428         atomic_store(&kobj->refcnt, 1);
     466 */
     467void kobject_initialize(kobject_t *kobj, kobject_type_t type)
     468{
     469        refcount_init(&kobj->refcnt);
    429470
    430471        mutex_initialize(&kobj->caps_list_lock, MUTEX_PASSIVE);
     
    432473
    433474        kobj->type = type;
    434         kobj->raw = raw;
    435475}
    436476
     
    455495                if (cap->kobject->type == type) {
    456496                        kobj = cap->kobject;
    457                         atomic_inc(&kobj->refcnt);
     497                        refcount_up(&kobj->refcnt);
    458498                }
    459499        }
     
    469509void kobject_add_ref(kobject_t *kobj)
    470510{
    471         atomic_inc(&kobj->refcnt);
     511        refcount_up(&kobj->refcnt);
    472512}
    473513
     
    481521void kobject_put(kobject_t *kobj)
    482522{
    483         if (atomic_postdec(&kobj->refcnt) == 1) {
    484                 KOBJECT_OP(kobj)->destroy(kobj->raw);
    485                 kobject_free(kobj);
     523        if (refcount_down(&kobj->refcnt)) {
     524                KOBJECT_OP(kobj)->destroy(kobj);
    486525        }
    487526}
Note: See TracChangeset for help on using the changeset viewer.