VirtualBox

Ignore:
Timestamp:
Oct 21, 2020 11:39:04 AM (4 years ago)
Author:
vboxsync
Message:

AMD IOMMU: bugref:9654: Add PDM interfaces for pfnPCIPhysGCPhys2CCPtr[ReadOnly] and merge IOMMU memory read/write interface into memory access interface with a flag.

File:
1 edited

Legend:

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

    r86339 r86661  
    321321    STAMCOUNTER             StatMemWriteR3;             /**< Number of memory write translation requests in R3. */
    322322    STAMCOUNTER             StatMemWriteRZ;             /**< Number of memory write translation requests in RZ. */
     323
     324    STAMCOUNTER             StatMemBulkReadR3;          /**< Number of memory read bulk translation requests in R3. */
     325    STAMCOUNTER             StatMemBulkReadRZ;          /**< Number of memory read bulk translation requests in RZ. */
     326
     327    STAMCOUNTER             StatMemBulkWriteR3;         /**< Number of memory read bulk translation requests in R3. */
     328    STAMCOUNTER             StatMemBulkWriteRZ;         /**< Number of memory read bulk translation requests in RZ. */
    323329
    324330    STAMCOUNTER             StatCmd;                    /**< Number of commands processed. */
     
    30613067
    30623068/**
    3063  * Memory read request from a device.
     3069 * Memory access transaction from a device.
    30643070 *
    30653071 * @returns VBox status code.
    30663072 * @param   pDevIns     The IOMMU device instance.
    30673073 * @param   uDevId      The device ID (bus, device, function).
    3068  * @param   uIova       The I/O virtual address being read.
    3069  * @param   cbRead      The number of bytes being read.
     3074 * @param   uIova       The I/O virtual address being accessed.
     3075 * @param   cbAccess    The number of bytes being accessed.
     3076 * @param   fFlags      The access flags, see PDMIOMMU_MEM_F_XXX.
    30703077 * @param   pGCPhysSpa  Where to store the translated system physical address.
    30713078 *
    30723079 * @thread  Any.
    30733080 */
    3074 static DECLCALLBACK(int) iommuAmdDeviceMemRead(PPDMDEVINS pDevIns, uint16_t uDevId, uint64_t uIova, size_t cbRead,
    3075                                                PRTGCPHYS pGCPhysSpa)
     3081static DECLCALLBACK(int) iommuAmdDeviceMemAccess(PPDMDEVINS pDevIns, uint16_t uDevId, uint64_t uIova, size_t cbAccess,
     3082                                                 uint32_t fFlags, PRTGCPHYS pGCPhysSpa)
    30763083{
    30773084    /* Validate. */
    3078     Assert(pDevIns);
    3079     Assert(pGCPhysSpa);
    3080     Assert(cbRead > 0);
    3081 
    3082     PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    3083 
    3084     /* Addresses are forwarded without translation when the IOMMU is disabled. */
     3085    AssertPtr(pDevIns);
     3086    AssertPtr(pGCPhysSpa);
     3087    Assert(cbAccess > 0);
     3088    Assert(!(fFlags & ~PDMIOMMU_MEM_F_VALID_MASK));
     3089
     3090    PIOMMU  pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    30853091    IOMMU_CTRL_T const Ctrl = iommuAmdGetCtrl(pThis);
    30863092    if (Ctrl.n.u1IommuEn)
    30873093    {
    3088         STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMemRead));
    3089         LogFunc(("uDevId=%#x uIova=%#RX64 cbRead=%u\n", uDevId, uIova, cbRead));
     3094        IOMMUOP enmOp;
     3095        uint8_t fAccess;
     3096        if (fFlags & PDMIOMMU_MEM_F_READ)
     3097        {
     3098            enmOp   = IOMMUOP_MEM_READ;
     3099            fAccess = IOMMU_IO_PERM_READ;
     3100            STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMemRead));
     3101        }
     3102        else
     3103        {
     3104            Assert(fFlags & PDMIOMMU_MEM_F_WRITE);
     3105            enmOp   = IOMMUOP_MEM_WRITE;
     3106            fAccess = IOMMU_IO_PERM_WRITE;
     3107            STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMemWrite));
     3108        }
     3109
     3110#ifdef LOG_ENABLED
     3111        static const char * const s_apszAccess[] = { "none", "read", "write" };
     3112        Assert(fAccess > 0 && fAccess < RT_ELEMENTS(s_apszAccess));
     3113        const char *pszAccess = s_apszAccess[fAccess];
     3114        LogFlowFunc(("uDevId=%#x uIova=%#RX64 szAccess=%s cbAccess=%zu\n", uDevId, uIova, pszAccess, cbAccess));
     3115#endif
    30903116
    30913117        /** @todo IOMMU: IOTLB cache lookup. */
    30923118
    30933119        /* Lookup the IOVA from the device table. */
    3094         int rc = iommuAmdLookupDeviceTable(pDevIns, uDevId, uIova, cbRead, IOMMU_IO_PERM_READ, IOMMUOP_MEM_READ, pGCPhysSpa);
     3120        int rc = iommuAmdLookupDeviceTable(pDevIns, uDevId, uIova, cbAccess, fAccess, enmOp, pGCPhysSpa);
    30953121        if (RT_SUCCESS(rc))
    3096             LogFlowFunc(("uDevId=%#x uIova=%#RX64 cRead=%u pGCPhysSpa=%#RGp\n", uDevId, uIova, cbRead, *pGCPhysSpa));
     3122        { /* likely */ }
    30973123        else
    3098             LogFunc(("Failed! uDevId=%#x uIova=%#RX64 cbWrite=%u rc=%Rrc\n", uDevId, uIova, cbRead, rc));
     3124            LogFunc(("DTE lookup failed! uDevId=%#x uIova=%#RX64 fAccess=%s cbAccess=%zu rc=%Rrc\n", uDevId, uIova, fAccess,
     3125                     cbAccess, rc));
    30993126        return rc;
    31003127    }
    31013128
     3129    /* Addresses are forwarded without translation when the IOMMU is disabled. */
    31023130    *pGCPhysSpa = uIova;
    31033131    return VINF_SUCCESS;
     
    31063134
    31073135/**
    3108  * Memory write request from a device.
     3136 * Memory access bulk (one or more 4K pages) request from a device.
    31093137 *
    31103138 * @returns VBox status code.
    3111  * @param   pDevIns     The IOMMU device instance.
    3112  * @param   uDevId      The device ID (bus, device, function).
    3113  * @param   uIova       The I/O virtual address being written.
    3114  * @param   cbWrite     The number of bytes being written.
    3115  * @param   pGCPhysSpa  Where to store the translated physical address.
     3139 * @param   pDevIns         The IOMMU device instance.
     3140 * @param   uDevId          The device ID (bus, device, function).
     3141 * @param   cPages          The number of pages being written.
     3142 * @param   pauIovas        The I/O virtual addresses for each page being accessed.
     3143 * @param   fFlags          The access flags, see PDMIOMMU_MEM_F_XXX.
     3144 * @param   paGCPhysSpa     Where to store the translated physical addresses.
    31163145 *
    31173146 * @thread  Any.
    31183147 */
    3119 static DECLCALLBACK(int) iommuAmdDeviceMemWrite(PPDMDEVINS pDevIns, uint16_t uDevId, uint64_t uIova, size_t cbWrite,
    3120                                                 PRTGCPHYS pGCPhysSpa)
     3148static DECLCALLBACK(int) iommuAmdDeviceMemBulkAccess(PPDMDEVINS pDevIns, uint16_t uDevId, size_t cIovas,
     3149                                                     uint64_t const *pauIovas, uint32_t fFlags, PRTGCPHYS paGCPhysSpa)
    31213150{
    31223151    /* Validate. */
    3123     Assert(pDevIns);
    3124     Assert(pGCPhysSpa);
    3125     Assert(cbWrite > 0);
     3152    AssertPtr(pDevIns);
     3153    Assert(cIovas > 0);
     3154    AssertPtr(pauIovas);
     3155    AssertPtr(paGCPhysSpa);
     3156    Assert(!(fFlags & ~PDMIOMMU_MEM_F_VALID_MASK));
    31263157
    31273158    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    3128 
    3129     /* Addresses are forwarded without translation when the IOMMU is disabled. */
    31303159    IOMMU_CTRL_T const Ctrl = iommuAmdGetCtrl(pThis);
    31313160    if (Ctrl.n.u1IommuEn)
    31323161    {
    3133         STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMemWrite));
     3162        IOMMUOP enmOp;
     3163        uint8_t fAccess;
     3164        if (fFlags & PDMIOMMU_MEM_F_READ)
     3165        {
     3166            enmOp   = IOMMUOP_MEM_READ;
     3167            fAccess = IOMMU_IO_PERM_READ;
     3168            STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMemBulkRead));
     3169        }
     3170        else
     3171        {
     3172            Assert(fFlags & PDMIOMMU_MEM_F_WRITE);
     3173            enmOp   = IOMMUOP_MEM_WRITE;
     3174            fAccess = IOMMU_IO_PERM_WRITE;
     3175            STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMemBulkWrite));
     3176        }
     3177
     3178#ifdef LOG_ENABLED
     3179        static const char * const s_apszAccess[] = { "none", "read", "write" };
     3180        Assert(fAccess > 0 && fAccess < RT_ELEMENTS(s_apszAccess));
     3181        const char *pszAccess = s_apszAccess[fAccess];
     3182        LogFlowFunc(("uDevId=%#x cIovas=%zu szAccess=%s\n", uDevId, cIovas, pszAccess));
     3183#endif
    31343184
    31353185        /** @todo IOMMU: IOTLB cache lookup. */
    31363186
    3137         /* Lookup the IOVA from the device table. */
    3138         int rc = iommuAmdLookupDeviceTable(pDevIns, uDevId, uIova, cbWrite, IOMMU_IO_PERM_WRITE, IOMMUOP_MEM_WRITE, pGCPhysSpa);
    3139         if (RT_SUCCESS(rc))
    3140             LogFlowFunc(("uDevId=%#x uIova=%#RX64 cbWrite=%u pGCPhysSpa=%#RGp\n", uDevId, uIova, cbWrite, *pGCPhysSpa));
    3141         else
    3142             LogFunc(("Failed! uDevId=%#x uIova=%#RX64 cbWrite=%u rc=%Rrc\n", uDevId, uIova, cbWrite, rc));
    3143         return rc;
    3144     }
    3145 
    3146     *pGCPhysSpa = uIova;
    3147     return VINF_SUCCESS;
    3148 }
     3187        /* Lookup each IOVA from the device table. */
     3188        for (size_t i = 0; i < cIovas; i++)
     3189        {
     3190            int rc = iommuAmdLookupDeviceTable(pDevIns, uDevId, pauIovas[i], X86_PAGE_SIZE, fAccess, enmOp, &paGCPhysSpa[i]);
     3191            if (RT_SUCCESS(rc))
     3192            { /* likely */ }
     3193            else
     3194            {
     3195                LogFunc(("Failed! uDevId=%#x uIova=%#RX64 fAccess=%u rc=%Rrc\n", uDevId, pauIovas[i], fAccess, rc));
     3196                return rc;
     3197            }
     3198        }
     3199    }
     3200    else
     3201    {
     3202        /* Addresses are forwarded without translation when the IOMMU is disabled. */
     3203        for (size_t i = 0; i < cIovas; i++)
     3204            paGCPhysSpa[i] = pauIovas[i];
     3205    }
     3206
     3207    return VINF_SUCCESS;
     3208}
     3209
    31493210
    31503211
     
    47914852    PDMIOMMUREGR3 IommuReg;
    47924853    RT_ZERO(IommuReg);
    4793     IommuReg.u32Version  = PDM_IOMMUREGCC_VERSION;
    4794     IommuReg.pfnMemRead  = iommuAmdDeviceMemRead;
    4795     IommuReg.pfnMemWrite = iommuAmdDeviceMemWrite;
    4796     IommuReg.pfnMsiRemap = iommuAmdDeviceMsiRemap;
    4797     IommuReg.u32TheEnd   = PDM_IOMMUREGCC_VERSION;
     4854    IommuReg.u32Version       = PDM_IOMMUREGCC_VERSION;
     4855    IommuReg.pfnMemAccess     = iommuAmdDeviceMemAccess;
     4856    IommuReg.pfnMemBulkAccess = iommuAmdDeviceMemBulkAccess;
     4857    IommuReg.pfnMsiRemap      = iommuAmdDeviceMsiRemap;
     4858    IommuReg.u32TheEnd        = PDM_IOMMUREGCC_VERSION;
    47984859    int rc = PDMDevHlpIommuRegister(pDevIns, &IommuReg, &pThisCC->CTX_SUFF(pIommuHlp), &pThis->idxIommu);
    47994860    if (RT_FAILURE(rc))
     
    49615022    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMemWriteR3,  STAMTYPE_COUNTER, "R3/MemWrite",  STAMUNIT_OCCURENCES, "Number of memory write translation requests in R3.");
    49625023    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMemWriteRZ,  STAMTYPE_COUNTER, "RZ/MemWrite",  STAMUNIT_OCCURENCES, "Number of memory write translation requests in RZ.");
     5024
     5025    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMemBulkReadR3,  STAMTYPE_COUNTER, "R3/MemBulkRead",  STAMUNIT_OCCURENCES, "Number of memory bulk read translation requests in R3.");
     5026    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMemBulkReadRZ,  STAMTYPE_COUNTER, "RZ/MemBulkRead",  STAMUNIT_OCCURENCES, "Number of memory bulk read translation requests in RZ.");
     5027
     5028    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMemBulkWriteR3, STAMTYPE_COUNTER, "R3/MemBulkWrite", STAMUNIT_OCCURENCES, "Number of memory bulk write translation requests in R3.");
     5029    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMemBulkWriteRZ, STAMTYPE_COUNTER, "RZ/MemBulkWrite", STAMUNIT_OCCURENCES, "Number of memory bulk write translation requests in RZ.");
    49635030
    49645031    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatCmd, STAMTYPE_COUNTER, "R3/Commands", STAMUNIT_OCCURENCES, "Number of commands processed (total).");
     
    50795146    PDMIOMMUREGCC IommuReg;
    50805147    RT_ZERO(IommuReg);
    5081     IommuReg.u32Version  = PDM_IOMMUREGCC_VERSION;
    5082     IommuReg.idxIommu    = pThis->idxIommu;
    5083     IommuReg.pfnMemRead  = iommuAmdDeviceMemRead;
    5084     IommuReg.pfnMemWrite = iommuAmdDeviceMemWrite;
    5085     IommuReg.pfnMsiRemap = iommuAmdDeviceMsiRemap;
    5086     IommuReg.u32TheEnd   = PDM_IOMMUREGCC_VERSION;
     5148    IommuReg.u32Version       = PDM_IOMMUREGCC_VERSION;
     5149    IommuReg.idxIommu         = pThis->idxIommu;
     5150    IommuReg.pfnMemAccess     = iommuAmdDeviceMemAccess;
     5151    IommuReg.pfnMemBulkAccess = iommuAmdDeviceMemBulkAccess;
     5152    IommuReg.pfnMsiRemap      = iommuAmdDeviceMsiRemap;
     5153    IommuReg.u32TheEnd        = PDM_IOMMUREGCC_VERSION;
    50875154    rc = PDMDevHlpIommuSetUpContext(pDevIns, &IommuReg, &pThisCC->CTX_SUFF(pIommuHlp));
    50885155    AssertRCReturn(rc, rc);
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