Changeset 45311 in vbox
- Timestamp:
- Apr 3, 2013 2:55:30 PM (11 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 5 edited
-
VMMAll/IOMAll.cpp (modified) (23 diffs)
-
VMMAll/IOMAllMMIO.cpp (modified) (32 diffs)
-
VMMR3/IOM.cpp (modified) (37 diffs)
-
include/IOMInline.h (modified) (2 diffs)
-
include/IOMInternal.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IOMAll.cpp
r45305 r45311 5 5 6 6 /* 7 * Copyright (C) 2006-201 2Oracle Corporation7 * Copyright (C) 2006-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 49 49 { 50 50 #ifdef IOM_WITH_CRIT_SECT_RW 51 return PDMCritSectRwIsWriteOwner(&pVM->iom.s.CritSect); 51 return PDMCritSectRwIsInitialized(&pVM->iom.s.CritSect) 52 && PDMCritSectRwIsWriteOwner(&pVM->iom.s.CritSect); 52 53 #else 53 54 return PDMCritSectIsOwner(&pVM->iom.s.CritSect); … … 230 231 * handle is buggy and doesn't handle all cases. */ 231 232 /* Take the IOM lock before performing any device I/O. */ 232 int rc2 = IOM_LOCK (pVM);233 int rc2 = IOM_LOCK_SHARED(pVM); 233 234 #ifndef IN_RING3 234 235 if (rc2 == VERR_SEM_BUSY) … … 275 276 { 276 277 STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->InRZToR3); }); 277 IOM_UNLOCK (pVM);278 IOM_UNLOCK_SHARED(pVM); 278 279 return VINF_IOM_R3_IOPORT_READ; 279 280 } … … 281 282 void *pvUser = pRange->pvUser; 282 283 PPDMDEVINS pDevIns = pRange->pDevIns; 283 IOM_UNLOCK (pVM);284 IOM_UNLOCK_SHARED(pVM); 284 285 285 286 /* … … 341 342 STAM_COUNTER_INC(&pStats->InRZToR3); 342 343 # endif 343 IOM_UNLOCK (pVM);344 IOM_UNLOCK_SHARED(pVM); 344 345 return VINF_IOM_R3_IOPORT_READ; 345 346 } … … 352 353 if (pStats) 353 354 STAM_COUNTER_INC(&pStats->CTX_SUFF_Z(In)); 354 else355 {356 # ifndef IN_RING3357 /* Ring-3 will have to create the statistics record. */358 IOM_UNLOCK(pVM);359 return VINF_IOM_R3_IOPORT_READ;360 # else361 pStats = iomR3IOPortStatsCreate(pVM, Port, NULL);362 if (pStats)363 STAM_COUNTER_INC(&pStats->CTX_SUFF_Z(In));364 # endif365 }366 355 #endif 367 356 … … 374 363 default: 375 364 AssertMsgFailed(("Invalid I/O port size %d. Port=%d\n", cbValue, Port)); 376 IOM_UNLOCK (pVM);365 IOM_UNLOCK_SHARED(pVM); 377 366 return VERR_IOM_INVALID_IOPORT_SIZE; 378 367 } 379 368 Log3(("IOMIOPortRead: Port=%RTiop *pu32=%08RX32 cb=%d rc=VINF_SUCCESS\n", Port, *pu32Value, cbValue)); 380 IOM_UNLOCK (pVM);369 IOM_UNLOCK_SHARED(pVM); 381 370 return VINF_SUCCESS; 382 371 } … … 404 393 { 405 394 /* Take the IOM lock before performing any device I/O. */ 406 int rc2 = IOM_LOCK (pVM);395 int rc2 = IOM_LOCK_SHARED(pVM); 407 396 #ifndef IN_RING3 408 397 if (rc2 == VERR_SEM_BUSY) … … 452 441 { 453 442 STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->InRZToR3); }); 454 IOM_UNLOCK (pVM);443 IOM_UNLOCK_SHARED(pVM); 455 444 return VINF_IOM_R3_IOPORT_READ; 456 445 } … … 458 447 void *pvUser = pRange->pvUser; 459 448 PPDMDEVINS pDevIns = pRange->pDevIns; 460 IOM_UNLOCK (pVM);449 IOM_UNLOCK_SHARED(pVM); 461 450 462 451 /* … … 505 494 STAM_COUNTER_INC(&pStats->InRZToR3); 506 495 # endif 507 IOM_UNLOCK (pVM);496 IOM_UNLOCK_SHARED(pVM); 508 497 return VINF_IOM_R3_IOPORT_READ; 509 498 } … … 516 505 if (pStats) 517 506 STAM_COUNTER_INC(&pStats->CTX_SUFF_Z(In)); 518 else519 {520 # ifndef IN_RING3521 /* Ring-3 will have to create the statistics record. */522 IOM_UNLOCK(pVM);523 return VINF_IOM_R3_IOPORT_READ;524 # else525 pStats = iomR3IOPortStatsCreate(pVM, Port, NULL);526 if (pStats)527 STAM_COUNTER_INC(&pStats->CTX_SUFF_Z(In));528 # endif529 }530 507 #endif 531 508 532 509 Log3(("IOMIOPortReadStr: Port=%RTiop pGCPtrDst=%p pcTransfer=%p:{%#x->%#x} cb=%d rc=VINF_SUCCESS\n", 533 510 Port, pGCPtrDst, pcTransfers, cTransfers, *pcTransfers, cb)); 534 IOM_UNLOCK (pVM);511 IOM_UNLOCK_SHARED(pVM); 535 512 return VINF_SUCCESS; 536 513 } … … 556 533 { 557 534 /* Take the IOM lock before performing any device I/O. */ 558 int rc2 = IOM_LOCK (pVM);535 int rc2 = IOM_LOCK_SHARED(pVM); 559 536 #ifndef IN_RING3 560 537 if (rc2 == VERR_SEM_BUSY) … … 603 580 { 604 581 STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->OutRZToR3); }); 605 IOM_UNLOCK (pVM);582 IOM_UNLOCK_SHARED(pVM); 606 583 return VINF_IOM_R3_IOPORT_WRITE; 607 584 } … … 609 586 void *pvUser = pRange->pvUser; 610 587 PPDMDEVINS pDevIns = pRange->pDevIns; 611 IOM_UNLOCK (pVM);588 IOM_UNLOCK_SHARED(pVM); 612 589 613 590 /* … … 655 632 STAM_COUNTER_INC(&pStats->OutRZToR3); 656 633 # endif 657 IOM_UNLOCK (pVM);634 IOM_UNLOCK_SHARED(pVM); 658 635 return VINF_IOM_R3_IOPORT_WRITE; 659 636 } … … 667 644 if (pStats) 668 645 STAM_COUNTER_INC(&pStats->CTX_SUFF_Z(Out)); 669 else670 {671 # ifndef IN_RING3672 /* R3 will have to create the statistics record. */673 IOM_UNLOCK(pVM);674 return VINF_IOM_R3_IOPORT_WRITE;675 # else676 pStats = iomR3IOPortStatsCreate(pVM, Port, NULL);677 if (pStats)678 STAM_COUNTER_INC(&pStats->CTX_SUFF_Z(Out));679 # endif680 }681 646 #endif 682 647 Log3(("IOMIOPortWrite: Port=%RTiop u32=%08RX32 cb=%d nop\n", Port, u32Value, cbValue)); 683 IOM_UNLOCK (pVM);648 IOM_UNLOCK_SHARED(pVM); 684 649 return VINF_SUCCESS; 685 650 } … … 707 672 { 708 673 /* Take the IOM lock before performing any device I/O. */ 709 int rc2 = IOM_LOCK (pVM);674 int rc2 = IOM_LOCK_SHARED(pVM); 710 675 #ifndef IN_RING3 711 676 if (rc2 == VERR_SEM_BUSY) … … 755 720 { 756 721 STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->OutRZToR3); }); 757 IOM_UNLOCK (pVM);722 IOM_UNLOCK_SHARED(pVM); 758 723 return VINF_IOM_R3_IOPORT_WRITE; 759 724 } … … 761 726 void *pvUser = pRange->pvUser; 762 727 PPDMDEVINS pDevIns = pRange->pDevIns; 763 IOM_UNLOCK (pVM);728 IOM_UNLOCK_SHARED(pVM); 764 729 765 730 /* … … 808 773 STAM_COUNTER_INC(&pStats->OutRZToR3); 809 774 # endif 810 IOM_UNLOCK (pVM);775 IOM_UNLOCK_SHARED(pVM); 811 776 return VINF_IOM_R3_IOPORT_WRITE; 812 777 } … … 819 784 if (pStats) 820 785 STAM_COUNTER_INC(&pStats->CTX_SUFF_Z(Out)); 821 else822 {823 # ifndef IN_RING3824 /* Ring-3 will have to create the statistics record. */825 IOM_UNLOCK(pVM);826 return VINF_IOM_R3_IOPORT_WRITE;827 # else828 pStats = iomR3IOPortStatsCreate(pVM, Port, NULL);829 if (pStats)830 STAM_COUNTER_INC(&pStats->CTX_SUFF_Z(Out));831 # endif832 }833 786 #endif 834 787 835 788 Log3(("IOMIOPortWriteStr: Port=%RTiop pGCPtrSrc=%p pcTransfer=%p:{%#x->%#x} cb=%d rc=VINF_SUCCESS\n", 836 789 Port, pGCPtrSrc, pcTransfers, cTransfers, *pcTransfers, cb)); 837 IOM_UNLOCK (pVM);790 IOM_UNLOCK_SHARED(pVM); 838 791 return VINF_SUCCESS; 839 792 } -
trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
r45305 r45311 5 5 6 6 /* 7 * Copyright (C) 2006-201 2Oracle Corporation7 * Copyright (C) 2006-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 277 277 { 278 278 #ifdef VBOX_WITH_STATISTICS 279 int rcSem = IOM_LOCK_SHARED(pVM); 280 if (rcSem == VERR_SEM_BUSY) 281 return VINF_IOM_R3_MMIO_WRITE; 279 282 PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, pVCpu, GCPhysFault, pRange); 280 Assert(pStats); 281 #endif 282 283 if (!pStats) 284 # ifdef IN_RING3 285 return VERR_NO_MEMORY; 286 # else 287 return VINF_IOM_R3_MMIO_WRITE; 288 # endif 283 289 STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfWrite), a); 290 #endif 291 284 292 VBOXSTRICTRC rc; 285 293 if (RT_LIKELY(pRange->CTX_SUFF(pfnWriteCallback))) … … 295 303 else 296 304 rc = VINF_SUCCESS; 305 297 306 STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfWrite), a); 298 307 STAM_COUNTER_INC(&pStats->Accesses); … … 484 493 { 485 494 #ifdef VBOX_WITH_STATISTICS 495 int rcSem = IOM_LOCK_SHARED(pVM); 496 if (rcSem == VERR_SEM_BUSY) 497 return VINF_IOM_R3_MMIO_READ; 486 498 PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, pVCpu, GCPhys, pRange); 487 Assert(pStats); 499 if (!pStats) 500 # ifdef IN_RING3 501 return VERR_NO_MEMORY; 502 # else 503 return VINF_IOM_R3_MMIO_READ; 504 # endif 488 505 STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfRead), a); 489 506 #endif … … 512 529 } 513 530 } 531 514 532 STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfRead), a); 515 533 STAM_COUNTER_INC(&pStats->Accesses); … … 977 995 { 978 996 #ifndef IN_RC 979 if ( CPUMIsGuestIn64BitCode( VMMGetCpu(pVM))997 if ( CPUMIsGuestIn64BitCode(pVCpu) 980 998 && pRegFrame->rcx >= _4G) 981 999 return VINF_EM_RAW_EMULATE_INSTR; … … 1489 1507 static int iomMMIOHandler(PVM pVM, PVMCPU pVCpu, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault, void *pvUser) 1490 1508 { 1491 int rc = IOM_LOCK (pVM);1509 int rc = IOM_LOCK_SHARED(pVM); 1492 1510 #ifndef IN_RING3 1493 1511 if (rc == VERR_SEM_BUSY) … … 1502 1520 Assert(pRange); 1503 1521 Assert(pRange == iomMmioGetRange(pVM, pVCpu, GCPhysFault)); 1504 1505 #ifdef VBOX_WITH_STATISTICS 1506 /* 1507 * Locate the statistics, if > PAGE_SIZE we'll use the first byte for everything. 1522 iomMmioRetainRange(pRange); 1523 #ifndef VBOX_WITH_STATISTICS 1524 IOM_UNLOCK_SHARED(pVM); 1525 1526 #else 1527 /* 1528 * Locate the statistics. 1508 1529 */ 1509 1530 PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, pVCpu, GCPhysFault, pRange); 1510 1531 if (!pStats) 1511 1532 { 1533 iomMmioReleaseRange(pVM, pRange); 1512 1534 # ifdef IN_RING3 1513 IOM_UNLOCK(pVM);1514 1535 return VERR_NO_MEMORY; 1515 1536 # else 1516 1537 STAM_PROFILE_STOP(&pVM->iom.s.StatRZMMIOHandler, a); 1517 1538 STAM_COUNTER_INC(&pVM->iom.s.StatRZMMIOFailures); 1518 IOM_UNLOCK(pVM);1519 1539 return VINF_IOM_R3_MMIO_READ_WRITE; 1520 1540 # endif … … 1545 1565 STAM_PROFILE_STOP(&pVM->iom.s.StatRZMMIOHandler, a); 1546 1566 STAM_COUNTER_INC(&pVM->iom.s.StatRZMMIOFailures); 1547 IOM_UNLOCK(pVM);1567 iomMmioReleaseRange(pVM, pRange); 1548 1568 return VINF_IOM_R3_MMIO_READ_WRITE; 1549 1569 } … … 1553 1573 * Retain the range and do locking. 1554 1574 */ 1555 iomMmioRetainRange(pRange);1556 1575 PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns); 1557 IOM_UNLOCK(pVM);1558 1576 rc = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_R3_MMIO_READ_WRITE); 1559 1577 if (rc != VINF_SUCCESS) … … 1571 1589 if (RT_FAILURE(rc)) 1572 1590 { 1591 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo)); 1573 1592 iomMmioReleaseRange(pVM, pRange); 1574 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));1575 1593 return rc; 1576 1594 } … … 1705 1723 1706 1724 STAM_PROFILE_STOP(&pVM->iom.s.StatRZMMIOHandler, a); 1725 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo)); 1707 1726 iomMmioReleaseRange(pVM, pRange); 1708 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));1709 1727 return rc; 1710 1728 } … … 1741 1759 VMMDECL(VBOXSTRICTRC) IOMMMIOPhysHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault) 1742 1760 { 1743 int rc2 = IOM_LOCK (pVM); NOREF(rc2);1761 int rc2 = IOM_LOCK_SHARED(pVM); NOREF(rc2); 1744 1762 #ifndef IN_RING3 1745 1763 if (rc2 == VERR_SEM_BUSY) … … 1748 1766 VBOXSTRICTRC rcStrict = iomMMIOHandler(pVM, pVCpu, (uint32_t)uErrorCode, pCtxCore, GCPhysFault, 1749 1767 iomMmioGetRange(pVM, pVCpu, GCPhysFault)); 1750 IOM_UNLOCK (pVM);1768 IOM_UNLOCK_SHARED(pVM); 1751 1769 return VBOXSTRICTRC_VAL(rcStrict); 1752 1770 } … … 1781 1799 * Validate the range. 1782 1800 */ 1783 int rc = IOM_LOCK (pVM);1801 int rc = IOM_LOCK_SHARED(pVM); 1784 1802 AssertRC(rc); 1785 1803 Assert(pRange == iomMmioGetRange(pVM, pVCpu, GCPhysFault)); … … 1790 1808 iomMmioRetainRange(pRange); 1791 1809 PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns); 1792 IOM_UNLOCK (pVM);1810 IOM_UNLOCK_SHARED(pVM); 1793 1811 rc = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_R3_MMIO_READ_WRITE); 1794 1812 if (rc != VINF_SUCCESS) … … 1828 1846 { 1829 1847 /* Take the IOM lock before performing any MMIO. */ 1830 VBOXSTRICTRC rc = IOM_LOCK (pVM);1848 VBOXSTRICTRC rc = IOM_LOCK_SHARED(pVM); 1831 1849 #ifndef IN_RING3 1832 1850 if (rc == VERR_SEM_BUSY) … … 1845 1863 { 1846 1864 AssertMsgFailed(("Handlers and page tables are out of sync or something! GCPhys=%RGp cbValue=%d\n", GCPhys, cbValue)); 1847 IOM_UNLOCK (pVM);1865 IOM_UNLOCK_SHARED(pVM); 1848 1866 return VERR_IOM_MMIO_RANGE_NOT_FOUND; 1849 1867 } 1850 #ifdef VBOX_WITH_STATISTICS 1868 iomMmioRetainRange(pRange); 1869 #ifndef VBOX_WITH_STATISTICS 1870 IOM_UNLOCK_SHARED(pVM); 1871 1872 #else /* VBOX_WITH_STATISTICS */ 1851 1873 PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, pVCpu, GCPhys, pRange); 1852 1874 if (!pStats) 1853 1875 { 1854 IOM_UNLOCK(pVM);1876 iomMmioReleaseRange(pVM, pRange); 1855 1877 # ifdef IN_RING3 1856 1878 return VERR_NO_MEMORY; … … 1867 1889 * Perform locking. 1868 1890 */ 1869 iomMmioRetainRange(pRange);1870 1891 PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns); 1871 IOM_UNLOCK(pVM);1872 1892 rc = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_R3_MMIO_WRITE); 1873 1893 if (rc != VINF_SUCCESS) … … 1893 1913 case VINF_SUCCESS: 1894 1914 Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=VINF_SUCCESS\n", GCPhys, *pu32Value, cbValue)); 1915 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo)); 1895 1916 iomMmioReleaseRange(pVM, pRange); 1896 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));1897 1917 return rc; 1898 1918 #ifndef IN_RING3 … … 1903 1923 default: 1904 1924 Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, VBOXSTRICTRC_VAL(rc))); 1925 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo)); 1905 1926 iomMmioReleaseRange(pVM, pRange); 1906 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));1907 1927 return rc; 1908 1928 … … 1910 1930 iomMMIODoRead00s(pu32Value, cbValue); 1911 1931 Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, VBOXSTRICTRC_VAL(rc))); 1932 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo)); 1912 1933 iomMmioReleaseRange(pVM, pRange); 1913 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));1914 1934 return VINF_SUCCESS; 1915 1935 … … 1917 1937 iomMMIODoReadFFs(pu32Value, cbValue); 1918 1938 Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, VBOXSTRICTRC_VAL(rc))); 1939 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo)); 1919 1940 iomMmioReleaseRange(pVM, pRange); 1920 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));1921 1941 return VINF_SUCCESS; 1922 1942 } … … 1927 1947 { 1928 1948 STAM_COUNTER_INC(&pStats->CTX_MID_Z(Read,ToR3)); 1929 IOM_UNLOCK(pVM);1949 iomMmioReleaseRange(pVM, pRange); 1930 1950 return VINF_IOM_R3_MMIO_READ; 1931 1951 } … … 1939 1959 iomMMIODoReadFFs(pu32Value, cbValue); 1940 1960 Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=VINF_SUCCESS\n", GCPhys, *pu32Value, cbValue)); 1941 IOM_UNLOCK(pVM);1961 iomMmioReleaseRange(pVM, pRange); 1942 1962 return VINF_SUCCESS; 1943 1963 } … … 1958 1978 { 1959 1979 /* Take the IOM lock before performing any MMIO. */ 1960 VBOXSTRICTRC rc = IOM_LOCK (pVM);1980 VBOXSTRICTRC rc = IOM_LOCK_SHARED(pVM); 1961 1981 #ifndef IN_RING3 1962 1982 if (rc == VERR_SEM_BUSY) … … 1975 1995 { 1976 1996 AssertMsgFailed(("Handlers and page tables are out of sync or something! GCPhys=%RGp cbValue=%d\n", GCPhys, cbValue)); 1977 IOM_UNLOCK (pVM);1997 IOM_UNLOCK_SHARED(pVM); 1978 1998 return VERR_IOM_MMIO_RANGE_NOT_FOUND; 1979 1999 } 1980 #ifdef VBOX_WITH_STATISTICS 2000 iomMmioRetainRange(pRange); 2001 #ifndef VBOX_WITH_STATISTICS 2002 IOM_UNLOCK_SHARED(pVM); 2003 2004 #else /* VBOX_WITH_STATISTICS */ 1981 2005 PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, pVCpu, GCPhys, pRange); 1982 2006 if (!pStats) 1983 2007 { 1984 IOM_UNLOCK(pVM);2008 iomMmioReleaseRange(pVM, pRange); 1985 2009 # ifdef IN_RING3 1986 2010 return VERR_NO_MEMORY; … … 1997 2021 * Perform locking. 1998 2022 */ 1999 iomMmioRetainRange(pRange);2000 2023 PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns); 2001 IOM_UNLOCK(pVM);2002 2024 rc = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_R3_MMIO_READ); 2003 2025 if (rc != VINF_SUCCESS) … … 2033 2055 { 2034 2056 STAM_COUNTER_INC(&pStats->CTX_MID_Z(Write,ToR3)); 2035 IOM_UNLOCK(pVM);2057 iomMmioReleaseRange(pVM, pRange); 2036 2058 return VINF_IOM_R3_MMIO_WRITE; 2037 2059 } … … 2044 2066 STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfWrite), a); 2045 2067 Log4(("IOMMMIOWrite: GCPhys=%RGp u32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, u32Value, cbValue, VINF_SUCCESS)); 2046 IOM_UNLOCK(pVM);2068 iomMmioReleaseRange(pVM, pRange); 2047 2069 return VINF_SUCCESS; 2048 2070 } … … 2409 2431 return VINF_SUCCESS; /* ignore */ 2410 2432 2411 int rc = IOM_LOCK (pVM);2433 int rc = IOM_LOCK_SHARED(pVM); 2412 2434 if (RT_FAILURE(rc)) 2413 2435 return VINF_SUCCESS; /* better luck the next time around */ … … 2431 2453 rc = PGMHandlerPhysicalPageAlias(pVM, pRange->GCPhys, GCPhys, GCPhysRemapped); 2432 2454 2433 IOM_UNLOCK (pVM);2455 IOM_UNLOCK_SHARED(pVM); 2434 2456 AssertRCReturn(rc, rc); 2435 2457 -
trunk/src/VBox/VMM/VMMR3/IOM.cpp
r45305 r45311 245 245 * (1) The irrelvant access not holding the lock is in assertion code. 246 246 */ 247 IOM_LOCK (pVM);247 IOM_LOCK_EXCL(pVM); 248 248 VMCPUID iCpu = pVM->cCpus; 249 249 while (iCpu-- > 0) … … 272 272 } 273 273 274 IOM_UNLOCK (pVM);274 IOM_UNLOCK_EXCL(pVM); 275 275 } 276 276 … … 415 415 * @param pszDesc Description. 416 416 */ 417 PIOMIOPORTSTATS iomR3IOPortStatsCreate(PVM pVM, RTIOPORT Port, const char *pszDesc)418 { 419 Assert(IOM_IS_EXCL_LOCK_OWNER(pVM));417 static PIOMIOPORTSTATS iomR3IOPortStatsCreate(PVM pVM, RTIOPORT Port, const char *pszDesc) 418 { 419 IOM_LOCK_EXCL(pVM); 420 420 421 421 /* check if it already exists. */ 422 422 PIOMIOPORTSTATS pPort = (PIOMIOPORTSTATS)RTAvloIOPortGet(&pVM->iom.s.pTreesR3->IOPortStatTree, Port); 423 423 if (pPort) 424 { 425 IOM_UNLOCK_EXCL(pVM); 424 426 return pPort; 427 } 425 428 426 429 /* allocate stats node. */ … … 433 436 if (RTAvloIOPortInsert(&pVM->iom.s.pTreesR3->IOPortStatTree, &pPort->Core)) 434 437 { 438 IOM_UNLOCK_EXCL(pVM); 439 435 440 /* put a name on common ports. */ 436 441 if (!pszDesc) … … 453 458 return pPort; 454 459 } 460 455 461 AssertMsgFailed(("what! Port=%d\n", Port)); 456 462 MMHyperFree(pVM, pPort); 457 463 } 464 IOM_UNLOCK_EXCL(pVM); 458 465 return NULL; 459 466 } … … 471 478 PIOMMMIOSTATS iomR3MMIOStatsCreate(PVM pVM, RTGCPHYS GCPhys, const char *pszDesc) 472 479 { 473 Assert(IOM_IS_EXCL_LOCK_OWNER(pVM)); 474 #ifdef DEBUG_sandervl 475 AssertGCPhys32(GCPhys); 476 #endif 480 IOM_LOCK_EXCL(pVM); 477 481 478 482 /* check if it already exists. */ 479 483 PIOMMMIOSTATS pStats = (PIOMMMIOSTATS)RTAvloGCPhysGet(&pVM->iom.s.pTreesR3->MmioStatTree, GCPhys); 480 484 if (pStats) 485 { 486 IOM_UNLOCK_EXCL(pVM); 481 487 return pStats; 488 } 482 489 483 490 /* allocate stats node. */ … … 490 497 if (RTAvloGCPhysInsert(&pVM->iom.s.pTreesR3->MmioStatTree, &pStats->Core)) 491 498 { 499 IOM_UNLOCK_EXCL(pVM); 500 492 501 rc = STAMR3RegisterF(pVM, &pStats->Accesses, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, pszDesc, "/IOM/MMIO/%RGp", GCPhys); AssertRC(rc); 493 502 rc = STAMR3RegisterF(pVM, &pStats->ProfReadR3, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, pszDesc, "/IOM/MMIO/%RGp/Read-R3", GCPhys); AssertRC(rc); … … 503 512 MMHyperFree(pVM, pStats); 504 513 } 514 IOM_UNLOCK_EXCL(pVM); 505 515 return NULL; 506 516 } … … 584 594 * Try Insert it. 585 595 */ 586 IOM_LOCK (pVM);596 IOM_LOCK_EXCL(pVM); 587 597 if (RTAvlroIOPortInsert(&pVM->iom.s.pTreesR3->IOPortTreeR3, &pRange->Core)) 588 598 { … … 591 601 iomR3IOPortStatsCreate(pVM, PortStart + iPort, pszDesc); 592 602 #endif 593 IOM_UNLOCK (pVM);603 IOM_UNLOCK_EXCL(pVM); 594 604 return VINF_SUCCESS; 595 605 } 596 IOM_UNLOCK (pVM);606 IOM_UNLOCK_EXCL(pVM); 597 607 598 608 /* conflict. */ … … 650 660 } 651 661 652 IOM_LOCK (pVM);662 IOM_LOCK_EXCL(pVM); 653 663 654 664 /* … … 662 672 { 663 673 AssertMsgFailed(("No R3! Port=#x %#x-%#x! (%s)\n", Port, PortStart, (unsigned)PortStart + cPorts - 1, pszDesc)); 664 IOM_UNLOCK (pVM);674 IOM_UNLOCK_EXCL(pVM); 665 675 return VERR_IOM_NO_R3_IOPORT_RANGE; 666 676 } … … 673 683 { 674 684 AssertMsgFailed(("Not owner! Port=%#x %#x-%#x! (%s)\n", Port, PortStart, (unsigned)PortStart + cPorts - 1, pszDesc)); 675 IOM_UNLOCK (pVM);685 IOM_UNLOCK_EXCL(pVM); 676 686 return VERR_IOM_NOT_IOPORT_RANGE_OWNER; 677 687 } … … 707 717 if (RTAvlroIOPortInsert(&pVM->iom.s.CTX_SUFF(pTrees)->IOPortTreeRC, &pRange->Core)) 708 718 { 709 IOM_UNLOCK (pVM);719 IOM_UNLOCK_EXCL(pVM); 710 720 return VINF_SUCCESS; 711 721 } … … 716 726 rc = VERR_IOM_IOPORT_RANGE_CONFLICT; 717 727 } 718 IOM_UNLOCK (pVM);728 IOM_UNLOCK_EXCL(pVM); 719 729 return rc; 720 730 } … … 765 775 } 766 776 767 IOM_LOCK(pVM); 777 IOM_LOCK_EXCL(pVM); 778 768 779 /* 769 780 * Validate that there are ring-3 ranges for the ports. … … 776 787 { 777 788 AssertMsgFailed(("No R3! Port=#x %#x-%#x! (%s)\n", Port, PortStart, (unsigned)PortStart + cPorts - 1, pszDesc)); 778 IOM_UNLOCK (pVM);789 IOM_UNLOCK_EXCL(pVM); 779 790 return VERR_IOM_NO_R3_IOPORT_RANGE; 780 791 } … … 787 798 { 788 799 AssertMsgFailed(("Not owner! Port=%#x %#x-%#x! (%s)\n", Port, PortStart, (unsigned)PortStart + cPorts - 1, pszDesc)); 789 IOM_UNLOCK (pVM);800 IOM_UNLOCK_EXCL(pVM); 790 801 return VERR_IOM_NOT_IOPORT_RANGE_OWNER; 791 802 } … … 821 832 if (RTAvlroIOPortInsert(&pVM->iom.s.CTX_SUFF(pTrees)->IOPortTreeR0, &pRange->Core)) 822 833 { 823 IOM_UNLOCK (pVM);834 IOM_UNLOCK_EXCL(pVM); 824 835 return VINF_SUCCESS; 825 836 } … … 830 841 rc = VERR_IOM_IOPORT_RANGE_CONFLICT; 831 842 } 832 IOM_UNLOCK (pVM);843 IOM_UNLOCK_EXCL(pVM); 833 844 return rc; 834 845 } … … 868 879 } 869 880 870 IOM_LOCK (pVM);881 IOM_LOCK_EXCL(pVM); 871 882 872 883 /* Flush the IO port lookup cache */ … … 889 900 AssertMsgFailed(("Removal of ports in range %#x-%#x rejected because not owner of %#x-%#x (%s)\n", 890 901 PortStart, PortLast, pRange->Core.Key, pRange->Core.KeyLast, pRange->pszDesc)); 891 IOM_UNLOCK (pVM);902 IOM_UNLOCK_EXCL(pVM); 892 903 return VERR_IOM_NOT_IOPORT_RANGE_OWNER; 893 904 } … … 953 964 if (RT_FAILURE(rc2)) 954 965 { 955 IOM_UNLOCK (pVM);966 IOM_UNLOCK_EXCL(pVM); 956 967 return rc2; 957 968 } … … 1036 1047 if (RT_FAILURE(rc2)) 1037 1048 { 1038 IOM_UNLOCK (pVM);1049 IOM_UNLOCK_EXCL(pVM); 1039 1050 return rc2; 1040 1051 } … … 1118 1129 if (RT_FAILURE(rc2)) 1119 1130 { 1120 IOM_UNLOCK (pVM);1131 IOM_UNLOCK_EXCL(pVM); 1121 1132 return rc2; 1122 1133 } … … 1147 1158 1148 1159 /* done */ 1149 IOM_UNLOCK (pVM);1160 IOM_UNLOCK_EXCL(pVM); 1150 1161 return rc; 1151 1162 } … … 1413 1424 * Try register it with PGM and then insert it into the tree. 1414 1425 */ 1415 IOM_LOCK(pVM);1416 iomR3FlushCache(pVM);1417 1426 rc = PGMR3PhysMMIORegister(pVM, GCPhysStart, cbRange, 1418 1427 IOMR3MMIOHandler, pRange, … … 1421 1430 if (RT_SUCCESS(rc)) 1422 1431 { 1432 IOM_LOCK_EXCL(pVM); 1423 1433 if (RTAvlroGCPhysInsert(&pVM->iom.s.pTreesR3->MMIOTree, &pRange->Core)) 1424 1434 { 1425 IOM_UNLOCK(pVM); 1435 iomR3FlushCache(pVM); 1436 IOM_UNLOCK_EXCL(pVM); 1426 1437 return VINF_SUCCESS; 1427 1438 } 1428 1439 1429 1440 /* bail out */ 1430 IOM_UNLOCK (pVM);1441 IOM_UNLOCK_EXCL(pVM); 1431 1442 DBGFR3Info(pVM->pUVM, "mmio", NULL, NULL); 1432 1443 AssertMsgFailed(("This cannot happen!\n")); 1433 1444 rc = VERR_IOM_IOPORT_IPE_3; 1434 1445 } 1435 else1436 IOM_UNLOCK(pVM);1437 1446 1438 1447 MMHyperFree(pVM, pRange); … … 1484 1493 * Find the MMIO range and check that the input matches. 1485 1494 */ 1486 IOM_LOCK (pVM);1495 IOM_LOCK_EXCL(pVM); 1487 1496 PIOMMMIORANGE pRange = iomMmioGetRange(pVM, pVCpu, GCPhysStart); 1488 AssertReturnStmt(pRange, IOM_UNLOCK (pVM), VERR_IOM_MMIO_RANGE_NOT_FOUND);1489 AssertReturnStmt(pRange->pDevInsR3 == pDevIns, IOM_UNLOCK (pVM), VERR_IOM_NOT_MMIO_RANGE_OWNER);1490 AssertReturnStmt(pRange->GCPhys == GCPhysStart, IOM_UNLOCK (pVM), VERR_IOM_INVALID_MMIO_RANGE);1491 AssertReturnStmt(pRange->cb == cbRange, IOM_UNLOCK (pVM), VERR_IOM_INVALID_MMIO_RANGE);1497 AssertReturnStmt(pRange, IOM_UNLOCK_EXCL(pVM), VERR_IOM_MMIO_RANGE_NOT_FOUND); 1498 AssertReturnStmt(pRange->pDevInsR3 == pDevIns, IOM_UNLOCK_EXCL(pVM), VERR_IOM_NOT_MMIO_RANGE_OWNER); 1499 AssertReturnStmt(pRange->GCPhys == GCPhysStart, IOM_UNLOCK_EXCL(pVM), VERR_IOM_INVALID_MMIO_RANGE); 1500 AssertReturnStmt(pRange->cb == cbRange, IOM_UNLOCK_EXCL(pVM), VERR_IOM_INVALID_MMIO_RANGE); 1492 1501 1493 1502 pRange->pvUserRC = pvUser; … … 1496 1505 pRange->pfnFillCallbackRC = pfnFillCallback; 1497 1506 pRange->pDevInsRC = MMHyperCCToRC(pVM, pDevIns); 1498 IOM_UNLOCK (pVM);1507 IOM_UNLOCK_EXCL(pVM); 1499 1508 1500 1509 return VINF_SUCCESS; … … 1543 1552 * Find the MMIO range and check that the input matches. 1544 1553 */ 1545 IOM_LOCK (pVM);1554 IOM_LOCK_EXCL(pVM); 1546 1555 PIOMMMIORANGE pRange = iomMmioGetRange(pVM, pVCpu, GCPhysStart); 1547 AssertReturnStmt(pRange, IOM_UNLOCK (pVM), VERR_IOM_MMIO_RANGE_NOT_FOUND);1548 AssertReturnStmt(pRange->pDevInsR3 == pDevIns, IOM_UNLOCK (pVM), VERR_IOM_NOT_MMIO_RANGE_OWNER);1549 AssertReturnStmt(pRange->GCPhys == GCPhysStart, IOM_UNLOCK (pVM), VERR_IOM_INVALID_MMIO_RANGE);1550 AssertReturnStmt(pRange->cb == cbRange, IOM_UNLOCK (pVM), VERR_IOM_INVALID_MMIO_RANGE);1556 AssertReturnStmt(pRange, IOM_UNLOCK_EXCL(pVM), VERR_IOM_MMIO_RANGE_NOT_FOUND); 1557 AssertReturnStmt(pRange->pDevInsR3 == pDevIns, IOM_UNLOCK_EXCL(pVM), VERR_IOM_NOT_MMIO_RANGE_OWNER); 1558 AssertReturnStmt(pRange->GCPhys == GCPhysStart, IOM_UNLOCK_EXCL(pVM), VERR_IOM_INVALID_MMIO_RANGE); 1559 AssertReturnStmt(pRange->cb == cbRange, IOM_UNLOCK_EXCL(pVM), VERR_IOM_INVALID_MMIO_RANGE); 1551 1560 1552 1561 pRange->pvUserR0 = pvUser; … … 1555 1564 pRange->pfnFillCallbackR0 = pfnFillCallback; 1556 1565 pRange->pDevInsR0 = MMHyperCCToR0(pVM, pDevIns); 1557 IOM_UNLOCK (pVM);1566 IOM_UNLOCK_EXCL(pVM); 1558 1567 1559 1568 return VINF_SUCCESS; … … 1591 1600 PVMCPU pVCpu = VMMGetCpu(pVM); Assert(pVCpu); 1592 1601 1593 IOM_LOCK (pVM);1602 IOM_LOCK_EXCL(pVM); 1594 1603 1595 1604 /* … … 1602 1611 if (!pRange) 1603 1612 { 1604 IOM_UNLOCK (pVM);1613 IOM_UNLOCK_EXCL(pVM); 1605 1614 return VERR_IOM_MMIO_RANGE_NOT_FOUND; 1606 1615 } 1607 1616 AssertMsgReturnStmt(pRange->pDevInsR3 == pDevIns, 1608 1617 ("Not owner! GCPhys=%RGp %RGp LB%#x %s\n", GCPhys, GCPhysStart, cbRange, pRange->pszDesc), 1609 IOM_UNLOCK (pVM),1618 IOM_UNLOCK_EXCL(pVM), 1610 1619 VERR_IOM_NOT_MMIO_RANGE_OWNER); 1611 1620 AssertMsgReturnStmt(pRange->Core.KeyLast <= GCPhysLast, 1612 1621 ("Incomplete R3 range! GCPhys=%RGp %RGp LB%#x %s\n", GCPhys, GCPhysStart, cbRange, pRange->pszDesc), 1613 IOM_UNLOCK (pVM),1622 IOM_UNLOCK_EXCL(pVM), 1614 1623 VERR_IOM_INCOMPLETE_MMIO_RANGE); 1615 1624 … … 1630 1639 Assert(pRange); 1631 1640 Assert(pRange->Core.Key == GCPhys && pRange->Core.KeyLast <= GCPhysLast); 1632 IOM_UNLOCK (pVM); /** @todo r=bird: Why are we leaving the lock here? We don't leave it when registering the range above... */1641 IOM_UNLOCK_EXCL(pVM); /* Lock order fun. */ 1633 1642 1634 1643 /* remove it from PGM */ … … 1636 1645 AssertRC(rc); 1637 1646 1638 IOM_LOCK (pVM);1647 IOM_LOCK_EXCL(pVM); 1639 1648 1640 1649 /* advance and free. */ … … 1648 1657 } 1649 1658 1650 IOM_UNLOCK (pVM);1659 IOM_UNLOCK_EXCL(pVM); 1651 1660 return VINF_SUCCESS; 1652 1661 } -
trunk/src/VBox/VMM/include/IOMInline.h
r45305 r45311 167 167 * @returns NULL if not found (R0/GC), or out of memory (R3). 168 168 * 169 * @param pVM Pointer to the VM. 170 * @param pVCpu Pointer to the virtual CPU structure of the caller. 171 * @param GCPhys Physical address to lookup. 172 * @param pRange The MMIO range. 169 * @param pVM Pointer to the VM. 170 * @param pVCpu Pointer to the virtual CPU structure of the caller. 171 * @param GCPhys Physical address to lookup. 172 * @param pRange The MMIO range. 173 * 174 * @remarks The caller holds the IOM critical section with shared access prior 175 * to calling this method. Upon return, the lock has been released! 176 * This is ugly, but it's a necessary evil since we cannot upgrade read 177 * locks to write locks and the whole purpose here is calling 178 * iomR3MMIOStatsCreate. 173 179 */ 174 180 DECLINLINE(PIOMMMIOSTATS) iomMmioGetStats(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, PIOMMMIORANGE pRange) 175 181 { 176 IOM_LOCK_SHARED_EX(pVM, VINF_SUCCESS);182 Assert(IOM_IS_SHARED_LOCK_OWNER(pVM)); 177 183 178 184 /* For large ranges, we'll put everything on the first byte. */ … … 187 193 # ifdef IN_RING3 188 194 if (!pStats) 189 pStats = iomR3MMIOStatsCreate(pVM, GCPhys, pRange->pszDesc); 195 { 196 IOM_UNLOCK_SHARED(pVM); 197 return iomR3MMIOStatsCreate(pVM, GCPhys, pRange->pszDesc); 198 } 190 199 # endif 191 200 } -
trunk/src/VBox/VMM/include/IOMInternal.h
r45305 r45311 423 423 void iomMmioFreeRange(PVM pVM, PIOMMMIORANGE pRange); 424 424 #ifdef IN_RING3 425 PIOMIOPORTSTATS iomR3IOPortStatsCreate(PVM pVM, RTIOPORT Port, const char *pszDesc);426 425 PIOMMMIOSTATS iomR3MMIOStatsCreate(PVM pVM, RTGCPHYS GCPhys, const char *pszDesc); 427 426 #endif /* IN_RING3 */ … … 436 435 /* IOM locking helpers. */ 437 436 #ifdef IOM_WITH_CRIT_SECT_RW 438 # define IOM_LOCK (a_pVM)PDMCritSectRwEnterExcl(&(a_pVM)->iom.s.CritSect, VERR_SEM_BUSY)439 # define IOM_UNLOCK (a_pVM)do { PDMCritSectRwLeaveExcl(&(a_pVM)->iom.s.CritSect); } while (0)440 # if 1/* for the time being (the lookup caches needs to be in VMCPU) */437 # define IOM_LOCK_EXCL(a_pVM) PDMCritSectRwEnterExcl(&(a_pVM)->iom.s.CritSect, VERR_SEM_BUSY) 438 # define IOM_UNLOCK_EXCL(a_pVM) do { PDMCritSectRwLeaveExcl(&(a_pVM)->iom.s.CritSect); } while (0) 439 # if 0 /* for the time being (the lookup caches needs to be in VMCPU) */ 441 440 # define IOM_LOCK_SHARED_EX(a_pVM, a_rcBusy) PDMCritSectRwEnterExcl(&(a_pVM)->iom.s.CritSect, (a_rcBusy)) 442 441 # define IOM_UNLOCK_SHARED(a_pVM) do { PDMCritSectRwLeaveExcl(&(a_pVM)->iom.s.CritSect); } while (0) … … 449 448 # define IOM_IS_EXCL_LOCK_OWNER(a_pVM) PDMCritSectRwIsWriteOwner(&(a_pVM)->iom.s.CritSect) 450 449 #else 451 # define IOM_LOCK (a_pVM)PDMCritSectEnter(&(a_pVM)->iom.s.CritSect, VERR_SEM_BUSY)452 # define IOM_UNLOCK (a_pVM)do { PDMCritSectLeave(&(a_pVM)->iom.s.CritSect); } while (0)450 # define IOM_LOCK_EXCL(a_pVM) PDMCritSectEnter(&(a_pVM)->iom.s.CritSect, VERR_SEM_BUSY) 451 # define IOM_UNLOCK_EXCL(a_pVM) do { PDMCritSectLeave(&(a_pVM)->iom.s.CritSect); } while (0) 453 452 # define IOM_LOCK_SHARED_EX(a_pVM, a_rcBusy) PDMCritSectEnter(&(a_pVM)->iom.s.CritSect, (a_rcBusy)) 454 453 # define IOM_UNLOCK_SHARED(a_pVM) do { PDMCritSectLeave(&(a_pVM)->iom.s.CritSect); } while (0)
Note:
See TracChangeset
for help on using the changeset viewer.

