Changeset 1619 in vbox for trunk/src/VBox/Additions/linux/module
- Timestamp:
- Mar 22, 2007 8:45:59 AM (18 years ago)
- Location:
- trunk/src/VBox/Additions/linux/module
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/linux/module/vboxmod.c
r1067 r1619 244 244 VbglGRFree(reqFull); 245 245 break; 246 } 247 248 case IOCTL_VBOXGUEST_HGCM_CALL: 249 { 250 VBoxGuestHGCMCallInfo callHeader, *hgcmR3, *hgcmR0; 251 uint8_t *pu8PointerData; 252 size_t cbPointerData = 0, offPointerData = 0; 253 int i, rc; 254 255 compiler_assert(_IOC_SIZE(IOCTL_VBOXGUEST_HGCM_CALL) == sizeof(VBoxGuestHGCMCallInfo)); 256 if (copy_from_user(&callHeader, (void*)arg, _IOC_SIZE(cmd))) 257 { 258 elog("IOCTL_VBOXGUEST_HGCM_CALL: copy_from_user failed!\n"); 259 return -EFAULT; 260 } 261 hgcmR3 = kmalloc(sizeof(*hgcmR3) + callHeader.cParms * sizeof(HGCMFunctionParameter), 262 GFP_KERNEL); 263 if (!hgcmR3) 264 { 265 elog("IOCTL_VBOXGUEST_HGCM_CALL: cannot allocate memory!\n"); 266 return -ENOMEM; 267 } 268 if (copy_from_user(hgcmR3, (void*)arg, 269 sizeof(*hgcmR3) + callHeader.cParms 270 * sizeof(HGCMFunctionParameter))) 271 { 272 elog("IOCTL_VBOXGUEST_HGCM_CALL: copy_from_user failed!\n"); 273 kfree(hgcmR3); 274 return -EFAULT; 275 } 276 hgcmR0 = kmalloc(sizeof(*hgcmR0) + callHeader.cParms * sizeof(HGCMFunctionParameter), 277 GFP_KERNEL); 278 if (!hgcmR0) 279 { 280 elog("IOCTL_VBOXGUEST_HGCM_CALL: cannot allocate memory!\n"); 281 kfree(hgcmR3); 282 return -ENOMEM; 283 } 284 hgcmR0->u32ClientID = callHeader.u32ClientID; 285 hgcmR0->u32Function = callHeader.u32Function; 286 hgcmR0->cParms = callHeader.cParms; 287 /* Calculate the total size of pointer space. Will normally be for a single pointer */ 288 for (i = 0; i < callHeader.cParms; ++i) 289 { 290 switch (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type) 291 { 292 case VMMDevHGCMParmType_32bit: 293 case VMMDevHGCMParmType_64bit: 294 break; 295 case VMMDevHGCMParmType_LinAddr: 296 case VMMDevHGCMParmType_LinAddr_In: 297 case VMMDevHGCMParmType_LinAddr_Out: 298 cbPointerData += VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size; 299 break; 300 default: 301 elog("IOCTL_VBOXGUEST_HGCM_CALL: unsupported or unknown parameter type\n"); 302 kfree(hgcmR3); 303 kfree(hgcmR0); 304 return -EINVAL; 305 } 306 } 307 pu8PointerData = kmalloc (cbPointerData, GFP_KERNEL); 308 /* Reconstruct the pointer parameter data in kernel space */ 309 if (pu8PointerData == NULL) 310 { 311 elog("IOCTL_VBOXGUEST_HGCM_CALL: out of memory allocating %d bytes for pointer data\n", 312 cbPointerData); 313 kfree(hgcmR3); 314 kfree(hgcmR0); 315 return -ENOMEM; 316 } 317 for (i = 0; i < callHeader.cParms; ++i) 318 { 319 VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].type 320 = VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type; 321 if ( (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type == VMMDevHGCMParmType_LinAddr) 322 || (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type 323 == VMMDevHGCMParmType_LinAddr_In)) 324 { 325 /* We are sending data to the host or sending and reading. */ 326 if (copy_from_user(&pu8PointerData[offPointerData], 327 VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.u.linearAddr, 328 VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size)) 329 { 330 elog("IOCTL_VBOXGUEST_HGCM_CALL: copy_from_user failed!\n"); 331 rc = -EFAULT; 332 goto hgcm_exit; 333 } 334 VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.u.linearAddr 335 = &pu8PointerData[offPointerData]; 336 VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.size 337 = VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size; 338 offPointerData += VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size; 339 } 340 else if (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type 341 == VMMDevHGCMParmType_LinAddr_Out) 342 { 343 /* We are reading data from the host */ 344 VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.u.linearAddr 345 = &pu8PointerData[offPointerData]; 346 VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.size 347 = VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size; 348 offPointerData += VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size; 349 } 350 else 351 { 352 /* If it is not a pointer, then it is a 32bit or 64bit value */ 353 VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.value64 354 = VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.value64; 355 } 356 } 357 /* Internal VBoxGuest IOCTL interface */ 358 rc = vboxadd_cmc_call(vboxDev, IOCTL_VBOXGUEST_HGCM_CALL, hgcmR0); 359 if (rc != VINF_SUCCESS) 360 { 361 elog("IOCTL_VBOXGUEST_HGCM_CALL: internal ioctl call failed, rc=%d\n", rc); 362 /** @todo We need a function to convert VBox error codes back to Linux. */ 363 rc = -EINVAL; 364 goto hgcm_exit; 365 } 366 for (i = 0; i < callHeader.cParms; ++i) 367 { 368 if ( (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type == VMMDevHGCMParmType_LinAddr) 369 || (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type 370 == VMMDevHGCMParmType_LinAddr_Out)) 371 { 372 /* We are sending data to the host or sending and reading. */ 373 if (copy_to_user(VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.u.linearAddr, 374 VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.u.linearAddr, 375 VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.size)) 376 { 377 elog("IOCTL_VBOXGUEST_HGCM_CALL: copy_to_user failed!\n"); 378 rc = -EFAULT; 379 goto hgcm_exit; 380 } 381 VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size 382 = VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.size; 383 } 384 else if (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type 385 != VMMDevHGCMParmType_LinAddr_Out) 386 { 387 /* If it is not a pointer, then it is a 32bit or 64bit value */ 388 VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.value64 389 = VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.value64; 390 } 391 } 392 hgcmR3->result = hgcmR0->result; 393 if (copy_to_user((void*)arg, hgcmR3, 394 sizeof(*hgcmR3) + callHeader.cParms * sizeof(HGCMFunctionParameter))) 395 { 396 elog("IOCTL_VBOXGUEST_HGCM_CALL: copy_to_user failed!\n"); 397 rc = -EFAULT; 398 goto hgcm_exit; 399 } 400 hgcm_exit: 401 kfree(hgcmR3); 402 kfree(hgcmR0); 403 kfree(pu8PointerData); 404 return rc; 246 405 } 247 406 -
trunk/src/VBox/Additions/linux/module/vboxmod.h
r1 r1619 67 67 if (n >= vboxadd_verbosity) printk (KERN_DEBUG "vboxadd: " __VA_ARGS__) 68 68 69 #define compiler_assert(val) \ 70 do { \ 71 switch(0) { \ 72 case 0: \ 73 case (val): \ 74 default: \ 75 break; \ 76 } \ 77 } while(0); 78 69 79 extern int vboxadd_cmc_init (void); 70 80 extern void vboxadd_cmc_fini (void);
Note:
See TracChangeset
for help on using the changeset viewer.