Changeset 2100 in vbox for trunk/src/VBox/Additions/linux/module
- Timestamp:
- Apr 16, 2007 1:20:11 PM (18 years ago)
- Location:
- trunk/src/VBox/Additions/linux/module
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/linux/module/Makefile
r1825 r2100 73 73 vboxmod.c=>vboxmod.c \ 74 74 cmc.c=>cmc.c \ 75 hgcmcall.c=>hgcmcall.c \ 75 76 vboxmod.h=>vboxmod.h \ 76 77 waitcompat.h=>waitcompat.h \ … … 88 89 vboxadd_DEFS = KBUILD_MODNAME=KBUILD_STR\(vboxadd\) KBUILD_BASENAME=KBUILD_STR\(vboxadd\) MODULE IN_RING0 IN_RT_R0 VBGL_VBOXGUEST EXPORT_SYMTAB VBGL_HGCM VBOX_HGCM 89 90 vboxadd_LIBS = $(PATH_LIB)/RuntimeLnx32GuestR0.a 90 vboxadd_SOURCES = vboxmod.c cmc.c 91 vboxadd_SOURCES = vboxmod.c cmc.c hgcmcall.c 91 92 vboxadd_INCS = $(PATH_ROOT)/src/VBox/Runtime/r0drv/linux 92 93 vboxadd_NOINST = 1 -
trunk/src/VBox/Additions/linux/module/vboxmod.c
r1667 r2100 27 27 #include "vboxmod.h" 28 28 #include "waitcompat.h" 29 #include <VBox/log.h> 29 30 30 31 #define VERSION "0.5" … … 41 42 const char *pszFile, const char *pszFunction) 42 43 { 43 elog ("!!Assertion Failed!!\n" 44 "Expression: %s\n" 45 "Location : %s(%d) %s\n", 46 pszExpr, pszFile, uLine, pszFunction); 44 elog("!!Assertion Failed!!\n" 45 "Expression: %s\n" 46 "Location : %s(%d) %s\n", 47 pszExpr, pszFile, uLine, pszFunction); 48 Log(("!!Assertion Failed!!\n" 49 "Expression: %s\n" 50 "Location : %s(%d) %s\n", 51 pszExpr, pszFile, uLine, pszFunction)); 47 52 } 48 53 … … 56 61 vsnprintf(msg, sizeof(msg) - 1, pszFormat, ap); 57 62 msg[sizeof(msg) - 1] = '\0'; 58 ilog ("%s", msg); 63 elog("%s", msg); 64 Log(("%s", msg)); 59 65 va_end(ap); 60 66 } 61 67 68 #if 0 /* We now have real backdoor logging */ 62 69 /* Backdoor logging function, needed by the runtime */ 63 70 RTDECL(size_t) RTLogBackdoorPrintf (const char *pszFormat, ...) … … 74 81 return n; 75 82 } 83 #endif 76 84 77 85 /** device extension structure (we only support one device instance) */ … … 252 260 case IOCTL_VBOXGUEST_HGCM_CALL: 253 261 { 254 VBoxGuestHGCMCallInfo callHeader, *hgcmR3, *hgcmR0; 255 uint8_t *pu8PointerData; 256 size_t cbPointerData = 0, offPointerData = 0; 257 int i, rc; 258 259 compiler_assert(_IOC_SIZE(IOCTL_VBOXGUEST_HGCM_CALL) == sizeof(VBoxGuestHGCMCallInfo)); 260 if (copy_from_user(&callHeader, (void*)arg, _IOC_SIZE(cmd))) 261 { 262 elog("IOCTL_VBOXGUEST_HGCM_CALL: copy_from_user failed!\n"); 263 return -EFAULT; 264 } 265 hgcmR3 = kmalloc(sizeof(*hgcmR3) + callHeader.cParms * sizeof(HGCMFunctionParameter), 266 GFP_KERNEL); 267 if (!hgcmR3) 268 { 269 elog("IOCTL_VBOXGUEST_HGCM_CALL: cannot allocate memory!\n"); 270 return -ENOMEM; 271 } 272 if (copy_from_user(hgcmR3, (void*)arg, 273 sizeof(*hgcmR3) + callHeader.cParms 274 * sizeof(HGCMFunctionParameter))) 275 { 276 elog("IOCTL_VBOXGUEST_HGCM_CALL: copy_from_user failed!\n"); 277 kfree(hgcmR3); 278 return -EFAULT; 279 } 280 hgcmR0 = kmalloc(sizeof(*hgcmR0) + callHeader.cParms * sizeof(HGCMFunctionParameter), 281 GFP_KERNEL); 282 if (!hgcmR0) 283 { 284 elog("IOCTL_VBOXGUEST_HGCM_CALL: cannot allocate memory!\n"); 285 kfree(hgcmR3); 286 return -ENOMEM; 287 } 288 hgcmR0->u32ClientID = callHeader.u32ClientID; 289 hgcmR0->u32Function = callHeader.u32Function; 290 hgcmR0->cParms = callHeader.cParms; 291 /* Calculate the total size of pointer space. Will normally be for a single pointer */ 292 for (i = 0; i < callHeader.cParms; ++i) 293 { 294 switch (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type) 295 { 296 case VMMDevHGCMParmType_32bit: 297 case VMMDevHGCMParmType_64bit: 298 break; 299 case VMMDevHGCMParmType_LinAddr: 300 case VMMDevHGCMParmType_LinAddr_In: 301 case VMMDevHGCMParmType_LinAddr_Out: 302 cbPointerData += VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size; 303 break; 304 default: 305 elog("IOCTL_VBOXGUEST_HGCM_CALL: unsupported or unknown parameter type\n"); 306 kfree(hgcmR3); 307 kfree(hgcmR0); 308 return -EINVAL; 309 } 310 } 311 pu8PointerData = kmalloc (cbPointerData, GFP_KERNEL); 312 /* Reconstruct the pointer parameter data in kernel space */ 313 if (pu8PointerData == NULL) 314 { 315 elog("IOCTL_VBOXGUEST_HGCM_CALL: out of memory allocating %d bytes for pointer data\n", 316 cbPointerData); 317 kfree(hgcmR3); 318 kfree(hgcmR0); 319 return -ENOMEM; 320 } 321 for (i = 0; i < callHeader.cParms; ++i) 322 { 323 VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].type 324 = VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type; 325 if ( (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type == VMMDevHGCMParmType_LinAddr) 326 || (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type 327 == VMMDevHGCMParmType_LinAddr_In)) 328 { 329 /* We are sending data to the host or sending and reading. */ 330 void *pvR3LinAddr 331 = (void *)VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.u.linearAddr; 332 if (copy_from_user(&pu8PointerData[offPointerData], 333 pvR3LinAddr, 334 VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size)) 335 { 336 elog("IOCTL_VBOXGUEST_HGCM_CALL: copy_from_user failed!\n"); 337 rc = -EFAULT; 338 goto hgcm_exit; 339 } 340 VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.u.linearAddr 341 = (vmmDevHypPtr)&pu8PointerData[offPointerData]; 342 VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.size 343 = VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size; 344 offPointerData += VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size; 345 } 346 else if (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type 347 == VMMDevHGCMParmType_LinAddr_Out) 348 { 349 /* We are reading data from the host */ 350 VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.u.linearAddr 351 = (vmmDevHypPtr)&pu8PointerData[offPointerData]; 352 VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.size 353 = VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size; 354 offPointerData += VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size; 355 } 356 else 357 { 358 /* If it is not a pointer, then it is a 32bit or 64bit value */ 359 VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.value64 360 = VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.value64; 361 } 362 } 363 /* Internal VBoxGuest IOCTL interface */ 364 rc = vboxadd_cmc_call(vboxDev, IOCTL_VBOXGUEST_HGCM_CALL, hgcmR0); 365 if (rc != VINF_SUCCESS) 366 { 367 elog("IOCTL_VBOXGUEST_HGCM_CALL: internal ioctl call failed, rc=%d\n", rc); 368 /** @todo We need a function to convert VBox error codes back to Linux. */ 369 rc = -EINVAL; 370 goto hgcm_exit; 371 } 372 for (i = 0; i < callHeader.cParms; ++i) 373 { 374 if ( (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type == VMMDevHGCMParmType_LinAddr) 375 || (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type 376 == VMMDevHGCMParmType_LinAddr_Out)) 377 { 378 /* We are sending data to the host or sending and reading. */ 379 void *pvR3LinAddr 380 = (void *)VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.u.linearAddr; 381 void *pvR0LinAddr 382 = (void *)VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.u.linearAddr; 383 if (copy_to_user(pvR3LinAddr, pvR0LinAddr, 384 VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.size)) 385 { 386 elog("IOCTL_VBOXGUEST_HGCM_CALL: copy_to_user failed!\n"); 387 rc = -EFAULT; 388 goto hgcm_exit; 389 } 390 VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size 391 = VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.size; 392 } 393 else if (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type 394 != VMMDevHGCMParmType_LinAddr_Out) 395 { 396 /* If it is not a pointer, then it is a 32bit or 64bit value */ 397 VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.value64 398 = VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.value64; 399 } 400 } 401 hgcmR3->result = hgcmR0->result; 402 if (copy_to_user((void*)arg, hgcmR3, 403 sizeof(*hgcmR3) + callHeader.cParms * sizeof(HGCMFunctionParameter))) 404 { 405 elog("IOCTL_VBOXGUEST_HGCM_CALL: copy_to_user failed!\n"); 406 rc = -EFAULT; 407 goto hgcm_exit; 408 } 409 hgcm_exit: 410 kfree(hgcmR3); 411 kfree(hgcmR0); 412 kfree(pu8PointerData); 413 return rc; 262 /* This IOCTL allows the guest to make an HGCM call from user space. The 263 OS-independant part of the Guest Additions already contain code for making an 264 HGCM call from the guest, but this code assumes that the call is made from the 265 kernel's address space. So before calling it, we have to copy all parameters 266 to the HGCM call from user space to kernel space and reconstruct the structures 267 passed to the call (which include pointers to other memory) inside the kernel's 268 address space. */ 269 return vbox_ioctl_hgcm_call(arg, vboxDev); 414 270 } 415 271 416 272 default: 417 273 { 418 printk(KERN_ERR "vboxadd_ioctl: unknown command: %x\n", cmd); 274 elog("vboxadd_ioctl: unknown command: %x, IOCTL_VBOXGUEST_HGCM_CALL is %x\n", cmd, 275 IOCTL_VBOXGUEST_HGCM_CALL); 276 Log(("vboxadd_ioctl: unknown command: %x, IOCTL_VBOXGUEST_HGCM_CALL is %x\n", cmd, 277 IOCTL_VBOXGUEST_HGCM_CALL)); 419 278 return -EINVAL; 420 279 } -
trunk/src/VBox/Additions/linux/module/vboxmod.h
r1621 r2100 81 81 DECLVBGL (int) vboxadd_cmc_call (void *opaque, uint32_t func, void *data); 82 82 83 /** 84 * This IOCTL wrapper allows the guest to make an HGCM call from user space. The 85 * OS-independant part of the Guest Additions already contain code for making an 86 * HGCM call from the guest, but this code assumes that the call is made from the 87 * kernel's address space. So before calling it, we have to copy all parameters 88 * to the HGCM call from user space to kernel space and reconstruct the structures 89 * passed to the call (which include pointers to other memory) inside the kernel's 90 * address space. 91 * 92 * @returns 0 on success or Linux error code on failure 93 * @param arg User space pointer to the call data structure 94 */ 95 extern int vbox_ioctl_hgcm_call(unsigned long arg, VBoxDevice *vboxDev); 96 83 97 #endif /* !VBOXMOD_H */
Note:
See TracChangeset
for help on using the changeset viewer.