Changeset eadaeae8 in mainline for kernel/generic/src


Ignore:
Timestamp:
2018-03-21T20:58:49Z (7 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
3be9d10
Parents:
874381a
Message:

Make capability handles type-safe

Define distinct pointer types for the handles of the supported
capability types and use them instead of integer handles. This makes it
virtually impossible to pass a non-handle or a handle of different type
instead of the proper handle. Also turn cap_handle_t into an "untyped"
capability handle that can be assigned to and from the "typed" handles.

This commit also fixes a bug in msim-con driver, which wrongly used the
IRQ number instead of the IRQ capability handle to unregister the IRQ.

This commit also fixes the wrong use of the capability handle instead
of error code in libusbhost.

Location:
kernel/generic/src
Files:
11 edited

Legend:

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

    r874381a readaeae8  
    9292{
    9393        cap_t *cap = hash_table_get_inst(item, cap_t, caps_link);
    94         return hash_mix(cap->handle);
     94        return hash_mix(CAP_HANDLE_RAW(cap->handle));
    9595}
    9696
     
    9898{
    9999        cap_handle_t *handle = (cap_handle_t *) key;
    100         return hash_mix(*handle);
     100        return hash_mix(CAP_HANDLE_RAW(*handle));
    101101}
    102102
     
    224224        assert(mutex_locked(&task->cap_info->lock));
    225225
    226         if ((handle < CAPS_START) || (handle > CAPS_LAST))
     226        if ((CAP_HANDLE_RAW(handle) < CAPS_START) ||
     227            (CAP_HANDLE_RAW(handle) > CAPS_LAST))
    227228                return NULL;
    228229        ht_link_t *link = hash_table_find(&task->cap_info->caps, &handle);
     
    329330void cap_free(task_t *task, cap_handle_t handle)
    330331{
    331         assert(handle >= CAPS_START);
    332         assert(handle <= CAPS_LAST);
     332        assert(CAP_HANDLE_RAW(handle) >= CAPS_START);
     333        assert(CAP_HANDLE_RAW(handle) <= CAPS_LAST);
    333334
    334335        mutex_lock(&task->cap_info->lock);
     
    338339
    339340        hash_table_remove_item(&task->cap_info->caps, &cap->caps_link);
    340         ra_free(task->cap_info->handles, handle, 1);
     341        ra_free(task->cap_info->handles, CAP_HANDLE_RAW(handle), 1);
    341342        slab_free(cap_cache, cap);
    342343        mutex_unlock(&task->cap_info->lock);
  • kernel/generic/src/ipc/ipc.c

    r874381a readaeae8  
    910910        mutex_lock(&phone->lock);
    911911        if (phone->state != IPC_PHONE_FREE) {
    912                 printf("%-11d %7" PRIun " ", cap->handle,
     912                printf("%-11d %7" PRIun " ", (int) CAP_HANDLE_RAW(cap->handle),
    913913                    atomic_get(&phone->active_calls));
    914914
  • kernel/generic/src/ipc/ipcrsc.c

    r874381a readaeae8  
    157157 * @return  An error code if a new capability cannot be allocated.
    158158 */
    159 errno_t phone_alloc(task_t *task, bool publish, cap_handle_t *phandle,
     159errno_t phone_alloc(task_t *task, bool publish, cap_phone_handle_t *phandle,
    160160    kobject_t **kobject)
    161161{
     
    199199 *
    200200 */
    201 void phone_dealloc(cap_handle_t handle)
     201void phone_dealloc(cap_phone_handle_t handle)
    202202{
    203203        kobject_t *kobj = cap_unpublish(TASK, handle, KOBJECT_TYPE_PHONE);
  • kernel/generic/src/ipc/irq.c

    r874381a readaeae8  
    314314 */
    315315errno_t ipc_irq_subscribe(answerbox_t *box, inr_t inr, sysarg_t imethod,
    316     irq_code_t *ucode, cap_handle_t *uspace_handle)
     316    irq_code_t *ucode, cap_irq_handle_t *uspace_handle)
    317317{
    318318        if ((inr < 0) || (inr > last_inr))
     
    390390 *
    391391 */
    392 errno_t ipc_irq_unsubscribe(answerbox_t *box, int handle)
     392errno_t ipc_irq_unsubscribe(answerbox_t *box, cap_irq_handle_t handle)
    393393{
    394394        kobject_t *kobj = cap_unpublish(TASK, handle, KOBJECT_TYPE_IRQ);
  • kernel/generic/src/ipc/kbox.c

    r874381a readaeae8  
    210210 *
    211211 */
    212 errno_t ipc_connect_kbox(task_id_t taskid, cap_handle_t *out_phone)
     212errno_t ipc_connect_kbox(task_id_t taskid, cap_phone_handle_t *out_phone)
    213213{
    214214        irq_spinlock_lock(&tasks_lock, true);
     
    252252
    253253        /* Allocate a new phone. */
    254         cap_handle_t phone_handle;
     254        cap_phone_handle_t phone_handle;
    255255        errno_t rc = phone_alloc(TASK, true, &phone_handle, NULL);
    256256        if (rc != EOK) {
  • kernel/generic/src/ipc/ops/conctmeto.c

    r874381a readaeae8  
    4646         * That will be done once the phone is connected.
    4747         */
    48         cap_handle_t phone_handle;
     48        cap_phone_handle_t phone_handle;
    4949        kobject_t *phone_obj;
    5050        errno_t rc = phone_alloc(TASK, false, &phone_handle, &phone_obj);
     
    5858
    5959        /* Remember the handle */
    60         call->priv = phone_handle;
     60        call->priv = CAP_HANDLE_RAW(phone_handle);
    6161
    6262        return EOK;
     
    6565static errno_t request_forget(call_t *call)
    6666{
    67         cap_handle_t phone_handle = (cap_handle_t) call->priv;
     67        cap_phone_handle_t phone_handle = (cap_handle_t) call->priv;
    6868
    69         if (phone_handle < 0)
     69        if (CAP_HANDLE_RAW(phone_handle) < 0)
    7070                return EOK;
    7171
     
    103103static errno_t answer_process(call_t *answer)
    104104{
    105         cap_handle_t phone_handle = (cap_handle_t) answer->priv;
     105        cap_phone_handle_t phone_handle = (cap_handle_t) answer->priv;
    106106        phone_t *phone = (phone_t *) IPC_GET_ARG5(answer->data);
    107107
    108108        if (IPC_GET_RETVAL(answer->data)) {
    109                 if (phone_handle >= 0) {
     109                if (CAP_HANDLE_RAW(phone_handle) >= 0) {
    110110                        /*
    111111                         * Cleanup the unpublished capability and drop
     
    123123                cap_publish(TASK, phone_handle, phone->kobject);
    124124
    125                 IPC_SET_ARG5(answer->data, phone_handle);
     125                IPC_SET_ARG5(answer->data, CAP_HANDLE_RAW(phone_handle));
    126126        }
    127127
  • kernel/generic/src/ipc/ops/concttome.c

    r874381a readaeae8  
    4242static int request_process(call_t *call, answerbox_t *box)
    4343{
    44         cap_handle_t phone_handle;
     44        cap_phone_handle_t phone_handle;
    4545        kobject_t *phone_obj;
    4646        errno_t rc = phone_alloc(TASK, false, &phone_handle, &phone_obj);
    4747        call->priv = (sysarg_t) phone_obj;
    48         IPC_SET_ARG5(call->data, (rc == EOK) ? phone_handle : -1);
     48        IPC_SET_ARG5(call->data,
     49            (rc == EOK) ? CAP_HANDLE_RAW(phone_handle) : CAP_NIL);
    4950        return 0;
    5051}
     
    5253static errno_t answer_cleanup(call_t *answer, ipc_data_t *olddata)
    5354{
    54         cap_handle_t phone_handle = (cap_handle_t) IPC_GET_ARG5(*olddata);
     55        cap_phone_handle_t phone_handle = (cap_handle_t) IPC_GET_ARG5(*olddata);
    5556        kobject_t *phone_obj = (kobject_t *) answer->priv;
    5657
    57         if (phone_handle >= 0) {
     58        if (CAP_HANDLE_VALID(phone_handle)) {
    5859                kobject_put(phone_obj);
    5960                cap_free(TASK, phone_handle);
     
    6566static errno_t answer_preprocess(call_t *answer, ipc_data_t *olddata)
    6667{
    67         cap_handle_t phone_handle = (cap_handle_t) IPC_GET_ARG5(*olddata);
     68        cap_phone_handle_t phone_handle = (cap_handle_t) IPC_GET_ARG5(*olddata);
    6869        kobject_t *phone_obj = (kobject_t *) answer->priv;
    6970
     
    7172                /* The connection was not accepted */
    7273                answer_cleanup(answer, olddata);
    73         } else if (phone_handle >= 0) {
     74        } else if (CAP_HANDLE_VALID(phone_handle)) {
    7475                /*
    7576                 * The connection was accepted
  • kernel/generic/src/ipc/ops/stchngath.c

    r874381a readaeae8  
    4545        task_t *other_task_s;
    4646
    47         kobject_t *sender_obj = kobject_get(TASK, IPC_GET_ARG5(call->data),
    48             KOBJECT_TYPE_PHONE);
     47        kobject_t *sender_obj = kobject_get(TASK,
     48            (cap_handle_t) IPC_GET_ARG5(call->data), KOBJECT_TYPE_PHONE);
    4949        if (!sender_obj)
    5050                return ENOENT;
     
    7878
    7979                kobject_t *recipient_obj = kobject_get(TASK,
    80                     IPC_GET_ARG1(answer->data), KOBJECT_TYPE_PHONE);
     80                    (cap_handle_t) IPC_GET_ARG1(answer->data),
     81                    KOBJECT_TYPE_PHONE);
    8182                if (!recipient_obj) {
    8283                        IPC_SET_RETVAL(answer->data, ENOENT);
  • kernel/generic/src/ipc/sysipc.c

    r874381a readaeae8  
    271271 *
    272272 */
    273 errno_t ipc_req_internal(cap_handle_t handle, ipc_data_t *data, sysarg_t priv)
     273errno_t
     274ipc_req_internal(cap_phone_handle_t handle, ipc_data_t *data, sysarg_t priv)
    274275{
    275276        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     
    362363 *
    363364 */
    364 sys_errno_t sys_ipc_call_async_fast(sysarg_t handle, sysarg_t imethod,
     365sys_errno_t sys_ipc_call_async_fast(cap_phone_handle_t handle, sysarg_t imethod,
    365366    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t label)
    366367{
     
    409410 *
    410411 */
    411 sys_errno_t sys_ipc_call_async_slow(sysarg_t handle, ipc_data_t *data,
     412sys_errno_t sys_ipc_call_async_slow(cap_phone_handle_t handle, ipc_data_t *data,
    412413    sysarg_t label)
    413414{
     
    466467 *
    467468 */
    468 static sys_errno_t sys_ipc_forward_common(sysarg_t chandle, sysarg_t phandle,
    469     sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
    470     sysarg_t arg4, sysarg_t arg5, unsigned int mode, bool slow)
     469static sys_errno_t sys_ipc_forward_common(cap_call_handle_t chandle,
     470    cap_phone_handle_t phandle, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
     471    sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, unsigned int mode, bool slow)
    471472{
    472473        kobject_t *ckobj = cap_unpublish(TASK, chandle, KOBJECT_TYPE_CALL);
     
    506507                if (method_is_system(IPC_GET_IMETHOD(call->data))) {
    507508                        if (IPC_GET_IMETHOD(call->data) == IPC_M_CONNECT_TO_ME)
    508                                 phone_dealloc(IPC_GET_ARG5(call->data));
     509                                phone_dealloc((cap_phone_handle_t)
     510                                    IPC_GET_ARG5(call->data));
    509511
    510512                        IPC_SET_ARG1(call->data, imethod);
     
    577579 *
    578580 */
    579 sys_errno_t sys_ipc_forward_fast(sysarg_t chandle, sysarg_t phandle,
    580     sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, unsigned int mode)
     581sys_errno_t sys_ipc_forward_fast(cap_call_handle_t chandle,
     582    cap_phone_handle_t phandle, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
     583    unsigned int mode)
    581584{
    582585        return sys_ipc_forward_common(chandle, phandle, imethod, arg1, arg2, 0,
     
    601604 *
    602605 */
    603 sys_errno_t sys_ipc_forward_slow(sysarg_t chandle, sysarg_t phandle,
    604     ipc_data_t *data, unsigned int mode)
     606sys_errno_t sys_ipc_forward_slow(cap_call_handle_t chandle,
     607    cap_phone_handle_t phandle, ipc_data_t *data, unsigned int mode)
    605608{
    606609        ipc_data_t newdata;
     
    631634 *
    632635 */
    633 sys_errno_t sys_ipc_answer_fast(sysarg_t chandle, sysarg_t retval, sysarg_t arg1,
    634     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
     636sys_errno_t sys_ipc_answer_fast(cap_call_handle_t chandle, sysarg_t retval,
     637    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
    635638{
    636639        kobject_t *kobj = cap_unpublish(TASK, chandle, KOBJECT_TYPE_CALL);
     
    678681 *
    679682 */
    680 sys_errno_t sys_ipc_answer_slow(sysarg_t chandle, ipc_data_t *data)
     683sys_errno_t sys_ipc_answer_slow(cap_call_handle_t chandle, ipc_data_t *data)
    681684{
    682685        kobject_t *kobj = cap_unpublish(TASK, chandle, KOBJECT_TYPE_CALL);
     
    722725 *
    723726 */
    724 sys_errno_t sys_ipc_hangup(sysarg_t handle)
     727sys_errno_t sys_ipc_hangup(cap_phone_handle_t handle)
    725728{
    726729        kobject_t *kobj = cap_unpublish(TASK, handle, KOBJECT_TYPE_PHONE);
     
    800803                goto restart;
    801804
    802         cap_handle_t handle;
     805        cap_handle_t handle = CAP_NIL;
    803806        errno_t rc = cap_alloc(TASK, &handle);
    804807        if (rc != EOK) {
     
    821824
    822825error:
    823         if (handle >= 0)
     826        if (CAP_HANDLE_VALID(handle))
    824827                cap_free(TASK, handle);
    825828
     
    861864 * @param ucode   Uspace pointer to the top-half pseudocode.
    862865 *
    863  * @param[out] uspace_handle  Uspace pointer to IRQ kernel object capability
     866 * @param[out] uspace_handle  Uspace pointer to IRQ capability handle
    864867 *
    865868 * @return EPERM
     
    867870 *
    868871 */
    869 sys_errno_t sys_ipc_irq_subscribe(inr_t inr, sysarg_t imethod, irq_code_t *ucode,
    870         cap_handle_t *uspace_handle)
     872sys_errno_t sys_ipc_irq_subscribe(inr_t inr, sysarg_t imethod,
     873    irq_code_t *ucode, cap_irq_handle_t *uspace_handle)
    871874{
    872875        if (!(perm_get(TASK) & PERM_IRQ_REG))
     
    878881/** Disconnect an IRQ handler from a task.
    879882 *
    880  * @param inr   IRQ number.
    881  * @param devno Device number.
     883 * @param handle  IRQ capability handle.
    882884 *
    883885 * @return Zero on success or EPERM on error.
    884886 *
    885887 */
    886 sys_errno_t sys_ipc_irq_unsubscribe(sysarg_t cap)
     888sys_errno_t sys_ipc_irq_unsubscribe(cap_irq_handle_t handle)
    887889{
    888890        if (!(perm_get(TASK) & PERM_IRQ_REG))
    889891                return EPERM;
    890892
    891         ipc_irq_unsubscribe(&TASK->answerbox, cap);
     893        ipc_irq_unsubscribe(&TASK->answerbox, handle);
    892894
    893895        return 0;
     
    899901 *
    900902 */
    901 sys_errno_t sys_ipc_connect_kbox(task_id_t *uspace_taskid, cap_handle_t *uspace_phone)
     903sys_errno_t sys_ipc_connect_kbox(task_id_t *uspace_taskid,
     904    cap_phone_handle_t *uspace_phone)
    902905{
    903906#ifdef CONFIG_UDEBUG
    904907        task_id_t taskid;
    905         cap_handle_t phone;
     908        cap_phone_handle_t phone;
    906909
    907910        errno_t rc = copy_from_uspace(&taskid, uspace_taskid, sizeof(task_id_t));
  • kernel/generic/src/mm/backend_user.c

    r874381a readaeae8  
    131131                log(LF_USPACE, LVL_FATAL,
    132132                    "Page-in request for page %#" PRIxPTR
    133                     " at pager %d failed with error %s.",
     133                    " at pager %p failed with error %s.",
    134134                    upage, pager_info->pager, str_error_name(rc));
    135135                return AS_PF_FAULT;
  • kernel/generic/src/proc/task.c

    r874381a readaeae8  
    245245        if ((ipc_box_0) &&
    246246            (container_check(ipc_box_0->task->container, task->container))) {
    247                 cap_handle_t phone_handle;
     247                cap_phone_handle_t phone_handle;
    248248                errno_t rc = phone_alloc(task, true, &phone_handle, NULL);
    249249                if (rc != EOK) {
Note: See TracChangeset for help on using the changeset viewer.