Page 1 of 1
Paging unmap pages
Posted: Mon Apr 14, 2008 6:52 am
by Jeko
When I unmap a page, which of them must I flush:
- Virtual addr of the page
- Virtual addr of the PTE that contains the page
- Virtual addr of the PDE that contains the page
I think only first two. The second only if it is possible to deallocate the frame of the page table used to map the page, so, if in the page table there isn't any other page.
Posted: Mon Apr 14, 2008 7:12 am
by jgraef
Hi,
It would be enough by setting the enable bit in the page table entry to 0. The simplest way is to set the whole dword to zero, because playing with bitmask would be just pointless.
Posted: Mon Apr 14, 2008 7:23 am
by Jeko
jgraef wrote:Hi,
It would be enough by setting the enable bit in the page table entry to 0. The simplest way is to set the whole dword to zero, because playing with bitmask would be just pointless.
Mustn't I flush any page?
Posted: Mon Apr 14, 2008 7:45 am
by Combuster
Yes, you should flush the entry. Try invlpg or reloading CR3. The processor doesn't maintain coherency between page tables in memory, and the TLB cache.
Posted: Mon Apr 14, 2008 8:08 am
by Jeko
I do something like this when I unmap a page:
Code: Select all
// Unmap the page.
*ADDR_TO_PTE(vir_addr) = 0;
// Invalidate the page in the TLB cache.
flush_tlb_single(vir_addr);
// Check if it is possible to deallocate the frame
// of the page table used to map the address
// So let's examine all entries in the page table
// where the address is mapped.
for (temp = PAGE_DIR_ALIGN(vir_addr);
temp < PAGE_DIR_ALIGN_UP(vir_addr);
temp += PAGE_SIZE) {
if ((*ADDR_TO_PTE(temp) & P_PRESENT) == P_PRESENT) {
return;
}
}
flush_tlb_single(ADDR_TO_PTE(vir_addr));
// No PTEs found... deallocate the page table!
push_frame(*ADDR_TO_PDE(vir_addr));
*ADDR_TO_PDE(vir_addr) = 0;