X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=arch%2Fx86%2Fmm%2Fpageattr.c;h=668205bca15eb46ae3a6871294b08e7943364190;hb=ce0c0e50f94e8c55b00a722e8c6e8d6c802be211;hp=c29ebd037254fb3252b75944e9649cdac1b3059a;hpb=a4928cffe6435caf427ae673131a633c1329dbf3;p=linux-2.6-omap-h63xx.git diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index c29ebd03725..668205bca15 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -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) @@ -483,9 +496,7 @@ static int split_large_page(pte_t *kpte, unsigned long address) goto out_unlock; pbase = (pte_t *)page_address(base); -#ifdef CONFIG_X86_32 - paravirt_alloc_pt(&init_mm, page_to_pfn(base)); -#endif + paravirt_alloc_pte(&init_mm, page_to_pfn(base)); ref_prot = pte_pgprot(pte_clrhuge(*kpte)); #ifdef CONFIG_X86_64 @@ -502,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: * @@ -779,14 +796,20 @@ static inline int change_page_attr_clear(unsigned long addr, int numpages, int _set_memory_uc(unsigned long addr, int numpages) { + /* + * for now UC MINUS. see comments in ioremap_nocache() + */ return change_page_attr_set(addr, numpages, - __pgprot(_PAGE_CACHE_UC)); + __pgprot(_PAGE_CACHE_UC_MINUS)); } int set_memory_uc(unsigned long addr, int numpages) { + /* + * for now UC MINUS. see comments in ioremap_nocache() + */ if (reserve_memtype(addr, addr + numpages * PAGE_SIZE, - _PAGE_CACHE_UC, NULL)) + _PAGE_CACHE_UC_MINUS, NULL)) return -EINVAL; return _set_memory_uc(addr, numpages); @@ -1025,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.