|
@@ -34,6 +34,19 @@ struct cpa_data {
|
|
|
unsigned force_split : 1;
|
|
|
};
|
|
|
|
|
|
+static unsigned long direct_pages_count[PG_LEVEL_NUM];
|
|
|
+
|
|
|
+void __meminit update_page_count(int level, unsigned long pages)
|
|
|
+{
|
|
|
+#ifdef CONFIG_PROC_FS
|
|
|
+ unsigned long flags;
|
|
|
+ /* Protect against CPA */
|
|
|
+ spin_lock_irqsave(&pgd_lock, flags);
|
|
|
+ direct_pages_count[level] += pages;
|
|
|
+ spin_unlock_irqrestore(&pgd_lock, flags);
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
|
|
static inline unsigned long highmap_start_pfn(void)
|
|
@@ -500,6 +513,12 @@ static int split_large_page(pte_t *kpte, unsigned long address)
|
|
|
for (i = 0; i < PTRS_PER_PTE; i++, pfn += pfninc)
|
|
|
set_pte(&pbase[i], pfn_pte(pfn, ref_prot));
|
|
|
|
|
|
+ if (address >= (unsigned long)__va(0) &&
|
|
|
+ address < (unsigned long)__va(max_pfn_mapped << PAGE_SHIFT)) {
|
|
|
+ direct_pages_count[level]--;
|
|
|
+ direct_pages_count[level - 1] += PTRS_PER_PTE;
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
* Install the new, split up pagetable. Important details here:
|
|
|
*
|
|
@@ -1029,6 +1048,22 @@ bool kernel_page_present(struct page *page)
|
|
|
|
|
|
#endif /* CONFIG_DEBUG_PAGEALLOC */
|
|
|
|
|
|
+#ifdef CONFIG_PROC_FS
|
|
|
+int arch_report_meminfo(char *page)
|
|
|
+{
|
|
|
+ int n;
|
|
|
+ n = sprintf(page, "DirectMap4k: %8lu\n"
|
|
|
+ "DirectMap2M: %8lu\n",
|
|
|
+ direct_pages_count[PG_LEVEL_4K],
|
|
|
+ direct_pages_count[PG_LEVEL_2M]);
|
|
|
+#ifdef CONFIG_X86_64
|
|
|
+ n += sprintf(page + n, "DirectMap1G: %8lu\n",
|
|
|
+ direct_pages_count[PG_LEVEL_1G]);
|
|
|
+#endif
|
|
|
+ return n;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
/*
|
|
|
* The testcases use internal knowledge of the implementation that shouldn't
|
|
|
* be exposed to the rest of the kernel. Include these directly here.
|