Changeset 91b60499 in mainline for kernel/generic/src/ipc/sysipc.c


Ignore:
Timestamp:
2017-09-30T06:29:42Z (7 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
300f4c4
Parents:
d076f16 (diff), 6636fb19 (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.
Message:

Merge support for capabilities from lp:~jakub/helenos/caps

This commit introduces capabilities as task-local names for references to kernel
objects. Kernel objects are reference-counted wrappers for a select group of
objects allocated in and by the kernel that can be made accessible to userspace
in a controlled way via integer handles.

So far, a kernel object encapsulates either an irq_t or a phone_t.

Support for the former lead to the removal of kernel-assigned devnos and
unsecure deregistration of IRQs in which a random task was able to unregister
some other task's IRQ.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/ipc/sysipc.c

    rd076f16 r91b60499  
    8585{
    8686        switch (imethod) {
    87         case IPC_M_CONNECTION_CLONE:
    88         case IPC_M_CLONE_ESTABLISH:
    8987        case IPC_M_PHONE_HUNGUP:
    9088                /* This message is meant only for the original recipient. */
     
    135133{
    136134        switch (IPC_GET_IMETHOD(call->data)) {
    137         case IPC_M_CONNECTION_CLONE:
    138         case IPC_M_CLONE_ESTABLISH:
    139135        case IPC_M_CONNECT_TO_ME:
    140136        case IPC_M_CONNECT_ME_TO:
     
    264260/** Make a call over IPC and wait for reply.
    265261 *
    266  * @param phoneid     Phone handle for the call.
    267  * @param data[inout] Structure with request/reply data.
    268  * @param priv        Value to be stored in call->priv.
     262 * @param handle       Phone capability handle for the call.
     263 * @param data[inout]  Structure with request/reply data.
     264 * @param priv         Value to be stored in call->priv.
    269265 *
    270266 * @return EOK on success.
     
    272268 *
    273269 */
    274 int ipc_req_internal(int phoneid, ipc_data_t *data, sysarg_t priv)
    275 {
    276         phone_t *phone;
    277         if (phone_get(phoneid, &phone) != EOK)
     270int ipc_req_internal(cap_handle_t handle, ipc_data_t *data, sysarg_t priv)
     271{
     272        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     273        if (!kobj->phone)
    278274                return ENOENT;
    279275       
     
    282278        memcpy(call->data.args, data->args, sizeof(data->args));
    283279       
    284         int rc = request_preprocess(call, phone);
     280        int rc = request_preprocess(call, kobj->phone);
    285281        if (!rc) {
    286282#ifdef CONFIG_UDEBUG
     
    289285
    290286                ipc_call_hold(call);
    291                 rc = ipc_call_sync(phone, call);
     287                rc = ipc_call_sync(kobj->phone, call);
    292288                spinlock_lock(&call->forget_lock);
    293289                bool forgotten = call->forget;
     
    316312                                assert(rc == EINTR);
    317313                        }
    318                         return rc;     
     314                        kobject_put(kobj);
     315                        return rc;
    319316                }
    320317
     
    325322        memcpy(data->args, call->data.args, sizeof(data->args));
    326323        ipc_call_free(call);
     324        kobject_put(kobj);
    327325       
    328326        return EOK;
     
    350348 * the generic function sys_ipc_call_async_slow().
    351349 *
    352  * @param phoneid Phone handle for the call.
    353  * @param imethod Interface and method of the call.
    354  * @param arg1    Service-defined payload argument.
    355  * @param arg2    Service-defined payload argument.
    356  * @param arg3    Service-defined payload argument.
    357  * @param arg4    Service-defined payload argument.
     350 * @param handle   Phone capability handle for the call.
     351 * @param imethod  Interface and method of the call.
     352 * @param arg1     Service-defined payload argument.
     353 * @param arg2     Service-defined payload argument.
     354 * @param arg3     Service-defined payload argument.
     355 * @param arg4     Service-defined payload argument.
    358356 *
    359357 * @return Call hash on success.
     
    363361 *
    364362 */
    365 sysarg_t sys_ipc_call_async_fast(sysarg_t phoneid, sysarg_t imethod,
     363sysarg_t sys_ipc_call_async_fast(sysarg_t handle, sysarg_t imethod,
    366364    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
    367365{
    368         phone_t *phone;
    369         if (phone_get(phoneid, &phone) != EOK)
     366        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     367        if (!kobj)
    370368                return IPC_CALLRET_FATAL;
    371369       
    372         if (check_call_limit(phone))
     370        if (check_call_limit(kobj->phone)) {
     371                kobject_put(kobj);
    373372                return IPC_CALLRET_TEMPORARY;
     373        }
    374374       
    375375        call_t *call = ipc_call_alloc(0);
     
    386386        IPC_SET_ARG5(call->data, 0);
    387387       
    388         int res = request_preprocess(call, phone);
     388        int res = request_preprocess(call, kobj->phone);
    389389       
    390390        if (!res)
    391                 ipc_call(phone, call);
     391                ipc_call(kobj->phone, call);
    392392        else
    393                 ipc_backsend_err(phone, call, res);
    394        
     393                ipc_backsend_err(kobj->phone, call, res);
     394       
     395        kobject_put(kobj);
    395396        return (sysarg_t) call;
    396397}
     
    398399/** Make an asynchronous IPC call allowing to transmit the entire payload.
    399400 *
    400  * @param phoneid Phone handle for the call.
     401 * @param handle  Phone capability for the call.
    401402 * @param data    Userspace address of call data with the request.
    402403 *
     
    404405 *
    405406 */
    406 sysarg_t sys_ipc_call_async_slow(sysarg_t phoneid, ipc_data_t *data)
    407 {
    408         phone_t *phone;
    409         if (phone_get(phoneid, &phone) != EOK)
     407sysarg_t sys_ipc_call_async_slow(sysarg_t handle, ipc_data_t *data)
     408{
     409        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     410        if (!kobj)
    410411                return IPC_CALLRET_FATAL;
    411412
    412         if (check_call_limit(phone))
     413        if (check_call_limit(kobj->phone)) {
     414                kobject_put(kobj);
    413415                return IPC_CALLRET_TEMPORARY;
     416        }
    414417
    415418        call_t *call = ipc_call_alloc(0);
     
    418421        if (rc != 0) {
    419422                ipc_call_free(call);
     423                kobject_put(kobj);
    420424                return (sysarg_t) rc;
    421425        }
    422426       
    423         int res = request_preprocess(call, phone);
     427        int res = request_preprocess(call, kobj->phone);
    424428       
    425429        if (!res)
    426                 ipc_call(phone, call);
     430                ipc_call(kobj->phone, call);
    427431        else
    428                 ipc_backsend_err(phone, call, res);
    429        
     432                ipc_backsend_err(kobj->phone, call, res);
     433       
     434        kobject_put(kobj);
    430435        return (sysarg_t) call;
    431436}
     
    435440 * Common code for both the fast and the slow version.
    436441 *
    437  * @param callid  Hash of the call to forward.
    438  * @param phoneid Phone handle to use for forwarding.
    439  * @param imethod New interface and method to use for the forwarded call.
    440  * @param arg1    New value of the first argument for the forwarded call.
    441  * @param arg2    New value of the second argument for the forwarded call.
    442  * @param arg3    New value of the third argument for the forwarded call.
    443  * @param arg4    New value of the fourth argument for the forwarded call.
    444  * @param arg5    New value of the fifth argument for the forwarded call.
    445  * @param mode    Flags that specify mode of the forward operation.
    446  * @param slow    If true, arg3, arg4 and arg5 are considered. Otherwise
    447  *                the function considers only the fast version arguments:
    448  *                i.e. arg1 and arg2.
     442 * @param callid   Hash of the call to forward.
     443 * @param handle   Phone capability to use for forwarding.
     444 * @param imethod  New interface and method to use for the forwarded call.
     445 * @param arg1     New value of the first argument for the forwarded call.
     446 * @param arg2     New value of the second argument for the forwarded call.
     447 * @param arg3     New value of the third argument for the forwarded call.
     448 * @param arg4     New value of the fourth argument for the forwarded call.
     449 * @param arg5     New value of the fifth argument for the forwarded call.
     450 * @param mode     Flags that specify mode of the forward operation.
     451 * @param slow     If true, arg3, arg4 and arg5 are considered. Otherwise
     452 *                 the function considers only the fast version arguments:
     453 *                 i.e. arg1 and arg2.
    449454 *
    450455 * @return 0 on succes, otherwise an error code.
     
    453458 *
    454459 */
    455 static sysarg_t sys_ipc_forward_common(sysarg_t callid, sysarg_t phoneid,
     460static sysarg_t sys_ipc_forward_common(sysarg_t callid, sysarg_t handle,
    456461    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
    457462    sysarg_t arg4, sysarg_t arg5, unsigned int mode, bool slow)
     
    468473        bool after_forward = false;
    469474        int rc;
    470         phone_t *phone;
    471        
    472         if (phone_get(phoneid, &phone) != EOK) {
     475
     476        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     477        if (!kobj) {
    473478                rc = ENOENT;
    474479                goto error;
     
    516521        }
    517522       
    518         rc = ipc_forward(call, phone, &TASK->answerbox, mode);
     523        rc = ipc_forward(call, kobj->phone, &TASK->answerbox, mode);
    519524        if (rc != EOK) {
    520525                after_forward = true;
     
    522527        }
    523528
     529        kobject_put(kobj);
    524530        return EOK;
    525531
     
    532538                ipc_answer(&TASK->answerbox, call);
    533539
     540        if (kobj)
     541                kobject_put(kobj);
    534542        return rc;
    535543}
     
    544552 * arguments are not set and these values are ignored.
    545553 *
    546  * @param callid  Hash of the call to forward.
    547  * @param phoneid Phone handle to use for forwarding.
    548  * @param imethod New interface and method to use for the forwarded call.
    549  * @param arg1    New value of the first argument for the forwarded call.
    550  * @param arg2    New value of the second argument for the forwarded call.
    551  * @param mode    Flags that specify mode of the forward operation.
     554 * @param callid   Hash of the call to forward.
     555 * @param handle  Phone handle to use for forwarding.
     556 * @param imethod  New interface and method to use for the forwarded call.
     557 * @param arg1     New value of the first argument for the forwarded call.
     558 * @param arg2     New value of the second argument for the forwarded call.
     559 * @param mode     Flags that specify mode of the forward operation.
    552560 *
    553561 * @return 0 on succes, otherwise an error code.
    554562 *
    555563 */
    556 sysarg_t sys_ipc_forward_fast(sysarg_t callid, sysarg_t phoneid,
     564sysarg_t sys_ipc_forward_fast(sysarg_t callid, sysarg_t handle,
    557565    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, unsigned int mode)
    558566{
    559         return sys_ipc_forward_common(callid, phoneid, imethod, arg1, arg2, 0, 0,
     567        return sys_ipc_forward_common(callid, handle, imethod, arg1, arg2, 0, 0,
    560568            0, mode, false);
    561569}
     
    571579 *
    572580 * @param callid  Hash of the call to forward.
    573  * @param phoneid Phone handle to use for forwarding.
     581 * @param handle Phone handle to use for forwarding.
    574582 * @param data    Userspace address of the new IPC data.
    575583 * @param mode    Flags that specify mode of the forward operation.
     
    578586 *
    579587 */
    580 sysarg_t sys_ipc_forward_slow(sysarg_t callid, sysarg_t phoneid,
     588sysarg_t sys_ipc_forward_slow(sysarg_t callid, sysarg_t handle,
    581589    ipc_data_t *data, unsigned int mode)
    582590{
     
    587595                return (sysarg_t) rc;
    588596       
    589         return sys_ipc_forward_common(callid, phoneid,
     597        return sys_ipc_forward_common(callid, handle,
    590598            IPC_GET_IMETHOD(newdata), IPC_GET_ARG1(newdata),
    591599            IPC_GET_ARG2(newdata), IPC_GET_ARG3(newdata),
     
    685693/** Hang up a phone.
    686694 *
    687  * @param Phone handle of the phone to be hung up.
     695 * @param handle  Phone capability handle of the phone to be hung up.
    688696 *
    689697 * @return 0 on success or an error code.
    690698 *
    691699 */
    692 sysarg_t sys_ipc_hangup(sysarg_t phoneid)
    693 {
    694         phone_t *phone;
    695        
    696         if (phone_get(phoneid, &phone) != EOK)
     700sysarg_t sys_ipc_hangup(sysarg_t handle)
     701{
     702        kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE);
     703        if (!kobj)
    697704                return ENOENT;
    698705       
    699         if (ipc_phone_hangup(phone))
     706        if (ipc_phone_hangup(kobj->phone)) {
     707                kobject_put(kobj);
    700708                return -1;
    701        
     709        }
     710       
     711        kobject_put(kobj);
    702712        return 0;
    703713}
     
    802812 *
    803813 * @param inr     IRQ number.
    804  * @param devno   Device number.
    805814 * @param imethod Interface and method to be associated with the notification.
    806815 * @param ucode   Uspace pointer to the top-half pseudocode.
    807816 *
    808  * @return EPERM or a return code returned by ipc_irq_subscribe().
    809  *
    810  */
    811 sysarg_t sys_ipc_irq_subscribe(inr_t inr, devno_t devno, sysarg_t imethod,
    812     irq_code_t *ucode)
     817 * @return IRQ kernel object capability
     818 * @return EPERM
     819 * @return Error code returned by ipc_irq_subscribe().
     820 *
     821 */
     822sysarg_t sys_ipc_irq_subscribe(inr_t inr, sysarg_t imethod, irq_code_t *ucode)
    813823{
    814824        if (!(perm_get(TASK) & PERM_IRQ_REG))
    815825                return EPERM;
    816826       
    817         return ipc_irq_subscribe(&TASK->answerbox, inr, devno, imethod, ucode);
     827        return ipc_irq_subscribe(&TASK->answerbox, inr, imethod, ucode);
    818828}
    819829
     
    826836 *
    827837 */
    828 sysarg_t sys_ipc_irq_unsubscribe(inr_t inr, devno_t devno)
     838sysarg_t sys_ipc_irq_unsubscribe(sysarg_t cap)
    829839{
    830840        if (!(perm_get(TASK) & PERM_IRQ_REG))
    831841                return EPERM;
    832842       
    833         ipc_irq_unsubscribe(&TASK->answerbox, inr, devno);
     843        ipc_irq_unsubscribe(&TASK->answerbox, cap);
    834844       
    835845        return 0;
Note: See TracChangeset for help on using the changeset viewer.