* Extract from the kernel page table the physical address * that is mapped by the given virtual address "va". */
| 1086 | * that is mapped by the given virtual address "va". |
| 1087 | */ |
| 1088 | vm_paddr_t |
| 1089 | pmap_kextract(vm_offset_t va) |
| 1090 | { |
| 1091 | vm_paddr_t pa; |
| 1092 | pt1_entry_t pte1; |
| 1093 | pt2_entry_t pte2; |
| 1094 | |
| 1095 | pte1 = pte1_load(kern_pte1(va)); |
| 1096 | if (pte1_is_section(pte1)) { |
| 1097 | pa = pte1_pa(pte1) | (va & PTE1_OFFSET); |
| 1098 | } else if (pte1_is_link(pte1)) { |
| 1099 | /* |
| 1100 | * We should beware of concurrent promotion that changes |
| 1101 | * pte1 at this point. However, it's not a problem as PT2 |
| 1102 | * page is preserved by promotion in PT2TAB. So even if |
| 1103 | * it happens, using of PT2MAP is still safe. |
| 1104 | * |
| 1105 | * QQQ: However, concurrent removing is a problem which |
| 1106 | * ends in abort on PT2MAP space. Locking must be used |
| 1107 | * to deal with this. |
| 1108 | */ |
| 1109 | pte2 = pte2_load(pt2map_entry(va)); |
| 1110 | pa = pte2_pa(pte2) | (va & PTE2_OFFSET); |
| 1111 | } |
| 1112 | else { |
| 1113 | panic("%s: va %#x pte1 %#x", __func__, va, pte1); |
| 1114 | } |
| 1115 | return (pa); |
| 1116 | } |
| 1117 | |
| 1118 | /* |
| 1119 | * Extract from the kernel page table the physical address |
no test coverage detected