* Walks the page tables to translate a kernel virtual address to a * physical address. Returns true if the kva is valid and stores the * physical address in pa if it is not NULL. */
| 1371 | * physical address in pa if it is not NULL. |
| 1372 | */ |
| 1373 | bool |
| 1374 | pmap_klookup(vm_offset_t va, vm_paddr_t *pa) |
| 1375 | { |
| 1376 | pt_entry_t *pte, tpte; |
| 1377 | register_t intr; |
| 1378 | uint64_t par; |
| 1379 | |
| 1380 | /* |
| 1381 | * Disable interrupts so we don't get interrupted between asking |
| 1382 | * for address translation, and getting the result back. |
| 1383 | */ |
| 1384 | intr = intr_disable(); |
| 1385 | par = arm64_address_translate_s1e1r(va); |
| 1386 | intr_restore(intr); |
| 1387 | |
| 1388 | if (PAR_SUCCESS(par)) { |
| 1389 | if (pa != NULL) |
| 1390 | *pa = (par & PAR_PA_MASK) | (va & PAR_LOW_MASK); |
| 1391 | return (true); |
| 1392 | } |
| 1393 | |
| 1394 | /* |
| 1395 | * Fall back to walking the page table. The address translation |
| 1396 | * instruction may fail when the page is in a break-before-make |
| 1397 | * sequence. As we only clear the valid bit in said sequence we |
| 1398 | * can walk the page table to find the physical address. |
| 1399 | */ |
| 1400 | |
| 1401 | pte = pmap_l1(kernel_pmap, va); |
| 1402 | if (pte == NULL) |
| 1403 | return (false); |
| 1404 | |
| 1405 | /* |
| 1406 | * A concurrent pmap_update_entry() will clear the entry's valid bit |
| 1407 | * but leave the rest of the entry unchanged. Therefore, we treat a |
| 1408 | * non-zero entry as being valid, and we ignore the valid bit when |
| 1409 | * determining whether the entry maps a block, page, or table. |
| 1410 | */ |
| 1411 | tpte = pmap_load(pte); |
| 1412 | if (tpte == 0) |
| 1413 | return (false); |
| 1414 | if ((tpte & ATTR_DESCR_TYPE_MASK) == ATTR_DESCR_TYPE_BLOCK) { |
| 1415 | if (pa != NULL) |
| 1416 | *pa = (tpte & ~ATTR_MASK) | (va & L1_OFFSET); |
| 1417 | return (true); |
| 1418 | } |
| 1419 | pte = pmap_l1_to_l2(&tpte, va); |
| 1420 | tpte = pmap_load(pte); |
| 1421 | if (tpte == 0) |
| 1422 | return (false); |
| 1423 | if ((tpte & ATTR_DESCR_TYPE_MASK) == ATTR_DESCR_TYPE_BLOCK) { |
| 1424 | if (pa != NULL) |
| 1425 | *pa = (tpte & ~ATTR_MASK) | (va & L2_OFFSET); |
| 1426 | return (true); |
| 1427 | } |
| 1428 | pte = pmap_l2_to_l3(&tpte, va); |
| 1429 | tpte = pmap_load(pte); |
| 1430 | if (tpte == 0) |
no test coverage detected