- Timestamp:
- 2007-12-23T21:21:41Z (18 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a92da0a
- Parents:
- 654b7db
- Location:
- kernel/generic
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/ipc/ipc.h
r654b7db ra55d5f9f 280 280 ipc_data_t data; 281 281 282 /** Buffer for IPC_M_DATA_ SEND. */282 /** Buffer for IPC_M_DATA_WRITE and IPC_M_DATA_READ. */ 283 283 uint8_t *buffer; 284 284 } call_t; -
kernel/generic/src/ipc/ipc.c
r654b7db ra55d5f9f 415 415 while (!list_empty(lst)) { 416 416 call = list_get_instance(lst->next, call_t, link); 417 if (call->buffer) 418 free(call->buffer); 417 419 list_remove(&call->link); 418 420 -
kernel/generic/src/ipc/sysipc.c
r654b7db ra55d5f9f 236 236 IPC_SET_RETVAL(answer->data, rc); 237 237 } 238 } else if (IPC_GET_METHOD(*olddata) == IPC_M_DATA_READ) { 239 ASSERT(!answer->buffer); 240 if (!IPC_GET_RETVAL(answer->data)) { 241 /* The recipient agreed to send data. */ 242 uintptr_t src = IPC_GET_ARG1(answer->data); 243 uintptr_t dst = IPC_GET_ARG1(*olddata); 244 size_t max_size = IPC_GET_ARG2(*olddata); 245 size_t size = IPC_GET_ARG2(answer->data); 246 if (size <= max_size) { 247 /* 248 * Copy the destination VA so that this piece of 249 * information is not lost. 250 */ 251 IPC_SET_ARG1(answer->data, dst); 252 253 answer->buffer = malloc(size, 0); 254 int rc = copy_from_uspace(answer->buffer, 255 (void *) src, size); 256 if (rc) { 257 IPC_SET_RETVAL(answer->data, rc); 258 free(answer->buffer); 259 answer->buffer = NULL; 260 } 261 } else { 262 IPC_SET_RETVAL(answer->data, ELIMIT); 263 } 264 } 238 265 } else if (IPC_GET_METHOD(*olddata) == IPC_M_DATA_WRITE) { 239 266 ASSERT(answer->buffer); 240 267 if (!IPC_GET_RETVAL(answer->data)) { 268 /* The recipient agreed to receive data. */ 241 269 int rc; 242 270 uintptr_t dst; 243 271 uintptr_t size; 272 uintptr_t max_size; 244 273 245 274 dst = IPC_GET_ARG1(answer->data); 246 275 size = IPC_GET_ARG3(answer->data); 247 248 rc = copy_to_uspace((void *) dst, answer->buffer, size); 249 if (rc != 0) 250 IPC_SET_RETVAL(answer->data, rc); 276 max_size = IPC_GET_ARG3(*olddata); 277 278 if (size <= max_size) { 279 rc = copy_to_uspace((void *) dst, 280 answer->buffer, size); 281 if (rc) 282 IPC_SET_RETVAL(answer->data, rc); 283 } else { 284 IPC_SET_RETVAL(answer->data, ELIMIT); 285 } 251 286 } 252 287 free(answer->buffer); … … 285 320 IPC_SET_ARG2(call->data, size); 286 321 break; 322 case IPC_M_DATA_READ: 323 size = IPC_GET_ARG2(call->data); 324 if ((size <= 0 || (size > DATA_XFER_LIMIT))) 325 return ELIMIT; 326 break; 287 327 case IPC_M_DATA_WRITE: 288 328 src = IPC_GET_ARG2(call->data); … … 325 365 IPC_SET_ARG5(call->data, call->priv); 326 366 } 367 368 if (call->buffer) { 369 /* This must be an affirmative answer to IPC_M_DATA_READ. */ 370 uintptr_t dst = IPC_GET_ARG1(call->data); 371 size_t size = IPC_GET_ARG2(call->data); 372 int rc = copy_to_uspace((void *) dst, call->buffer, size); 373 if (rc) 374 IPC_SET_RETVAL(call->data, rc); 375 free(call->buffer); 376 call->buffer = NULL; 377 } 327 378 } 328 379
Note:
See TracChangeset
for help on using the changeset viewer.