Changeset 7918fce in mainline for kernel/generic/src


Ignore:
Timestamp:
2007-07-11T20:31:45Z (18 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
975f62f
Parents:
398d967
Message:

Implement a new mechanism for copying data between two address spaces based on
IPC. New system method IPC_M_DATA_SEND is introduced. The implementation is
generic and does not make use of any possible architecture optimizations such as
direct copy from one address space to another.

Location:
kernel/generic/src/ipc
Files:
2 edited

Legend:

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

    r398d967 r7918fce  
    6868        call->callerbox = &TASK->answerbox;
    6969        call->sender = TASK;
     70        call->buffer = NULL;
    7071}
    7172
     
    108109{
    109110        ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));
     111        /* Check to see if we have data in the IPC_M_DATA_SEND buffer. */
     112        if (call->buffer)
     113                free(call->buffer);
    110114        slab_free(ipc_call_slab, call);
    111115}
     
    293297       
    294298        spinlock_lock(&phone->lock);
    295         if (phone->state == IPC_PHONE_FREE || phone->state == IPC_PHONE_HUNGUP ||
     299        if (phone->state == IPC_PHONE_FREE ||
     300            phone->state == IPC_PHONE_HUNGUP ||
    296301            phone->state == IPC_PHONE_CONNECTING) {
    297302                spinlock_unlock(&phone->lock);
  • kernel/generic/src/ipc/sysipc.c

    r398d967 r7918fce  
    5050#include <print.h>
    5151
     52/** Maximum buffer size allowed for IPC_M_DATA_SEND requests. */
     53#define DATA_SEND_LIMIT         (64 * 1024)
     54
    5255#define GET_CHECK_PHONE(phone, phoneid, err) \
    5356{ \
     
    8689static inline int is_forwardable(unative_t method)
    8790{
    88         if (method == IPC_M_PHONE_HUNGUP || method == IPC_M_AS_AREA_SEND ||
    89             method == IPC_M_AS_AREA_RECV)
    90                 return 0; /* This message is meant only for the receiver */
    91         return 1;
     91        switch (method) {
     92        case IPC_M_PHONE_HUNGUP:
     93        case IPC_M_AS_AREA_SEND:
     94        case IPC_M_AS_AREA_RECV:
     95        case IPC_M_DATA_SEND:
     96                /* This message is meant only for the original recipient. */
     97                return 0;
     98        default:
     99                return 1;
     100        }
    92101}
    93102
     
    107116static inline int answer_need_old(call_t *call)
    108117{
    109         if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME)
     118        switch (IPC_GET_METHOD(call->data)) {
     119        case IPC_M_CONNECT_TO_ME:
     120        case IPC_M_CONNECT_ME_TO:
     121        case IPC_M_AS_AREA_SEND:
     122        case IPC_M_AS_AREA_RECV:
     123        case IPC_M_DATA_SEND:
    110124                return 1;
    111         if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_ME_TO)
    112                 return 1;
    113         if (IPC_GET_METHOD(call->data) == IPC_M_AS_AREA_SEND)
    114                 return 1;
    115         if (IPC_GET_METHOD(call->data) == IPC_M_AS_AREA_RECV)
    116                 return 1;
    117         return 0;
     125        default:
     126                return 0;
     127        }
    118128}
    119129
     
    202212                        IPC_SET_RETVAL(answer->data, rc);
    203213                }
     214        } else if (IPC_GET_METHOD(*olddata) == IPC_M_DATA_SEND) {
     215                if (!IPC_GET_RETVAL(answer->data)) {
     216                        int rc;
     217                        uintptr_t dst;
     218                        uintptr_t size;
     219
     220                        ASSERT(answer->buffer);
     221
     222                        dst = IPC_GET_ARG1(answer->data);
     223                        size = IPC_GET_ARG3(answer->data);
     224
     225                        rc = copy_to_uspace((void *) dst, answer->buffer, size);
     226                        if (rc != 0)
     227                                IPC_SET_RETVAL(answer->data, rc);
     228                        free(answer->buffer);
     229                        answer->buffer = NULL;
     230                }
    204231        }
    205232        return 0;
     
    216243        int newphid;
    217244        size_t size;
     245        uintptr_t src;
     246        int rc;
    218247
    219248        switch (IPC_GET_METHOD(call->data)) {
     
    233262                IPC_SET_ARG2(call->data, size);
    234263                break;
     264        case IPC_M_DATA_SEND:
     265                src = IPC_GET_ARG2(call->data);
     266                size = IPC_GET_ARG3(call->data);
     267               
     268                if ((size <= 0) || (size > DATA_SEND_LIMIT))
     269                        return ELIMIT;
     270               
     271                call->buffer = (uint8_t *) malloc(size, 0);
     272                rc = copy_from_uspace(call->buffer, (void *) src, size);
     273                if (rc != 0) {
     274                        free(call->buffer);
     275                        return rc;
     276                }
     277                break;
    235278        default:
    236279                break;
     
    327370 * @param phoneid       Phone handle for the call.
    328371 * @param question      Userspace address of call data with the request.
    329  * @param reply         Userspace address of call data where to store the answer.
     372 * @param reply         Userspace address of call data where to store the
     373 *                      answer.
    330374 *
    331375 * @return              Zero on success or an error code.
Note: See TracChangeset for help on using the changeset viewer.