summaryrefslogtreecommitdiff
path: root/src/VBox/VMM/include/IOMInline.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/VMM/include/IOMInline.h')
-rw-r--r--src/VBox/VMM/include/IOMInline.h53
1 files changed, 33 insertions, 20 deletions
diff --git a/src/VBox/VMM/include/IOMInline.h b/src/VBox/VMM/include/IOMInline.h
index 3804e9e1..7c7ac41e 100644
--- a/src/VBox/VMM/include/IOMInline.h
+++ b/src/VBox/VMM/include/IOMInline.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -34,7 +34,7 @@
*/
DECLINLINE(CTX_SUFF(PIOMIOPORTRANGE)) iomIOPortGetRange(PVM pVM, RTIOPORT Port)
{
- Assert(PDMCritSectIsOwner(&pVM->iom.s.CritSect));
+ Assert(IOM_IS_SHARED_LOCK_OWNER(pVM));
return (CTX_SUFF(PIOMIOPORTRANGE))RTAvlroIOPortRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->CTX_SUFF(IOPortTree), Port);
}
@@ -50,7 +50,7 @@ DECLINLINE(CTX_SUFF(PIOMIOPORTRANGE)) iomIOPortGetRange(PVM pVM, RTIOPORT Port)
*/
DECLINLINE(PIOMIOPORTRANGER3) iomIOPortGetRangeR3(PVM pVM, RTIOPORT Port)
{
- Assert(PDMCritSectIsOwner(&pVM->iom.s.CritSect));
+ Assert(IOM_IS_SHARED_LOCK_OWNER(pVM));
return (PIOMIOPORTRANGER3)RTAvlroIOPortRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->IOPortTreeR3, Port);
}
@@ -62,15 +62,16 @@ DECLINLINE(PIOMIOPORTRANGER3) iomIOPortGetRangeR3(PVM pVM, RTIOPORT Port)
* @returns NULL if address not in a MMIO range.
*
* @param pVM Pointer to the VM.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param GCPhys Physical address to lookup.
*/
-DECLINLINE(PIOMMMIORANGE) iomMmioGetRange(PVM pVM, RTGCPHYS GCPhys)
+DECLINLINE(PIOMMMIORANGE) iomMmioGetRange(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys)
{
- Assert(PDMCritSectIsOwner(&pVM->iom.s.CritSect));
- PIOMMMIORANGE pRange = pVM->iom.s.CTX_SUFF(pMMIORangeLast);
+ Assert(IOM_IS_SHARED_LOCK_OWNER(pVM));
+ PIOMMMIORANGE pRange = pVCpu->iom.s.CTX_SUFF(pMMIORangeLast);
if ( !pRange
|| GCPhys - pRange->GCPhys >= pRange->cb)
- pVM->iom.s.CTX_SUFF(pMMIORangeLast) = pRange
+ pVCpu->iom.s.CTX_SUFF(pMMIORangeLast) = pRange
= (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->MMIOTree, GCPhys);
return pRange;
}
@@ -97,22 +98,23 @@ DECLINLINE(void) iomMmioRetainRange(PIOMMMIORANGE pRange)
* @returns NULL if address not in a MMIO range.
*
* @param pVM Pointer to the VM.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param GCPhys Physical address to lookup.
*/
-DECLINLINE(PIOMMMIORANGE) iomMmioGetRangeWithRef(PVM pVM, RTGCPHYS GCPhys)
+DECLINLINE(PIOMMMIORANGE) iomMmioGetRangeWithRef(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys)
{
- int rc = PDMCritSectEnter(&pVM->iom.s.CritSect, VINF_SUCCESS);
+ int rc = IOM_LOCK_SHARED_EX(pVM, VINF_SUCCESS);
AssertRCReturn(rc, NULL);
- PIOMMMIORANGE pRange = pVM->iom.s.CTX_SUFF(pMMIORangeLast);
+ PIOMMMIORANGE pRange = pVCpu->iom.s.CTX_SUFF(pMMIORangeLast);
if ( !pRange
|| GCPhys - pRange->GCPhys >= pRange->cb)
- pVM->iom.s.CTX_SUFF(pMMIORangeLast) = pRange
+ pVCpu->iom.s.CTX_SUFF(pMMIORangeLast) = pRange
= (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->MMIOTree, GCPhys);
if (pRange)
iomMmioRetainRange(pRange);
- PDMCritSectLeave(&pVM->iom.s.CritSect);
+ IOM_UNLOCK_SHARED(pVM);
return pRange;
}
@@ -139,14 +141,15 @@ DECLINLINE(void) iomMmioReleaseRange(PVM pVM, PIOMMMIORANGE pRange)
* @returns NULL if address not in a MMIO range.
*
* @param pVM Pointer to the VM.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param GCPhys Physical address to lookup.
*/
-DECLINLINE(PIOMMMIORANGE) iomMMIOGetRangeUnsafe(PVM pVM, RTGCPHYS GCPhys)
+DECLINLINE(PIOMMMIORANGE) iomMMIOGetRangeUnsafe(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys)
{
- PIOMMMIORANGE pRange = pVM->iom.s.CTX_SUFF(pMMIORangeLast);
+ PIOMMMIORANGE pRange = pVCpu->iom.s.CTX_SUFF(pMMIORangeLast);
if ( !pRange
|| GCPhys - pRange->GCPhys >= pRange->cb)
- pVM->iom.s.CTX_SUFF(pMMIORangeLast) = pRange
+ pVCpu->iom.s.CTX_SUFF(pMMIORangeLast) = pRange
= (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->MMIOTree, GCPhys);
return pRange;
}
@@ -164,29 +167,39 @@ DECLINLINE(PIOMMMIORANGE) iomMMIOGetRangeUnsafe(PVM pVM, RTGCPHYS GCPhys)
* @returns NULL if not found (R0/GC), or out of memory (R3).
*
* @param pVM Pointer to the VM.
+ * @param pVCpu Pointer to the virtual CPU structure of the caller.
* @param GCPhys Physical address to lookup.
* @param pRange The MMIO range.
+ *
+ * @remarks The caller holds the IOM critical section with shared access prior
+ * to calling this method. Upon return, the lock has been released!
+ * This is ugly, but it's a necessary evil since we cannot upgrade read
+ * locks to write locks and the whole purpose here is calling
+ * iomR3MMIOStatsCreate.
*/
-DECLINLINE(PIOMMMIOSTATS) iomMmioGetStats(PVM pVM, RTGCPHYS GCPhys, PIOMMMIORANGE pRange)
+DECLINLINE(PIOMMMIOSTATS) iomMmioGetStats(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, PIOMMMIORANGE pRange)
{
- PDMCritSectEnter(&pVM->iom.s.CritSect, VINF_SUCCESS);
+ Assert(IOM_IS_SHARED_LOCK_OWNER(pVM));
/* For large ranges, we'll put everything on the first byte. */
if (pRange->cb > PAGE_SIZE)
GCPhys = pRange->GCPhys;
- PIOMMMIOSTATS pStats = pVM->iom.s.CTX_SUFF(pMMIOStatsLast);
+ PIOMMMIOSTATS pStats = pVCpu->iom.s.CTX_SUFF(pMMIOStatsLast);
if ( !pStats
|| pStats->Core.Key != GCPhys)
{
pStats = (PIOMMMIOSTATS)RTAvloGCPhysGet(&pVM->iom.s.CTX_SUFF(pTrees)->MmioStatTree, GCPhys);
# ifdef IN_RING3
if (!pStats)
- pStats = iomR3MMIOStatsCreate(pVM, GCPhys, pRange->pszDesc);
+ {
+ IOM_UNLOCK_SHARED(pVM);
+ return iomR3MMIOStatsCreate(pVM, GCPhys, pRange->pszDesc);
+ }
# endif
}
- PDMCritSectLeave(&pVM->iom.s.CritSect);
+ IOM_UNLOCK_SHARED(pVM);
return pStats;
}
#endif /* VBOX_WITH_STATISTICS */