aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/mm/pageattr.c48
-rw-r--r--include/asm-x86/pgtable.h6
2 files changed, 31 insertions, 23 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 668205bca15e..0a3f5e047f89 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -34,18 +34,40 @@ struct cpa_data {
34 unsigned force_split : 1; 34 unsigned force_split : 1;
35}; 35};
36 36
37#ifdef CONFIG_PROC_FS
37static unsigned long direct_pages_count[PG_LEVEL_NUM]; 38static unsigned long direct_pages_count[PG_LEVEL_NUM];
38 39
39void __meminit update_page_count(int level, unsigned long pages) 40void update_page_count(int level, unsigned long pages)
40{ 41{
41#ifdef CONFIG_PROC_FS
42 unsigned long flags; 42 unsigned long flags;
43
43 /* Protect against CPA */ 44 /* Protect against CPA */
44 spin_lock_irqsave(&pgd_lock, flags); 45 spin_lock_irqsave(&pgd_lock, flags);
45 direct_pages_count[level] += pages; 46 direct_pages_count[level] += pages;
46 spin_unlock_irqrestore(&pgd_lock, flags); 47 spin_unlock_irqrestore(&pgd_lock, flags);
48}
49
50static void split_page_count(int level)
51{
52 direct_pages_count[level]--;
53 direct_pages_count[level - 1] += PTRS_PER_PTE;
54}
55
56int arch_report_meminfo(char *page)
57{
58 int n = sprintf(page, "DirectMap4k: %8lu\n"
59 "DirectMap2M: %8lu\n",
60 direct_pages_count[PG_LEVEL_4K],
61 direct_pages_count[PG_LEVEL_2M]);
62#ifdef CONFIG_X86_64
63 n += sprintf(page + n, "DirectMap1G: %8lu\n",
64 direct_pages_count[PG_LEVEL_1G]);
47#endif 65#endif
66 return n;
48} 67}
68#else
69static inline void split_page_count(int level) { }
70#endif
49 71
50#ifdef CONFIG_X86_64 72#ifdef CONFIG_X86_64
51 73
@@ -514,10 +536,8 @@ static int split_large_page(pte_t *kpte, unsigned long address)
514 set_pte(&pbase[i], pfn_pte(pfn, ref_prot)); 536 set_pte(&pbase[i], pfn_pte(pfn, ref_prot));
515 537
516 if (address >= (unsigned long)__va(0) && 538 if (address >= (unsigned long)__va(0) &&
517 address < (unsigned long)__va(max_pfn_mapped << PAGE_SHIFT)) { 539 address < (unsigned long)__va(max_pfn_mapped << PAGE_SHIFT))
518 direct_pages_count[level]--; 540 split_page_count(level);
519 direct_pages_count[level - 1] += PTRS_PER_PTE;
520 }
521 541
522 /* 542 /*
523 * Install the new, split up pagetable. Important details here: 543 * Install the new, split up pagetable. Important details here:
@@ -1048,22 +1068,6 @@ bool kernel_page_present(struct page *page)
1048 1068
1049#endif /* CONFIG_DEBUG_PAGEALLOC */ 1069#endif /* CONFIG_DEBUG_PAGEALLOC */
1050 1070
1051#ifdef CONFIG_PROC_FS
1052int 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
1067/* 1071/*
1068 * The testcases use internal knowledge of the implementation that shouldn't 1072 * The testcases use internal knowledge of the implementation that shouldn't
1069 * be exposed to the rest of the kernel. Include these directly here. 1073 * be exposed to the rest of the kernel. Include these directly here.
diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h
index 111564fa5e70..bd26559dc8e8 100644
--- a/include/asm-x86/pgtable.h
+++ b/include/asm-x86/pgtable.h
@@ -372,7 +372,11 @@ enum {
372 PG_LEVEL_NUM 372 PG_LEVEL_NUM
373}; 373};
374 374
375void update_page_count(int level, unsigned long pages); 375#ifdef CONFIG_PROC_FS
376extern void update_page_count(int level, unsigned long pages);
377#else
378static inline void update_page_count(int level, unsigned long pages) { }
379#endif
376 380
377/* 381/*
378 * Helper function that returns the kernel pagetable entry controlling 382 * Helper function that returns the kernel pagetable entry controlling