summaryrefslogtreecommitdiff
path: root/src/VBox/VMM/include/PDMInternal.h
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-03-26 19:21:20 +0000
committer <>2014-05-08 15:03:54 +0000
commitfb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch)
treec2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/VMM/include/PDMInternal.h
parent58ed4748338f9466599adfc8a9171280ed99e23f (diff)
downloadVirtualBox-master.tar.gz
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/VMM/include/PDMInternal.h')
-rw-r--r--src/VBox/VMM/include/PDMInternal.h182
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