Changeset 87371 in vbox
- Timestamp:
- Jan 22, 2021 2:42:17 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/pdmdev.h
r87127 r87371 1283 1283 * 1284 1284 * @returns VBox status code. 1285 * @param pDevIns The IOMMU device instance. 1286 * @param uDevId The device identifier (bus, device, function). 1287 * @param uIova The I/O virtual address being accessed. 1288 * @param cbAccess The number of bytes being accessed. 1289 * @param fFlags Access flags, see PDMIOMMU_MEM_F_XXX. 1290 * @param pGCPhysSpa Where to store the translated system physical address. 1285 * @param pDevIns The IOMMU device instance. 1286 * @param uDevId The device identifier (bus, device, function). 1287 * @param uIova The I/O virtual address being accessed. 1288 * @param cbAccess The number of bytes being accessed. 1289 * @param fFlags Access flags, see PDMIOMMU_MEM_F_XXX. 1290 * @param pGCPhysSpa Where to store the translated system physical address. 1291 * @param pcbContiguous Where to store the number of contiguous bytes translated 1292 * and permission-checked. 1291 1293 * 1292 1294 * @thread Any. 1293 1295 */ 1294 1296 DECLR0CALLBACKMEMBER(int, pfnMemAccess,(PPDMDEVINS pDevIns, uint16_t uDevId, uint64_t uIova, size_t cbAccess, 1295 uint32_t fFlags, PRTGCPHYS pGCPhysSpa ));1297 uint32_t fFlags, PRTGCPHYS pGCPhysSpa, size_t *pcbContiguous)); 1296 1298 1297 1299 /** … … 1333 1335 1334 1336 /** Current PDMIOMMUREG version number. */ 1335 #define PDM_IOMMUREGR0_VERSION PDM_VERSION_MAKE(0xff10, 2, 0)1337 #define PDM_IOMMUREGR0_VERSION PDM_VERSION_MAKE(0xff10, 3, 0) 1336 1338 1337 1339 … … 1351 1353 * 1352 1354 * @returns VBox status code. 1353 * @param pDevIns The IOMMU device instance. 1354 * @param uDevId The device identifier (bus, device, function). 1355 * @param uIova The I/O virtual address being accessed. 1356 * @param cbAccess The number of bytes being accessed. 1357 * @param fFlags Access flags, see PDMIOMMU_MEM_F_XXX. 1358 * @param pGCPhysSpa Where to store the translated system physical address. 1355 * @param pDevIns The IOMMU device instance. 1356 * @param uDevId The device identifier (bus, device, function). 1357 * @param uIova The I/O virtual address being accessed. 1358 * @param cbAccess The number of bytes being accessed. 1359 * @param fFlags Access flags, see PDMIOMMU_MEM_F_XXX. 1360 * @param pGCPhysSpa Where to store the translated system physical address. 1361 * @param pcbContiguous Where to store the number of contiguous bytes translated 1362 * and permission-checked. 1359 1363 * 1360 1364 * @thread Any. 1361 1365 */ 1362 1366 DECLRCCALLBACKMEMBER(int, pfnMemAccess,(PPDMDEVINS pDevIns, uint16_t uDevId, uint64_t uIova, size_t cbAccess, 1363 uint32_t fFlags, PRTGCPHYS pGCPhysSpa ));1367 uint32_t fFlags, PRTGCPHYS pGCPhysSpa, size_t *pcbContiguous)); 1364 1368 1365 1369 /** … … 1401 1405 1402 1406 /** Current PDMIOMMUREG version number. */ 1403 #define PDM_IOMMUREGRC_VERSION PDM_VERSION_MAKE(0xff11, 2, 0)1407 #define PDM_IOMMUREGRC_VERSION PDM_VERSION_MAKE(0xff11, 3, 0) 1404 1408 1405 1409 … … 1419 1423 * 1420 1424 * @returns VBox status code. 1421 * @param pDevIns The IOMMU device instance. 1422 * @param uDevId The device identifier (bus, device, function). 1423 * @param uIova The I/O virtual address being accessed. 1424 * @param cbAccess The number of bytes being accessed. 1425 * @param fFlags Access flags, see PDMIOMMU_MEM_F_XXX. 1426 * @param pGCPhysSpa Where to store the translated system physical address. 1425 * @param pDevIns The IOMMU device instance. 1426 * @param uDevId The device identifier (bus, device, function). 1427 * @param uIova The I/O virtual address being accessed. 1428 * @param cbAccess The number of bytes being accessed. 1429 * @param fFlags Access flags, see PDMIOMMU_MEM_F_XXX. 1430 * @param pGCPhysSpa Where to store the translated system physical address. 1431 * @param pcbContiguous Where to store the number of contiguous bytes translated 1432 * and permission-checked. 1427 1433 * 1428 1434 * @thread Any. 1429 1435 */ 1430 1436 DECLR3CALLBACKMEMBER(int, pfnMemAccess,(PPDMDEVINS pDevIns, uint16_t uDevId, uint64_t uIova, size_t cbAccess, 1431 uint32_t fFlags, PRTGCPHYS pGCPhysSpa ));1437 uint32_t fFlags, PRTGCPHYS pGCPhysSpa, size_t *pcbContiguous)); 1432 1438 1433 1439 /** … … 1469 1475 1470 1476 /** Current PDMIOMMUREG version number. */ 1471 #define PDM_IOMMUREGR3_VERSION PDM_VERSION_MAKE(0xff12, 2, 0)1477 #define PDM_IOMMUREGR3_VERSION PDM_VERSION_MAKE(0xff12, 3, 0) 1472 1478 1473 1479 /** IOMMU registration structure for the current context. */ -
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
r87343 r87371 2882 2882 * 2883 2883 * @returns VBox status code. 2884 * @param pDevIns The IOMMU instance data. 2885 * @param uDevId The device ID. 2886 * @param uIova The I/O virtual address to lookup. 2887 * @param cbAccess The size of the access. 2888 * @param fAccess The access permissions (IOMMU_IO_PERM_XXX). This is the 2889 * permissions for the access being made. 2890 * @param enmOp The IOMMU operation being performed. 2891 * @param pGCPhysSpa Where to store the translated system physical address. Only 2892 * valid when translation succeeds and VINF_SUCCESS is 2893 * returned! 2884 * @param pDevIns The IOMMU instance data. 2885 * @param uDevId The device ID. 2886 * @param uIova The I/O virtual address to lookup. 2887 * @param cbAccess The size of the access. 2888 * @param fAccess The access permissions (IOMMU_IO_PERM_XXX). This is the 2889 * permissions for the access being made. 2890 * @param enmOp The IOMMU operation being performed. 2891 * @param pGCPhysSpa Where to store the translated system physical address. Only 2892 * valid when VINF_SUCCESS is returned! 2893 * @param pcbContiguous Where to store the number of contiguous bytes translated 2894 * and permission-checked. Only valid when VINF_SUCCESS is 2895 * returned! 2894 2896 * 2895 2897 * @thread Any. 2896 2898 */ 2897 2899 static int iommuAmdLookupDeviceTable(PPDMDEVINS pDevIns, uint16_t uDevId, uint64_t uIova, size_t cbAccess, uint8_t fAccess, 2898 IOMMUOP enmOp, PRTGCPHYS pGCPhysSpa )2900 IOMMUOP enmOp, PRTGCPHYS pGCPhysSpa, size_t *pcbContiguous) 2899 2901 { 2900 2902 PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); … … 2912 2914 { 2913 2915 /** @todo IOMMU: Add to IOLTB cache. */ 2914 *pGCPhysSpa = uIova; 2916 *pGCPhysSpa = uIova; 2917 *pcbContiguous = cbAccess; 2915 2918 STAM_PROFILE_ADV_STOP(&pThis->StatDteLookup, a); 2916 2919 return VINF_SUCCESS; … … 2940 2943 { 2941 2944 /** @todo IOMMU: Add to IOLTB cache. */ 2942 *pGCPhysSpa = uIova; 2945 *pGCPhysSpa = uIova; 2946 *pcbContiguous = cbAccess; 2943 2947 STAM_PROFILE_ADV_STOP(&pThis->StatDteLookup, a); 2944 2948 return VINF_SUCCESS; 2945 2949 } 2946 2950 2947 /** @todo IOMMU: Perhaps do the <= 4K access case first, if the generic loop 2948 * below gets too expensive and when we have iommuAmdWalkIoPageDirectory. */ 2949 2950 uint64_t uBaseIova = uIova & X86_PAGE_4K_BASE_MASK; 2951 RTGCPHYS GCPhysSpa = NIL_RTGCPHYS; 2952 size_t cbRemaining = cbAccess; 2953 uint64_t uIovaPage = uIova & X86_PAGE_4K_BASE_MASK; 2951 2954 uint64_t offIova = uIova & X86_PAGE_4K_OFFSET_MASK; 2952 uint64_t cb Remaining = cbAccess;2955 uint64_t cbPages = 0; 2953 2956 for (;;) 2954 2957 { 2955 2958 /* Walk the I/O page tables to translate the IOVA and check permission for the access. */ 2956 2959 IOWALKRESULT WalkResult; 2957 rc = iommuAmdWalkIoPageTable(pDevIns, uDevId, uBaseIova, fAccess, &Dte, enmOp, &WalkResult); 2960 RT_ZERO(WalkResult); 2961 rc = iommuAmdWalkIoPageTable(pDevIns, uDevId, uIovaPage, fAccess, &Dte, enmOp, &WalkResult); 2958 2962 if (RT_SUCCESS(rc)) 2959 2963 { 2960 /** @todo IOMMU: Split large pages into 4K IOTLB entries and add to IOTLB cache. */2961 2962 2964 /* If translation is disabled for this device (root paging mode is 0), we're done. */ 2963 2965 if (WalkResult.cShift == 0) 2964 2966 { 2965 *pGCPhysSpa = uIova; 2967 GCPhysSpa = uIova; 2968 cbRemaining = 0; 2966 2969 break; 2967 2970 } 2968 2971 2969 /* Store the translated base address before continuing to check permissions for anymore pages. */2972 /* Store the translated address before continuing to access more pages. */ 2970 2973 Assert(WalkResult.cShift >= X86_PAGE_4K_SHIFT); 2971 2974 if (cbRemaining == cbAccess) … … 2973 2976 uint64_t const offMask = ~(UINT64_C(0xffffffffffffffff) << WalkResult.cShift); 2974 2977 uint64_t const offSpa = uIova & offMask; 2975 *pGCPhysSpa = WalkResult.GCPhysSpa | offSpa;2978 GCPhysSpa = WalkResult.GCPhysSpa | offSpa; 2976 2979 } 2977 2978 /* If the access exceeds the page size, check permissions for the subsequent page. */ 2979 uint64_t const cbPhysPage = UINT64_C(1) << WalkResult.cShift; 2980 if (cbRemaining > cbPhysPage - offIova) 2980 /* Check if addresses translated so far are physically contiguous. */ 2981 else if ((GCPhysSpa & X86_PAGE_4K_BASE_MASK) + cbPages == WalkResult.GCPhysSpa) 2982 { /* likely */ } 2983 else 2984 break; 2985 2986 /* Check if we need to access more pages. */ 2987 uint64_t const cbSpa = UINT64_C(1) << WalkResult.cShift; 2988 if (cbRemaining > cbSpa - offIova) 2981 2989 { 2982 cbRemaining -= (cbPhysPage - offIova); 2983 uBaseIova += cbPhysPage; /** @todo r=ramshankar: Should we mask the offset based on page size here? */ 2984 offIova = 0; 2990 cbRemaining -= (cbSpa - offIova); /* Calculate how much more we need to access. */ 2991 cbPages += cbSpa; /* Update size of all pages read thus far. */ 2992 uIovaPage += cbSpa; /* Update address of the next access. */ 2993 offIova = 0; /* After the first page, all pages are accessed from offset 0. */ 2985 2994 } 2986 2995 else 2996 { 2997 cbRemaining = 0; 2987 2998 break; 2999 } 2988 3000 } 2989 3001 else 2990 3002 { 2991 LogFunc(("I/O page table walk failed. uIova=%#RX64 uBaseIova=%#RX64 fAccess=%u rc=%Rrc\n", uIova, 2992 uBaseIova, fAccess, rc)); 2993 *pGCPhysSpa = NIL_RTGCPHYS; 2994 STAM_PROFILE_ADV_STOP(&pThis->StatDteLookup, a); 2995 return rc; 3003 GCPhysSpa = NIL_RTGCPHYS; 3004 cbRemaining = 0; 3005 break; 2996 3006 } 2997 3007 } 2998 3008 3009 *pGCPhysSpa = GCPhysSpa; 3010 *pcbContiguous = cbAccess - cbRemaining; 3011 AssertMsg(*pcbContiguous > 0 && *pcbContiguous <= cbAccess, ("cbAccess=%zu pcbContig=%zu\n", cbAccess, *pcbContiguous)); 2999 3012 STAM_PROFILE_ADV_STOP(&pThis->StatDteLookup, a); 3000 3013 return rc; 3001 3014 } 3002 3015 3016 *pGCPhysSpa = NIL_RTGCPHYS; 3017 *pcbContiguous = 0; 3003 3018 LogFunc(("Failed to read device table entry. uDevId=%#x rc=%Rrc\n", uDevId, rc)); 3004 3019 STAM_PROFILE_ADV_STOP(&pThis->StatDteLookup, a); … … 3011 3026 * 3012 3027 * @returns VBox status code. 3013 * @param pDevIns The IOMMU device instance. 3014 * @param uDevId The device ID (bus, device, function). 3015 * @param uIova The I/O virtual address being accessed. 3016 * @param cbAccess The number of bytes being accessed. 3017 * @param fFlags The access flags, see PDMIOMMU_MEM_F_XXX. 3018 * @param pGCPhysSpa Where to store the translated system physical address. 3019 * 3028 * @param pDevIns The IOMMU device instance. 3029 * @param uDevId The device ID (bus, device, function). 3030 * @param uIova The I/O virtual address being accessed. 3031 * @param cbAccess The number of bytes being accessed. 3032 * @param fFlags The access flags, see PDMIOMMU_MEM_F_XXX. 3033 * @param pGCPhysSpa Where to store the translated system physical address. Only 3034 * valid when VINF_SUCCESS is returned! 3035 * @param pcbContiguous Where to store the number of contiguous bytes translated 3036 * and permission-checked. Only valid when VINF_SUCCESS is 3037 * returned! 3020 3038 * @thread Any. 3021 3039 */ 3022 3040 static DECLCALLBACK(int) iommuAmdDeviceMemAccess(PPDMDEVINS pDevIns, uint16_t uDevId, uint64_t uIova, size_t cbAccess, 3023 uint32_t fFlags, PRTGCPHYS pGCPhysSpa )3041 uint32_t fFlags, PRTGCPHYS pGCPhysSpa, size_t *pcbContiguous) 3024 3042 { 3025 3043 /* Validate. */ … … 3029 3047 Assert(!(fFlags & ~PDMIOMMU_MEM_F_VALID_MASK)); 3030 3048 3031 PIOMMU 3049 PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); 3032 3050 IOMMU_CTRL_T const Ctrl = iommuAmdGetCtrl(pThis); 3033 3051 if (Ctrl.n.u1IommuEn) … … 3059 3077 3060 3078 /* Lookup the IOVA from the device table. */ 3061 int rc = iommuAmdLookupDeviceTable(pDevIns, uDevId, uIova, cbAccess, fAccess, enmOp, pGCPhysSpa );3079 int rc = iommuAmdLookupDeviceTable(pDevIns, uDevId, uIova, cbAccess, fAccess, enmOp, pGCPhysSpa, pcbContiguous); 3062 3080 if (RT_SUCCESS(rc)) 3063 3081 { /* likely */ } … … 3069 3087 3070 3088 /* Addresses are forwarded without translation when the IOMMU is disabled. */ 3071 *pGCPhysSpa = uIova; 3089 *pGCPhysSpa = uIova; 3090 *pcbContiguous = cbAccess; 3072 3091 return VINF_SUCCESS; 3073 3092 } … … 3129 3148 for (size_t i = 0; i < cIovas; i++) 3130 3149 { 3131 int rc = iommuAmdLookupDeviceTable(pDevIns, uDevId, pauIovas[i], X86_PAGE_SIZE, fAccess, enmOp, &paGCPhysSpa[i]); 3150 size_t cbContig; 3151 int rc = iommuAmdLookupDeviceTable(pDevIns, uDevId, pauIovas[i], X86_PAGE_SIZE, fAccess, enmOp, &paGCPhysSpa[i], 3152 &cbContig); 3132 3153 if (RT_SUCCESS(rc)) 3133 3154 { /* likely */ } … … 3137 3158 return rc; 3138 3159 } 3160 Assert(cbContig == X86_PAGE_SIZE); 3139 3161 } 3140 3162 } -
trunk/src/VBox/VMM/VMMR0/PDMR0DevHlp.cpp
r86661 r87371 162 162 Assert(idxBus < RT_ELEMENTS(pGVM->pdmr0.s.aPciBuses)); 163 163 PPDMPCIBUSR0 pBus = &pGVM->pdmr0.s.aPciBuses[idxBus]; 164 165 RTGCPHYS GCPhysOut;166 164 uint16_t const uDeviceId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn); 167 int rc = pIommu->pfnMemAccess(pDevInsIommu, uDeviceId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut); 168 if (RT_SUCCESS(rc)) 169 GCPhys = GCPhysOut; 170 else 165 int rc = VINF_SUCCESS; 166 while (cbRead > 0) 171 167 { 172 Log(("pdmR0DevHlp_PCIPhysRead: IOMMU translation failed. uDeviceId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDeviceId, 173 GCPhys, cbRead, rc)); 174 return rc; 168 RTGCPHYS GCPhysOut; 169 size_t cbContig; 170 rc = pIommu->pfnMemAccess(pDevInsIommu, uDeviceId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut, &cbContig); 171 if (RT_SUCCESS(rc)) 172 { 173 /** @todo Handle strict return codes from PGMPhysRead. */ 174 rc = pDevIns->pHlpR0->pfnPhysRead(pDevIns, GCPhysOut, pvBuf, cbRead, fFlags); 175 if (RT_SUCCESS(rc)) 176 { 177 cbRead -= cbContig; 178 pvBuf = (void *)((uintptr_t)pvBuf + cbContig); 179 GCPhys += cbContig; 180 } 181 else 182 break; 183 } 184 else 185 { 186 Log(("pdmR0DevHlp_PCIPhysRead: IOMMU translation failed. uDeviceId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDeviceId, 187 GCPhys, cbRead, rc)); 188 break; 189 } 175 190 } 191 return rc; 176 192 } 177 193 #endif … … 207 223 #ifdef VBOX_WITH_IOMMU_AMD 208 224 /** @todo IOMMU: Optimize/re-organize things here later. */ 209 PGVM pGVM 210 PPDMIOMMUR0 pIommu 211 PPDMDEVINS 225 PGVM pGVM = pDevIns->Internal.s.pGVM; 226 PPDMIOMMUR0 pIommu = &pGVM->pdmr0.s.aIommus[0]; 227 PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns); 212 228 if ( pDevInsIommu 213 229 && pDevInsIommu != pDevIns) … … 216 232 Assert(idxBus < RT_ELEMENTS(pGVM->pdmr0.s.aPciBuses)); 217 233 PPDMPCIBUSR0 pBus = &pGVM->pdmr0.s.aPciBuses[idxBus]; 218 219 RTGCPHYS GCPhysOut;220 234 uint16_t const uDeviceId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn); 221 int rc = pIommu->pfnMemAccess(pDevInsIommu, uDeviceId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, &GCPhysOut); 222 if (RT_SUCCESS(rc)) 223 GCPhys = GCPhysOut; 224 else 235 int rc = VINF_SUCCESS; 236 while (cbWrite > 0) 225 237 { 226 Log(("pdmR0DevHlp_PCIPhysWrite: IOMMU translation failed. uDeviceId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDeviceId, 227 GCPhys, cbWrite, rc)); 228 return rc; 238 RTGCPHYS GCPhysOut; 239 size_t cbContig; 240 rc = pIommu->pfnMemAccess(pDevInsIommu, uDeviceId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, &GCPhysOut, &cbContig); 241 if (RT_SUCCESS(rc)) 242 { 243 /** @todo Handle strict return codes from PGMPhysWrite. */ 244 rc = pDevIns->pHlpR0->pfnPhysWrite(pDevIns, GCPhysOut, pvBuf, cbWrite, fFlags); 245 if (RT_SUCCESS(rc)) 246 { 247 cbWrite -= cbContig; 248 pvBuf = (const void *)((uintptr_t)pvBuf + cbContig); 249 GCPhys += cbContig; 250 } 251 else 252 break; 253 } 254 else 255 { 256 Log(("pdmR0DevHlp_PCIPhysWrite: IOMMU translation failed. uDeviceId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDeviceId, 257 GCPhys, cbWrite, rc)); 258 break; 259 } 229 260 } 261 return rc; 230 262 } 231 263 #endif -
trunk/src/VBox/VMM/VMMR0/PDMR0DevHlpTracing.cpp
r86661 r87371 323 323 Assert(idxBus < RT_ELEMENTS(pGVM->pdmr0.s.aPciBuses)); 324 324 PPDMPCIBUSR0 pBus = &pGVM->pdmr0.s.aPciBuses[idxBus]; 325 326 RTGCPHYS GCPhysOut;327 325 uint16_t const uDeviceId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn); 328 int rc = pIommu->pfnMemAccess(pDevInsIommu, uDeviceId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut); 329 if (RT_SUCCESS(rc)) 330 GCPhys = GCPhysOut; 331 else 326 int rc = VINF_SUCCESS; 327 while (cbRead > 0) 332 328 { 333 Log(("pdmR0DevHlp_PCIPhysRead: IOMMU translation failed. uDeviceId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDeviceId, 334 GCPhys, cbRead, rc)); 335 return rc; 329 RTGCPHYS GCPhysOut; 330 size_t cbContig; 331 rc = pIommu->pfnMemAccess(pDevInsIommu, uDeviceId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut, &cbContig); 332 if (RT_SUCCESS(rc)) 333 { 334 /** @todo Handle strict return codes from PGMPhysRead. */ 335 rc = pDevIns->pHlpR0->pfnPhysRead(pDevIns, GCPhysOut, pvBuf, cbRead, fFlags); 336 if (RT_SUCCESS(rc)) 337 { 338 cbRead -= cbContig; 339 pvBuf = (void *)((uintptr_t)pvBuf + cbContig); 340 GCPhys += cbContig; 341 } 342 else 343 break; 344 } 345 else 346 { 347 Log(("pdmR0DevHlp_PCIPhysRead: IOMMU translation failed. uDeviceId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDeviceId, 348 GCPhys, cbRead, rc)); 349 break; 350 } 336 351 } 352 return rc; 337 353 } 338 354 #endif … … 377 393 Assert(idxBus < RT_ELEMENTS(pGVM->pdmr0.s.aPciBuses)); 378 394 PPDMPCIBUSR0 pBus = &pGVM->pdmr0.s.aPciBuses[idxBus]; 379 380 RTGCPHYS GCPhysOut;381 395 uint16_t const uDeviceId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn); 382 int rc = pIommu->pfnMemAccess(pDevInsIommu, uDeviceId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, &GCPhysOut); 383 if (RT_SUCCESS(rc)) 384 GCPhys = GCPhysOut; 385 else 396 int rc = VINF_SUCCESS; 397 while (cbWrite > 0) 386 398 { 387 Log(("pdmR0DevHlp_PCIPhysWrite: IOMMU translation failed. uDeviceId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDeviceId, 388 GCPhys, cbWrite, rc)); 389 return rc; 399 RTGCPHYS GCPhysOut; 400 size_t cbContig; 401 rc = pIommu->pfnMemAccess(pDevInsIommu, uDeviceId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, &GCPhysOut, &cbContig); 402 if (RT_SUCCESS(rc)) 403 { 404 /** @todo Handle strict return codes from PGMPhysWrite. */ 405 rc = pDevIns->pHlpR0->pfnPhysWrite(pDevIns, GCPhysOut, pvBuf, cbWrite, fFlags); 406 if (RT_SUCCESS(rc)) 407 { 408 cbWrite -= cbContig; 409 pvBuf = (const void *)((uintptr_t)pvBuf + cbContig); 410 GCPhys += cbContig; 411 } 412 else 413 break; 414 } 415 else 416 { 417 Log(("pdmR0DevHlp_PCIPhysWrite: IOMMU translation failed. uDeviceId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDeviceId, 418 GCPhys, cbWrite, rc)); 419 break; 420 } 390 421 } 422 return rc; 391 423 } 392 424 #endif -
trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp
r87127 r87371 1831 1831 Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses)); 1832 1832 PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus]; 1833 1834 RTGCPHYS GCPhysOut;1835 1833 uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn); 1836 int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut); 1837 if (RT_SUCCESS(rc)) 1838 GCPhys = GCPhysOut; 1839 else 1834 int rc = VINF_SUCCESS; 1835 while (cbRead > 0) 1840 1836 { 1841 Log(("pdmR3DevHlp_PCIPhysRead: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys, 1842 cbRead, rc)); 1843 return rc; 1837 RTGCPHYS GCPhysOut; 1838 size_t cbContig; 1839 rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut, &cbContig); 1840 if (RT_SUCCESS(rc)) 1841 { 1842 /** @todo Handle strict return codes from PGMPhysRead. */ 1843 rc = pDevIns->pHlpR3->pfnPhysRead(pDevIns, GCPhysOut, pvBuf, cbContig, fFlags); 1844 if (RT_SUCCESS(rc)) 1845 { 1846 cbRead -= cbContig; 1847 pvBuf = (void *)((uintptr_t)pvBuf + cbContig); 1848 GCPhys += cbContig; 1849 } 1850 else 1851 break; 1852 } 1853 else 1854 { 1855 AssertMsgFailed(("Here\n")); 1856 Log(("pdmR3DevHlp_PCIPhysRead: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys, 1857 cbRead, rc)); 1858 break; 1859 } 1844 1860 } 1861 return rc; 1845 1862 } 1846 1863 #endif … … 1885 1902 Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses)); 1886 1903 PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus]; 1887 1888 RTGCPHYS GCPhysOut;1889 1904 uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn); 1890 int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, &GCPhysOut); 1891 if (RT_SUCCESS(rc)) 1892 GCPhys = GCPhysOut; 1893 else 1905 int rc = VINF_SUCCESS; 1906 while (cbWrite > 0) 1894 1907 { 1895 Log(("pdmR3DevHlp_PCIPhysWrite: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys, 1896 cbWrite, rc)); 1897 return rc; 1908 RTGCPHYS GCPhysOut; 1909 size_t cbContig; 1910 rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, &GCPhysOut, &cbContig); 1911 if (RT_SUCCESS(rc)) 1912 { 1913 /** @todo Handle strict return codes from PGMPhysWrite. */ 1914 rc = pDevIns->pHlpR3->pfnPhysWrite(pDevIns, GCPhysOut, pvBuf, cbContig, fFlags); 1915 if (RT_SUCCESS(rc)) 1916 { 1917 cbWrite -= cbContig; 1918 pvBuf = (const void *)((uintptr_t)pvBuf + cbContig); 1919 GCPhys += cbContig; 1920 } 1921 else 1922 break; 1923 } 1924 else 1925 { 1926 Log(("pdmR3DevHlp_PCIPhysWrite: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys, 1927 cbWrite, rc)); 1928 break; 1929 } 1898 1930 } 1931 return rc; 1899 1932 } 1900 1933 #endif … … 1936 1969 Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses)); 1937 1970 PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus]; 1938 1971 uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn); 1939 1972 RTGCPHYS GCPhysOut; 1940 uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn); 1941 int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, X86_PAGE_SIZE, PDMIOMMU_MEM_F_WRITE, &GCPhysOut); 1973 size_t cbContig; 1974 int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys & X86_PAGE_BASE_MASK, X86_PAGE_SIZE, PDMIOMMU_MEM_F_WRITE, 1975 &GCPhysOut, &cbContig); 1942 1976 if (RT_SUCCESS(rc)) 1977 { 1943 1978 GCPhys = GCPhysOut; 1979 Assert(cbContig == X86_PAGE_SIZE); 1980 } 1944 1981 else 1945 1982 { … … 1986 2023 Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses)); 1987 2024 PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus]; 1988 2025 uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn); 1989 2026 RTGCPHYS GCPhysOut; 1990 uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn); 1991 int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, X86_PAGE_SIZE, PDMIOMMU_MEM_F_READ, &GCPhysOut); 2027 size_t cbContig; 2028 int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys & X86_PAGE_BASE_MASK, X86_PAGE_SIZE, PDMIOMMU_MEM_F_READ, 2029 &GCPhysOut, &cbContig); 1992 2030 if (RT_SUCCESS(rc)) 2031 { 1993 2032 GCPhys = GCPhysOut; 2033 Assert(cbContig == X86_PAGE_SIZE); 2034 } 1994 2035 else 1995 2036 { -
trunk/src/VBox/VMM/VMMR3/PDMDevHlpTracing.cpp
r86661 r87371 429 429 Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses)); 430 430 PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus]; 431 432 RTGCPHYS GCPhysOut;433 431 uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn); 434 int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut); 435 if (RT_SUCCESS(rc)) 436 GCPhys = GCPhysOut; 437 else 432 int rc = VINF_SUCCESS; 433 while (cbRead > 0) 438 434 { 439 Log(("pdmR3DevHlp_PCIPhysRead: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys, 440 cbRead, rc)); 441 return rc; 435 RTGCPHYS GCPhysOut; 436 size_t cbContig; 437 rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut, &cbContig); 438 if (RT_SUCCESS(rc)) 439 { 440 /** @todo Handle strict return codes from PGMPhysRead. */ 441 rc = pDevIns->pHlpR3->pfnPhysRead(pDevIns, GCPhysOut, pvBuf, cbRead, fFlags); 442 if (RT_SUCCESS(rc)) 443 { 444 cbRead -= cbContig; 445 pvBuf = (void *)((uintptr_t)pvBuf + cbContig); 446 GCPhys += cbContig; 447 } 448 else 449 break; 450 } 451 else 452 { 453 Log(("pdmR3DevHlp_PCIPhysRead: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys, 454 cbRead, rc)); 455 break; 456 } 442 457 } 443 444 GCPhys = GCPhysOut; 458 return rc; 445 459 } 446 460 #endif … … 485 499 Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses)); 486 500 PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus]; 487 488 RTGCPHYS GCPhysOut;489 501 uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn); 490 int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, & GCPhysOut); 491 if (RT_SUCCESS(rc)) 492 GCPhys = GCPhysOut; 493 else 502 int rc = VINF_SUCCESS; 503 while (cbWrite > 0) 494 504 { 495 Log(("pdmR3DevHlp_PCIPhysRead: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys, 496 cbWrite, rc)); 497 return rc; 505 RTGCPHYS GCPhysOut; 506 size_t cbContig; 507 rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, &GCPhysOut, &cbContig); 508 if (RT_SUCCESS(rc)) 509 { 510 /** @todo Handle strict return codes from PGMPhysWrite. */ 511 rc = pDevIns->pHlpR3->pfnPhysWrite(pDevIns, GCPhysOut, pvBuf, cbContig, fFlags); 512 if (RT_SUCCESS(rc)) 513 { 514 cbWrite -= cbContig; 515 pvBuf = (const void *)((uintptr_t)pvBuf + cbContig); 516 GCPhys += cbContig; 517 } 518 else 519 break; 520 } 521 else 522 { 523 Log(("pdmR3DevHlp_PCIPhysWrite: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys, 524 cbWrite, rc)); 525 break; 526 } 498 527 } 499 500 GCPhys = GCPhysOut; 528 return rc; 501 529 } 502 530 #endif -
trunk/src/VBox/VMM/include/PDMInternal.h
r86661 r87371 700 700 /** @copydoc PDMIOMMUREGR3::pfnMemAccess */ 701 701 DECLR3CALLBACKMEMBER(int, pfnMemAccess,(PPDMDEVINS pDevIns, uint16_t uDevId, uint64_t uDva, size_t cbAccess, 702 uint32_t fFlags, PRTGCPHYS pGCPhysSpa ));702 uint32_t fFlags, PRTGCPHYS pGCPhysSpa, size_t *pcbContig)); 703 703 /** @copydoc PDMIOMMUREGR3::pfnMemBulkAccess */ 704 704 DECLR3CALLBACKMEMBER(int, pfnMemBulkAccess,(PPDMDEVINS pDevIns, uint16_t uDevId, size_t cIovas, uint64_t const *pauIovas, … … 722 722 /** @copydoc PDMIOMMUREGR3::pfnMemAccess */ 723 723 DECLR0CALLBACKMEMBER(int, pfnMemAccess,(PPDMDEVINS pDevIns, uint16_t uDevId, uint64_t uDva, size_t cbAccess, 724 uint32_t fFlags, PRTGCPHYS pGCPhysSpa ));724 uint32_t fFlags, PRTGCPHYS pGCPhysSpa, size_t *pcbContig)); 725 725 /** @copydoc PDMIOMMUREGR3::pfnMemBulkAccess */ 726 726 DECLR0CALLBACKMEMBER(int, pfnMemBulkAccess,(PPDMDEVINS pDevIns, uint16_t uDevId, size_t cIovas, uint64_t const *pauIovas,
Note:
See TracChangeset
for help on using the changeset viewer.