VirtualBox

Changeset 86145 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Sep 17, 2020 10:31:47 AM (4 years ago)
Author:
vboxsync
Message:

AMD IOMMU: bugref:9654 Fix unmapping MMIO region when the region address changes, resetting IOMMU base address register to 0.
Also fix setting the PCI Bus master bit on VM reset. The VM now seems to behave identically on VM reset wrt to the IOMMU.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp

    r86132 r86145  
    926926    iommuAmdCmdThreadWakeUpIfNeeded(pDevIns);
    927927
    928     LogFlowFunc(("Set CmdBufHeadPtr to %#RX32\n", offBuf));
     928    Log5Func(("Set CmdBufHeadPtr to %#RX32\n", offBuf));
    929929    return VINF_SUCCESS;
    930930}
     
    967967    iommuAmdCmdThreadWakeUpIfNeeded(pDevIns);
    968968
    969     LogFlowFunc(("Set CmdBufTailPtr to %#RX32\n", offBuf));
     969    Log5Func(("Set CmdBufTailPtr to %#RX32\n", offBuf));
    970970    return VINF_SUCCESS;
    971971}
     
    11041104    Assert(!(off & (cb - 1)));
    11051105
    1106     LogFlowFunc(("off=%#x cb=%u uValue=%#RX64\n", off, cb, uValue));
     1106    Log5Func(("off=%#x cb=%u uValue=%#RX64\n", off, cb, uValue));
    11071107
    11081108    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     
    12511251    PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev);
    12521252
    1253     LogFlowFunc(("off=%#x\n", off));
     1253    Log5Func(("off=%#x\n", off));
    12541254
    12551255    /** @todo IOMMU: fine-grained locking? */
     
    14101410static void iommuAmdRaiseMsiInterrupt(PPDMDEVINS pDevIns)
    14111411{
     1412    LogFlowFunc(("\n"));
    14121413    if (iommuAmdIsMsiEnabled(pDevIns))
     1414    {
     1415        LogFunc(("Raising MSI\n"));
    14131416        PDMDevHlpPCISetIrq(pDevIns, 0, PDM_IRQ_LEVEL_HIGH);
     1417    }
    14141418}
    14151419
     
    30423046                        {
    30433047                            Assert(EvtError.n.u4EvtCode == IOMMU_EVT_COMMAND_HW_ERROR);
     3048                            LogFunc(("Raising command hardware error. Cmd=%#x -> COMMAND_HW_ERROR\n", Cmd.n.u4Opcode));
    30443049                            iommuAmdRaiseCmdHwErrorEvent(pDevIns, (PCEVT_CMD_HW_ERR_T)&EvtError);
    30453050                        }
     
    30493054                else
    30503055                {
     3056                    LogFunc(("Failed to read command at %#RGp. rc=%Rrc -> COMMAND_HW_ERROR\n", GCPhysCmd, rc));
    30513057                    EVT_CMD_HW_ERR_T EvtCmdHwErr;
    30523058                    iommuAmdInitCmdHwErrorEvent(GCPhysCmd, &EvtCmdHwErr);
     
    30893095    /** @todo IOMMU: PCI config read stat counter. */
    30903096    VBOXSTRICTRC rcStrict = PDMDevHlpPCIConfigRead(pDevIns, pPciDev, uAddress, cb, pu32Value);
    3091     Log3Func(("Reading PCI config register %#x (cb=%u) -> %#x %Rrc\n", uAddress, cb, *pu32Value,
    3092               VBOXSTRICTRC_VAL(rcStrict)));
     3097    Log3Func(("uAddress=%#x (cb=%u) -> %#x. rc=%Rrc\n", uAddress, cb, *pu32Value, VBOXSTRICTRC_VAL(rcStrict)));
    30933098    return rcStrict;
    30943099}
     
    31223127    IOMMU_LOCK(pDevIns);
    31233128
    3124     VBOXSTRICTRC rcStrict = VERR_INVALID_FUNCTION;
     3129    VBOXSTRICTRC rcStrict = VERR_IOMMU_IPE_3;
    31253130    switch (uAddress)
    31263131    {
     
    31373142            if (pThis->IommuBar.n.u1Enable)
    31383143            {
    3139                 Assert(pThis->hMmio != NIL_IOMMMIOHANDLE);
    3140                 Assert(PDMDevHlpMmioGetMappingAddress(pDevIns, pThis->hMmio) == NIL_RTGCPHYS);
     3144                Assert(pThis->hMmio != NIL_IOMMMIOHANDLE);  /* Paranoia. Ensure we have a valid IOM MMIO handle. */
    31413145                Assert(!pThis->ExtFeat.n.u1PerfCounterSup); /* Base is 16K aligned when performance counters aren't supported. */
    3142                 RTGCPHYS const GCPhysMmioBase = RT_MAKE_U64(pThis->IommuBar.au32[0] & 0xffffc000, pThis->IommuBar.au32[1]);
     3146                RTGCPHYS const GCPhysMmioBase     = RT_MAKE_U64(pThis->IommuBar.au32[0] & 0xffffc000, pThis->IommuBar.au32[1]);
     3147                RTGCPHYS const GCPhysMmioBasePrev = PDMDevHlpMmioGetMappingAddress(pDevIns, pThis->hMmio);
     3148
     3149                /* If the MMIO region is already mapped at the specified address, we're done. */
     3150                Assert(GCPhysMmioBase != NIL_RTGCPHYS);
     3151                if (GCPhysMmioBasePrev == GCPhysMmioBase)
     3152                {
     3153                    rcStrict = VINF_SUCCESS;
     3154                    break;
     3155                }
     3156
     3157                /* Unmap the previous MMIO region (which is at a different address). */
     3158                if (GCPhysMmioBasePrev != NIL_RTGCPHYS)
     3159                {
     3160                    LogFlowFunc(("Unmapping previous MMIO region at %#RGp\n", GCPhysMmioBasePrev));
     3161                    rcStrict = PDMDevHlpMmioUnmap(pDevIns, pThis->hMmio);
     3162                    if (RT_FAILURE(rcStrict))
     3163                    {
     3164                        LogFunc(("Failed to unmap MMIO region at %#RGp. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     3165                        break;
     3166                    }
     3167                }
     3168
     3169                /* Map the newly specified MMIO region. */
     3170                LogFlowFunc(("Mapping MMIO region at %#RGp\n", GCPhysMmioBase));
    31433171                rcStrict = PDMDevHlpMmioMap(pDevIns, pThis->hMmio, GCPhysMmioBase);
    31443172                if (RT_FAILURE(rcStrict))
    3145                     LogFunc(("Failed to map IOMMU MMIO region at %#RGp. rc=%Rrc\n", GCPhysMmioBase, rcStrict));
     3173                {
     3174                    LogFunc(("Failed to unmap MMIO region at %#RGp. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     3175                    break;
     3176                }
    31463177            }
     3178            else
     3179                rcStrict = VINF_SUCCESS;
    31473180            break;
    31483181        }
     
    31743207    IOMMU_UNLOCK(pDevIns);
    31753208
    3176     Log3Func(("PCI config write: %#x -> To %#x (%u) %Rrc\n", u32Value, uAddress, cb, VBOXSTRICTRC_VAL(rcStrict)));
     3209    Log3Func(("uAddress=%#x (cb=%u) with %#x. rc=%Rrc\n", uAddress, cb, u32Value, VBOXSTRICTRC_VAL(rcStrict)));
    31773210    return rcStrict;
    31783211}
     
    39503983    PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev);
    39513984
     3985    IOMMU_LOCK_NORET(pDevIns);
     3986
    39523987    LogFlowFunc(("\n"));
    39533988
     
    40154050    pThis->PprLogBOverflowEarly.u64  = 0;
    40164051
     4052    pThis->IommuBar.u64              = 0;
    40174053    PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_BASE_ADDR_REG_LO, 0);
    40184054    PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_BASE_ADDR_REG_HI, 0);
    40194055
    4020     /*
    4021      * I ASSUME all MMIO regions mapped by a PDM device are automatically unmapped
    4022      * on VM reset. If not, we need to enable the following...
    4023      */
    4024 #if 0
    4025     /* Unmap the MMIO region on reset if it has been mapped previously. */
    4026     Assert(pThis->hMmio != NIL_IOMMMIOHANDLE);
    4027     if (PDMDevHlpMmioGetMappingAddress(pDevIns, pThis->hMmio) != NIL_RTGCPHYS)
    4028         PDMDevHlpMmioUnmap(pDevIns, pThis->hMmio);
    4029 #endif
     4056    PDMPciDevSetCommand(pPciDev, VBOX_PCI_COMMAND_MASTER);
     4057
     4058    IOMMU_UNLOCK(pDevIns);
    40304059}
    40314060
     
    40954124    PDMPciDevSetVendorId(pPciDev,          IOMMU_PCI_VENDOR_ID);       /* AMD */
    40964125    PDMPciDevSetDeviceId(pPciDev,          IOMMU_PCI_DEVICE_ID);       /* VirtualBox IOMMU device */
    4097     PDMPciDevSetCommand(pPciDev,           VBOX_PCI_COMMAND_MASTER);   /* Enable bus master (as we write to main memory) */
     4126    PDMPciDevSetCommand(pPciDev,           VBOX_PCI_COMMAND_MASTER);   /* Enable bus master (as we directly access main memory) */
    40984127    PDMPciDevSetStatus(pPciDev,            VBOX_PCI_STATUS_CAP_LIST);  /* Capability list supported */
    40994128    PDMPciDevSetRevisionId(pPciDev,        IOMMU_PCI_REVISION_ID);     /* VirtualBox specific device implementation revision */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette