Ignore:
File:
1 edited

Legend:

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

    r8add9ca5 rab34cc9  
    4040#include <debug.h>
    4141#include <ipc/ipc.h>
     42#include <abi/ipc/methods.h>
    4243#include <ipc/sysipc.h>
    4344#include <ipc/irq.h>
    4445#include <ipc/ipcrsc.h>
     46#include <ipc/event.h>
    4547#include <ipc/kbox.h>
    4648#include <synch/waitq.h>
     
    5254#include <mm/as.h>
    5355#include <print.h>
     56#include <macros.h>
    5457
    5558/**
     
    133136        case IPC_M_DATA_WRITE:
    134137        case IPC_M_DATA_READ:
     138        case IPC_M_STATE_CHANGE_AUTHORIZE:
    135139                return true;
    136140        default:
     
    163167        case IPC_M_DATA_WRITE:
    164168        case IPC_M_DATA_READ:
     169        case IPC_M_STATE_CHANGE_AUTHORIZE:
    165170                return true;
    166171        default:
     
    248253                        /* The connection was accepted */
    249254                        phone_connect(phoneid, &answer->sender->answerbox);
    250                         /* Set 'task hash' as arg4 of response */
    251                         IPC_SET_ARG4(answer->data, (sysarg_t) TASK);
    252255                        /* Set 'phone hash' as arg5 of response */
    253256                        IPC_SET_ARG5(answer->data,
     
    333336                free(answer->buffer);
    334337                answer->buffer = NULL;
     338        } else if (IPC_GET_IMETHOD(*olddata) == IPC_M_STATE_CHANGE_AUTHORIZE) {
     339                if (!IPC_GET_RETVAL(answer->data)) {
     340                        /* The recipient authorized the change of state. */
     341                        phone_t *recipient_phone;
     342                        task_t *other_task_s;
     343                        task_t *other_task_r;
     344                        int rc;
     345
     346                        rc = phone_get(IPC_GET_ARG1(answer->data),
     347                            &recipient_phone);
     348                        if (rc != EOK) {
     349                                IPC_SET_RETVAL(answer->data, ENOENT);
     350                                return ENOENT;
     351                        }
     352
     353                        mutex_lock(&recipient_phone->lock);
     354                        if (recipient_phone->state != IPC_PHONE_CONNECTED) {
     355                                mutex_unlock(&recipient_phone->lock);
     356                                IPC_SET_RETVAL(answer->data, EINVAL);
     357                                return EINVAL;
     358                        }
     359
     360                        other_task_r = recipient_phone->callee->task;
     361                        other_task_s = (task_t *) IPC_GET_ARG5(*olddata);
     362
     363                        /*
     364                         * See if both the sender and the recipient meant the
     365                         * same third party task.
     366                         */
     367                        if (other_task_r != other_task_s) {
     368                                IPC_SET_RETVAL(answer->data, EINVAL);
     369                                rc = EINVAL;
     370                        } else {
     371                                rc = event_task_notify_5(other_task_r,
     372                                    EVENT_TASK_STATE_CHANGE, false,
     373                                    IPC_GET_ARG1(*olddata),
     374                                    IPC_GET_ARG2(*olddata),
     375                                    IPC_GET_ARG3(*olddata),
     376                                    LOWER32(olddata->task_id),
     377                                    UPPER32(olddata->task_id));
     378                                IPC_SET_RETVAL(answer->data, rc);
     379                        }
     380
     381                        mutex_unlock(&recipient_phone->lock);
     382                        return rc;
     383                }
    335384        }
    336385       
     
    426475        case IPC_M_DATA_READ: {
    427476                size_t size = IPC_GET_ARG2(call->data);
    428                 if ((size <= 0 || (size > DATA_XFER_LIMIT)))
    429                         return ELIMIT;
    430                
     477                if (size > DATA_XFER_LIMIT) {
     478                        int flags = IPC_GET_ARG3(call->data);
     479                        if (flags & IPC_XF_RESTRICT)
     480                                IPC_SET_ARG2(call->data, DATA_XFER_LIMIT);
     481                        else
     482                                return ELIMIT;
     483                }
    431484                break;
    432485        }
     
    435488                size_t size = IPC_GET_ARG2(call->data);
    436489               
    437                 if (size > DATA_XFER_LIMIT)
    438                         return ELIMIT;
     490                if (size > DATA_XFER_LIMIT) {
     491                        int flags = IPC_GET_ARG3(call->data);
     492                        if (flags & IPC_XF_RESTRICT) {
     493                                size = DATA_XFER_LIMIT;
     494                                IPC_SET_ARG2(call->data, size);
     495                        } else
     496                                return ELIMIT;
     497                }
    439498               
    440499                call->buffer = (uint8_t *) malloc(size, 0);
     
    447506                break;
    448507        }
     508        case IPC_M_STATE_CHANGE_AUTHORIZE: {
     509                phone_t *sender_phone;
     510                task_t *other_task_s;
     511
     512                if (phone_get(IPC_GET_ARG5(call->data), &sender_phone) != EOK)
     513                        return ENOENT;
     514
     515                mutex_lock(&sender_phone->lock);
     516                if (sender_phone->state != IPC_PHONE_CONNECTED) {
     517                        mutex_unlock(&sender_phone->lock);
     518                        return EINVAL;
     519                }
     520
     521                other_task_s = sender_phone->callee->task;
     522
     523                mutex_unlock(&sender_phone->lock);
     524
     525                /* Remember the third party task hash. */
     526                IPC_SET_ARG5(call->data, (sysarg_t) other_task_s);
     527                break;
     528        }
    449529#ifdef CONFIG_UDEBUG
    450         case IPC_M_DEBUG_ALL:
     530        case IPC_M_DEBUG:
    451531                return udebug_request_preprocess(call, phone);
    452532#endif
     
    483563                /*
    484564                 * This must be an affirmative answer to IPC_M_DATA_READ
    485                  * or IPC_M_DEBUG_ALL/UDEBUG_M_MEM_READ...
     565                 * or IPC_M_DEBUG/UDEBUG_M_MEM_READ...
    486566                 *
    487567                 */
     
    519599       
    520600        switch (IPC_GET_IMETHOD(call->data)) {
    521         case IPC_M_DEBUG_ALL:
     601        case IPC_M_DEBUG:
    522602                return -1;
    523603        default:
Note: See TracChangeset for help on using the changeset viewer.