| 1 |
|
| 2 | |
| 3 | * Copyright (C) 2014 ARM Ltd.
|
| 4 |
|
| 5 | #ifndef __ASM_PTDUMP_H
|
| 6 | #define __ASM_PTDUMP_H
|
| 7 |
|
| 8 | #include <linux/ptdump.h>
|
| 9 |
|
| 10 | #ifdef CONFIG_PTDUMP
|
| 11 |
|
| 12 | #include <linux/mm_types.h>
|
| 13 | #include <linux/seq_file.h>
|
| 14 |
|
| 15 | struct addr_marker {
|
| 16 | unsigned long start_address;
|
| 17 | char *name;
|
| 18 | };
|
| 19 |
|
| 20 | struct ptdump_info {
|
| 21 | struct mm_struct *mm;
|
| 22 | const struct addr_marker *markers;
|
| 23 | unsigned long base_addr;
|
| 24 | };
|
| 25 |
|
| 26 | struct ptdump_prot_bits {
|
| 27 | ptval_t mask;
|
| 28 | ptval_t val;
|
| 29 | const char *set;
|
| 30 | const char *clear;
|
| 31 | };
|
| 32 |
|
| 33 | struct ptdump_pg_level {
|
| 34 | const struct ptdump_prot_bits *bits;
|
| 35 | char name[4];
|
| 36 | int num;
|
| 37 | ptval_t mask;
|
| 38 | };
|
| 39 |
|
| 40 | |
| 41 | * The page dumper groups page table entries of the same type into a single
|
| 42 | * description. It uses pg_state to track the range information while
|
| 43 | * iterating over the pte entries. When the continuity is broken it then
|
| 44 | * dumps out a description of the range.
|
| 45 |
|
| 46 | struct ptdump_pg_state {
|
| 47 | struct ptdump_state ptdump;
|
| 48 | struct ptdump_pg_level *pg_level;
|
| 49 | struct seq_file *seq;
|
| 50 | const struct addr_marker *marker;
|
| 51 | const struct mm_struct *mm;
|
| 52 | unsigned long start_address;
|
| 53 |
|
| 54 | unsigned long end_address;
|
| 55 | int level;
|
| 56 | ptval_t current_prot;
|
| 57 | bool check_wx;
|
| 58 | unsigned long wx_pages;
|
| 59 | unsigned long uxn_pages;
|
| 60 | };
|
| 61 |
|
| 62 | void ptdump_walk(struct seq_file *s, struct ptdump_info *info);
|
| 63 | void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
|
| 64 | pteval_t val);
|
| 65 | void note_page_pte(struct ptdump_state *st, unsigned long addr, pte_t pte);
|
| 66 | void note_page_pmd(struct ptdump_state *st, unsigned long addr, pmd_t pmd);
|
| 67 | void note_page_pud(struct ptdump_state *st, unsigned long addr, pud_t pud);
|
| 68 | void note_page_p4d(struct ptdump_state *st, unsigned long addr, p4d_t p4d);
|
| 69 | void note_page_pgd(struct ptdump_state *st, unsigned long addr, pgd_t pgd);
|
| 70 | void note_page_flush(struct ptdump_state *st);
|
| 71 | #ifdef CONFIG_PTDUMP_DEBUGFS
|
| 72 | #define EFI_RUNTIME_MAP_END DEFAULT_MAP_WINDOW_64
|
| 73 | void __init ptdump_debugfs_register(struct ptdump_info *info, const char *name);
|
| 74 | #else
|
| 75 | static inline void ptdump_debugfs_register(struct ptdump_info *info,
|
| 76 | const char *name) { }
|
| 77 | #endif
|
| 78 | #else
|
| 79 | static inline void note_page(struct ptdump_state *pt_st, unsigned long addr,
|
| 80 | int level, pteval_t val) { }
|
| 81 | static inline void note_page_pte(struct ptdump_state *st, unsigned long addr, pte_t pte) { }
|
| 82 | static inline void note_page_pmd(struct ptdump_state *st, unsigned long addr, pmd_t pmd) { }
|
| 83 | static inline void note_page_pud(struct ptdump_state *st, unsigned long addr, pud_t pud) { }
|
| 84 | static inline void note_page_p4d(struct ptdump_state *st, unsigned long addr, p4d_t p4d) { }
|
| 85 | static inline void note_page_pgd(struct ptdump_state *st, unsigned long addr, pgd_t pgd) { }
|
| 86 | static inline void note_page_flush(struct ptdump_state *st) { }
|
| 87 | #endif
|
| 88 |
|
| 89 | #endif
|