diff options
Diffstat (limited to 'arch/i386/mm')
| -rw-r--r-- | arch/i386/mm/hugetlbpage.c | 12 | ||||
| -rw-r--r-- | arch/i386/mm/init.c | 6 | ||||
| -rw-r--r-- | arch/i386/mm/pageattr.c | 20 |
3 files changed, 16 insertions, 22 deletions
diff --git a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c index d524127c9afc..a7d891585411 100644 --- a/arch/i386/mm/hugetlbpage.c +++ b/arch/i386/mm/hugetlbpage.c | |||
| @@ -48,18 +48,6 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) | |||
| 48 | return (pte_t *) pmd; | 48 | return (pte_t *) pmd; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | /* | ||
| 52 | * This function checks for proper alignment of input addr and len parameters. | ||
| 53 | */ | ||
| 54 | int is_aligned_hugepage_range(unsigned long addr, unsigned long len) | ||
| 55 | { | ||
| 56 | if (len & ~HPAGE_MASK) | ||
| 57 | return -EINVAL; | ||
| 58 | if (addr & ~HPAGE_MASK) | ||
| 59 | return -EINVAL; | ||
| 60 | return 0; | ||
| 61 | } | ||
| 62 | |||
| 63 | #if 0 /* This is just for testing */ | 51 | #if 0 /* This is just for testing */ |
| 64 | struct page * | 52 | struct page * |
| 65 | follow_huge_addr(struct mm_struct *mm, unsigned long address, int write) | 53 | follow_huge_addr(struct mm_struct *mm, unsigned long address, int write) |
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 2700f01994ba..7ba55a6e2dbc 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c | |||
| @@ -270,7 +270,7 @@ static void __init permanent_kmaps_init(pgd_t *pgd_base) | |||
| 270 | 270 | ||
| 271 | static void __meminit free_new_highpage(struct page *page) | 271 | static void __meminit free_new_highpage(struct page *page) |
| 272 | { | 272 | { |
| 273 | set_page_count(page, 1); | 273 | init_page_count(page); |
| 274 | __free_page(page); | 274 | __free_page(page); |
| 275 | totalhigh_pages++; | 275 | totalhigh_pages++; |
| 276 | } | 276 | } |
| @@ -727,7 +727,7 @@ void free_initmem(void) | |||
| 727 | addr = (unsigned long)(&__init_begin); | 727 | addr = (unsigned long)(&__init_begin); |
| 728 | for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { | 728 | for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { |
| 729 | ClearPageReserved(virt_to_page(addr)); | 729 | ClearPageReserved(virt_to_page(addr)); |
| 730 | set_page_count(virt_to_page(addr), 1); | 730 | init_page_count(virt_to_page(addr)); |
| 731 | memset((void *)addr, 0xcc, PAGE_SIZE); | 731 | memset((void *)addr, 0xcc, PAGE_SIZE); |
| 732 | free_page(addr); | 732 | free_page(addr); |
| 733 | totalram_pages++; | 733 | totalram_pages++; |
| @@ -766,7 +766,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) | |||
| 766 | printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); | 766 | printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); |
| 767 | for (; start < end; start += PAGE_SIZE) { | 767 | for (; start < end; start += PAGE_SIZE) { |
| 768 | ClearPageReserved(virt_to_page(start)); | 768 | ClearPageReserved(virt_to_page(start)); |
| 769 | set_page_count(virt_to_page(start), 1); | 769 | init_page_count(virt_to_page(start)); |
| 770 | free_page(start); | 770 | free_page(start); |
| 771 | totalram_pages++; | 771 | totalram_pages++; |
| 772 | } | 772 | } |
diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c index d0cadb33b54c..92c3d9f0e731 100644 --- a/arch/i386/mm/pageattr.c +++ b/arch/i386/mm/pageattr.c | |||
| @@ -51,6 +51,13 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot, | |||
| 51 | if (!base) | 51 | if (!base) |
| 52 | return NULL; | 52 | return NULL; |
| 53 | 53 | ||
| 54 | /* | ||
| 55 | * page_private is used to track the number of entries in | ||
| 56 | * the page table page that have non standard attributes. | ||
| 57 | */ | ||
| 58 | SetPagePrivate(base); | ||
| 59 | page_private(base) = 0; | ||
| 60 | |||
| 54 | address = __pa(address); | 61 | address = __pa(address); |
| 55 | addr = address & LARGE_PAGE_MASK; | 62 | addr = address & LARGE_PAGE_MASK; |
| 56 | pbase = (pte_t *)page_address(base); | 63 | pbase = (pte_t *)page_address(base); |
| @@ -143,11 +150,12 @@ __change_page_attr(struct page *page, pgprot_t prot) | |||
| 143 | return -ENOMEM; | 150 | return -ENOMEM; |
| 144 | set_pmd_pte(kpte,address,mk_pte(split, ref_prot)); | 151 | set_pmd_pte(kpte,address,mk_pte(split, ref_prot)); |
| 145 | kpte_page = split; | 152 | kpte_page = split; |
| 146 | } | 153 | } |
| 147 | get_page(kpte_page); | 154 | page_private(kpte_page)++; |
| 148 | } else if ((pte_val(*kpte) & _PAGE_PSE) == 0) { | 155 | } else if ((pte_val(*kpte) & _PAGE_PSE) == 0) { |
| 149 | set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL)); | 156 | set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL)); |
| 150 | __put_page(kpte_page); | 157 | BUG_ON(page_private(kpte_page) == 0); |
| 158 | page_private(kpte_page)--; | ||
| 151 | } else | 159 | } else |
| 152 | BUG(); | 160 | BUG(); |
| 153 | 161 | ||
| @@ -157,10 +165,8 @@ __change_page_attr(struct page *page, pgprot_t prot) | |||
| 157 | * replace it with a largepage. | 165 | * replace it with a largepage. |
| 158 | */ | 166 | */ |
| 159 | if (!PageReserved(kpte_page)) { | 167 | if (!PageReserved(kpte_page)) { |
| 160 | /* memleak and potential failed 2M page regeneration */ | 168 | if (cpu_has_pse && (page_private(kpte_page) == 0)) { |
| 161 | BUG_ON(!page_count(kpte_page)); | 169 | ClearPagePrivate(kpte_page); |
| 162 | |||
| 163 | if (cpu_has_pse && (page_count(kpte_page) == 1)) { | ||
| 164 | list_add(&kpte_page->lru, &df_list); | 170 | list_add(&kpte_page->lru, &df_list); |
| 165 | revert_page(kpte_page, address); | 171 | revert_page(kpte_page, address); |
| 166 | } | 172 | } |
