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) |