Changeset 22613 in vbox
- Timestamp:
- Aug 31, 2009 3:40:33 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
r22531 r22613 62 62 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) 63 63 # define VBOX_USE_INSERT_PAGE 64 #endif 65 #if defined(CONFIG_X86_PAE) \ 66 && ( HAVE_26_STYLE_REMAP_PAGE_RANGE \ 67 || (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11))) 68 # define VBOX_USE_PAE_HACK 64 69 #endif 65 70 … … 1147 1152 1148 1153 1154 #ifdef VBOX_USE_PAE_HACK 1155 /** 1156 * Replace the PFN of a PTE entry of a reserved page. This hack is required for older Linux 1157 * kernels which don't provide remap_pfn_range(). 1158 */ 1159 static int fixPte(struct mm_struct *mm, unsigned long ulAddr, unsigned long long u64Phys) 1160 { 1161 int rc = -ENOMEM; 1162 pgd_t *pgd; 1163 1164 spin_lock(&mm->page_table_lock); 1165 1166 pgd = pgd_offset(mm, ulAddr); 1167 if (!pgd_none(*pgd) && !pgd_bad(*pgd)) 1168 { 1169 pmd_t *pmd = pmd_offset(pgd, ulAddr); 1170 if (!pmd_none(*pmd)) 1171 { 1172 pte_t *ptep = pte_offset_map(pmd, ulAddr); 1173 if (ptep) 1174 { 1175 pte_t pte = *ptep; 1176 pte.pte_high &= 0xfff00000; 1177 pte.pte_high |= ((u64Phys >> 32) & 0x000fffff); 1178 pte.pte_low &= 0x00000fff; 1179 pte.pte_low |= (u64Phys & 0xfffff000); 1180 set_pte(ptep, pte); 1181 pte_unmap(ptep); 1182 rc = 0; 1183 } 1184 } 1185 } 1186 1187 spin_unlock(&mm->page_table_lock); 1188 return rc; 1189 } 1190 #endif /* VBOX_USE_PAE_HACK */ 1191 1192 1149 1193 int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process) 1150 1194 { … … 1184 1228 const size_t cPages = pMemLnxToMap->Core.cb >> PAGE_SHIFT; 1185 1229 size_t iPage; 1230 #ifdef VBOX_USE_PAE_HACK 1231 struct page *pDummyPage = alloc_page(GFP_USER); 1232 RTHCPHYS DummyPhys; 1233 1234 if (!pDummyPage) 1235 goto error; 1236 1237 SetPageReserved(pDummyPage); 1238 DummyPhys = page_to_phys(pDummyPage); 1239 #endif 1186 1240 rc = 0; 1187 1241 if (pMemLnxToMap->cPages) … … 1190 1244 { 1191 1245 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) 1192 uint64_t u64Phys = page_to_phys(pMemLnxToMap->apPages[iPage]);1246 RTHCPHYS Phys = page_to_phys(pMemLnxToMap->apPages[iPage]); 1193 1247 #endif 1194 1248 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(HAVE_26_STYLE_REMAP_PAGE_RANGE) … … 1196 1250 AssertBreakStmt(vma, rc = VERR_INTERNAL_ERROR); 1197 1251 #endif 1198 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) && defined(RT_ARCH_X86)1252 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && defined(RT_ARCH_X86) 1199 1253 /* remap_page_range() limitation on x86 */ 1200 1254 AssertBreakStmt(u64Phys < _4G, rc = VERR_NO_MEMORY); … … 1206 1260 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) 1207 1261 rc = remap_pfn_range(vma, ulAddrCur, page_to_pfn(pMemLnxToMap->apPages[iPage]), PAGE_SIZE, fPg); 1208 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(HAVE_26_STYLE_REMAP_PAGE_RANGE)1262 #elif defined(VBOX_USE_PAE_HACK) 1209 1263 rc = remap_page_range(vma, ulAddrCur, u64Phys, PAGE_SIZE, fPg); 1264 if (rc) 1265 { 1266 rc = VERR_NO_MEMORY; 1267 break; 1268 } 1269 rc = fixPte(pTask->mm, ulAddrCur, u64Phys); 1210 1270 #else /* 2.4 */ 1211 1271 rc = remap_page_range(ulAddrCur, u64Phys, PAGE_SIZE, fPg); 1212 1272 #endif 1213 1273 if (rc) 1274 { 1275 rc = VERR_NO_MEMORY; 1214 1276 break; 1277 } 1215 1278 } 1216 1279 } … … 1235 1298 AssertBreakStmt(vma, rc = VERR_INTERNAL_ERROR); 1236 1299 #endif 1237 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) && defined(RT_ARCH_X86)1300 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && defined(RT_ARCH_X86) 1238 1301 /* remap_page_range() limitation on x86 */ 1239 1302 AssertBreakStmt(Phys < _4G, rc = VERR_NO_MEMORY); … … 1242 1305 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) 1243 1306 rc = remap_pfn_range(vma, ulAddrCur, Phys, PAGE_SIZE, fPg); 1244 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(HAVE_26_STYLE_REMAP_PAGE_RANGE) 1245 rc = remap_page_range(vma, ulAddrCur, Phys, PAGE_SIZE, fPg); 1307 #elif defined(VBOX_USE_PAE_HACK) 1308 rc = remap_page_range(vma, ulAddrCur, DummyPhys, PAGE_SIZE, fPg); 1309 if (rc) 1310 { 1311 rc = VERR_NO_MEMORY; 1312 break; 1313 } 1314 rc = fixPte(pTask->mm, ulAddrCur, Phys); 1246 1315 #else /* 2.4 */ 1247 1316 rc = remap_page_range(ulAddrCur, Phys, PAGE_SIZE, fPg); 1248 1317 #endif 1249 1318 if (rc) 1319 { 1320 rc = VERR_NO_MEMORY; 1250 1321 break; 1322 } 1251 1323 } 1252 1324 } 1253 1325 } 1326 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) && defined(CONFIG_X86_PAE) 1327 __free_page(pDummyPage); 1328 #endif 1254 1329 if (!rc) 1255 1330 { … … 1270 1345 } 1271 1346 1347 #ifdef VBOX_USE_PAE_HACK 1348 error: 1349 #endif 1272 1350 up_write(&pTask->mm->mmap_sem); 1273 1351
Note:
See TracChangeset
for help on using the changeset viewer.