VirtualBox

Changeset 88281 in vbox for trunk/src/VBox/Devices/PC


Ignore:
Timestamp:
Mar 24, 2021 3:03:53 PM (4 years ago)
Author:
vboxsync
Message:

Intel IOMMU: bugref:9967 ACPI: Adjustments for Intel IOMMU (DMAR). WIP.

File:
1 edited

Legend:

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

    r87773 r88281  
    3939#ifdef VBOX_WITH_IOMMU_AMD
    4040# include <VBox/iommu-amd.h>
     41#endif
     42#ifdef VBOX_WITH_IOMMU_INTEL
     43# include <VBox/iommu-intel.h>
    4144#endif
    4245
     
    372375    /** if the 64-bit prefetchable memory window is shown to the guest */
    373376    bool                fPciPref64Enabled;
    374     /** If the IOMMU device should be enabled */
    375     bool                fUseIommu;
     377    /** If the IOMMU (AMD) device should be enabled */
     378    bool                fUseIommuAmd;
     379    /** If the IOMMU (Intel) device should be enabled */
     380    bool                fUseIommuIntel;
     381    /** Padding. */
     382    bool                afPadding0[3];
    376383    /** Primary NIC PCI address. */
    377384    uint32_t            u32NicPciAddress;
     
    829836AssertCompileMemberAlignment(ACPITBLIOMMU, IvhdType11Start, 4);
    830837AssertCompileMemberAlignment(ACPITBLIOMMU, IvhdType11End, 4);
    831 #endif
     838#endif  /* VBOX_WITH_IOMMU_AMD */
     839
     840#ifdef VBOX_WITH_IOMMU_INTEL
     841/** Intel IOMMU: DMAR (DMA Remapping) Reporting Structure.
     842 *  In accordance with the AMD spec. */
     843typedef struct ACPIDMAR
     844{
     845    ACPITBLHEADER       Hdr;
     846    /** Host-address Width (N+1 physical bits addressable). */
     847    uint8_t             uHostAddrWidth;
     848    /** Flags, see ACPI_DMAR_F_XXX. */
     849    uint8_t             fFlags;
     850    /** Reserved. */
     851    uint8_t             abRsvd[10];
     852    /* Remapping Structures[] follows. */
     853} ACPIDMAR;
     854AssertCompileSize(ACPIDMAR, 48);
     855AssertCompileMemberOffset(ACPIDMAR, uHostAddrWidth, 36);
     856AssertCompileMemberOffset(ACPIDMAR, fFlags, 37);
     857
     858/**
     859 * Intel VT-d: The ACPI table.
     860 */
     861typedef struct ACPITBLVTD
     862{
     863    ACPIDMAR            Dmar;
     864    ACPIDRHD            Drhd;
     865} ACPITBLDMAR;
     866#endif  /* VBOX_WITH_IOMMU_INTEL */
    832867
    833868/** MCFG Descriptor Structure */
     
    33163351    Ivrs.IvhdType11Hpet   = Ivrs.IvhdType10Hpet;
    33173352
    3318     /* Finally, Compute checksum. */
     3353    /* Finally, compute checksum. */
    33193354    Ivrs.Hdr.header.u8Checksum = acpiR3Checksum(&Ivrs, sizeof(Ivrs));
    33203355
    33213356    /* Plant the ACPI table. */
    33223357    acpiR3PhysCopy(pDevIns, addr, (const uint8_t *)&Ivrs, sizeof(Ivrs));
     3358}
     3359#endif
     3360
     3361
     3362#ifdef VBOX_WITH_IOMMU_INTEL
     3363/**
     3364 * Plant the Intel IOMMU (VT-d) descriptor.
     3365 */
     3366static void acpiR3SetupIommuIntel(PPDMDEVINS pDevIns, PACPISTATE pThis, RTGCPHYS32 addr)
     3367{
     3368    ACPITBLVTD VtdTable;
     3369    RT_ZERO(VtdTable);
     3370
     3371    /* VT-d/DMAR header. */
     3372    acpiR3PrepareHeader(pThis, &VtdTable.Dmar.Hdr, "DMAR", sizeof(ACPITBLVTD), ACPI_DMAR_REVISION);
     3373
     3374    /** @todo Populate rest of DMAR table. */
     3375
     3376    /* Finally, compute checksum. */
     3377    VtdTable.Dmar.Hdr.u8Checksum = acpiR3Checksum(&VtdTable, sizeof(VtdTable));
     3378
     3379    /* Plant the ACPI table. */
     3380    acpiR3PhysCopy(pDevIns, addr, (const uint8_t *)&VtdTable, sizeof(VtdTable));
    33233381}
    33243382#endif
     
    34243482    RTGCPHYS32 GCPhysCur, GCPhysRsdt, GCPhysXsdt, GCPhysFadtAcpi1, GCPhysFadtAcpi2, GCPhysFacs, GCPhysDsdt;
    34253483    RTGCPHYS32 GCPhysHpet = 0;
    3426 #ifdef VBOX_WITH_IOMMU_AMD
    3427     RTGCPHYS32 GCPhysIommuAmd = 0;
     3484#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
     3485    RTGCPHYS32 GCPhysIommu = 0;
    34283486#endif
    34293487    RTGCPHYS32 GCPhysApic = 0;
     
    34323490    RTGCPHYS32 aGCPhysCust[MAX_CUST_TABLES] = {0};
    34333491    uint32_t   addend = 0;
    3434 #ifdef VBOX_WITH_IOMMU_AMD
     3492#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
    34353493    RTGCPHYS32 aGCPhysRsdt[8 + MAX_CUST_TABLES];
    34363494    RTGCPHYS32 aGCPhysXsdt[8 + MAX_CUST_TABLES];
     
    34423500    uint32_t   iMadt  = 0;
    34433501    uint32_t   iHpet  = 0;
    3444 #ifdef VBOX_WITH_IOMMU_AMD
    3445     uint32_t   iIommuAmd = 0;
     3502#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
     3503    uint32_t   iIommu = 0;
    34463504#endif
    34473505    uint32_t   iSsdt  = 0;
     
    34593517
    34603518#ifdef VBOX_WITH_IOMMU_AMD
    3461     if (pThis->fUseIommu)
    3462         iIommuAmd = cAddr++;    /* IOMMU (AMD) */
     3519    if (pThis->fUseIommuAmd)
     3520        iIommu = cAddr++;      /* IOMMU (AMD) */
     3521#endif
     3522
     3523#ifdef VBOX_WITH_IOMMU_INTEL
     3524    if (pThis->fUseIommuIntel)
     3525        iIommu = cAddr++;      /* IOMMU (AMD) */
    34633526#endif
    34643527
     
    35383601    }
    35393602#ifdef VBOX_WITH_IOMMU_AMD
    3540     if (pThis->fUseIommu)
    3541     {
    3542         GCPhysIommuAmd = GCPhysCur;
     3603    if (pThis->fUseIommuAmd)
     3604    {
     3605        GCPhysIommu = GCPhysCur;
    35433606        GCPhysCur = RT_ALIGN_32(GCPhysCur + sizeof(ACPITBLIOMMU), 16);
    35443607    }
    35453608#endif
     3609#ifdef VBOX_WITH_IOMMU_INTEL
     3610    if (pThis->fUseIommuIntel)
     3611    {
     3612        GCPhysIommu = GCPhysCur;
     3613        GCPhysCur = RT_ALIGN_32(GCPhysCur + sizeof(ACPITBLVTD), 16);
     3614    }
     3615#endif
     3616
    35463617    if (pThis->fUseMcfg)
    35473618    {
     
    36173688    }
    36183689#ifdef VBOX_WITH_IOMMU_AMD
    3619     if (pThis->fUseIommu)
    3620     {
    3621         acpiR3SetupIommuAmd(pDevIns, pThis, GCPhysIommuAmd + addend);
    3622         aGCPhysRsdt[iIommuAmd] = GCPhysIommuAmd + addend;
    3623         aGCPhysXsdt[iIommuAmd] = GCPhysIommuAmd + addend;
     3690    if (pThis->fUseIommuAmd)
     3691    {
     3692        acpiR3SetupIommuAmd(pDevIns, pThis, GCPhysIommu + addend);
     3693        aGCPhysRsdt[iIommu] = GCPhysIommu + addend;
     3694        aGCPhysXsdt[iIommu] = GCPhysIommu + addend;
     3695    }
     3696#endif
     3697#ifdef VBOX_WITH_IOMMU_INTEL
     3698    if (pThis->fUseIommuIntel)
     3699    {
     3700        acpiR3SetupIommuIntel(pDevIns, pThis, GCPhysIommu + addend);
     3701        aGCPhysRsdt[iIommu] = GCPhysIommu + addend;
     3702        aGCPhysXsdt[iIommu] = GCPhysIommu + addend;
    36243703    }
    36253704#endif
     
    41404219
    41414220#ifdef VBOX_WITH_IOMMU_AMD
    4142     /* Query whether an IOMMU AMD is enabled. */
    4143     rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "IommuAmdEnabled", &pThis->fUseIommu, false);
     4221    /* Query whether an IOMMU (AMD) is enabled. */
     4222    rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "IommuAmdEnabled", &pThis->fUseIommuAmd, false);
    41444223    if (RT_FAILURE(rc))
    4145         return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"IommuEnabled\""));
    4146 
    4147     if (pThis->fUseIommu)
     4224        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"IommuAmdEnabled\""));
     4225
     4226    if (pThis->fUseIommuAmd)
    41484227    {
    41494228        /* Query IOMMU AMD address (IOMA). */
     
    41724251    }
    41734252#endif
     4253
     4254#ifdef VBOX_WITH_IOMMU_INTEL
     4255    /* Query whether an IOMMU (Intel) is enabled. */
     4256    rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "IommuIntelEnabled", &pThis->fUseIommuIntel, false);
     4257    if (RT_FAILURE(rc))
     4258        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to read \"IommuIntelEnabled\""));
     4259#endif
     4260
     4261    /* Don't even think about enabling an Intel and an AMD IOMMU at the same time! */
     4262    if (   pThis->fUseIommuAmd
     4263        && pThis->fUseIommuIntel)
     4264        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Cannot enable Intel and AMD IOMMU simultaneously!"));
    41744265
    41754266    /* Try to attach the other CPUs */
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