VirtualBox

Ignore:
Timestamp:
Apr 13, 2021 5:50:44 AM (4 years ago)
Author:
vboxsync
Message:

Intel IOMMU: bugref:9967 Main: Use the same I/O APIC PCI address reservation as we do on AMD, as it keeps things simpler than moving PCI devices/slots around again.
Also for now don't opt out of x2APIC (seems Linux VMs are configured with x2APIC by default, so let's try get things working with x2APIC).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/DevACPI.cpp

    r88342 r88484  
    866866    ACPIDMAR            Dmar;
    867867    ACPIDRHD            Drhd;
    868     /* ACPIDMARDEVSCOPE    DevScope; */
     868    ACPIDMARDEVSCOPE    DevScopeIoApic;
    869869} ACPITBLVTD;
    870870#endif  /* VBOX_WITH_IOMMU_INTEL */
     
    33853385
    33863386    /* DRHD. */
    3387     VtdTable.Drhd.cbLength     = sizeof(ACPIDRHD) /* + sizeof(VtdTable.DevScope) */;
     3387    VtdTable.Drhd.cbLength     = sizeof(ACPIDRHD);
    33883388    VtdTable.Drhd.fFlags       = ACPI_DRHD_F_INCLUDE_PCI_ALL;
    33893389    VtdTable.Drhd.uRegBaseAddr = DMAR_MMIO_BASE_PHYSADDR;
     3390
     3391    /* Device Scopes: I/O APIC. */
     3392    if (pThis->u8UseIOApic)
     3393    {
     3394        uint8_t const uIoApicBus = 0;
     3395        uint8_t const uIoApicDev = RT_HI_U16(pThis->u32SbIoApicPciAddress);
     3396        uint8_t const uIoApicFn  = RT_LO_U16(pThis->u32SbIoApicPciAddress);
     3397
     3398        VtdTable.DevScopeIoApic.uType          = ACPIDMARDEVSCOPE_TYPE_IOAPIC;
     3399        VtdTable.DevScopeIoApic.cbLength       = sizeof(ACPIDMARDEVSCOPE);
     3400        VtdTable.DevScopeIoApic.idEnum         = pThis->cCpus;   /* The I/O APIC ID, see u8IOApicId in acpiR3SetupMadt(). */
     3401        VtdTable.DevScopeIoApic.uStartBusNum   = uIoApicBus;
     3402        VtdTable.DevScopeIoApic.Path.uDevice   = uIoApicDev;
     3403        VtdTable.DevScopeIoApic.Path.uFunction = uIoApicFn;
     3404
     3405        VtdTable.Drhd.cbLength += sizeof(VtdTable.DevScopeIoApic);
     3406    }
    33903407
    33913408    /* Finally, compute checksum. */
     
    35383555#ifdef VBOX_WITH_IOMMU_INTEL
    35393556    if (pThis->fUseIommuIntel)
    3540         iIommu = cAddr++;      /* IOMMU (AMD) */
     3557        iIommu = cAddr++;      /* IOMMU (Intel) */
    35413558#endif
    35423559
     
    35553572    Assert(cAddr < RT_ELEMENTS(aGCPhysXsdt));
    35563573
    3557     cbRsdt += cAddr*sizeof(uint32_t);  /* each entry: 32 bits phys. address. */
    3558     cbXsdt += cAddr*sizeof(uint64_t);  /* each entry: 64 bits phys. address. */
     3574    cbRsdt += cAddr * sizeof(uint32_t);  /* each entry: 32 bits phys. address. */
     3575    cbXsdt += cAddr * sizeof(uint64_t);  /* each entry: 64 bits phys. address. */
    35593576
    35603577    /*
     
    42434260    {
    42444261        /* Query IOMMU AMD address (IOMA). */
    4245         rc = pHlp->pfnCFGMQueryU32Def(pCfg, "IommuPciAddress", &pThis->u32IommuPciAddress, 0);
     4262        rc = pHlp->pfnCFGMQueryU32(pCfg, "IommuPciAddress", &pThis->u32IommuPciAddress);
    42464263        if (RT_FAILURE(rc))
    42474264            return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"IommuPciAddress\""));
    42484265
    42494266        /* Query southbridge I/O APIC address (required when an AMD IOMMU is configured). */
    4250         rc = pHlp->pfnCFGMQueryU32Def(pCfg, "SbIoApicPciAddress", &pThis->u32SbIoApicPciAddress, 0);
     4267        rc = pHlp->pfnCFGMQueryU32(pCfg, "SbIoApicPciAddress", &pThis->u32SbIoApicPciAddress);
    42514268        if (RT_FAILURE(rc))
    42524269            return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"SbIoApicAddress\""));
     
    42584275            LogRel(("ACPI: Warning! AMD IOMMU assigned the PCI host bridge address.\n"));
    42594276
    4260         /* Warn if the SB IOAPIC is not at the required address if an AMD IOMMU is configured. */
     4277        /* Warn if the IOAPIC is not at the expected address. */
    42614278        if (pThis->u32SbIoApicPciAddress != RT_MAKE_U32(VBOX_PCI_FN_SB_IOAPIC, VBOX_PCI_DEV_SB_IOAPIC))
    42624279        {
    4263             /** @todo Maybe make this a VM startup failure later. */
    4264             LogRel(("ACPI: Warning! Southbridge I/O APIC not at %#x:%#x:%#x when an AMD IOMMU is present.\n",
     4280            LogRel(("ACPI: Southbridge I/O APIC not at %#x:%#x:%#x when an AMD IOMMU is present.\n",
    42654281                    VBOX_PCI_BUS_SB_IOAPIC, VBOX_PCI_DEV_SB_IOAPIC, VBOX_PCI_FN_SB_IOAPIC));
     4282            return PDMDEV_SET_ERROR(pDevIns, VERR_MISMATCH, N_("Configuration error: \"SbIoApicAddress\" mismatch"));
    42664283        }
    42674284    }
     
    42774294    {
    42784295        /* Query IOMMU Intel address. */
    4279         rc = pHlp->pfnCFGMQueryU32Def(pCfg, "IommuPciAddress", &pThis->u32IommuPciAddress, 0);
     4296        rc = pHlp->pfnCFGMQueryU32(pCfg, "IommuPciAddress", &pThis->u32IommuPciAddress);
    42804297        if (RT_FAILURE(rc))
    42814298            return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"IommuPciAddress\""));
     4299
     4300        /* Get the reserved I/O APIC PCI address (required when an Intel IOMMU is configured). */
     4301        rc = pHlp->pfnCFGMQueryU32(pCfg, "SbIoApicPciAddress", &pThis->u32SbIoApicPciAddress);
     4302        if (RT_FAILURE(rc))
     4303            return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"SbIoApicAddress\""));
     4304
     4305        /* Warn if the IOAPIC is not at the expected address. */
     4306        if (pThis->u32SbIoApicPciAddress != RT_MAKE_U32(VBOX_PCI_FN_SB_IOAPIC, VBOX_PCI_DEV_SB_IOAPIC))
     4307        {
     4308            LogRel(("ACPI: Southbridge I/O APIC not at %#x:%#x:%#x when an Intel IOMMU is present.\n",
     4309                    VBOX_PCI_BUS_SB_IOAPIC, VBOX_PCI_DEV_SB_IOAPIC, VBOX_PCI_FN_SB_IOAPIC));
     4310            return PDMDEV_SET_ERROR(pDevIns, VERR_MISMATCH, N_("Configuration error: \"SbIoApicAddress\" mismatch"));
     4311        }
    42824312    }
    42834313#endif
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