Changeset 5817 in vbox for trunk/src/VBox/Additions/linux
- Timestamp:
- Nov 22, 2007 5:57:32 PM (17 years ago)
- Location:
- trunk/src/VBox/Additions/linux/module
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/linux/module/vboxmod.c
r5606 r5817 33 33 MODULE_VERSION(VBOX_VERSION_STRING); 34 34 #endif 35 36 /***************************************************************************** 37 * Macros * 38 *****************************************************************************/ 39 40 /* We need to define these ones here as they only exist in kernels 2.6 and up */ 41 42 #define __vbox_wait_event_interruptible_timeout(wq, condition, timeout, ret) \ 43 do { \ 44 int __ret = 0; \ 45 if (!(condition)) { \ 46 wait_queue_t __wait; \ 47 unsigned long expire; \ 48 init_waitqueue_entry(&__wait, current); \ 49 \ 50 expire = timeout + jiffies; \ 51 add_wait_queue(&wq, &__wait); \ 52 for (;;) { \ 53 set_current_state(TASK_INTERRUPTIBLE); \ 54 if (condition) \ 55 break; \ 56 if (jiffies > expire) { \ 57 ret = jiffies - expire; \ 58 break; \ 59 } \ 60 if (!signal_pending(current)) { \ 61 schedule_timeout(timeout); \ 62 continue; \ 63 } \ 64 ret = -ERESTARTSYS; \ 65 break; \ 66 } \ 67 current->state = TASK_RUNNING; \ 68 remove_wait_queue(&wq, &__wait); \ 69 } \ 70 } while (0) 71 72 /* 73 retval == 0; condition met; we're good. 74 retval < 0; interrupted by signal. 75 retval > 0; timed out. 76 */ 77 #define vbox_wait_event_interruptible_timeout(wq, condition, timeout) \ 78 ({ \ 79 int __ret = 0; \ 80 if (!(condition)) \ 81 __vbox_wait_event_interruptible_timeout(wq, condition, \ 82 timeout, __ret); \ 83 __ret; \ 84 }) 85 35 86 36 87 /* This is called by our assert macros to find out whether we want … … 100 151 if (ASMAtomicCmpXchgU32(&hgcm_connections[i].client_id, client_id, 0)) { 101 152 hgcm_connections[i].filp = filp; 153 #ifdef DEBUG 154 LogRelFunc(("Registered client ID %d, file pointer %p at position %d in the table.\n", 155 client_id, filp, i)); 156 #endif 102 157 found = true; 103 158 } … … 120 175 for (i = 0; (i < MAX_HGCM_CONNECTIONS) && (false == found); ++i) { 121 176 if (hgcm_connections[i].client_id == client_id) { 177 #ifdef DEBUG 178 LogRelFunc(("Unregistered client ID %d, file pointer %p at position %d in the table.\n", 179 client_id, hgcm_connections[i].filp, i)); 180 #endif 181 hgcm_connections[i].filp = NULL; 122 182 hgcm_connections[i].client_id = 0; 123 183 found = true; … … 144 204 for (i = 0; i < MAX_HGCM_CONNECTIONS; ++i) { 145 205 if (hgcm_connections[i].filp == filp) { 206 VBoxGuestHGCMDisconnectInfo infoDisconnect; 207 #ifdef DEBUG 208 LogRelFunc(("Unregistered client ID %d, file pointer %p at position %d in the table.\n", 209 hgcm_connections[i].client_id, filp, i)); 210 #endif 211 infoDisconnect.u32ClientID = hgcm_connections[i].client_id; 212 vboxadd_cmc_call(vboxDev, IOCTL_VBOXGUEST_HGCM_DISCONNECT, 213 &infoDisconnect); 214 hgcm_connections[i].filp = NULL; 146 215 hgcm_connections[i].client_id = 0; 147 216 } … … 171 240 } 172 241 173 /**174 * Wait for event175 *176 */177 static void178 vboxadd_wait_for_event_helper (VBoxDevice *dev, long timeout,179 uint32_t in_mask, uint32_t * out_mask)180 {181 BUG ();182 }183 184 242 static void 185 243 vboxadd_wait_for_event (VBoxGuestWaitEventInfo * info) 186 244 { 187 long timeout; 188 189 timeout = msecs_to_jiffies (info->u32TimeoutIn); 190 vboxadd_wait_for_event_helper (vboxDev, timeout, 191 info->u32EventMaskIn, 192 &info->u32EventFlagsOut); 193 } 194 245 long timeleft; 246 uint32_t cInterruptions = vboxDev->u32GuestInterruptions; 247 uint32_t in_mask = info->u32EventMaskIn; 248 249 info->u32Result = VBOXGUEST_WAITEVENT_OK; 250 timeleft = vbox_wait_event_interruptible_timeout 251 (vboxDev->eventq, 252 (vboxDev->u32Events & in_mask) 253 || (vboxDev->u32GuestInterruptions != cInterruptions), 254 msecs_to_jiffies (info->u32TimeoutIn)); 255 if (vboxDev->u32GuestInterruptions != cInterruptions) { 256 info->u32Result = VBOXGUEST_WAITEVENT_INTERRUPTED; 257 } 258 if (timeleft < 0) { 259 info->u32Result = VBOXGUEST_WAITEVENT_INTERRUPTED; 260 } 261 if (timeleft == 0) { 262 info->u32Result = VBOXGUEST_WAITEVENT_TIMEOUT; 263 } 264 info->u32EventFlagsOut = vboxDev->u32Events & in_mask; 265 vboxDev->u32Events &= ~in_mask; 266 } 267 268 /** 269 * IOCtl handler - wait for an event from the host. 270 * 271 * @returns Linux kernel return code 272 * @param ptr User space pointer to a structure describing the event 273 */ 274 static int vboxadd_wait_event(void *ptr) 275 { 276 int rc = 0; 277 VBoxGuestWaitEventInfo info; 278 279 if (copy_from_user (&info, ptr, sizeof (info))) { 280 LogRelFunc (("IOCTL_VBOXGUEST_WAITEVENT: can not get event info\n")); 281 rc = -EFAULT; 282 } 283 284 if (0 == rc) { 285 vboxadd_wait_for_event (&info); 286 287 if (copy_to_user (ptr, &info, sizeof (info))) { 288 LogRelFunc (("IOCTL_VBOXGUEST_WAITEVENT: can not put out_mask\n")); 289 rc = -EFAULT; 290 } 291 } 292 return 0; 293 } 195 294 196 295 /** … … 222 321 } else { 223 322 /* Register that the connection is associated with this file pointer. */ 323 LogRelFunc(("Connected, client ID %u\n", info.u32ClientID)); 224 324 rc = vboxadd_register_hgcm_connection(info.u32ClientID, filp); 225 325 if (0 != rc) { … … 251 351 unsigned int cmd, unsigned long arg) 252 352 { 253 switch (cmd) 254 { 353 int rc = 0; 354 355 switch (cmd) { 255 356 case IOCTL_VBOXGUEST_WAITEVENT: 256 { 257 VBoxGuestWaitEventInfo info; 258 char *ptr = (void *) arg; 259 260 if (copy_from_user (&info, ptr, sizeof (info))) 261 { 262 LogRelFunc (("IOCTL_VBOXGUEST_WAITEVENT: can not get event info\n")); 263 return -EFAULT; 264 } 265 266 vboxadd_wait_for_event (&info); 267 268 ptr += offsetof (VBoxGuestWaitEventInfo, u32EventFlagsOut); 269 if (put_user (info.u32EventFlagsOut, (uint32_t*)ptr)) 270 { 271 LogRelFunc (("IOCTL_VBOXGUEST_WAITEVENT: can not put out_mask\n")); 272 return -EFAULT; 273 } 274 return 0; 275 } 276 277 case IOCTL_VBOXGUEST_VMMREQUEST: 278 { 357 rc = vboxadd_wait_event((void *) arg); 358 break; 359 360 case VBOXGUEST_IOCTL_WAITEVENT_INTERRUPT_ALL: 361 ++vboxDev->u32GuestInterruptions; 362 break; 363 364 case IOCTL_VBOXGUEST_VMMREQUEST: { 279 365 VMMDevRequestHeader reqHeader; 280 366 VMMDevRequestHeader *reqFull = NULL; … … 283 369 int rc; 284 370 285 if (_IOC_SIZE(cmd) != sizeof(VMMDevRequestHeader)) 286 { 287 LogRelFunc(("IOCTL_VBOXGUEST_VMMREQUEST: invalid VMM request structure size: %d\n", 288 _IOC_SIZE(cmd))); 289 return -EINVAL; 290 } 371 AssertCompileSize(VMMDevRequestHeader, _IOC_SIZE(cmd)); 291 372 if (copy_from_user(&reqHeader, (void*)arg, _IOC_SIZE(cmd))) 292 373 { … … 361 442 362 443 case IOCTL_VBOXGUEST_HGCM_CALL: 363 {364 444 /* This IOCTL allows the guest to make an HGCM call from user space. The 365 445 OS-independant part of the Guest Additions already contain code for making an … … 369 449 passed to the call (which include pointers to other memory) inside the kernel's 370 450 address space. */ 371 r eturnvbox_ioctl_hgcm_call(arg, vboxDev);372 }451 rc = vbox_ioctl_hgcm_call(arg, vboxDev); 452 break; 373 453 374 454 case IOCTL_VBOXGUEST_HGCM_CONNECT: 375 { 376 return vboxadd_hgcm_connect(filp, arg); 377 } 455 rc = vboxadd_hgcm_connect(filp, arg); 456 break; 378 457 379 458 default: 380 { 381 LogRelFunc(("unknown command: %x\n", cmd)); 382 return -EINVAL; 383 } 384 } 385 return 0; 459 LogRelFunc(("unknown command: %x\n", cmd)); 460 rc = -EINVAL; 461 break; 462 } 463 return rc; 386 464 } 387 465 -
trunk/src/VBox/Additions/linux/module/vboxmod.h
r4071 r5817 51 51 /** event synchronization */ 52 52 wait_queue_head_t eventq; 53 /** number of times the guest has interrupted the event loop - 54 implemented as a counter to prevent one waiter swallowing the 55 event. */ 56 uint32_t u32GuestInterruptions; 53 57 }; 54 58
Note:
See TracChangeset
for help on using the changeset viewer.