Subversion Repositories HelenOS

Rev

Rev 2471 | Rev 2556 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2471 Rev 2494
Line 47... Line 47...
47
#include <syscall/copy.h>
47
#include <syscall/copy.h>
48
#include <security/cap.h>
48
#include <security/cap.h>
49
#include <mm/as.h>
49
#include <mm/as.h>
50
#include <print.h>
50
#include <print.h>
51
 
51
 
-
 
52
/** Maximum buffer size allowed for IPC_M_DATA_SEND requests. */
-
 
53
#define DATA_SEND_LIMIT     (64 * 1024)
-
 
54
 
52
#define GET_CHECK_PHONE(phone, phoneid, err) \
55
#define GET_CHECK_PHONE(phone, phoneid, err) \
53
{ \
56
{ \
54
    if (phoneid > IPC_MAX_PHONES) { \
57
    if (phoneid > IPC_MAX_PHONES) { \
55
        err; \
58
        err; \
56
    } \
59
    } \
Line 83... Line 86...
83
 * @return      Return 1 if the method is forwardable.
86
 * @return      Return 1 if the method is forwardable.
84
 *          Otherwise return 0.
87
 *          Otherwise return 0.
85
 */
88
 */
86
static inline int is_forwardable(unative_t method)
89
static inline int is_forwardable(unative_t method)
87
{
90
{
-
 
91
    switch (method) {
-
 
92
    case IPC_M_PHONE_HUNGUP:
88
    if (method == IPC_M_PHONE_HUNGUP || method == IPC_M_AS_AREA_SEND ||
93
    case IPC_M_AS_AREA_SEND:
89
        method == IPC_M_AS_AREA_RECV)
94
    case IPC_M_AS_AREA_RECV:
-
 
95
    case IPC_M_DATA_SEND:
90
        return 0; /* This message is meant only for the receiver */
96
        /* This message is meant only for the original recipient. */
-
 
97
        return 0;
-
 
98
    default:
91
    return 1;
99
        return 1;
-
 
100
    }
92
}
101
}
93
 
102
 
94
 
103
 
95
/***********************************************************************
104
/***********************************************************************
96
 * Functions that preprocess answer before sending it to the recepient.
105
 * Functions that preprocess answer before sending it to the recepient.
Line 104... Line 113...
104
 * @return      Return 1 if the old call contents should be saved.
113
 * @return      Return 1 if the old call contents should be saved.
105
 *          Return 0 otherwise.
114
 *          Return 0 otherwise.
106
 */
115
 */
107
static inline int answer_need_old(call_t *call)
116
static inline int answer_need_old(call_t *call)
108
{
117
{
109
    if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME)
118
    switch (IPC_GET_METHOD(call->data)) {
110
        return 1;
119
    case IPC_M_CONNECT_TO_ME:
111
    if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_ME_TO)
120
    case IPC_M_CONNECT_ME_TO:
112
        return 1;
-
 
113
    if (IPC_GET_METHOD(call->data) == IPC_M_AS_AREA_SEND)
121
    case IPC_M_AS_AREA_SEND:
114
        return 1;
122
    case IPC_M_AS_AREA_RECV:
115
    if (IPC_GET_METHOD(call->data) == IPC_M_AS_AREA_RECV)
123
    case IPC_M_DATA_SEND:
116
        return 1;
124
        return 1;
-
 
125
    default:
117
    return 0;
126
        return 0;
-
 
127
    }
118
}
128
}
119
 
129
 
120
/** Interpret process answer as control information.
130
/** Interpret process answer as control information.
121
 *
131
 *
122
 * This function is called directly after sys_ipc_answer().
132
 * This function is called directly after sys_ipc_answer().
Line 199... Line 209...
199
            rc = as_area_share(AS, IPC_GET_ARG1(answer->data),
209
            rc = as_area_share(AS, IPC_GET_ARG1(answer->data),
200
                IPC_GET_ARG2(*olddata), as, IPC_GET_ARG1(*olddata),
210
                IPC_GET_ARG2(*olddata), as, IPC_GET_ARG1(*olddata),
201
                IPC_GET_ARG2(answer->data));
211
                IPC_GET_ARG2(answer->data));
202
            IPC_SET_RETVAL(answer->data, rc);
212
            IPC_SET_RETVAL(answer->data, rc);
203
        }
213
        }
-
 
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
        }
204
    }
231
    }
205
    return 0;
232
    return 0;
206
}
233
}
207
 
234
 
208
/** Called before the request is sent.
235
/** Called before the request is sent.
Line 213... Line 240...
213
 */
240
 */
214
static int request_preprocess(call_t *call)
241
static int request_preprocess(call_t *call)
215
{
242
{
216
    int newphid;
243
    int newphid;
217
    size_t size;
244
    size_t size;
-
 
245
    uintptr_t src;
-
 
246
    int rc;
218
 
247
 
219
    switch (IPC_GET_METHOD(call->data)) {
248
    switch (IPC_GET_METHOD(call->data)) {
220
    case IPC_M_CONNECT_ME_TO:
249
    case IPC_M_CONNECT_ME_TO:
221
        newphid = phone_alloc();
250
        newphid = phone_alloc();
222
        if (newphid < 0)
251
        if (newphid < 0)
Line 230... Line 259...
230
        size = as_get_size(IPC_GET_ARG1(call->data));
259
        size = as_get_size(IPC_GET_ARG1(call->data));
231
        if (!size)
260
        if (!size)
232
            return EPERM;
261
            return EPERM;
233
        IPC_SET_ARG2(call->data, size);
262
        IPC_SET_ARG2(call->data, size);
234
        break;
263
        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;
235
    default:
278
    default:
236
        break;
279
        break;
237
    }
280
    }
238
    return 0;
281
    return 0;
239
}
282
}
Line 324... Line 367...
324
 
367
 
325
/** Make a synchronous IPC call allowing to transmit the entire payload.
368
/** Make a synchronous IPC call allowing to transmit the entire payload.
326
 *
369
 *
327
 * @param phoneid   Phone handle for the call.
370
 * @param phoneid   Phone handle for the call.
328
 * @param question  Userspace address of call data with the request.
371
 * @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.
330
 *
374
 *
331
 * @return      Zero on success or an error code.
375
 * @return      Zero on success or an error code.
332
 */
376
 */
333
unative_t sys_ipc_call_sync(unative_t phoneid, ipc_data_t *question,
377
unative_t sys_ipc_call_sync(unative_t phoneid, ipc_data_t *question,
334
    ipc_data_t *reply)
378
    ipc_data_t *reply)