Changeset 9e87562 in mainline for kernel/generic/src/cap


Ignore:
Timestamp:
2017-09-18T20:52:12Z (8 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6abfd250
Parents:
e5f5ce0
Message:

Make all accesses to capabilites exclusive

This commit makes sure that all accesses to the capabilities array and other
metadata are protected by a mutex. This is necessary for future resizing of the
capabilities array.

Group task's capabilities by type so that it is possible to visit all
capabilities of the given type effectively.

Provide cap_publish() and cap_unpublish() to automate steps that make the
capability visible/invisible to userspace and insert/remove the capability from
the respective type list.

File:
1 edited

Legend:

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

    re5f5ce0 r9e87562  
    3535#include <cap/cap.h>
    3636#include <proc/task.h>
    37 #include <synch/spinlock.h>
     37#include <synch/mutex.h>
    3838#include <abi/errno.h>
    3939#include <mm/slab.h>
     40#include <adt/list.h>
    4041
    4142void cap_initialize(cap_t *cap, int handle)
     
    4445        cap->handle = handle;
    4546        cap->can_reclaim = NULL;
     47        link_initialize(&cap->link);
    4648}
    4749
    4850void caps_task_alloc(task_t *task)
    4951{
    50         task->caps = malloc(sizeof(cap_t) * MAX_CAPS, 0);
     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);
    5154}
    5255
    5356void caps_task_init(task_t *task)
    5457{
     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
    5563        for (int i = 0; i < MAX_CAPS; i++)
    56                 cap_initialize(&task->caps[i], i);
     64                cap_initialize(&task->cap_info->caps[i], i);
    5765}
    5866
    5967void caps_task_free(task_t *task)
    6068{
    61         free(task->caps);
     69        free(task->cap_info->caps);
     70        free(task->cap_info);
     71}
     72
     73bool caps_apply_to_all(task_t *task, cap_type_t type,
     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);
    6298}
    6399
    64100cap_t *cap_get(task_t *task, int handle, cap_type_t type)
    65101{
     102        assert(mutex_locked(&task->cap_info->lock));
     103
    66104        if ((handle < 0) || (handle >= MAX_CAPS))
    67105                return NULL;
    68         if (task->caps[handle].type != type)
     106        if (task->cap_info->caps[handle].type != type)
    69107                return NULL;
    70         return &task->caps[handle];
    71 }
    72 
    73 cap_t *cap_get_current(int handle, cap_type_t type)
    74 {
    75         return cap_get(TASK, handle, type);
     108        return &task->cap_info->caps[handle];
    76109}
    77110
     
    80113        int handle;
    81114
    82         irq_spinlock_lock(&task->lock, true);
     115        mutex_lock(&task->cap_info->lock);
    83116        for (handle = 0; handle < MAX_CAPS; handle++) {
    84                 cap_t *cap = &task->caps[handle];
     117                cap_t *cap = &task->cap_info->caps[handle];
    85118                if (cap->type > CAP_TYPE_ALLOCATED) {
    86119                        if (cap->can_reclaim && cap->can_reclaim(cap))
     
    89122                if (cap->type == CAP_TYPE_INVALID) {
    90123                        cap->type = CAP_TYPE_ALLOCATED;
    91                         irq_spinlock_unlock(&task->lock, true);
     124                        mutex_unlock(&task->cap_info->lock);
    92125                        return handle;
    93126                }
    94127        }
    95         irq_spinlock_unlock(&task->lock, true);
     128        mutex_unlock(&task->cap_info->lock);
    96129
    97130        return ELIMIT;
     131}
     132
     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;
    98157}
    99158
     
    102161        assert(handle >= 0);
    103162        assert(handle < MAX_CAPS);
    104         assert(task->caps[handle].type == CAP_TYPE_ALLOCATED);
     163        assert(task->cap_info->caps[handle].type == CAP_TYPE_ALLOCATED);
    105164
    106         irq_spinlock_lock(&task->lock, true);
    107         cap_initialize(&task->caps[handle], handle);
    108         irq_spinlock_unlock(&task->lock, true);
     165        mutex_lock(&task->cap_info->lock);
     166        cap_initialize(&task->cap_info->caps[handle], handle);
     167        mutex_unlock(&task->cap_info->lock);
    109168}
    110169
Note: See TracChangeset for help on using the changeset viewer.