- Timestamp:
- Aug 2, 2021 2:15:42 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
r90448 r90478 81 81 #ifdef IOMMU_WITH_IOTLBE_CACHE 82 82 /** The maximum number of IOTLB entries. */ 83 # define IOMMU_IOTLBE_MAX 9683 # define IOMMU_IOTLBE_MAX 64 84 84 /** The mask of bits covering the domain ID in the IOTLBE key. */ 85 85 # define IOMMU_IOTLB_DOMAIN_ID_MASK UINT64_C(0xffffff0000000000) … … 183 183 #endif /* IOMMU_WITH_DTE_CACHE */ 184 184 185 /** Acquires the PDMlock (returns a_rcBusy on contention). */185 /** Acquires the IOMMU lock (returns a_rcBusy on contention). */ 186 186 #define IOMMU_LOCK_RET(a_pDevIns, a_pThisCC, a_rcBusy) \ 187 187 do { \ … … 193 193 } while (0) 194 194 195 /** Acquires the PDM lock (can fail under extraordinary circumstance inin ring-0). */195 /** Acquires the IOMMU lock (can fail under extraordinary circumstance in ring-0). */ 196 196 #define IOMMU_LOCK(a_pDevIns, a_pThisCC) \ 197 197 do { \ … … 900 900 901 901 /** 902 * Adds a device-table entry to the cache. 903 * 904 * @returns VBox status code. 905 * @retval VERR_OUT_OF_RESOURCES if the cache is full. 902 * Adds a DTE cache entry at the given index. 903 * 904 * @param pThis The shared IOMMU device state. 905 * @param idxDte The index of the DTE cache entry. 906 * @param idDevice The device ID (bus, device, function). 907 * @param fOrMask Device flags to set, see IOMMU_DTE_CACHE_F_XXX. 908 * @param idDomain The domain ID. 909 * 910 * @remarks Requires the cache lock to be taken. 911 */ 912 DECL_FORCE_INLINE(void) iommuAmdDteCacheAddAtIndex(PIOMMU pThis, uint16_t idxDte, uint16_t idDevice, uint16_t fFlags, 913 uint16_t idDomain) 914 { 915 pThis->aDeviceIds[idxDte] = idDevice; 916 pThis->aDteCache[idxDte].fFlags = fFlags; 917 pThis->aDteCache[idxDte].idDomain = idDomain; 918 } 919 920 921 /** 922 * Adds a DTE cache entry. 906 923 * 907 924 * @param pDevIns The IOMMU instance data. … … 909 926 * @param pDte The device table entry. 910 927 */ 911 static int iommuAmdDteCacheAdd(PPDMDEVINS pDevIns, uint16_t idDevice, PCDTE_T pDte) 912 { 913 int rc = VINF_SUCCESS; 928 static void iommuAmdDteCacheAdd(PPDMDEVINS pDevIns, uint16_t idDevice, PCDTE_T pDte) 929 { 914 930 uint16_t const fFlags = iommuAmdGetBasicDevFlags(pDte) | IOMMU_DTE_CACHE_F_PRESENT; 915 931 uint16_t const idDomain = pDte->n.u16DomainId; … … 920 936 uint16_t const cDteCache = RT_ELEMENTS(pThis->aDteCache); 921 937 uint16_t idxDte = iommuAmdDteCacheEntryLookup(pThis, idDevice); 922 if (idxDte >= cDteCache) 923 { 924 idxDte = iommuAmdDteCacheEntryGetUnused(pThis); 925 if (idxDte < cDteCache) 926 { 927 pThis->aDeviceIds[idxDte] = idDevice; 928 pThis->aDteCache[idxDte].fFlags = fFlags; 929 pThis->aDteCache[idxDte].idDomain = idDomain; 930 } 931 else 932 rc = VERR_OUT_OF_RESOURCES; 933 } 934 /* else: A DTE cache entry already exists, do nothing. */ 938 if ( idxDte >= cDteCache /* Not found. */ 939 && (idxDte = iommuAmdDteCacheEntryGetUnused(pThis)) < cDteCache) /* Get new/unused slot index. */ 940 iommuAmdDteCacheAddAtIndex(pThis, idxDte, idDevice, fFlags, idDomain); 935 941 936 942 IOMMU_CACHE_UNLOCK(pDevIns, pThis); 937 return rc; 938 } 939 940 941 /** 942 * Adds one or more I/O device flags if the device is already present in the cache. 943 } 944 945 946 /** 947 * Updates flags for an existing DTE cache entry given its index. 948 * 949 * @param pThis The shared IOMMU device state. 950 * @param idxDte The index of the DTE cache entry. 951 * @param fOrMask Device flags to add to the existing flags, see 952 * IOMMU_DTE_CACHE_F_XXX. 953 * @param fAndMask Device flags to remove from the existing flags, see 954 * IOMMU_DTE_CACHE_F_XXX. 955 * 956 * @remarks Requires the cache lock to be taken. 957 */ 958 DECL_FORCE_INLINE(void) iommuAmdDteCacheUpdateFlagsForIndex(PIOMMU pThis, uint16_t idxDte, uint16_t fOrMask, uint16_t fAndMask) 959 { 960 uint16_t const fOldFlags = pThis->aDteCache[idxDte].fFlags; 961 uint16_t const fNewFlags = (fOldFlags | fOrMask) & ~fAndMask; 962 Assert(fOldFlags & IOMMU_DTE_CACHE_F_PRESENT); 963 pThis->aDteCache[idxDte].fFlags = fNewFlags; 964 } 965 966 967 /** 968 * Adds a new DTE cache entry or updates flags for an existing DTE cache entry. 969 * If the cache is full, nothing happens. 970 * 971 * @param pDevIns The IOMMU instance data. 972 * @param pDte The device table entry. 973 * @param idDevice The device ID (bus, device, function). 974 * @param fOrMask Device flags to add to the existing flags, see 975 * IOMMU_DTE_CACHE_F_XXX. 976 * @param fAndMask Device flags to remove from the existing flags, see 977 * IOMMU_DTE_CACHE_F_XXX. 978 */ 979 static void iommuAmdDteCacheAddOrUpdateFlags(PPDMDEVINS pDevIns, PCDTE_T pDte, uint16_t idDevice, uint16_t fOrMask, 980 uint16_t fAndMask) 981 { 982 PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); 983 IOMMU_CACHE_LOCK(pDevIns, pThis); 984 985 uint16_t const cDteCache = RT_ELEMENTS(pThis->aDteCache); 986 uint16_t idxDte = iommuAmdDteCacheEntryLookup(pThis, idDevice); 987 if (idxDte < cDteCache) 988 iommuAmdDteCacheUpdateFlagsForIndex(pThis, idxDte, fOrMask, fAndMask); 989 else if ((idxDte = iommuAmdDteCacheEntryGetUnused(pThis)) < cDteCache) 990 { 991 uint16_t const fFlags = (iommuAmdGetBasicDevFlags(pDte) | IOMMU_DTE_CACHE_F_PRESENT | fOrMask) & ~fAndMask; 992 iommuAmdDteCacheAddAtIndex(pThis, idxDte, idDevice, fFlags, pDte->n.u16DomainId); 993 } 994 /* else: cache is full, shouldn't really happen. */ 995 996 IOMMU_CACHE_UNLOCK(pDevIns, pThis); 997 } 998 999 1000 /** 1001 * Updates flags for an existing DTE cache entry. 943 1002 * 944 1003 * @param pDevIns The IOMMU instance data. … … 956 1015 uint16_t const cDteCache = RT_ELEMENTS(pThis->aDteCache); 957 1016 uint16_t const idxDte = iommuAmdDteCacheEntryLookup(pThis, idDevice); 958 if ( idxDte < cDteCache 959 && (pThis->aDteCache[idxDte].fFlags & IOMMU_DTE_CACHE_F_PRESENT)) 960 { 961 uint16_t const fNewFlags = (pThis->aDteCache[idxDte].fFlags | fOrMask) & ~fAndMask; 962 pThis->aDteCache[idxDte].fFlags = fNewFlags; 963 } 1017 if (idxDte < cDteCache) 1018 iommuAmdDteCacheUpdateFlagsForIndex(pThis, idxDte, fOrMask, fAndMask); 964 1019 965 1020 IOMMU_CACHE_UNLOCK(pDevIns, pThis); … … 3983 4038 if (RT_SUCCESS(rc)) 3984 4039 { 3985 #ifdef IOMMU_WITH_IOTLBE_CACHE3986 iommuAmdDteCacheAdd(pDevIns, idDevice, &Dte);3987 #endif3988 4040 if (Dte.n.u1Valid) 3989 4041 { … … 4035 4087 { 4036 4088 /* Update that addresses requires translation (cumulative permissions of DTE and I/O page tables). */ 4037 iommuAmdDteCacheUpdateFlags(pDevIns, idDevice, IOMMU_DTE_CACHE_F_ADDR_TRANSLATE, 0 /* fAndMask */); 4089 iommuAmdDteCacheAddOrUpdateFlags(pDevIns, &Dte, idDevice, IOMMU_DTE_CACHE_F_ADDR_TRANSLATE, 4090 0 /* fAndMask */); 4038 4091 /* Update IOTLB for the contiguous range of I/O virtual addresses. */ 4039 4092 iommuAmdIotlbAddRange(pDevIns, Aux.idDomain, uIova & X86_PAGE_4K_BASE_MASK, cbContiguous, &AddrOut); … … 4053 4106 #ifdef IOMMU_WITH_IOTLBE_CACHE 4054 4107 /* Update that addresses permissions of DTE apply (but omit address translation). */ 4055 iommuAmdDteCacheUpdateFlags(pDevIns, idDevice, IOMMU_DTE_CACHE_F_IO_PERM, IOMMU_DTE_CACHE_F_ADDR_TRANSLATE); 4108 iommuAmdDteCacheAddOrUpdateFlags(pDevIns, &Dte, idDevice, IOMMU_DTE_CACHE_F_IO_PERM, 4109 IOMMU_DTE_CACHE_F_ADDR_TRANSLATE); 4056 4110 #endif 4057 4111 }
Note:
See TracChangeset
for help on using the changeset viewer.