Changeset 86661 in vbox for trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
- Timestamp:
- Oct 21, 2020 11:39:04 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
r86339 r86661 321 321 STAMCOUNTER StatMemWriteR3; /**< Number of memory write translation requests in R3. */ 322 322 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. */ 323 329 324 330 STAMCOUNTER StatCmd; /**< Number of commands processed. */ … … 3061 3067 3062 3068 /** 3063 * Memory read requestfrom a device.3069 * Memory access transaction from a device. 3064 3070 * 3065 3071 * @returns VBox status code. 3066 3072 * @param pDevIns The IOMMU device instance. 3067 3073 * @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. 3070 3077 * @param pGCPhysSpa Where to store the translated system physical address. 3071 3078 * 3072 3079 * @thread Any. 3073 3080 */ 3074 static DECLCALLBACK(int) iommuAmdDeviceMem Read(PPDMDEVINS pDevIns, uint16_t uDevId, uint64_t uIova, size_t cbRead,3075 PRTGCPHYS pGCPhysSpa)3081 static DECLCALLBACK(int) iommuAmdDeviceMemAccess(PPDMDEVINS pDevIns, uint16_t uDevId, uint64_t uIova, size_t cbAccess, 3082 uint32_t fFlags, PRTGCPHYS pGCPhysSpa) 3076 3083 { 3077 3084 /* 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); 3085 3091 IOMMU_CTRL_T const Ctrl = iommuAmdGetCtrl(pThis); 3086 3092 if (Ctrl.n.u1IommuEn) 3087 3093 { 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 3090 3116 3091 3117 /** @todo IOMMU: IOTLB cache lookup. */ 3092 3118 3093 3119 /* Lookup the IOVA from the device table. */ 3094 int rc = iommuAmdLookupDeviceTable(pDevIns, uDevId, uIova, cb Read, IOMMU_IO_PERM_READ, IOMMUOP_MEM_READ, pGCPhysSpa);3120 int rc = iommuAmdLookupDeviceTable(pDevIns, uDevId, uIova, cbAccess, fAccess, enmOp, pGCPhysSpa); 3095 3121 if (RT_SUCCESS(rc)) 3096 LogFlowFunc(("uDevId=%#x uIova=%#RX64 cRead=%u pGCPhysSpa=%#RGp\n", uDevId, uIova, cbRead, *pGCPhysSpa));3122 { /* likely */ } 3097 3123 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)); 3099 3126 return rc; 3100 3127 } 3101 3128 3129 /* Addresses are forwarded without translation when the IOMMU is disabled. */ 3102 3130 *pGCPhysSpa = uIova; 3103 3131 return VINF_SUCCESS; … … 3106 3134 3107 3135 /** 3108 * Memory writerequest from a device.3136 * Memory access bulk (one or more 4K pages) request from a device. 3109 3137 * 3110 3138 * @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. 3116 3145 * 3117 3146 * @thread Any. 3118 3147 */ 3119 static DECLCALLBACK(int) iommuAmdDeviceMem Write(PPDMDEVINS pDevIns, uint16_t uDevId, uint64_t uIova, size_t cbWrite,3120 PRTGCPHYS pGCPhysSpa)3148 static DECLCALLBACK(int) iommuAmdDeviceMemBulkAccess(PPDMDEVINS pDevIns, uint16_t uDevId, size_t cIovas, 3149 uint64_t const *pauIovas, uint32_t fFlags, PRTGCPHYS paGCPhysSpa) 3121 3150 { 3122 3151 /* 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)); 3126 3157 3127 3158 PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); 3128 3129 /* Addresses are forwarded without translation when the IOMMU is disabled. */3130 3159 IOMMU_CTRL_T const Ctrl = iommuAmdGetCtrl(pThis); 3131 3160 if (Ctrl.n.u1IommuEn) 3132 3161 { 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 3134 3184 3135 3185 /** @todo IOMMU: IOTLB cache lookup. */ 3136 3186 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 3149 3210 3150 3211 … … 4791 4852 PDMIOMMUREGR3 IommuReg; 4792 4853 RT_ZERO(IommuReg); 4793 IommuReg.u32Version = PDM_IOMMUREGCC_VERSION;4794 IommuReg.pfnMem Read = iommuAmdDeviceMemRead;4795 IommuReg.pfnMem Write = 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; 4798 4859 int rc = PDMDevHlpIommuRegister(pDevIns, &IommuReg, &pThisCC->CTX_SUFF(pIommuHlp), &pThis->idxIommu); 4799 4860 if (RT_FAILURE(rc)) … … 4961 5022 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMemWriteR3, STAMTYPE_COUNTER, "R3/MemWrite", STAMUNIT_OCCURENCES, "Number of memory write translation requests in R3."); 4962 5023 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."); 4963 5030 4964 5031 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatCmd, STAMTYPE_COUNTER, "R3/Commands", STAMUNIT_OCCURENCES, "Number of commands processed (total)."); … … 5079 5146 PDMIOMMUREGCC IommuReg; 5080 5147 RT_ZERO(IommuReg); 5081 IommuReg.u32Version = PDM_IOMMUREGCC_VERSION;5082 IommuReg.idxIommu = pThis->idxIommu;5083 IommuReg.pfnMem Read = iommuAmdDeviceMemRead;5084 IommuReg.pfnMem Write = 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; 5087 5154 rc = PDMDevHlpIommuSetUpContext(pDevIns, &IommuReg, &pThisCC->CTX_SUFF(pIommuHlp)); 5088 5155 AssertRCReturn(rc, rc);
Note:
See TracChangeset
for help on using the changeset viewer.