- Timestamp:
- Mar 3, 2015 7:49:35 PM (10 years ago)
- Location:
- trunk/src/VBox/Additions/common/VBoxGuest
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c
r53484 r54606 967 967 } 968 968 969 970 969 /** log and dbg_log parameter getter. */ 971 970 static int vboxguestLinuxParamLogGrpGet(char *pszBuf, struct kernel_param *pParam) … … 993 992 } 994 993 995 996 994 /** log and dbg_log_flags parameter getter. */ 997 995 static int vboxguestLinuxParamLogFlagsGet(char *pszBuf, struct kernel_param *pParam) … … 1019 1017 } 1020 1018 1021 1022 1019 /** log and dbg_log_dest parameter getter. */ 1023 1020 static int vboxguestLinuxParamLogDstGet(char *pszBuf, struct kernel_param *pParam) … … 1029 1026 return strlen(pszBuf); 1030 1027 } 1028 1029 1030 /** r3_log_to_host parameter setter. */ 1031 static int vboxguestLinuxParamR3LogToHostSet(const char *pszValue, struct kernel_param *pParam) 1032 { 1033 if ( pszValue == NULL 1034 || *pszValue == '\0' 1035 || *pszValue == 'n' 1036 || *pszValue == 'N' 1037 || *pszValue == 'y' 1038 || *pszValue == 'y' 1039 || *pszValue == 'd' 1040 || *pszValue == 'D' 1041 || !strcmp(pszValue, "off") 1042 ) 1043 g_DevExt.fLoggingEnabled = false; 1044 else 1045 g_DevExt.fLoggingEnabled = true; 1046 return 0; 1047 } 1048 1049 /** r3_log_to_host parameter getter. */ 1050 static int vboxguestLinuxParamR3LogToHostGet(char *pszBuf, struct kernel_param *pParam) 1051 { 1052 strcpy(pszBuf, g_DevExt.fLoggingEnabled ? "enabled" : "disabled"); 1053 return strlen(pszBuf); 1054 } 1055 1031 1056 1032 1057 /* … … 1041 1066 module_param_call(dbg_log_dest, vboxguestLinuxParamLogDstSet, vboxguestLinuxParamLogDstGet, NULL, 0664); 1042 1067 # endif 1068 module_param_call(r3_log_to_host, vboxguestLinuxParamR3LogToHostSet, vboxguestLinuxParamR3LogToHostGet, NULL, 0664); 1043 1069 1044 1070 #endif /* 2.6.0 and later */ -
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
r54601 r54606 90 90 #endif 91 91 static int VBoxGuestCommonIOCtl_CancelAllWaitEvents(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession); 92 static int vboxGuestUpdateHostFlags(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, unsigned fFlags);92 static void vbgdBitUsageTrackerClear(PVBOXGUESTBITUSAGETRACER pTracker); 93 93 static uint32_t vbgdGetAllowedEventMaskForSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession); 94 static int vbgdUpdateCapabilitiesOnHost(PVBOXGUESTDEVEXT pDevExt); 94 static int vbgdResetEventFilterOnHost(PVBOXGUESTDEVEXT pDevExt, uint32_t fFixedEvents); 95 static int vbgdResetMouseStatusOnHost(PVBOXGUESTDEVEXT pDevExt); 96 static int vbgdResetCapabilitiesOnHost(PVBOXGUESTDEVEXT pDevExt); 97 static int vbgdSetSessionEventFilter(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, 98 uint32_t fOrMask, uint32_t fNotMask, bool fSessionTermination); 99 static int vbgdSetSessionMouseStatus(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, 100 uint32_t fOrMask, uint32_t fNotMask, bool fSessionTermination); 101 static int vbgdSetSessionCapabilities(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, 102 uint32_t fOrMask, uint32_t fNoMask, bool fSessionTermination); 95 103 static int vbgdAcquireSessionCapabilities(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fOrMask, 96 104 uint32_t fNotMask, VBOXGUESTCAPSACQUIRE_FLAGS enmFlags, bool fSessionTermination); 97 static int vbgdSetSessionCapabilities(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fOrMask, uint32_t fNoMask);98 105 static int vbgdDispatchEventsLocked(PVBOXGUESTDEVEXT pDevExt, uint32_t fEvents); 99 106 … … 852 859 pDevExt->IOPortBase = IOPortBase; 853 860 pDevExt->pVMMDevMemory = NULL; 854 pDevExt->fFixedEvents = fFixedEvents;855 861 pDevExt->hGuestMappings = NIL_RTR0MEMOBJ; 856 862 pDevExt->EventSpinlock = NIL_RTSPINLOCK; … … 882 888 pDevExt->pReqGuestHeartbeat = NULL; 883 889 890 pDevExt->fFixedEvents = fFixedEvents; 891 vbgdBitUsageTrackerClear(&pDevExt->EventFilterTracker); 892 pDevExt->fEventFilterHost = UINT32_MAX; /* forces a report */ 893 894 vbgdBitUsageTrackerClear(&pDevExt->MouseStatusTracker); 895 pDevExt->fMouseStatusHost = UINT32_MAX; /* forces a report */ 896 897 pDevExt->u32AcquireModeGuestCaps = 0; 898 pDevExt->u32SetModeGuestCaps = 0; 899 pDevExt->u32GuestCapsAcquired = 0; 900 vbgdBitUsageTrackerClear(&pDevExt->SetGuestCapsTracker); 901 pDevExt->fGuestCapsHost = UINT32_MAX; /* forces a report */ 902 884 903 /* 885 904 * If there is an MMIO region validate the version and size. … … 902 921 } 903 922 904 pDevExt->u32AcquireModeGuestCaps = 0;905 pDevExt->u32SetModeGuestCaps = 0;906 pDevExt->u32GuestCapsAcquired = 0;907 RT_ZERO(pDevExt->acGuestCapsSet);908 pDevExt->fGuestCapsHost = UINT32_MAX; /* forces a report */909 910 923 /* 911 924 * Create the wait and session spinlocks as well as the ballooning mutex. … … 949 962 { 950 963 /* 951 * Set the fixed event and disable the guest graphics capability 952 * by default. The guest specific graphics driver will re-enable 953 * the graphics capability if and when appropriate. 964 * Set the fixed event and make sure guest capabilities are cleared. 954 965 */ 955 rc = vb oxGuestUpdateHostFlags(pDevExt, NULL, HostFlags_FilterMask);966 rc = vbgdResetEventFilterOnHost(pDevExt, pDevExt->fFixedEvents); 956 967 if (RT_SUCCESS(rc)) 957 968 { 958 rc = vbgd UpdateCapabilitiesOnHost(pDevExt);969 rc = vbgdResetCapabilitiesOnHost(pDevExt); 959 970 if (RT_SUCCESS(rc)) 960 971 { 972 /* 973 * Initialize stuff which may fail without requiring the driver init to fail. 974 */ 961 975 vboxGuestInitFixateGuestMappings(pDevExt); 962 976 vbgdHeartbeatInit(pDevExt); 963 977 978 /* 979 * Done! 980 */ 964 981 rc = VBoxGuestReportDriverStatus(true /* Driver is active */); 965 982 if (RT_FAILURE(rc)) … … 1055 1072 /* Update the host flags (mouse status etc) not to reflect this session. */ 1056 1073 pDevExt->fFixedEvents = 0; 1057 vboxGuestUpdateHostFlags(pDevExt, NULL, HostFlags_All); 1074 vbgdResetEventFilterOnHost(pDevExt, 0 /*fFixedEvents*/); 1075 vbgdResetCapabilitiesOnHost(pDevExt); 1076 vbgdResetMouseStatusOnHost(pDevExt); 1077 1058 1078 vboxGuestCloseMemBalloon(pDevExt, (PVBOXGUESTSESSION)NULL); 1059 1079 … … 1178 1198 vbgdAcquireSessionCapabilities(pDevExt, pSession, 0, UINT32_MAX, VBOXGUESTCAPSACQUIRE_FLAGS_NONE, 1179 1199 true /*fSessionTermination*/); 1180 vbgdSetSessionCapabilities(pDevExt, pSession, 0 /*fOrMask*/, UINT32_MAX /*fNotMask*/); 1200 vbgdSetSessionCapabilities(pDevExt, pSession, 0 /*fOrMask*/, UINT32_MAX /*fNotMask*/, true /*fSessionTermination*/); 1201 vbgdSetSessionEventFilter(pDevExt, pSession, 0 /*fOrMask*/, UINT32_MAX /*fNotMask*/, true /*fSessionTermination*/); 1202 vbgdSetSessionMouseStatus(pDevExt, pSession, 0 /*fOrMask*/, UINT32_MAX /*fNotMask*/, true /*fSessionTermination*/); 1181 1203 1182 1204 VBoxGuestCommonIOCtl_CancelAllWaitEvents(pDevExt, pSession); … … 1200 1222 vboxGuestCloseMemBalloon(pDevExt, pSession); 1201 1223 RTMemFree(pSession); 1202 1203 /* Update the host flags (mouse status etc) not to reflect this session. */1204 vboxGuestUpdateHostFlags(pDevExt, NULL,1205 HostFlags_All1206 #ifdef RT_OS_WINDOWS1207 & ~HostFlags_MouseStatus1208 #endif1209 );1210 1224 } 1211 1225 … … 1894 1908 1895 1909 1896 static int VBoxGuestCommonIOCtl_CtlFilterMask(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,1897 VBoxGuestFilterMaskInfo *pInfo)1898 {1899 int rc;1900 1901 if ((pInfo->u32OrMask | pInfo->u32NotMask) & ~VMMDEV_EVENT_VALID_EVENT_MASK)1902 return VERR_INVALID_PARAMETER;1903 RTSpinlockAcquire(pDevExt->SessionSpinlock);1904 pSession->fFilterMask |= pInfo->u32OrMask;1905 pSession->fFilterMask &= ~pInfo->u32NotMask;1906 RTSpinlockRelease(pDevExt->SessionSpinlock);1907 rc = vboxGuestUpdateHostFlags(pDevExt, pSession, HostFlags_FilterMask);1908 return rc;1909 }1910 1911 1912 /**1913 * Sets the mouse status features for this session and updates them1914 * globally.1915 *1916 * @returns VBox status code.1917 *1918 * @param pDevExt The device extention.1919 * @param pSession The session.1920 * @param fFeatures New bitmap of enabled features.1921 */1922 static int vboxGuestCommonIOCtl_SetMouseStatus(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fFeatures)1923 {1924 int rc;1925 1926 if (fFeatures & ~VMMDEV_MOUSE_GUEST_MASK)1927 return VERR_INVALID_PARAMETER;1928 /* Since this is more of a negative feature we invert it to get the real1929 * feature (when the guest does not need the host cursor). */1930 fFeatures ^= VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR;1931 RTSpinlockAcquire(pDevExt->SessionSpinlock);1932 pSession->fMouseStatus = fFeatures;1933 RTSpinlockRelease(pDevExt->SessionSpinlock);1934 rc = vboxGuestUpdateHostFlags(pDevExt, pSession, HostFlags_MouseStatus);1935 return rc;1936 }1937 1938 1910 #ifdef VBOX_WITH_HGCM 1939 1911 … … 2406 2378 NOREF(pch); 2407 2379 NOREF(cbData); 2380 RTAssertMsg2Weak("\nVBoxGuestCommonIOCtl_Log: cbData=%#x\n", cbData); 2408 2381 if (pDevExt->fLoggingEnabled) 2409 2382 RTLogBackdoorPrintf("%.*s", cbData, pch); … … 2423 2396 2424 2397 /** 2425 * Sets the interrupt filter mask during initialization and termination. 2426 * 2427 * This will ASSUME that we're the ones in carge over the mask, so 2428 * we'll simply clear all bits we don't set. 2429 * 2430 * @returns VBox status code (ignored). 2431 * @param fMask The new mask. 2432 */ 2433 static int vboxGuestSetFilterMask(VMMDevCtlGuestFilterMask *pReq, uint32_t fMask) 2398 * Clears a bit usage tracker (init time). 2399 * 2400 * @param pTracker The tracker to clear. 2401 */ 2402 static void vbgdBitUsageTrackerClear(PVBOXGUESTBITUSAGETRACER pTracker) 2403 { 2404 uint32_t iBit; 2405 AssertCompile(sizeof(pTracker->acPerBitUsage) == 32 * sizeof(uint32_t)); 2406 2407 for (iBit = 0; iBit < 32; iBit++) 2408 pTracker->acPerBitUsage[iBit] = 0; 2409 pTracker->fMask = 0; 2410 } 2411 2412 2413 #ifdef VBOX_STRICT 2414 /** 2415 * Checks that pTracker->fMask is correct and that the usage values are within 2416 * the valid range. 2417 * 2418 * @param pTracker The tracker. 2419 * @param cMax Max valid usage value. 2420 * @param pszWhat Identifies the tracker in assertions. 2421 */ 2422 static void vbgdBitUsageTrackerCheckMask(PCVBOXGUESTBITUSAGETRACER pTracker, uint32_t cMax, const char *pszWhat) 2423 { 2424 uint32_t fMask = 0; 2425 uint32_t iBit; 2426 AssertCompile(sizeof(pTracker->acPerBitUsage) == 32 * sizeof(uint32_t)); 2427 2428 for (iBit = 0; iBit < 32; iBit++) 2429 if (pTracker->acPerBitUsage[iBit]) 2430 { 2431 fMask |= RT_BIT_32(iBit); 2432 AssertMsg(pTracker->acPerBitUsage[iBit] <= cMax, 2433 ("%s: acPerBitUsage[%u]=%#x cMax=%#x\n", pszWhat, iBit, pTracker->acPerBitUsage[iBit], cMax)); 2434 } 2435 2436 AssertMsg(fMask == pTracker->fMask, ("%s: %#x vs %#x\n", pszWhat, fMask, pTracker->fMask)); 2437 } 2438 #endif 2439 2440 2441 /** 2442 * Applies a change to the bit usage tracker. 2443 * 2444 * 2445 * @returns true if the mask changed, false if not. 2446 * @param pTracker The bit usage tracker. 2447 * @param fChanged The bits to change. 2448 * @param fPrevious The previous value of the bits. 2449 * @param cMax The max valid usage value for assertions. 2450 * @param pszWhat Identifies the tracker in assertions. 2451 */ 2452 static bool vbgdBitUsageTrackerChange(PVBOXGUESTBITUSAGETRACER pTracker, uint32_t fChanged, uint32_t fPrevious, 2453 uint32_t cMax, const char *pszWhat) 2454 { 2455 bool fGlobalChange = false; 2456 uint32_t iBit; 2457 AssertCompile(sizeof(pTracker->acPerBitUsage) == 32 * sizeof(uint32_t)); 2458 2459 for (iBit = ASMBitFirstSetU32(fChanged) - 1; iBit < 32; iBit++) 2460 { 2461 uint32_t const fBitMask = RT_BIT_32(iBit); 2462 if (fBitMask & fChanged) 2463 { 2464 if (fChanged & fPrevious) 2465 { 2466 pTracker->acPerBitUsage[iBit] -= 1; 2467 AssertMsg(pTracker->acPerBitUsage[iBit] <= cMax, 2468 ("%s: acPerBitUsage[%u]=%#x cMax=%#x\n", pszWhat, iBit, pTracker->acPerBitUsage[iBit], cMax)); 2469 if (pTracker->acPerBitUsage[iBit] == 0) 2470 { 2471 fGlobalChange = true; 2472 pTracker->fMask &= ~fBitMask; 2473 } 2474 } 2475 else 2476 { 2477 pTracker->acPerBitUsage[iBit] += 1; 2478 AssertMsg(pTracker->acPerBitUsage[iBit] > 0 && pTracker->acPerBitUsage[iBit] <= cMax, 2479 ("pTracker->acPerBitUsage[%u]=%#x cMax=%#x\n", pszWhat, iBit, pTracker->acPerBitUsage[iBit], cMax)); 2480 if (pTracker->acPerBitUsage[iBit] == 1) 2481 { 2482 fGlobalChange = true; 2483 pTracker->fMask |= fBitMask; 2484 } 2485 } 2486 fChanged &= ~fBitMask; 2487 if (!fChanged) 2488 break; 2489 } 2490 } 2491 2492 #ifdef VBOX_STRICT 2493 vbgdBitUsageTrackerCheckMask(pTracker, cMax, pszWhat); 2494 #endif 2495 NOREF(pszWhat); NOREF(cMax); 2496 return fGlobalChange; 2497 } 2498 2499 2500 /** 2501 * Init and termination worker for resetting the (host) event filter on the host 2502 * 2503 * @returns VBox status code. 2504 * @param pDevExt The device extension. 2505 * @param fFixedEvents Fixed events (init time). 2506 */ 2507 static int vbgdResetEventFilterOnHost(PVBOXGUESTDEVEXT pDevExt, uint32_t fFixedEvents) 2508 { 2509 VMMDevCtlGuestFilterMask *pReq; 2510 int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_CtlGuestFilterMask); 2511 if (RT_SUCCESS(rc)) 2512 { 2513 pReq->u32NotMask = UINT32_MAX & ~fFixedEvents; 2514 pReq->u32OrMask = fFixedEvents; 2515 rc = VbglGRPerform(&pReq->header); 2516 if (RT_FAILURE(rc)) 2517 LogRelFunc(("failed with rc=%Rrc\n", rc)); 2518 VbglGRFree(&pReq->header); 2519 } 2520 return rc; 2521 } 2522 2523 2524 /** 2525 * Changes the event filter mask for the given session. 2526 * 2527 * This is called in response to VBOXGUEST_IOCTL_CTL_FILTER_MASK as well as to 2528 * do session cleanup. 2529 * 2530 * @returns VBox status code. 2531 * @param pDevExt The device extension. 2532 * @param pSession The session. 2533 * @param fOrMask The events to add. 2534 * @param fNotMask The events to remove. 2535 * @param fSessionTermination Set if we're called by the session cleanup code. 2536 * This tweaks the error handling so we perform 2537 * proper session cleanup even if the host 2538 * misbehaves. 2539 * 2540 * @remarks Takes the session spinlock. 2541 */ 2542 static int vbgdSetSessionEventFilter(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, 2543 uint32_t fOrMask, uint32_t fNotMask, bool fSessionTermination) 2544 { 2545 VMMDevCtlGuestFilterMask *pReq; 2546 uint32_t fChanged; 2547 uint32_t fPrevious; 2548 int rc; 2549 2550 /* 2551 * Preallocate a request buffer so we can do all in one go without leaving the spinlock. 2552 */ 2553 rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_CtlGuestFilterMask); 2554 if (RT_SUCCESS(rc)) 2555 { /* nothing */ } 2556 else if (!fSessionTermination) 2557 { 2558 LogRel(("vbgdSetSessionFilterMask: VbglGRAlloc failure: %Rrc\n", rc)); 2559 return rc; 2560 } 2561 else 2562 pReq = NULL; /* Ignore failure, we must do session cleanup. */ 2563 2564 2565 RTSpinlockAcquire(pDevExt->SessionSpinlock); 2566 2567 /* 2568 * Apply the changes to the session mask. 2569 */ 2570 fPrevious = pSession->fEventFilter; 2571 pSession->fEventFilter |= fOrMask; 2572 pSession->fEventFilter &= fNotMask; 2573 2574 /* 2575 * If anything actually changed, update the global usage counters. 2576 */ 2577 fChanged = fPrevious ^ pSession->fEventFilter; 2578 if (fChanged) 2579 { 2580 bool fGlobalChange = vbgdBitUsageTrackerChange(&pDevExt->EventFilterTracker, fChanged, fPrevious, 2581 pDevExt->cSessions, "EventFilterTracker"); 2582 2583 /* 2584 * If there are global changes, update the event filter on the host. 2585 */ 2586 if (fGlobalChange || pDevExt->fEventFilterHost == UINT32_MAX) 2587 { 2588 Assert(pReq || fSessionTermination); 2589 if (pReq) 2590 { 2591 pReq->u32OrMask = pDevExt->fFixedEvents | pDevExt->EventFilterTracker.fMask; 2592 if (pReq->u32OrMask == pDevExt->fEventFilterHost) 2593 rc = VINF_SUCCESS; 2594 else 2595 { 2596 pDevExt->fEventFilterHost = pReq->u32OrMask; 2597 pReq->u32NotMask = ~pReq->u32OrMask; 2598 rc = VbglGRPerform(&pReq->header); 2599 if (RT_FAILURE(rc)) 2600 { 2601 /* 2602 * Failed, roll back (unless it's session termination time). 2603 */ 2604 pDevExt->fEventFilterHost = UINT32_MAX; 2605 if (!fSessionTermination) 2606 { 2607 vbgdBitUsageTrackerChange(&pDevExt->EventFilterTracker, fChanged, pSession->fEventFilter, 2608 pDevExt->cSessions, "EventFilterTracker"); 2609 pSession->fEventFilter = fPrevious; 2610 } 2611 } 2612 } 2613 } 2614 else 2615 rc = VINF_SUCCESS; 2616 } 2617 } 2618 2619 RTSpinlockRelease(pDevExt->SessionSpinlock); 2620 if (pReq) 2621 VbglGRFree(&pReq->header); 2622 return rc; 2623 } 2624 2625 2626 /** 2627 * Handle VBOXGUEST_IOCTL_CTL_FILTER_MASK. 2628 * 2629 * @returns VBox status code. 2630 * 2631 * @param pDevExt The device extension. 2632 * @param pSession The session. 2633 * @param pInfo The request. 2634 */ 2635 static int VBoxGuestCommonIOCtl_CtlFilterMask(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, 2636 VBoxGuestFilterMaskInfo *pInfo) 2637 { 2638 LogFlow(("VBoxGuestCommonIOCtl: CTL_FILTER_MASK or=%#x not=%#x\n", pInfo->u32OrMask, pInfo->u32NotMask)); 2639 2640 if ((pInfo->u32OrMask | pInfo->u32NotMask) & ~VMMDEV_EVENT_VALID_EVENT_MASK) 2641 { 2642 Log(("VBoxGuestCommonIOCtl: CTL_FILTER_MASK or=%#x not=%#x: Invalid masks!\n", pInfo->u32OrMask, pInfo->u32NotMask)); 2643 return VERR_INVALID_PARAMETER; 2644 } 2645 2646 return vbgdSetSessionEventFilter(pDevExt, pSession, pInfo->u32OrMask, pInfo->u32NotMask, false /*fSessionTermination*/); 2647 } 2648 2649 2650 /** 2651 * Init and termination worker for set mouse feature status to zero on the host. 2652 * 2653 * @returns VBox status code. 2654 * @param pDevExt The device extension. 2655 */ 2656 static int vbgdResetMouseStatusOnHost(PVBOXGUESTDEVEXT pDevExt) 2657 { 2658 VMMDevReqMouseStatus *pReq; 2659 int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_SetMouseStatus); 2660 if (RT_SUCCESS(rc)) 2661 { 2662 pReq->mouseFeatures = 0; 2663 pReq->pointerXPos = 0; 2664 pReq->pointerYPos = 0; 2665 rc = VbglGRPerform(&pReq->header); 2666 if (RT_FAILURE(rc)) 2667 LogRelFunc(("failed with rc=%Rrc\n", rc)); 2668 VbglGRFree(&pReq->header); 2669 } 2670 return rc; 2671 } 2672 2673 2674 /** 2675 * Changes the mouse status mask for the given session. 2676 * 2677 * This is called in response to VBOXGUEST_IOCTL_SET_MOUSE_STATUS as well as to 2678 * do session cleanup. 2679 * 2680 * @returns VBox status code. 2681 * @param pDevExt The device extension. 2682 * @param pSession The session. 2683 * @param fOrMask The status flags to add. 2684 * @param fNotMask The status flags to remove. 2685 * @param fSessionTermination Set if we're called by the session cleanup code. 2686 * This tweaks the error handling so we perform 2687 * proper session cleanup even if the host 2688 * misbehaves. 2689 * 2690 * @remarks Takes the session spinlock. 2691 */ 2692 static int vbgdSetSessionMouseStatus(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, 2693 uint32_t fOrMask, uint32_t fNotMask, bool fSessionTermination) 2694 { 2695 VMMDevReqMouseStatus *pReq; 2696 uint32_t fChanged; 2697 uint32_t fPrevious; 2698 int rc; 2699 2700 /* 2701 * Preallocate a request buffer so we can do all in one go without leaving the spinlock. 2702 */ 2703 rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_SetMouseStatus); 2704 if (RT_SUCCESS(rc)) 2705 { /* nothing */ } 2706 else if (!fSessionTermination) 2707 { 2708 LogRel(("vbgdSetSessionMouseStatus: VbglGRAlloc failure: %Rrc\n", rc)); 2709 return rc; 2710 } 2711 else 2712 pReq = NULL; /* Ignore failure, we must do session cleanup. */ 2713 2714 2715 RTSpinlockAcquire(pDevExt->SessionSpinlock); 2716 2717 /* 2718 * Apply the changes to the session mask. 2719 */ 2720 fPrevious = pSession->fMouseStatus; 2721 pSession->fMouseStatus |= fOrMask; 2722 pSession->fMouseStatus &= fNotMask; 2723 2724 /* 2725 * If anything actually changed, update the global usage counters. 2726 */ 2727 fChanged = fPrevious ^ pSession->fMouseStatus; 2728 if (fChanged) 2729 { 2730 bool fGlobalChange = vbgdBitUsageTrackerChange(&pDevExt->MouseStatusTracker, fChanged, fPrevious, 2731 pDevExt->cSessions, "MouseStatusTracker"); 2732 2733 /* 2734 * If there are global changes, update the event filter on the host. 2735 */ 2736 if (fGlobalChange || pDevExt->fMouseStatusHost == UINT32_MAX) 2737 { 2738 Assert(pReq || fSessionTermination); 2739 if (pReq) 2740 { 2741 /* Since VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR is inverted in the session 2742 * capabilities we invert it again here before sending it to the host. */ 2743 pReq->mouseFeatures = pDevExt->MouseStatusTracker.fMask ^ VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR; 2744 if (pReq->mouseFeatures == pDevExt->fMouseStatusHost) 2745 rc = VINF_SUCCESS; 2746 else 2747 { 2748 pDevExt->fMouseStatusHost = pReq->mouseFeatures; 2749 pReq->pointerXPos = 0; 2750 pReq->pointerYPos = 0; 2751 rc = VbglGRPerform(&pReq->header); 2752 if (RT_FAILURE(rc)) 2753 { 2754 /* 2755 * Failed, roll back (unless it's session termination time). 2756 */ 2757 pDevExt->fMouseStatusHost = UINT32_MAX; 2758 if (!fSessionTermination) 2759 { 2760 vbgdBitUsageTrackerChange(&pDevExt->MouseStatusTracker, fChanged, pSession->fMouseStatus, 2761 pDevExt->cSessions, "MouseStatusTracker"); 2762 pSession->fMouseStatus = fPrevious; 2763 } 2764 } 2765 } 2766 } 2767 else 2768 rc = VINF_SUCCESS; 2769 } 2770 } 2771 2772 RTSpinlockRelease(pDevExt->SessionSpinlock); 2773 if (pReq) 2774 VbglGRFree(&pReq->header); 2775 return rc; 2776 } 2777 2778 2779 /** 2780 * Sets the mouse status features for this session and updates them globally. 2781 * 2782 * @returns VBox status code. 2783 * 2784 * @param pDevExt The device extention. 2785 * @param pSession The session. 2786 * @param fFeatures New bitmap of enabled features. 2787 */ 2788 static int vboxGuestCommonIOCtl_SetMouseStatus(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fFeatures) 2434 2789 { 2435 2790 int rc; 2436 2437 pReq->u32OrMask = fMask; 2438 pReq->u32NotMask = ~fMask; 2439 rc = VbglGRPerform(&pReq->header); 2440 if (RT_FAILURE(rc)) 2441 LogRel(("vboxGuestSetFilterMask: failed with rc=%Rrc\n", rc)); 2442 return rc; 2443 } 2444 2445 2446 /** 2447 * Sets the mouse status to the host. 2448 * 2449 * This will ASSUME that we're the ones in charge of the mask, so 2450 * we'll simply clear all bits we don't set. 2451 * 2452 * @returns VBox status code. 2453 * @param fMask The new mask. 2454 */ 2455 static int vboxGuestSetMouseStatus(VMMDevReqMouseStatus *pReq, uint32_t fMask) 2456 { 2457 int rc; 2458 2459 pReq->mouseFeatures = fMask; 2460 pReq->pointerXPos = 0; 2461 pReq->pointerYPos = 0; 2462 rc = VbglGRPerform(&pReq->header); 2463 if (RT_FAILURE(rc)) 2464 LogRelFunc(("failed with rc=%Rrc\n", rc)); 2465 return rc; 2466 } 2467 2468 2469 static int vboxGuestGetHostFlagsFromSessions(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, 2470 uint32_t *pfFilterMask, uint32_t *pfMouseStatus) 2471 { 2472 PVBOXGUESTSESSION pIterator; 2473 uint32_t fFilterMask = 0; 2474 uint32_t fMouseStatus = 0; 2475 unsigned cSessions = 0; 2476 int rc = VINF_SUCCESS; 2477 2478 /** @todo r=bird: Please just do the global bit counting thing. This code 2479 * gives me the [performances] creeps. */ 2480 RTListForEach(&pDevExt->SessionList, pIterator, VBOXGUESTSESSION, ListNode) 2481 { 2482 fFilterMask |= pIterator->fFilterMask; 2483 fMouseStatus |= pIterator->fMouseStatus; 2484 ++cSessions; 2485 } 2486 if (!cSessions) 2487 if (fFilterMask | fMouseStatus) 2488 rc = VERR_INTERNAL_ERROR; 2489 if (cSessions == 1 && pSession) 2490 if ( fFilterMask != pSession->fFilterMask 2491 || fMouseStatus != pSession->fMouseStatus) 2492 rc = VERR_INTERNAL_ERROR; 2493 if (cSessions > 1 && pSession) 2494 if ( ~fFilterMask & pSession->fFilterMask 2495 || ~fMouseStatus & pSession->fMouseStatus) 2496 rc = VERR_INTERNAL_ERROR; 2497 *pfFilterMask = fFilterMask; 2498 *pfMouseStatus = fMouseStatus; 2499 return rc; 2500 } 2501 2502 2503 /** 2504 * Calls the host and set the filter mask, capabilities and/or mouse status. 2505 * 2506 * Check which host flags in a given category are being asserted by some guest 2507 * session and assert exactly those on the host which are being asserted by one 2508 * or more sessions. pCallingSession is purely for sanity checking and can be 2509 * NULL. 2510 * 2511 * @note Takes the session spin-lock. 2512 */ 2513 static int vboxGuestUpdateHostFlags(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, unsigned fFlags) 2514 { 2515 int rc; 2516 VMMDevCtlGuestFilterMask *pFilterReq = NULL; 2517 VMMDevReqMouseStatus *pStatusReq = NULL; 2518 uint32_t fFilterMask = 0; 2519 uint32_t fMouseStatus = 0; 2520 2521 rc = VbglGRAlloc((VMMDevRequestHeader **)&pFilterReq, sizeof(*pFilterReq), 2522 VMMDevReq_CtlGuestFilterMask); 2523 if (RT_SUCCESS(rc)) 2524 rc = VbglGRAlloc((VMMDevRequestHeader **)&pStatusReq, 2525 sizeof(*pStatusReq), VMMDevReq_SetMouseStatus); 2526 if (RT_SUCCESS(rc)) 2527 { 2528 RTSpinlockAcquire(pDevExt->SessionSpinlock); 2529 rc = vboxGuestGetHostFlagsFromSessions(pDevExt, pSession, &fFilterMask, &fMouseStatus); 2530 if (RT_SUCCESS(rc)) 2531 { 2532 fFilterMask |= pDevExt->fFixedEvents; 2533 /* Since VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR is inverted in the session 2534 * capabilities we invert it again before sending it to the host. */ 2535 fMouseStatus ^= VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR; 2536 if (fFlags & HostFlags_FilterMask) 2537 vboxGuestSetFilterMask(pFilterReq, fFilterMask); 2538 if (fFlags & HostFlags_MouseStatus) 2539 vboxGuestSetMouseStatus(pStatusReq, fMouseStatus); 2540 } 2541 RTSpinlockRelease(pDevExt->SessionSpinlock); 2542 } 2543 if (pFilterReq) 2544 VbglGRFree(&pFilterReq->header); 2545 if (pStatusReq) 2546 VbglGRFree(&pStatusReq->header); 2547 2548 return rc; 2549 } 2550 2551 2552 /** 2553 * Return the mask of VMM device events that this session is allowed to see. 2791 LogFlow(("VBoxGuestCommonIOCtl: CTL_FILTER_MASK features=%#x\n", fFeatures)); 2792 2793 if (fFeatures & ~VMMDEV_MOUSE_GUEST_MASK) 2794 return VERR_INVALID_PARAMETER; 2795 2796 /* Since this is more of a negative feature we invert it to get the real 2797 * feature (when the guest does not need the host cursor). */ 2798 fFeatures ^= VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR; 2799 2800 return vbgdSetSessionMouseStatus(pDevExt, pSession, fFeatures, ~fFeatures, false /*fSessionTermination*/); 2801 } 2802 2803 2804 /** 2805 * Return the mask of VMM device events that this session is allowed to see (wrt 2806 * to "acquire" mode guest capabilities). 2554 2807 * 2555 2808 * The events associated with guest capabilities in "acquire" mode will be … … 2600 2853 2601 2854 /** 2855 * Init and termination worker for set guest capabilities to zero on the host. 2856 * 2857 * @returns VBox status code. 2858 * @param pDevExt The device extension. 2859 */ 2860 static int vbgdResetCapabilitiesOnHost(PVBOXGUESTDEVEXT pDevExt) 2861 { 2862 VMMDevReqGuestCapabilities2 *pReq; 2863 int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_SetGuestCapabilities); 2864 if (RT_SUCCESS(rc)) 2865 { 2866 pReq->u32NotMask = UINT32_MAX; 2867 pReq->u32OrMask = 0; 2868 rc = VbglGRPerform(&pReq->header); 2869 2870 if (RT_FAILURE(rc)) 2871 LogRelFunc(("failed with rc=%Rrc\n", rc)); 2872 VbglGRFree(&pReq->header); 2873 } 2874 return rc; 2875 } 2876 2877 2878 /** 2602 2879 * Sets the guest capabilities to the host while holding the lock. 2603 2880 * … … 2613 2890 uint32_t iBit; 2614 2891 2615 pReq->u32OrMask = pDevExt->u32GuestCapsAcquired; 2616 for (iBit = 0; iBit < 32; iBit++) 2617 if (pDevExt->acGuestCapsSet[iBit] > 0) 2618 pReq->u32OrMask |= RT_BIT_32(iBit); 2619 2892 pReq->u32OrMask = pDevExt->u32GuestCapsAcquired | pDevExt->SetGuestCapsTracker.fMask; 2620 2893 if (pReq->u32OrMask == pDevExt->fGuestCapsHost) 2621 2894 rc = VINF_SUCCESS; … … 2634 2907 2635 2908 /** 2636 * Sets the guest capabilities to the host. 2637 * 2638 * This will ASSUME that we're the ones in charge of the mask, so 2639 * we'll simply clear all bits we don't set. 2640 * 2641 * @returns VBox status code. 2642 * @param fMask The new mask. 2643 */ 2644 static int vbgdUpdateCapabilitiesOnHost(PVBOXGUESTDEVEXT pDevExt) 2645 { 2646 VMMDevReqGuestCapabilities2 *pReq; 2647 int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_SetGuestCapabilities); 2648 if (RT_SUCCESS(rc)) 2649 { 2650 RTSpinlockAcquire(pDevExt->SessionSpinlock); 2651 2652 rc = vbgdUpdateCapabilitiesOnHostWithReqAndLock(pDevExt, pReq); 2653 2654 RTSpinlockRelease(pDevExt->SessionSpinlock); 2655 2656 if (RT_FAILURE(rc)) 2657 LogRelFunc(("failed with rc=%Rrc\n", rc)); 2658 VbglGRFree(&pReq->header); 2659 } 2660 return rc; 2661 } 2662 2663 2664 /** 2665 * Switch a set of capabilities into "acuquire" mode and (maybe) acquire them 2666 * for the given session. 2909 * Switch a set of capabilities into "acquire" mode and (maybe) acquire them for 2910 * the given session. 2667 2911 * 2668 2912 * This is called in response to VBOXGUEST_IOCTL_GUEST_CAPS_ACQUIRE as well as … … 2719 2963 return VERR_INVALID_PARAMETER; 2720 2964 } 2965 Assert(!fOrMask || !fSessionTermination); 2721 2966 2722 2967 /* The fNotMask no need to have all values valid, invalid ones will simply be ignored. */ … … 2730 2975 { 2731 2976 rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_SetGuestCapabilities); 2732 if (RT_FAILURE(rc)) 2977 if (RT_SUCCESS(rc)) 2978 { /* do nothing */ } 2979 else if (!fSessionTermination) 2733 2980 { 2734 2981 LogRel(("vbgdAcquireSessionCapabilities: pSession=%p fOrMask=%#x fNotMask=%#x enmFlags=%#x: VbglGRAlloc failure: %Rrc\n", … … 2736 2983 return rc; 2737 2984 } 2985 else 2986 pReq = NULL; /* Ignore failure, we must do session cleanup. */ 2738 2987 } 2739 2988 … … 2742 2991 * 2743 2992 * Note! We currently ignore anyone which may already have "set" the capabilities 2744 * in fOrMask. This is simple, but perhaps not the best idea?2993 * in fOrMask. Perhaps not the best way to handle it, but it's simple... 2745 2994 */ 2746 2995 RTSpinlockAcquire(pDevExt->EventSpinlock); … … 2772 3021 return VINF_SUCCESS; 2773 3022 } 2774 Assert(pReq );3023 Assert(pReq || fSessionTermination); 2775 3024 2776 3025 /* … … 2803 3052 * If something changes (which is very likely), tell the host. 2804 3053 */ 2805 if (fSessionAddedCaps || fSessionRemovedCaps )2806 { 2807 rc = vbgdUpdateCapabilitiesOnHostWithReqAndLock(pDevExt, pReq);2808 if ( RT_FAILURE(rc))3054 if (fSessionAddedCaps || fSessionRemovedCaps || pDevExt->fGuestCapsHost == UINT32_MAX) 3055 { 3056 Assert(pReq || fSessionTermination); 3057 if (pReq) 2809 3058 { 2810 /* 2811 * Failed, roll back. Except, don't roll back session cleanups. 2812 */ 2813 if (fSessionAddedCaps) 3059 rc = vbgdUpdateCapabilitiesOnHostWithReqAndLock(pDevExt, pReq); 3060 if (RT_FAILURE(rc) && !fSessionTermination) 2814 3061 { 2815 pSession->u32AquiredGuestCaps &= ~fSessionAddedCaps; 2816 pDevExt->u32GuestCapsAcquired &= ~fSessionAddedCaps; 3062 /* Failed, roll back. */ 3063 if (fSessionAddedCaps) 3064 { 3065 pSession->u32AquiredGuestCaps &= ~fSessionAddedCaps; 3066 pDevExt->u32GuestCapsAcquired &= ~fSessionAddedCaps; 3067 } 3068 if (fSessionRemovedCaps) 3069 { 3070 pSession->u32AquiredGuestCaps |= fSessionRemovedCaps; 3071 pDevExt->u32GuestCapsAcquired |= fSessionRemovedCaps; 3072 } 3073 3074 RTSpinlockRelease(pDevExt->EventSpinlock); 3075 LogRel(("vbgdAcquireSessionCapabilities: VBoxGuestSetGuestCapabilities failed: rc=%Rrc\n", rc)); 3076 VbglGRFree(&pReq->header); 3077 return rc; 2817 3078 } 2818 if (fSessionRemovedCaps && !fSessionTermination)2819 {2820 pSession->u32AquiredGuestCaps |= fSessionRemovedCaps;2821 pDevExt->u32GuestCapsAcquired |= fSessionRemovedCaps;2822 }2823 2824 RTSpinlockRelease(pDevExt->EventSpinlock);2825 LogRel(("vbgdAcquireSessionCapabilities: VBoxGuestSetGuestCapabilities failed: rc=%Rrc\n", rc));2826 VbglGRFree(&pReq->header);2827 return rc;2828 3079 } 2829 3080 } 2830 2831 3081 } 2832 3082 else … … 2840 3090 2841 3091 RTSpinlockRelease(pDevExt->EventSpinlock); 2842 VbglGRFree(&pReq->header); 3092 if (pReq) 3093 VbglGRFree(&pReq->header); 2843 3094 2844 3095 /* … … 2905 3156 * @param fOrMask The capabilities to add. 2906 3157 * @param fNotMask The capabilities to remove. 3158 * @param fSessionTermination Set if we're called by the session cleanup code. 3159 * This tweaks the error handling so we perform 3160 * proper session cleanup even if the host 3161 * misbehaves. 2907 3162 * 2908 3163 * @remarks Takes the session spinlock. 2909 3164 */ 2910 static int vbgdSetSessionCapabilities(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fOrMask, uint32_t fNotMask) 2911 { 2912 int rc; 3165 static int vbgdSetSessionCapabilities(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, 3166 uint32_t fOrMask, uint32_t fNotMask, bool fSessionTermination) 3167 { 3168 /* 3169 * Preallocate a request buffer so we can do all in one go without leaving the spinlock. 3170 */ 3171 VMMDevReqGuestCapabilities2 *pReq; 3172 int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_SetGuestCapabilities); 3173 if (RT_SUCCESS(rc)) 3174 { /* nothing */ } 3175 else if (!fSessionTermination) 3176 { 3177 LogRel(("vbgdSetSessionCapabilities: VbglGRAlloc failure: %Rrc\n", rc)); 3178 return rc; 3179 } 3180 else 3181 pReq = NULL; /* Ignore failure, we must do session cleanup. */ 3182 3183 2913 3184 RTSpinlockAcquire(pDevExt->SessionSpinlock); 2914 3185 … … 2935 3206 if (fChanged) 2936 3207 { 2937 bool fGlobalChange = false; 2938 uint32_t iBit; 2939 for (iBit = ASMBitFirstSetU32(fChanged) - 1; iBit < 32; iBit++) 2940 if (RT_BIT_32(iBit) & fChanged) 3208 bool fGlobalChange = vbgdBitUsageTrackerChange(&pDevExt->SetGuestCapsTracker, fChanged, fPrevious, 3209 pDevExt->cSessions, "SetGuestCapsTracker"); 3210 3211 /* 3212 * If there are global changes, update the capabilities on the host. 3213 */ 3214 if (fGlobalChange || pDevExt->fGuestCapsHost == UINT32_MAX) 3215 { 3216 Assert(pReq || fSessionTermination); 3217 if (pReq) 2941 3218 { 2942 if (fChanged & fPrevious) 3219 rc = vbgdUpdateCapabilitiesOnHostWithReqAndLock(pDevExt, pReq); 3220 3221 /* On failure, roll back (unless it's session termination time). */ 3222 if (RT_FAILURE(rc) && !fSessionTermination) 2943 3223 { 2944 pDevExt->acGuestCapsSet[iBit] -= 1; 2945 AssertMsg(pDevExt->acGuestCapsSet[iBit] <= pDevExt->cSessions, 2946 ("pDevExt->acGuestCaps[%u]=%#x cSessions=%#x\n", 2947 iBit, pDevExt->acGuestCapsSet[iBit], pDevExt->cSessions)); 2948 fGlobalChange |= pDevExt->acGuestCapsSet[iBit] == 0; 3224 vbgdBitUsageTrackerChange(&pDevExt->SetGuestCapsTracker, fChanged, pSession->fCapabilities, 3225 pDevExt->cSessions, "SetGuestCapsTracker"); 3226 pSession->fCapabilities = fPrevious; 2949 3227 } 2950 else2951 {2952 pDevExt->acGuestCapsSet[iBit] += 1;2953 AssertMsg(pDevExt->acGuestCapsSet[iBit] > 0 && pDevExt->acGuestCapsSet[iBit] <= pDevExt->cSessions,2954 ("pDevExt->acGuestCaps[%u]=%#x cSessions=%#x\n",2955 iBit, pDevExt->acGuestCapsSet[iBit], pDevExt->cSessions));2956 fGlobalChange |= pDevExt->acGuestCapsSet[iBit] == 1;2957 }2958 fChanged &= ~RT_BIT_32(iBit);2959 if (!fChanged)2960 break;2961 3228 } 2962 2963 /*2964 * If there were global changes, update the capabilities on the host.2965 */2966 if (fGlobalChange)2967 {2968 RTSpinlockRelease(pDevExt->SessionSpinlock);2969 2970 return vbgdUpdateCapabilitiesOnHost(pDevExt);2971 3229 } 2972 3230 } 2973 rc = VINF_SUCCESS;2974 3231 } 2975 3232 #ifndef VBOXGUEST_DISREGARD_ACQUIRE_MODE_GUEST_CAPS … … 2979 3236 2980 3237 RTSpinlockRelease(pDevExt->SessionSpinlock); 3238 if (pReq) 3239 VbglGRFree(&pReq->header); 2981 3240 return rc; 2982 3241 } … … 2999 3258 3000 3259 if (!((pInfo->u32OrMask | pInfo->u32NotMask) & ~VMMDEV_GUEST_CAPABILITIES_MASK)) 3001 rc = vbgdSetSessionCapabilities(pDevExt, pSession, pInfo->u32OrMask, pInfo->u32NotMask );3260 rc = vbgdSetSessionCapabilities(pDevExt, pSession, pInfo->u32OrMask, pInfo->u32NotMask, false /*fSessionTermination*/); 3002 3261 else 3003 3262 rc = VERR_INVALID_PARAMETER; -
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
r54601 r54606 109 109 typedef VBOXGUESTMEMBALLOON *PVBOXGUESTMEMBALLOON; 110 110 111 112 /** 113 * Per bit usage tracker for a uint32_t mask. 114 * 115 * Used for optimal handling of guest properties, mouse status and event filter. 116 */ 117 typedef struct VBOXGUESTBITUSAGETRACER 118 { 119 /** Per bit usage counters. */ 120 uint32_t acPerBitUsage[32]; 121 /** The current mask according to acPerBitUsage. */ 122 uint32_t fMask; 123 } VBOXGUESTBITUSAGETRACER; 124 /** Pointer to a per bit usage tracker. */ 125 typedef VBOXGUESTBITUSAGETRACER *PVBOXGUESTBITUSAGETRACER; 126 /** Pointer to a const per bit usage tracker. */ 127 typedef VBOXGUESTBITUSAGETRACER const *PCVBOXGUESTBITUSAGETRACER; 128 129 111 130 /** 112 131 * VBox guest device (data) extension. … … 118 137 /** Pointer to the mapping of the VMMDev adapter memory. */ 119 138 VMMDevMemory volatile *pVMMDevMemory; 120 /** Events we won't permit anyone to filter out. */121 uint32_t fFixedEvents;122 139 /** The memory object reserving space for the guest mappings. */ 123 140 RTR0MEMOBJ hGuestMappings; … … 173 190 VBoxGuestMouseSetNotifyCallback MouseNotifyCallback; 174 191 175 /** @name Guest Capabilities. 192 /** @name Host Event Filtering 193 * @{ */ 194 /** Events we won't permit anyone to filter out. */ 195 uint32_t fFixedEvents; 196 /** Usage counters for the host events. (Fixed events are not included.) */ 197 VBOXGUESTBITUSAGETRACER EventFilterTracker; 198 /** The event filter last reported to the host (UINT32_MAX on failure). */ 199 uint32_t fEventFilterHost; 200 /** @} */ 201 202 /** @name Mouse Status 203 * @{ */ 204 /** Usage counters for the mouse statuses (VMMDEV_MOUSE_XXX). */ 205 VBOXGUESTBITUSAGETRACER MouseStatusTracker; 206 /** The mouse status last reported to the host (UINT32_MAX on failure). */ 207 uint32_t fMouseStatusHost; 208 /** @} */ 209 210 /** @name Guest Capabilities 176 211 * @{ */ 177 212 /** Guest capabilities which have been set to "acquire" mode. This means … … 190 225 /** Usage counters for guest capabilities in "set" mode. Indexed by 191 226 * capability bit number, one count per session using a capability. */ 192 uint32_t acGuestCapsSet[32];193 /** The set guest capabilities reported to the host. */227 VBOXGUESTBITUSAGETRACER SetGuestCapsTracker; 228 /** The guest capabilities last reported to the host (UINT32_MAX on failure). */ 194 229 uint32_t fGuestCapsHost; 195 230 /** @} */ … … 241 276 * Used to implement polling. */ 242 277 uint32_t volatile u32MousePosChangedSeq; 243 /** VMMDev events requested. An event type requested in any guest session244 * will be added to the host filter.245 * Use under the VBOXGUESTDEVEXT#SessionSpinlocklock. */246 uint32_t f FilterMask;278 /** Host events requested by the session. 279 * An event type requested in any guest session will be added to the host 280 * filter. Protected by VBOXGUESTDEVEXT::SessionSpinlock. */ 281 uint32_t fEventFilter; 247 282 /** Guest capabilities held in "acquired" by this session. 248 283 * Protected by VBOXGUESTDEVEXT::SessionSpinlock, but is unfortunately read
Note:
See TracChangeset
for help on using the changeset viewer.