- Timestamp:
- Apr 13, 2021 5:50:44 AM (4 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuIntel.h
r88342 r88484 31 31 #define DMAR_PCI_REVISION_ID 0x01 32 32 33 /** Feature/capability flags exposed to the guest (x2APIC Opt Out until we get 34 * regular APIC setup working). */ 35 #define DMAR_ACPI_DMAR_FLAGS (ACPI_DMAR_F_INTR_REMAP | ACPI_DMAR_F_X2APIC_OPT_OUT) 33 /** Feature/capability flags exposed to the guest. */ 34 #define DMAR_ACPI_DMAR_FLAGS ACPI_DMAR_F_INTR_REMAP 36 35 37 36 /** The MMIO base address of the DMAR unit (taken from real hardware). */ -
trunk/src/VBox/Devices/PC/DevACPI.cpp
r88342 r88484 866 866 ACPIDMAR Dmar; 867 867 ACPIDRHD Drhd; 868 /* ACPIDMARDEVSCOPE DevScope; */868 ACPIDMARDEVSCOPE DevScopeIoApic; 869 869 } ACPITBLVTD; 870 870 #endif /* VBOX_WITH_IOMMU_INTEL */ … … 3385 3385 3386 3386 /* DRHD. */ 3387 VtdTable.Drhd.cbLength = sizeof(ACPIDRHD) /* + sizeof(VtdTable.DevScope) */;3387 VtdTable.Drhd.cbLength = sizeof(ACPIDRHD); 3388 3388 VtdTable.Drhd.fFlags = ACPI_DRHD_F_INCLUDE_PCI_ALL; 3389 3389 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 } 3390 3407 3391 3408 /* Finally, compute checksum. */ … … 3538 3555 #ifdef VBOX_WITH_IOMMU_INTEL 3539 3556 if (pThis->fUseIommuIntel) 3540 iIommu = cAddr++; /* IOMMU ( AMD) */3557 iIommu = cAddr++; /* IOMMU (Intel) */ 3541 3558 #endif 3542 3559 … … 3555 3572 Assert(cAddr < RT_ELEMENTS(aGCPhysXsdt)); 3556 3573 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. */ 3559 3576 3560 3577 /* … … 4243 4260 { 4244 4261 /* Query IOMMU AMD address (IOMA). */ 4245 rc = pHlp->pfnCFGMQueryU32 Def(pCfg, "IommuPciAddress", &pThis->u32IommuPciAddress, 0);4262 rc = pHlp->pfnCFGMQueryU32(pCfg, "IommuPciAddress", &pThis->u32IommuPciAddress); 4246 4263 if (RT_FAILURE(rc)) 4247 4264 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"IommuPciAddress\"")); 4248 4265 4249 4266 /* Query southbridge I/O APIC address (required when an AMD IOMMU is configured). */ 4250 rc = pHlp->pfnCFGMQueryU32 Def(pCfg, "SbIoApicPciAddress", &pThis->u32SbIoApicPciAddress, 0);4267 rc = pHlp->pfnCFGMQueryU32(pCfg, "SbIoApicPciAddress", &pThis->u32SbIoApicPciAddress); 4251 4268 if (RT_FAILURE(rc)) 4252 4269 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"SbIoApicAddress\"")); … … 4258 4275 LogRel(("ACPI: Warning! AMD IOMMU assigned the PCI host bridge address.\n")); 4259 4276 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. */ 4261 4278 if (pThis->u32SbIoApicPciAddress != RT_MAKE_U32(VBOX_PCI_FN_SB_IOAPIC, VBOX_PCI_DEV_SB_IOAPIC)) 4262 4279 { 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", 4265 4281 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")); 4266 4283 } 4267 4284 } … … 4277 4294 { 4278 4295 /* Query IOMMU Intel address. */ 4279 rc = pHlp->pfnCFGMQueryU32 Def(pCfg, "IommuPciAddress", &pThis->u32IommuPciAddress, 0);4296 rc = pHlp->pfnCFGMQueryU32(pCfg, "IommuPciAddress", &pThis->u32IommuPciAddress); 4280 4297 if (RT_FAILURE(rc)) 4281 4298 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 } 4282 4312 } 4283 4313 #endif -
trunk/src/VBox/Main/src-client/BusAssignmentManager.cpp
r88333 r88484 255 255 * Intel IOMMU. 256 256 * The VT-d misc, address remapping, system management device is 257 * located at BDF 00:5:0 on real hardware so we mimick the same. 258 * LSI logic remains at 0:20:0. 257 * located at BDF 0:5:0 on real hardware but we use 0:1:0 since that 258 * slot isn't used for anything else. 259 * 260 * While we could place the I/O APIC anywhere, we keep it consistent 261 * with the AMD IOMMU and we assign the LSI Logic controller to 262 * device number 23 (and I/O APIC at device 20). 259 263 */ 260 264 static const DeviceAssignmentRule g_aIch9IommuIntelRules[] = 261 265 { 262 266 /* Intel IOMMU. */ 263 {"iommu-intel", 0, 5, 0, 0}, 267 {"iommu-intel", 0, 1, 0, 0}, 268 /* Intel IOMMU: Reserved for I/O APIC. */ 269 {"sb-ioapic", 0, 20, 0, 0}, 264 270 265 271 /* Storage controller */ 266 {"lsilogic", 0, 2 0, 0, 1},272 {"lsilogic", 0, 23, 0, 1}, 267 273 { NULL, -1, -1, -1, 0} 268 274 }; -
trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
r88343 r88484 831 831 hrc = pMachine->COMGETTER(ParavirtDebug)(strParavirtDebug.asOutParam()); H(); 832 832 833 BOOL fIOAPIC; 834 hrc = biosSettings->COMGETTER(IOAPICEnabled)(&fIOAPIC); H(); 835 833 836 ChipsetType_T chipsetType; 834 837 hrc = pMachine->COMGETTER(ChipsetType)(&chipsetType); H(); … … 870 873 #endif 871 874 } 875 872 876 if (iommuType == IommuType_Intel) 873 877 { … … 877 881 #endif 878 882 } 879 if ( (iommuType == IommuType_AMD || iommuType == IommuType_Intel) 880 && chipsetType != ChipsetType_ICH9) 883 884 if ( iommuType == IommuType_AMD 885 || iommuType == IommuType_Intel) 886 { 887 if (chipsetType != ChipsetType_ICH9) 881 888 return VMR3SetError(pUVM, VERR_INVALID_PARAMETER, RT_SRC_POS, 882 889 N_("IOMMU uses MSIs which requires the ICH9 chipset implementation.")); 890 if (!fIOAPIC) 891 return VMR3SetError(pUVM, VERR_INVALID_PARAMETER, RT_SRC_POS, 892 N_("IOMMU requires an I/O APIC for remapping interrupts.")); 893 } 883 894 #else 884 895 IommuType_T const iommuType = IommuType_None; … … 896 907 hrc = pMachine->COMGETTER(OSTypeId)(osTypeId.asOutParam()); H(); 897 908 LogRel(("Guest OS type: '%s'\n", Utf8Str(osTypeId).c_str())); 898 899 BOOL fIOAPIC;900 hrc = biosSettings->COMGETTER(IOAPICEnabled)(&fIOAPIC); H();901 909 902 910 APICMode_T apicMode; … … 1607 1615 InsertConfigNode(pInst, "Config", &pCfg); 1608 1616 hrc = pBusMgr->assignPCIDevice("iommu-intel", pInst); H(); 1617 1618 /* 1619 * Reserve a specific PCI address for the I/O APIC when using 1620 * an Intel IOMMU. For convenience we use the same address as 1621 * we do on AMD, see @bugref{9967#c13}. 1622 */ 1623 PCIBusAddress PCIAddr = PCIBusAddress(VBOX_PCI_BUS_SB_IOAPIC, VBOX_PCI_DEV_SB_IOAPIC, VBOX_PCI_FN_SB_IOAPIC); 1624 hrc = pBusMgr->assignPCIDevice("sb-ioapic", NULL /* pCfg */, PCIAddr, true /*fGuestAddressRequired*/); H(); 1609 1625 } 1610 1626 } … … 3384 3400 if (pBusMgr->findPCIAddress("sb-ioapic", 0, Address)) 3385 3401 { 3386 uint32_t u32SbIoapicAddress = (Address.miDevice << 16) | Address.miFn;3402 uint32_t const u32SbIoapicAddress = (Address.miDevice << 16) | Address.miFn; 3387 3403 InsertConfigInteger(pCfg, "SbIoApicPciAddress", u32SbIoapicAddress); 3388 3404 } 3389 3405 else 3390 LogRel(("IOMMU: AMD IOMMU is enabled, but southbridge I/O APIC is not assigned a PCI address!\n")); 3406 return VMR3SetError(pUVM, VERR_INVALID_PARAMETER, RT_SRC_POS, 3407 N_("AMD IOMMU is enabled, but the I/O APIC is not assigned a PCI address!")); 3391 3408 } 3392 3409 } … … 3399 3416 InsertConfigInteger(pCfg, "IommuIntelEnabled", true); 3400 3417 InsertConfigInteger(pCfg, "IommuPciAddress", u32IommuAddress); 3418 if (pBusMgr->findPCIAddress("sb-ioapic", 0, Address)) 3419 { 3420 uint32_t const u32SbIoapicAddress = (Address.miDevice << 16) | Address.miFn; 3421 InsertConfigInteger(pCfg, "SbIoApicPciAddress", u32SbIoapicAddress); 3422 } 3423 else 3424 return VMR3SetError(pUVM, VERR_INVALID_PARAMETER, RT_SRC_POS, 3425 N_("Intel IOMMU is enabled, but the I/O APIC is not assigned a PCI address!")); 3401 3426 } 3402 3427 }
Note:
See TracChangeset
for help on using the changeset viewer.