| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | #include "mos/mm/paging/dump.hpp" |
| 4 | |
| 5 | #include "mos/mm/paging/iterator.hpp" |
| 6 | #include "mos/syslog/printk.hpp" |
| 7 | #include "mos/tasks/task_types.hpp" |
| 8 | |
| 9 | static void pagetable_do_dump(ptr_t vaddr, ptr_t vaddr_end, VMFlags flags, pfn_t pfn, pfn_t pfn_end, ptr_t *prev_end_vaddr) |
| 10 | { |
| 11 | if (vaddr - *prev_end_vaddr > MOS_PAGE_SIZE) |
| 12 | pr_info(" VGROUP: " PTR_FMT, vaddr); |
| 13 | |
| 14 | pr_info2(" " PTR_RANGE " -> " PFN_RANGE ", %5zd pages, %pvf, %c%c, %s" , // |
| 15 | vaddr, // |
| 16 | vaddr_end, // |
| 17 | pfn, // |
| 18 | pfn_end, // |
| 19 | (ALIGN_UP_TO_PAGE(vaddr_end) - vaddr) / MOS_PAGE_SIZE, // |
| 20 | (void *) &flags, // |
| 21 | flags & VM_CACHE_DISABLED ? 'C' : '-', // |
| 22 | flags & VM_GLOBAL ? 'G' : '-', // |
| 23 | flags & VM_USER ? "user" : "kernel" // |
| 24 | ); |
| 25 | |
| 26 | *prev_end_vaddr = vaddr_end; |
| 27 | } |
| 28 | |
| 29 | void mm_dump_pagetable(MMContext *mmctx) |
| 30 | { |
| 31 | pr_info("Page Table:" ); |
| 32 | ptr_t tmp = 0; |
| 33 | spinlock_acquire(&mmctx->mm_lock); |
| 34 | |
| 35 | pagetable_iter_t iter = { .pgd.max.next.table: 0 }; |
| 36 | pagetable_iter_init(it: &iter, pgd: mmctx->pgd, vaddr: 0, MOS_USER_END_VADDR); |
| 37 | |
| 38 | pagetable_iter_range_t *range; |
| 39 | while ((range = pagetable_iter_next(it: &iter))) |
| 40 | if (range->present) |
| 41 | pagetable_do_dump(vaddr: range->vaddr, vaddr_end: range->vaddr_end, flags: range->flags, pfn: range->pfn, pfn_end: range->pfn_end, prev_end_vaddr: &tmp); |
| 42 | |
| 43 | pagetable_iter_init(it: &iter, pgd: mmctx->pgd, MOS_KERNEL_START_VADDR, end: 0xffffffffffffffff); |
| 44 | while ((range = pagetable_iter_next(it: &iter))) |
| 45 | if (range->present) |
| 46 | pagetable_do_dump(vaddr: range->vaddr, vaddr_end: range->vaddr_end, flags: range->flags, pfn: range->pfn, pfn_end: range->pfn_end, prev_end_vaddr: &tmp); |
| 47 | |
| 48 | spinlock_release(&mmctx->mm_lock); |
| 49 | } |
| 50 | |
| 51 | void mm_dump_current_pagetable() |
| 52 | { |
| 53 | const char *cpu_pagetable_source = current_cpu->mm_context == platform_info->kernel_mm ? "Kernel" : NULL; |
| 54 | |
| 55 | if (current_thread) |
| 56 | { |
| 57 | pr_emph("Current task: thread %pt, process %pp" , current_thread, current_process); |
| 58 | pr_emph("Task Page Table:" ); |
| 59 | mm_dump_pagetable(current_process->mm); |
| 60 | if (current_cpu->mm_context == current_process->mm) |
| 61 | cpu_pagetable_source = "Current Process" ; |
| 62 | } |
| 63 | else |
| 64 | { |
| 65 | pr_emph("Kernel Page Table:" ); |
| 66 | mm_dump_pagetable(mmctx: platform_info->kernel_mm); |
| 67 | } |
| 68 | |
| 69 | if (cpu_pagetable_source) |
| 70 | { |
| 71 | pr_emph("CPU Page Table: %s" , cpu_pagetable_source); |
| 72 | } |
| 73 | else |
| 74 | { |
| 75 | pr_emph("CPU Page Table:" ); |
| 76 | mm_dump_pagetable(current_cpu->mm_context); |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | MOS_PANIC_HOOK_FEAT(vmm, mm_dump_current_pagetable, "dump current pagetable" ); |
| 81 | |