Rev 826 | Rev 1044 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 826 | Rev 832 | ||
---|---|---|---|
Line 101... | Line 101... | ||
101 | * |
101 | * |
102 | * Remove any mapping of 'page' within address space 'as'. |
102 | * Remove any mapping of 'page' within address space 'as'. |
103 | * TLB shootdown should follow in order to make effects of |
103 | * TLB shootdown should follow in order to make effects of |
104 | * this call visible. |
104 | * this call visible. |
105 | * |
105 | * |
- | 106 | * Empty page tables except PTL0 are freed. |
|
- | 107 | * |
|
106 | * The address space must be locked and interrupts must be disabled. |
108 | * The address space must be locked and interrupts must be disabled. |
107 | * |
109 | * |
108 | * @param as Address space to wich page belongs. |
110 | * @param as Address space to wich page belongs. |
109 | * @param page Virtual address of the page to be demapped. |
111 | * @param page Virtual address of the page to be demapped. |
110 | */ |
112 | */ |
111 | void pt_mapping_remove(as_t *as, __address page) |
113 | void pt_mapping_remove(as_t *as, __address page) |
112 | { |
114 | { |
113 | pte_t *ptl0, *ptl1, *ptl2, *ptl3; |
115 | pte_t *ptl0, *ptl1, *ptl2, *ptl3; |
- | 116 | bool empty = true; |
|
- | 117 | int i; |
|
- | 118 | ||
- | 119 | /* |
|
- | 120 | * First, remove the mapping, if it exists. |
|
- | 121 | */ |
|
114 | 122 | ||
115 | ptl0 = (pte_t *) PA2KA((__address) as->page_table); |
123 | ptl0 = (pte_t *) PA2KA((__address) as->page_table); |
116 | 124 | ||
117 | if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) |
125 | if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) |
118 | return; |
126 | return; |
Line 129... | Line 137... | ||
129 | 137 | ||
130 | ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page))); |
138 | ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page))); |
131 | 139 | ||
132 | /* Destroy the mapping. Setting to PAGE_NOT_PRESENT is not sufficient. */ |
140 | /* Destroy the mapping. Setting to PAGE_NOT_PRESENT is not sufficient. */ |
133 | memsetb((__address) &ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0); |
141 | memsetb((__address) &ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0); |
- | 142 | ||
- | 143 | /* |
|
- | 144 | * Second, free all empty tables along the way from PTL3 down to PTL0. |
|
- | 145 | */ |
|
- | 146 | ||
- | 147 | /* check PTL3 */ |
|
- | 148 | for (i = 0; i < PTL3_ENTRIES; i++) { |
|
- | 149 | if (PTE_VALID(&ptl3[i])) { |
|
- | 150 | empty = false; |
|
- | 151 | break; |
|
- | 152 | } |
|
- | 153 | } |
|
- | 154 | if (empty) { |
|
- | 155 | /* |
|
- | 156 | * PTL3 is empty. |
|
- | 157 | * Release the frame and remove PTL3 pointer from preceding table. |
|
- | 158 | */ |
|
- | 159 | frame_free(ADDR2PFN(KA2PA((__address) ptl3))); |
|
- | 160 | if (PTL2_ENTRIES) |
|
- | 161 | memsetb((__address) &ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0); |
|
- | 162 | else if (PTL1_ENTRIES) |
|
- | 163 | memsetb((__address) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); |
|
- | 164 | else |
|
- | 165 | memsetb((__address) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); |
|
- | 166 | } else { |
|
- | 167 | /* |
|
- | 168 | * PTL3 is not empty. |
|
- | 169 | * Therefore, there must be a path from PTL0 to PTL3 and |
|
- | 170 | * thus nothing to free in higher levels. |
|
- | 171 | */ |
|
- | 172 | return; |
|
- | 173 | } |
|
- | 174 | ||
- | 175 | /* check PTL2, empty is still true */ |
|
- | 176 | if (PTL2_ENTRIES) { |
|
- | 177 | for (i = 0; i < PTL2_ENTRIES; i++) { |
|
- | 178 | if (PTE_VALID(&ptl2[i])) { |
|
- | 179 | empty = false; |
|
- | 180 | break; |
|
- | 181 | } |
|
- | 182 | } |
|
- | 183 | if (empty) { |
|
- | 184 | /* |
|
- | 185 | * PTL2 is empty. |
|
- | 186 | * Release the frame and remove PTL2 pointer from preceding table. |
|
- | 187 | */ |
|
- | 188 | frame_free(ADDR2PFN(KA2PA((__address) ptl2))); |
|
- | 189 | if (PTL1_ENTRIES) |
|
- | 190 | memsetb((__address) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); |
|
- | 191 | else |
|
- | 192 | memsetb((__address) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); |
|
- | 193 | } |
|
- | 194 | else { |
|
- | 195 | /* |
|
- | 196 | * PTL2 is not empty. |
|
- | 197 | * Therefore, there must be a path from PTL0 to PTL2 and |
|
- | 198 | * thus nothing to free in higher levels. |
|
- | 199 | */ |
|
- | 200 | return; |
|
- | 201 | } |
|
- | 202 | } |
|
- | 203 | ||
- | 204 | /* check PTL1, empty is still true */ |
|
- | 205 | if (PTL1_ENTRIES) { |
|
- | 206 | for (i = 0; i < PTL1_ENTRIES; i++) { |
|
- | 207 | if (PTE_VALID(&ptl1[i])) { |
|
- | 208 | empty = false; |
|
- | 209 | break; |
|
- | 210 | } |
|
- | 211 | } |
|
- | 212 | if (empty) { |
|
- | 213 | /* |
|
- | 214 | * PTL1 is empty. |
|
- | 215 | * Release the frame and remove PTL1 pointer from preceding table. |
|
- | 216 | */ |
|
- | 217 | frame_free(ADDR2PFN(KA2PA((__address) ptl1))); |
|
- | 218 | memsetb((__address) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); |
|
- | 219 | } |
|
- | 220 | } |
|
- | 221 | ||
134 | } |
222 | } |
135 | 223 | ||
136 | /** Find mapping for virtual page in hierarchical page tables. |
224 | /** Find mapping for virtual page in hierarchical page tables. |
137 | * |
225 | * |
138 | * Find mapping for virtual page. |
226 | * Find mapping for virtual page. |