diff options
Diffstat (limited to 'src/VBox/VMM/include/PDMInternal.h')
| -rw-r--r-- | src/VBox/VMM/include/PDMInternal.h | 182 |
1 files changed, 147 insertions, 35 deletions
diff --git a/src/VBox/VMM/include/PDMInternal.h b/src/VBox/VMM/include/PDMInternal.h index ba8c6445..e247e73a 100644 --- a/src/VBox/VMM/include/PDMInternal.h +++ b/src/VBox/VMM/include/PDMInternal.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2011 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -25,10 +25,14 @@ #include <VBox/vusb.h> #include <VBox/vmm/pdmasynccompletion.h> #ifdef VBOX_WITH_NETSHAPER -#include <VBox/vmm/pdmnetshaper.h> -#endif /* VBOX_WITH_NETSHAPER */ +# include <VBox/vmm/pdmnetshaper.h> +#endif +#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION +# include <VBox/vmm/pdmasynccompletion.h> +#endif #include <VBox/vmm/pdmblkcache.h> #include <VBox/vmm/pdmcommon.h> +#include <VBox/sup.h> #include <iprt/assert.h> #include <iprt/critsect.h> #ifdef IN_RING3 @@ -52,10 +56,19 @@ RT_C_DECLS_BEGIN /** @def PDMCRITSECT_STRICT * Enables/disables PDM critsect strictness like deadlock detection. */ -#if (defined(RT_LOCK_STRICT) && defined(IN_RING3) && !defined(IEM_VERIFICATION_MODE)) || defined(DOXYGEN_RUNNING) +#if (defined(RT_LOCK_STRICT) && defined(IN_RING3) && !defined(IEM_VERIFICATION_MODE) && !defined(PDMCRITSECT_STRICT)) \ + || defined(DOXYGEN_RUNNING) # define PDMCRITSECT_STRICT #endif +/** @def PDMCRITSECT_STRICT + * Enables/disables PDM read/write critsect strictness like deadlock + * detection. */ +#if (defined(RT_LOCK_STRICT) && defined(IN_RING3) && !defined(IEM_VERIFICATION_MODE) && !defined(PDMCRITSECTRW_STRICT)) \ + || defined(DOXYGEN_RUNNING) +# define PDMCRITSECTRW_STRICT +#endif + /******************************************************************************* * Structures and Typedefs * @@ -259,7 +272,8 @@ typedef struct PDMDRVINSINT */ typedef struct PDMCRITSECTINT { - /** The critical section core which is shared with IPRT. */ + /** The critical section core which is shared with IPRT. + * @note The semaphore is a SUPSEMEVENT. */ RTCRITSECT Core; /** Pointer to the next critical section. * This chain is used for relocating pVMRC and device cleanup. */ @@ -306,6 +320,64 @@ typedef PDMCRITSECTINT *PPDMCRITSECTINT; /** + * Private critical section data. + */ +typedef struct PDMCRITSECTRWINT +{ + /** The read/write critical section core which is shared with IPRT. + * @note The semaphores are SUPSEMEVENT and SUPSEMEVENTMULTI. */ + RTCRITSECTRW Core; + + /** Pointer to the next critical section. + * This chain is used for relocating pVMRC and device cleanup. */ + R3PTRTYPE(struct PDMCRITSECTRWINT *) pNext; + /** Owner identifier. + * This is pDevIns if the owner is a device. Similarly for a driver or service. + * PDMR3CritSectInit() sets this to point to the critsect itself. */ + RTR3PTR pvKey; + /** Pointer to the VM - R3Ptr. */ + PVMR3 pVMR3; + /** Pointer to the VM - R0Ptr. */ + PVMR0 pVMR0; + /** Pointer to the VM - GCPtr. */ + PVMRC pVMRC; +#if HC_ARCH_BITS == 64 + /** Alignment padding. */ + RTRCPTR RCPtrPadding; +#endif + /** The lock name. */ + R3PTRTYPE(const char *) pszName; + /** R0/RC write lock contention. */ + STAMCOUNTER StatContentionRZEnterExcl; + /** R0/RC write unlock contention. */ + STAMCOUNTER StatContentionRZLeaveExcl; + /** R0/RC read lock contention. */ + STAMCOUNTER StatContentionRZEnterShared; + /** R0/RC read unlock contention. */ + STAMCOUNTER StatContentionRZLeaveShared; + /** R0/RC writes. */ + STAMCOUNTER StatRZEnterExcl; + /** R0/RC reads. */ + STAMCOUNTER StatRZEnterShared; + /** R3 write lock contention. */ + STAMCOUNTER StatContentionR3EnterExcl; + /** R3 read lock contention. */ + STAMCOUNTER StatContentionR3EnterShared; + /** R3 writes. */ + STAMCOUNTER StatR3EnterExcl; + /** R3 reads. */ + STAMCOUNTER StatR3EnterShared; + /** Profiling the time the section is write locked. */ + STAMPROFILEADV StatWriteLocked; +} PDMCRITSECTRWINT; +AssertCompileMemberAlignment(PDMCRITSECTRWINT, StatContentionRZEnterExcl, 8); +AssertCompileMemberAlignment(PDMCRITSECTRWINT, Core.u64State, 8); +/** Pointer to private critical section data. */ +typedef PDMCRITSECTRWINT *PPDMCRITSECTRWINT; + + + +/** * The usual device/driver/internal/external stuff. */ typedef enum @@ -351,6 +423,7 @@ typedef struct PDMTHREADINT #define PDMUSBINSINT_DECLARED #define PDMDRVINSINT_DECLARED #define PDMCRITSECTINT_DECLARED +#define PDMCRITSECTRWINT_DECLARED #define PDMTHREADINT_DECLARED #ifdef ___VBox_pdm_h # error "Invalid header PDM order. Include PDMInternal.h before VBox/vmm/pdm.h!" @@ -487,13 +560,13 @@ typedef struct PDMAPIC /** Pointer to the APIC device instance - R3 Ptr. */ PPDMDEVINSR3 pDevInsR3; /** @copydoc PDMAPICREG::pfnGetInterruptR3 */ - DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, uint32_t *puTagSrc)); + DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t *puTagSrc)); /** @copydoc PDMAPICREG::pfnHasPendingIrqR3 */ - DECLR3CALLBACKMEMBER(bool, pfnHasPendingIrqR3,(PPDMDEVINS pDevIns)); + DECLR3CALLBACKMEMBER(bool, pfnHasPendingIrqR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t *pu8PendingIrq)); /** @copydoc PDMAPICREG::pfnSetBaseR3 */ - DECLR3CALLBACKMEMBER(void, pfnSetBaseR3,(PPDMDEVINS pDevIns, uint64_t u64Base)); + DECLR3CALLBACKMEMBER(void, pfnSetBaseR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint64_t u64Base)); /** @copydoc PDMAPICREG::pfnGetBaseR3 */ - DECLR3CALLBACKMEMBER(uint64_t, pfnGetBaseR3,(PPDMDEVINS pDevIns)); + DECLR3CALLBACKMEMBER(uint64_t, pfnGetBaseR3,(PPDMDEVINS pDevIns, VMCPUID idCpu)); /** @copydoc PDMAPICREG::pfnSetTPRR3 */ DECLR3CALLBACKMEMBER(void, pfnSetTPRR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t u8TPR)); /** @copydoc PDMAPICREG::pfnGetTPRR3 */ @@ -511,13 +584,13 @@ typedef struct PDMAPIC /** Pointer to the APIC device instance - R0 Ptr. */ PPDMDEVINSR0 pDevInsR0; /** @copydoc PDMAPICREG::pfnGetInterruptR3 */ - DECLR0CALLBACKMEMBER(int, pfnGetInterruptR0,(PPDMDEVINS pDevIns, uint32_t *puTagSrc)); + DECLR0CALLBACKMEMBER(int, pfnGetInterruptR0,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t *puTagSrc)); /** @copydoc PDMAPICREG::pfnHasPendingIrqR3 */ - DECLR0CALLBACKMEMBER(bool, pfnHasPendingIrqR0,(PPDMDEVINS pDevIns)); + DECLR0CALLBACKMEMBER(bool, pfnHasPendingIrqR0,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t *pu8PendingIrq)); /** @copydoc PDMAPICREG::pfnSetBaseR3 */ - DECLR0CALLBACKMEMBER(void, pfnSetBaseR0,(PPDMDEVINS pDevIns, uint64_t u64Base)); + DECLR0CALLBACKMEMBER(void, pfnSetBaseR0,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint64_t u64Base)); /** @copydoc PDMAPICREG::pfnGetBaseR3 */ - DECLR0CALLBACKMEMBER(uint64_t, pfnGetBaseR0,(PPDMDEVINS pDevIns)); + DECLR0CALLBACKMEMBER(uint64_t, pfnGetBaseR0,(PPDMDEVINS pDevIns, VMCPUID idCpu)); /** @copydoc PDMAPICREG::pfnSetTPRR3 */ DECLR0CALLBACKMEMBER(void, pfnSetTPRR0,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t u8TPR)); /** @copydoc PDMAPICREG::pfnGetTPRR3 */ @@ -535,13 +608,13 @@ typedef struct PDMAPIC /** Pointer to the APIC device instance - RC Ptr. */ PPDMDEVINSRC pDevInsRC; /** @copydoc PDMAPICREG::pfnGetInterruptR3 */ - DECLRCCALLBACKMEMBER(int, pfnGetInterruptRC,(PPDMDEVINS pDevIns, uint32_t *puTagSrc)); + DECLRCCALLBACKMEMBER(int, pfnGetInterruptRC,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t *puTagSrc)); /** @copydoc PDMAPICREG::pfnHasPendingIrqR3 */ - DECLRCCALLBACKMEMBER(bool, pfnHasPendingIrqRC,(PPDMDEVINS pDevIns)); + DECLRCCALLBACKMEMBER(bool, pfnHasPendingIrqRC,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t *pu8PendingIrq)); /** @copydoc PDMAPICREG::pfnSetBaseR3 */ - DECLRCCALLBACKMEMBER(void, pfnSetBaseRC,(PPDMDEVINS pDevIns, uint64_t u64Base)); + DECLRCCALLBACKMEMBER(void, pfnSetBaseRC,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint64_t u64Base)); /** @copydoc PDMAPICREG::pfnGetBaseR3 */ - DECLRCCALLBACKMEMBER(uint64_t, pfnGetBaseRC,(PPDMDEVINS pDevIns)); + DECLRCCALLBACKMEMBER(uint64_t, pfnGetBaseRC,(PPDMDEVINS pDevIns, VMCPUID idCpu)); /** @copydoc PDMAPICREG::pfnSetTPRR3 */ DECLRCCALLBACKMEMBER(void, pfnSetTPRRC,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t u8TPR)); /** @copydoc PDMAPICREG::pfnGetTPRR3 */ @@ -615,10 +688,6 @@ typedef struct PDMPCIBUS /** @copydoc PDMPCIBUSREG::pfnSetConfigCallbacksR3 */ DECLR3CALLBACKMEMBER(void, pfnSetConfigCallbacksR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld, PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld)); - /** @copydoc PDMPCIBUSREG::pfnSaveExecR3 */ - DECLR3CALLBACKMEMBER(int, pfnSaveExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle)); - /** @copydoc PDMPCIBUSREG::pfnLoadExecR3 */ - DECLR3CALLBACKMEMBER(int, pfnLoadExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle)); /** @copydoc PDMPCIBUSREG::pfnFakePCIBIOSR3 */ DECLR3CALLBACKMEMBER(int, pfnFakePCIBIOSR3,(PPDMDEVINS pDevIns)); @@ -945,16 +1014,36 @@ typedef struct PDMBLKCACHEGLOBAL *PPDMBLKCACHEGLOBAL; /** * PDM VMCPU Instance data. - * Changes to this must checked against the padding of the cfgm union in VMCPU! + * Changes to this must checked against the padding of the pdm union in VMCPU! */ typedef struct PDMCPU { - /** The number of entries in the apQueuedCritSectsLeaves table that's currently in use. */ + /** The number of entries in the apQueuedCritSectsLeaves table that's currently + * in use. */ uint32_t cQueuedCritSectLeaves; uint32_t uPadding0; /**< Alignment padding.*/ - /** Critical sections queued in RC/R0 because of contention preventing leave to complete. (R3 Ptrs) + /** Critical sections queued in RC/R0 because of contention preventing leave to + * complete. (R3 Ptrs) + * We will return to Ring-3 ASAP, so this queue doesn't have to be very long. */ + R3PTRTYPE(PPDMCRITSECT) apQueuedCritSectLeaves[8]; + + /** The number of entries in the apQueuedCritSectRwExclLeaves table that's + * currently in use. */ + uint32_t cQueuedCritSectRwExclLeaves; + uint32_t uPadding1; /**< Alignment padding.*/ + /** Read/write critical sections queued in RC/R0 because of contention + * preventing exclusive leave to complete. (R3 Ptrs) + * We will return to Ring-3 ASAP, so this queue doesn't have to be very long. */ + R3PTRTYPE(PPDMCRITSECTRW) apQueuedCritSectRwExclLeaves[8]; + + /** The number of entries in the apQueuedCritSectsRwShrdLeaves table that's + * currently in use. */ + uint32_t cQueuedCritSectRwShrdLeaves; + uint32_t uPadding2; /**< Alignment padding.*/ + /** Read/write critical sections queued in RC/R0 because of contention + * preventing shared leave to complete. (R3 Ptrs) * We will return to Ring-3 ASAP, so this queue doesn't have to be very long. */ - R3PTRTYPE(PPDMCRITSECT) apQueuedCritSectsLeaves[8]; + R3PTRTYPE(PPDMCRITSECTRW) apQueuedCritSectRwShrdLeaves[8]; } PDMCPU; @@ -1073,6 +1162,8 @@ typedef struct PDMUSERPERVM PPDMMOD pModules; /** List of initialized critical sections. (LIFO) */ R3PTRTYPE(PPDMCRITSECTINT) pCritSects; + /** List of initialized read/write critical sections. (LIFO) */ + R3PTRTYPE(PPDMCRITSECTRWINT) pRwCritSects; /** Head of the PDM Thread list. (singly linked) */ R3PTRTYPE(PPDMTHREAD) pThreads; /** Tail of the PDM Thread list. (singly linked) */ @@ -1085,13 +1176,14 @@ typedef struct PDMUSERPERVM /** Head of the templates. Singly linked, protected by ListCritSect. */ R3PTRTYPE(PPDMASYNCCOMPLETIONTEMPLATE) pAsyncCompletionTemplates; /** @} */ + + /** Global block cache data. */ + R3PTRTYPE(PPDMBLKCACHEGLOBAL) pBlkCacheGlobal; #ifdef VBOX_WITH_NETSHAPER /** Pointer to network shaper instance. */ R3PTRTYPE(PPDMNETSHAPER) pNetShaper; #endif /* VBOX_WITH_NETSHAPER */ - R3PTRTYPE(PPDMBLKCACHEGLOBAL) pBlkCacheGlobal; - } PDMUSERPERVM; /** Pointer to the PDM data kept in the UVM. */ typedef PDMUSERPERVM *PPDMUSERPERVM; @@ -1154,14 +1246,22 @@ extern const PDMPCIRAWHLPR3 g_pdmR3DevPciRawHlp; #ifdef IN_RING3 bool pdmR3IsValidName(const char *pszName); -int pdmR3CritSectInitStats(PVM pVM); -void pdmR3CritSectRelocate(PVM pVM); -int pdmR3CritSectInitDevice(PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, va_list va); -int pdmR3CritSectInitDeviceAuto(PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, - const char *pszNameFmt, ...); -int pdmR3CritSectDeleteDevice(PVM pVM, PPDMDEVINS pDevIns); -int pdmR3CritSectInitDriver(PVM pVM, PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...); -int pdmR3CritSectDeleteDriver(PVM pVM, PPDMDRVINS pDrvIns); +int pdmR3CritSectBothInitStats(PVM pVM); +void pdmR3CritSectBothRelocate(PVM pVM); +int pdmR3CritSectBothDeleteDevice(PVM pVM, PPDMDEVINS pDevIns); +int pdmR3CritSectBothDeleteDriver(PVM pVM, PPDMDRVINS pDrvIns); +int pdmR3CritSectInitDevice( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, + const char *pszNameFmt, va_list va); +int pdmR3CritSectInitDeviceAuto( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, + const char *pszNameFmt, ...); +int pdmR3CritSectInitDriver( PVM pVM, PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, + const char *pszNameFmt, ...); +int pdmR3CritSectRwInitDevice( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL, + const char *pszNameFmt, va_list va); +int pdmR3CritSectRwInitDeviceAuto( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL, + const char *pszNameFmt, ...); +int pdmR3CritSectRwInitDriver( PVM pVM, PPDMDRVINS pDrvIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL, + const char *pszNameFmt, ...); int pdmR3DevInit(PVM pVM); PPDMDEV pdmR3DevLookup(PVM pVM, const char *pszName); @@ -1206,6 +1306,13 @@ int pdmR3ThreadSuspendAll(PVM pVM); int pdmR3AsyncCompletionInit(PVM pVM); int pdmR3AsyncCompletionTerm(PVM pVM); void pdmR3AsyncCompletionResume(PVM pVM); +int pdmR3AsyncCompletionTemplateCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEDEV pfnCompleted, const char *pszDesc); +int pdmR3AsyncCompletionTemplateCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, + PFNPDMASYNCCOMPLETEDRV pfnCompleted, void *pvTemplateUser, const char *pszDesc); +int pdmR3AsyncCompletionTemplateCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEUSB pfnCompleted, const char *pszDesc); +int pdmR3AsyncCompletionTemplateDestroyDevice(PVM pVM, PPDMDEVINS pDevIns); +int pdmR3AsyncCompletionTemplateDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns); +int pdmR3AsyncCompletionTemplateDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns); #endif #ifdef VBOX_WITH_NETSHAPER @@ -1223,6 +1330,11 @@ void pdmLock(PVM pVM); int pdmLockEx(PVM pVM, int rc); void pdmUnlock(PVM pVM); +#if defined(IN_RING3) || defined(IN_RING0) +void pdmCritSectRwLeaveSharedQueued(PPDMCRITSECTRW pThis); +void pdmCritSectRwLeaveExclQueued(PPDMCRITSECTRW pThis); +#endif + /** @} */ RT_C_DECLS_END |
