VirtualBox

Changeset 85007 in vbox


Ignore:
Timestamp:
Jun 30, 2020 5:19:25 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
138905
Message:

AMD IOMMU: bugref:9654 PDM, Main: Changes for southbridge I/O APIC and related PCI address assignment.

Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/pci.h

    r84826 r85007  
    475475#define PCIBDF_MAKE(a_uBus, a_uDevFn)   (((a_uBus) << VBOX_PCI_BUS_SHIFT) | (a_uDevFn))
    476476
     477/** Southbridge I/O APIC (w/ AMD IOMMU): Bus. */
     478#define VBOX_PCI_BUS_SB_IOAPIC      0
     479/** Southbridge I/O APIC (w/ AMD IOMMU): Device. */
     480#define VBOX_PCI_DEV_SB_IOAPIC      0x14
     481/** Southbridge I/O APIC (w/ AMD IOMMU): Function. */
     482#define VBOX_PCI_FN_SB_IOAPIC       0
     483/** PCI BDF (hardcoded by linux guests) reserved for the SB I/O APIC when using VMs
     484 *  with an AMD IOMMU. */
     485#define VBOX_PCI_BDF_SB_IOAPIC      PCIBDF_MAKE(VBOX_PCI_BUS_SB_IOAPIC, \
     486                                                VBOX_PCI_DEVFN_MAKE(VBOX_PCI_DEV_SB_IOAPIC, VBOX_PCI_FN_SB_IOAPIC))
    477487
    478488#if defined(__cplusplus) && defined(IN_RING3)
  • trunk/include/VBox/vmm/pdmdev.h

    r84826 r85007  
    496496/** PCI bus brigde. */
    497497#define PDM_DEVREG_CLASS_BUS_PCI                RT_BIT(2)
    498 /** ISA bus brigde. */
    499 #define PDM_DEVREG_CLASS_BUS_ISA                RT_BIT(3)
     498/** PCI built-in device (e.g. PCI root complex devices). */
     499#define PDM_DEVREG_CLASS_PCI_BUILTIN            RT_BIT(3)
    500500/** Input device (mouse, keyboard, joystick, HID, ...). */
    501501#define PDM_DEVREG_CLASS_INPUT                  RT_BIT(4)
  • trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp

    r84858 r85007  
    58685868static DECLCALLBACK(int) iommuAmdR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
    58695869{
    5870     NOREF(iInstance);
    5871 
    58725870    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    5873     PIOMMU          pThis   = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    5874     PIOMMUCC        pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PIOMMUCC);
    5875     PCPDMDEVHLPR3   pHlp    = pDevIns->pHlpR3;
    5876     int             rc;
     5871    RT_NOREF2(iInstance, pCfg);
    58775872    LogFlowFunc(("\n"));
    58785873
     5874    PIOMMU   pThis   = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     5875    PIOMMUCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PIOMMUCC);
    58795876    pThisCC->pDevInsR3 = pDevIns;
    5880 
    5881     /*
    5882      * Validate and read the configuration.
    5883      */
    5884     PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "Device|Function", "");
    5885 
    5886     uint8_t uPciDevice;
    5887     rc = pHlp->pfnCFGMQueryU8Def(pCfg, "Device", &uPciDevice, 0);
    5888     if (RT_FAILURE(rc))
    5889         return PDMDEV_SET_ERROR(pDevIns, rc, N_("IOMMU: Failed to query \"Device\""));
    5890 
    5891     uint8_t uPciFunction;
    5892     rc = pHlp->pfnCFGMQueryU8Def(pCfg, "Function", &uPciFunction, 2);
    5893     if (RT_FAILURE(rc))
    5894         return PDMDEV_SET_ERROR(pDevIns, rc, N_("IOMMU: Failed to query \"Function\""));
    58955877
    58965878    /*
     
    59045886    IommuReg.pfnMsiRemap = iommuAmdDeviceMsiRemap;
    59055887    IommuReg.u32TheEnd   = PDM_IOMMUREGCC_VERSION;
    5906     rc = PDMDevHlpIommuRegister(pDevIns, &IommuReg, &pThisCC->CTX_SUFF(pIommuHlp), &pThis->idxIommu);
     5888    int rc = PDMDevHlpIommuRegister(pDevIns, &IommuReg, &pThisCC->CTX_SUFF(pIommuHlp), &pThis->idxIommu);
    59075889    if (RT_FAILURE(rc))
    59085890        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to register ourselves as an IOMMU device"));
     
    60075989     * Register the PCI function with PDM.
    60085990     */
    6009     rc = PDMDevHlpPCIRegisterEx(pDevIns, pPciDev, 0 /* fFlags */, uPciDevice, uPciFunction, "amd-iommu");
     5991    rc = PDMDevHlpPCIRegister(pDevIns, pPciDev);
    60105992    AssertLogRelRCReturn(rc, rc);
    60115993
     
    61606142    /* .szName = */                 "iommu-amd",
    61616143    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RZ | PDM_DEVREG_FLAGS_NEW_STYLE,
    6162     /* .fClass = */                 PDM_DEVREG_CLASS_BUS_ISA,   /* Instantiate after PDM_DEVREG_CLASS_BUS_PCI */
     6144    /* .fClass = */                 PDM_DEVREG_CLASS_PCI_BUILTIN,
    61636145    /* .cMaxInstances = */          ~0U,
    61646146    /* .uSharedVersion = */         42,
  • trunk/src/VBox/Devices/Bus/DevPCI.cpp

    r84826 r85007  
    14321432    /* .szName = */                 "pci",
    14331433    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RZ | PDM_DEVREG_FLAGS_NEW_STYLE,
    1434     /* .fClass = */                 PDM_DEVREG_CLASS_BUS_PCI | PDM_DEVREG_CLASS_BUS_ISA,
     1434    /* .fClass = */                 PDM_DEVREG_CLASS_BUS_PCI,
    14351435    /* .cMaxInstances = */          1,
    14361436    /* .uSharedVersion = */         42,
  • trunk/src/VBox/Devices/Bus/DevPciIch9.cpp

    r84826 r85007  
    38663866    /* .szName = */                 "ich9pci",
    38673867    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RZ | PDM_DEVREG_FLAGS_NEW_STYLE,
    3868     /* .fClass = */                 PDM_DEVREG_CLASS_BUS_PCI | PDM_DEVREG_CLASS_BUS_ISA,
     3868    /* .fClass = */                 PDM_DEVREG_CLASS_BUS_PCI,
    38693869    /* .cMaxInstances = */          1,
    38703870    /* .uSharedVersion = */         42,
  • trunk/src/VBox/Devices/PC/DevIoApic.cpp

    r84868 r85007  
    2424#include <VBox/vmm/hm.h>
    2525#include <VBox/msi.h>
     26#include <Vbox/pci.h>
    2627#include <VBox/vmm/pdmdev.h>
    2728
     
    165166#define IOAPIC_DIRECT_OFF_DATA                  0x10
    166167#define IOAPIC_DIRECT_OFF_EOI                   0x40    /* Newer I/O APIC only. */
    167 
    168 /** The I/O APIC's Bus:Device:Function. */
    169 #define IOAPIC_BUS_DEV_FN                       NIL_PCIBDF
    170168
    171169/* Use PDM critsect for now for I/O APIC locking, see @bugref{8245#c121}. */
     
    657655        uint32_t const uPinMask = UINT32_C(1) << idxRte;
    658656        if (pThis->uIrr & uPinMask)
    659             ioapicSignalIntrForRte(pDevIns, pThis, pThisCC, IOAPIC_BUS_DEV_FN, idxRte);
     657            ioapicSignalIntrForRte(pDevIns, pThis, pThisCC, VBOX_PCI_BDF_SB_IOAPIC, idxRte);
    660658
    661659        IOAPIC_UNLOCK(pDevIns, pThis, pThisCC);
     
    772770                uint32_t const uPinMask = UINT32_C(1) << idxRte;
    773771                if (pThis->uIrr & uPinMask)
    774                     ioapicSignalIntrForRte(pDevIns, pThis, pThisCC, IOAPIC_BUS_DEV_FN, idxRte);
     772                    ioapicSignalIntrForRte(pDevIns, pThis, pThisCC, VBOX_PCI_BDF_SB_IOAPIC, idxRte);
    775773            }
    776774        }
  • trunk/src/VBox/Main/Makefile.kmk

    r84618 r85007  
    878878        $(if $(VBOX_WITH_DRAG_AND_DROP_GH),VBOX_WITH_DRAG_AND_DROP_GH,) \
    879879        $(if $(VBOX_WITH_USB),VBOX_WITH_USB,) \
    880         $(if $(VBOX_WITH_VRDEAUTH_IN_VBOXSVC),VBOX_WITH_VRDEAUTH_IN_VBOXSVC,)
     880        $(if $(VBOX_WITH_VRDEAUTH_IN_VBOXSVC),VBOX_WITH_VRDEAUTH_IN_VBOXSVC,) \
     881        $(if $(VBOX_WITH_IOMMU_AMD),VBOX_WITH_IOMMU_AMD,)
    881882ifdef VBOX_WITH_NETSHAPER
    882883 VBoxC_DEFS += VBOX_WITH_NETSHAPER
  • trunk/src/VBox/Main/include/BusAssignmentManager.h

    r82968 r85007  
    4747    };
    4848
    49     static BusAssignmentManager *createInstance(ChipsetType_T chipsetType);
     49    static BusAssignmentManager *createInstance(ChipsetType_T chipsetType, bool fIommu);
    5050    virtual void AddRef();
    5151    virtual void Release();
  • trunk/src/VBox/Main/src-client/BusAssignmentManager.cpp

    r82968 r85007  
    6868
    6969    /* Storage controllers */
    70     {"lsilogic",      0, 20, 0,  1},
    7170    {"buslogic",      0, 21, 0,  1},
    7271    {"lsilogicsas",   0, 22, 0,  1},
     
    111110    {"piix3ide",      0,  1,  1, 0},
    112111    {"ahci",          0, 13,  0, 1},
     112    {"lsilogic",      0, 20,  0, 1},
    113113    {"pcibridge",     0, 24,  0, 0},
    114114    {"pcibridge",     0, 25,  0, 0},
     
    229229};
    230230
     231
     232#ifdef VBOX_WITH_IOMMU_AMD
     233/*
     234 * AMD IOMMU and LSI Logic controller rules.
     235 *
     236 * Since the PCI slot (BDF=00:20.0) of the LSI Logic controller
     237 * conflicts with the SB I/O APIC, we assign the LSI Logic controller
     238 * to device number 23 when the VM is configured for an AMD IOMMU.
     239 */
     240static const DeviceAssignmentRule aIch9IommuLsiRules[] =
     241{
     242    /* AMD IOMMU. */
     243    {"iommu-amd",     0,  0,  2, 0},
     244    /* AMD IOMMU: Reserved for southbridge I/O APIC. */
     245    {"sb-ioapic",     0, 20,  0, 0},
     246
     247    /* Storage controller */
     248    {"lsilogic",      0, 23,  0, 1},
     249    { NULL,          -1, -1, -1, 0}
     250};
     251#endif
     252
     253/* LSI Logic Controller. */
     254static const DeviceAssignmentRule aIch9LsiRules[] =
     255{
     256    /* Storage controller */
     257    {"lsilogic",      0, 20,  0, 1},
     258    { NULL,          -1, -1, -1, 0}
     259};
     260
    231261/* Aliasing rules */
    232262static const DeviceAliasRule aDeviceAliases[] =
     
    280310    ChipsetType_T    mChipsetType;
    281311    const char *     mpszBridgeName;
     312    bool             mfIommu;
    282313    PCIMap           mPCIMap;
    283314    ReversePCIMap    mReversePCIMap;
     
    289320    {}
    290321
    291     HRESULT init(ChipsetType_T chipsetType);
     322    HRESULT init(ChipsetType_T chipsetType, bool fIommu);
    292323
    293324    HRESULT record(const char *pszName, PCIBusAddress& GuestAddress, PCIBusAddress HostAddress);
     
    301332};
    302333
    303 HRESULT BusAssignmentManager::State::init(ChipsetType_T chipsetType)
     334HRESULT BusAssignmentManager::State::init(ChipsetType_T chipsetType, bool fIommu)
    304335{
    305336    mChipsetType = chipsetType;
     337    mfIommu = fIommu;
    306338    switch (chipsetType)
    307339    {
     
    340372}
    341373
    342 bool    BusAssignmentManager::State::findPCIAddress(const char *pszDevName, int iInstance, PCIBusAddress& Address)
     374bool BusAssignmentManager::State::findPCIAddress(const char *pszDevName, int iInstance, PCIBusAddress& Address)
    343375{
    344376    PCIDeviceRecord devRec(pszDevName);
     
    358390{
    359391    size_t iRuleset, iRule;
    360     const DeviceAssignmentRule *aArrays[2] = {aGenericRules, NULL};
     392    const DeviceAssignmentRule *aArrays[3] = {aGenericRules, NULL, NULL};
    361393
    362394    switch (mChipsetType)
     
    366398            break;
    367399        case ChipsetType_ICH9:
     400        {
    368401            aArrays[1] = aIch9Rules;
     402#ifdef VBOX_WITH_IOMMU_AMD
     403            if (mfIommu)
     404                aArrays[2] = aIch9IommuLsiRules;
     405            else
     406#endif
     407            {
     408                aArrays[2] = aIch9LsiRules;
     409            }
    369410            break;
     411        }
    370412        default:
    371413            AssertFailed();
     
    405447    PCIRulesList matchingRules;
    406448
    407     addMatchingRules(pszName,  matchingRules);
     449    addMatchingRules(pszName, matchingRules);
    408450    const char *pszAlias = findAlias(pszName);
    409451    if (pszAlias)
     
    468510}
    469511
    470 BusAssignmentManager *BusAssignmentManager::createInstance(ChipsetType_T chipsetType)
     512BusAssignmentManager *BusAssignmentManager::createInstance(ChipsetType_T chipsetType, bool fIommu)
    471513{
    472514    BusAssignmentManager *pInstance = new BusAssignmentManager();
    473     pInstance->pState->init(chipsetType);
     515    pInstance->pState->init(chipsetType, fIommu);
    474516    Assert(pInstance);
    475517    return pInstance;
     
    537579        return rc;
    538580
    539     rc = InsertConfigInteger(pCfg, "PCIBusNo",      GuestAddress.miBus);
    540     if (FAILED(rc))
    541         return rc;
    542     rc = InsertConfigInteger(pCfg, "PCIDeviceNo",   GuestAddress.miDevice);
    543     if (FAILED(rc))
    544         return rc;
    545     rc = InsertConfigInteger(pCfg, "PCIFunctionNo", GuestAddress.miFn);
    546     if (FAILED(rc))
    547         return rc;
     581    if (pCfg)
     582    {
     583        rc = InsertConfigInteger(pCfg, "PCIBusNo",      GuestAddress.miBus);
     584        if (FAILED(rc))
     585            return rc;
     586        rc = InsertConfigInteger(pCfg, "PCIDeviceNo",   GuestAddress.miDevice);
     587        if (FAILED(rc))
     588            return rc;
     589        rc = InsertConfigInteger(pCfg, "PCIFunctionNo", GuestAddress.miFn);
     590        if (FAILED(rc))
     591            return rc;
     592    }
    548593
    549594    /* Check if the bus is still unknown, i.e. the bridge to it is missing */
  • trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp

    r84618 r85007  
    801801    }
    802802
    803     BusAssignmentManager *pBusMgr = mBusMgr = BusAssignmentManager::createInstance(chipsetType);
     803    /** @todo Get IOMMU from pMachine and pass info to createInstance() below. */
     804    BusAssignmentManager *pBusMgr = mBusMgr = BusAssignmentManager::createInstance(chipsetType, false /* fIommu */);
    804805
    805806    ULONG cCpus = 1;
     
    14931494            hrc = i_attachRawPCIDevices(pUVM, pBusMgr, pDevices);                           H();
    14941495#endif
    1495         }
     1496
     1497#ifdef VBOX_WITH_IOMMU_AMD
     1498            /* AMD IOMMU. */
     1499            /** @todo Get IOMMU from pMachine. */
     1500            InsertConfigNode(pDevices, "iommu-amd", &pDev);
     1501            InsertConfigNode(pDev,     "0", &pInst);
     1502            InsertConfigInteger(pInst, "Trusted",   1); /* boolean */
     1503            InsertConfigNode(pInst,    "Config", &pCfg);
     1504            hrc = pBusMgr->assignPCIDevice("iommu-amd", pInst);                             H();
     1505
     1506            /*
     1507             * Reserve the specific PCI address of the "SB I/O APIC" when using
     1508             * an AMD IOMMU. Required by Linux guests, see @bugref{9654#c23}.
     1509             */
     1510            PCIBusAddress PCIAddr = PCIBusAddress(VBOX_PCI_BUS_SB_IOAPIC, VBOX_PCI_DEV_SB_IOAPIC, VBOX_PCI_FN_SB_IOAPIC);
     1511            hrc = pBusMgr->assignPCIDevice("sb-ioapic", NULL /* pCfg */, PCIAddr, true /*fGuestAddressRequired*/);  H();
     1512#endif
     1513        }
     1514        /** @todo IOMMU: Disallow creating a VM without ICH9 chipset if an IOMMU is
     1515         *        configured. */
    14961516
    14971517        /*
  • trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp

    r84854 r85007  
    3636#include <VBox/version.h>
    3737#include <VBox/log.h>
     38#include <VBox/pci.h>
    3839#include <VBox/err.h>
    3940#include <iprt/asm.h>
     
    14571458                            rc);
    14581459
     1460#ifdef VBOX_WITH_IOMMU_AMD
     1461        /** @todo IOMMU: Restrict this to the AMD flavor of IOMMU only at runtime. */
     1462        PPDMIOMMU  pIommu       = &pVM->pdm.s.aIommus[0];
     1463        PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
     1464        if (pDevInsIommu)
     1465        {
     1466            /*
     1467             * If the PCI device/function number has been explicitly specified via CFGM,
     1468             * ensure it's not the BDF reserved for the southbridge I/O APIC expected
     1469             * by linux guests when using an AMD IOMMU, see @bugref{9654#c23}.
     1470             */
     1471            uint16_t const uDevFn    = VBOX_PCI_DEVFN_MAKE(uPciDevNo, uPciFunNo);
     1472            uint16_t const uBusDevFn = PCIBDF_MAKE(u8Bus, uDevFn);
     1473            if (uBusDevFn == VBOX_PCI_BDF_SB_IOAPIC)
     1474            {
     1475                LogRel(("Configuration error: PCI BDF (%u:%u:%u) conflicts with SB I/O APIC (%s/%d/%d)\n", u8Bus,
     1476                        uCfgDevice, uCfgFunction, pDevIns->pReg->szName, pDevIns->iInstance, pPciDev->Int.s.idxSubDev));
     1477                return VERR_NOT_AVAILABLE;
     1478            }
     1479        }
     1480#endif
    14591481
    14601482        /*
Note: See TracChangeset for help on using the changeset viewer.

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