diff options
Diffstat (limited to 'arch/x86/mm/pageattr.c')
-rw-r--r-- | arch/x86/mm/pageattr.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 60bcb5b6a37e..668205bca15e 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -34,6 +34,19 @@ struct cpa_data { | |||
34 | unsigned force_split : 1; | 34 | unsigned force_split : 1; |
35 | }; | 35 | }; |
36 | 36 | ||
37 | static unsigned long direct_pages_count[PG_LEVEL_NUM]; | ||
38 | |||
39 | void __meminit update_page_count(int level, unsigned long pages) | ||
40 | { | ||
41 | #ifdef CONFIG_PROC_FS | ||
42 | unsigned long flags; | ||
43 | /* Protect against CPA */ | ||
44 | spin_lock_irqsave(&pgd_lock, flags); | ||
45 | direct_pages_count[level] += pages; | ||
46 | spin_unlock_irqrestore(&pgd_lock, flags); | ||
47 | #endif | ||
48 | } | ||
49 | |||
37 | #ifdef CONFIG_X86_64 | 50 | #ifdef CONFIG_X86_64 |
38 | 51 | ||
39 | static inline unsigned long highmap_start_pfn(void) | 52 | static inline unsigned long highmap_start_pfn(void) |
@@ -500,6 +513,12 @@ static int split_large_page(pte_t *kpte, unsigned long address) | |||
500 | for (i = 0; i < PTRS_PER_PTE; i++, pfn += pfninc) | 513 | for (i = 0; i < PTRS_PER_PTE; i++, pfn += pfninc) |
501 | set_pte(&pbase[i], pfn_pte(pfn, ref_prot)); | 514 | set_pte(&pbase[i], pfn_pte(pfn, ref_prot)); |
502 | 515 | ||
516 | if (address >= (unsigned long)__va(0) && | ||
517 | address < (unsigned long)__va(max_pfn_mapped << PAGE_SHIFT)) { | ||
518 | direct_pages_count[level]--; | ||
519 | direct_pages_count[level - 1] += PTRS_PER_PTE; | ||
520 | } | ||
521 | |||
503 | /* | 522 | /* |
504 | * Install the new, split up pagetable. Important details here: | 523 | * Install the new, split up pagetable. Important details here: |
505 | * | 524 | * |
@@ -1029,6 +1048,22 @@ bool kernel_page_present(struct page *page) | |||
1029 | 1048 | ||
1030 | #endif /* CONFIG_DEBUG_PAGEALLOC */ | 1049 | #endif /* CONFIG_DEBUG_PAGEALLOC */ |
1031 | 1050 | ||
1051 | #ifdef CONFIG_PROC_FS | ||
1052 | int arch_report_meminfo(char *page) | ||
1053 | { | ||
1054 | int n; | ||
1055 | n = sprintf(page, "DirectMap4k: %8lu\n" | ||
1056 | "DirectMap2M: %8lu\n", | ||
1057 | direct_pages_count[PG_LEVEL_4K], | ||
1058 | direct_pages_count[PG_LEVEL_2M]); | ||
1059 | #ifdef CONFIG_X86_64 | ||
1060 | n += sprintf(page + n, "DirectMap1G: %8lu\n", | ||
1061 | direct_pages_count[PG_LEVEL_1G]); | ||
1062 | #endif | ||
1063 | return n; | ||
1064 | } | ||
1065 | #endif | ||
1066 | |||
1032 | /* | 1067 | /* |
1033 | * The testcases use internal knowledge of the implementation that shouldn't | 1068 | * The testcases use internal knowledge of the implementation that shouldn't |
1034 | * be exposed to the rest of the kernel. Include these directly here. | 1069 | * be exposed to the rest of the kernel. Include these directly here. |