Changeset 100355 in vbox for trunk/src/VBox/Runtime/r0drv/linux
- Timestamp:
- Jul 4, 2023 6:37:35 AM (23 months ago)
- svn:sync-xref-src-repo-rev:
- 158085
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
r100319 r100355 149 149 /** Pointer to the linux memory object. */ 150 150 typedef RTR0MEMOBJLNX *PRTR0MEMOBJLNX; 151 152 153 /********************************************************************************************************************************* 154 * Global Variables * 155 *********************************************************************************************************************************/ 156 /* 157 * Linux allows only a coarse selection of zones for 158 * allocations matching a particular maximum physical address. 159 * 160 * Sorted from high to low physical address! 161 */ 162 static const struct 163 { 164 RTHCPHYS PhysHighest; 165 gfp_t fGfp; 166 } g_aZones[] = 167 { 168 { NIL_RTHCPHYS, GFP_KERNEL }, 169 #if (defined(RT_ARCH_AMD64) || defined(CONFIG_X86_PAE)) && defined(GFP_DMA32) 170 { _4G - 1, GFP_DMA32 }, /* ZONE_DMA32: 0-4GB */ 171 #elif defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64) 172 { _4G - 1, GFP_DMA }, /* ZONE_DMA: 0-4GB */ 173 #endif 174 #if defined(RT_ARCH_AMD64) 175 { _16M - 1, GFP_DMA }, /* ZONE_DMA: 0-16MB */ 176 #elif defined(RT_ARCH_X86) 177 { 896 * _1M - 1, GFP_USER }, /* ZONE_NORMAL (32-bit hosts): 0-896MB */ 178 #endif 179 }; 151 180 152 181 … … 972 1001 973 1002 974 DECLHIDDEN(int) rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable, const char *pszTag) 1003 DECLHIDDEN(int) rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, 1004 bool fExecutable, const char *pszTag) 975 1005 { 976 1006 IPRT_LINUX_SAVE_EFL_AC(); 977 1007 PRTR0MEMOBJLNX pMemLnx; 978 1008 int rc; 979 980 #if (defined(RT_ARCH_AMD64) || defined(RT_ARCH_ARM64) || defined(CONFIG_X86_PAE)) && defined(GFP_DMA32) 981 /* ZONE_DMA32: 0-4GB */ 982 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_CONT, cb, PAGE_SIZE, GFP_DMA32, 983 true /* contiguous */, fExecutable, VERR_NO_CONT_MEMORY, pszTag); 984 if (RT_FAILURE(rc)) 985 #endif 986 #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_ARM64) 987 /* ZONE_DMA: 0-16MB */ 988 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_CONT, cb, PAGE_SIZE, GFP_DMA, 1009 uint32_t idxZone; 1010 1011 /* 1012 * The last zone must be able to satisfy the PhysHighest requirement or there 1013 * will be no zone at all. 1014 */ 1015 if (g_aZones[RT_ELEMENTS(g_aZones) - 1].PhysHighest > PhysHighest) 1016 { 1017 IPRT_LINUX_RESTORE_EFL_AC(); 1018 AssertMsgFailedReturn(("No zone can satisfy PhysHighest=%RHp!\n", PhysHighest), 1019 VERR_NO_CONT_MEMORY); 1020 } 1021 1022 /* Find the first zone matching our PhysHighest requirement. */ 1023 idxZone = 0; 1024 for (;;) 1025 { 1026 if (g_aZones[idxZone].PhysHighest <= PhysHighest) 1027 break; /* We found a zone satisfying the requirement. */ 1028 idxZone++; 1029 } 1030 1031 /* Now try to allocate pages from all the left zones until one succeeds. */ 1032 for (;;) 1033 { 1034 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_CONT, cb, PAGE_SIZE, g_aZones[idxZone].fGfp, 989 1035 true /* contiguous */, fExecutable, VERR_NO_CONT_MEMORY, pszTag); 990 #else 991 /* ZONE_NORMAL (32-bit hosts): 0-896MB */ 992 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_CONT, cb, PAGE_SIZE, GFP_USER, 993 true /* contiguous */, fExecutable, VERR_NO_CONT_MEMORY, pszTag); 994 #endif 1036 idxZone++; 1037 if (RT_SUCCESS(rc) || idxZone == RT_ELEMENTS(g_aZones)) 1038 break; 1039 } 995 1040 if (RT_SUCCESS(rc)) 996 1041 { … … 998 1043 if (RT_SUCCESS(rc)) 999 1044 { 1000 #if defined(RT_STRICT) && (defined(RT_ARCH_AMD64) || defined(CONFIG_HIGHMEM64G))1045 #if defined(RT_STRICT) 1001 1046 size_t iPage = pMemLnx->cPages; 1002 1047 while (iPage-- > 0) 1003 Assert(page_to_phys(pMemLnx->apPages[iPage]) < _4G);1048 Assert(page_to_phys(pMemLnx->apPages[iPage]) < PhysHighest); 1004 1049 #endif 1005 1050 pMemLnx->Core.u.Cont.Phys = page_to_phys(pMemLnx->apPages[0]);
Note:
See TracChangeset
for help on using the changeset viewer.