Recursively free all pages and page tables, including the page table at the given table_physaddr.
(physical_memory_offset: VirtAddr,
frame_allocator: &mut MultilevelBitmapFrameAllocator,
physaddr: PhysAddr,
level: u16)
| 647 | /// Recursively free all pages and page tables, including the page |
| 648 | /// table at the given table_physaddr. |
| 649 | fn free_pages_rec(physical_memory_offset: VirtAddr, |
| 650 | frame_allocator: &mut MultilevelBitmapFrameAllocator, |
| 651 | physaddr: PhysAddr, |
| 652 | level: u16) { |
| 653 | |
| 654 | if level == 0 { |
| 655 | // A frame, not a table |
| 656 | frame_allocator.deallocate_frame( |
| 657 | PhysFrame::containing_address(physaddr)); |
| 658 | return; |
| 659 | } |
| 660 | |
| 661 | let table = unsafe{&mut *(physical_memory_offset |
| 662 | + physaddr.as_u64()) |
| 663 | .as_mut_ptr() as &mut PageTable}; |
| 664 | for entry in table.iter() { |
| 665 | if !entry.is_unused() { |
| 666 | if level == 1 || entry.flags().contains(PageTableFlags::HUGE_PAGE) { |
| 667 | // Maps a frame, not a page table |
| 668 | if entry.flags().contains(PageTableFlags::PRESENT | |
| 669 | PageTableFlags::WRITABLE | |
| 670 | PageTableFlags::USER_ACCESSIBLE) { |
| 671 | // A user frame => deallocate |
| 672 | frame_allocator.deallocate_frame( |
| 673 | entry.frame().unwrap()); |
| 674 | } |
| 675 | } else { |
| 676 | // A page table |
| 677 | free_pages_rec(physical_memory_offset, |
| 678 | frame_allocator, |
| 679 | entry.addr(), |
| 680 | level - 1); |
| 681 | } |
| 682 | } |
| 683 | } |
| 684 | // Free page table |
| 685 | frame_allocator.deallocate_frame( |
| 686 | PhysFrame::from_start_address(physaddr).unwrap()); |
| 687 | } |
| 688 | |
| 689 | /// Free all user-accessible pages and the page table frames |
| 690 | /// |
no test coverage detected