diff options
Diffstat (limited to 'arch/m68k/mm/motorola.c')
-rw-r--r-- | arch/m68k/mm/motorola.c | 61 |
1 files changed, 32 insertions, 29 deletions
diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c index 73651e093c4d..62283bc2ed79 100644 --- a/arch/m68k/mm/motorola.c +++ b/arch/m68k/mm/motorola.c @@ -92,7 +92,7 @@ void mmu_page_dtor(void *page) } /* ++andreas: {get,free}_pointer_table rewritten to use unused fields from - struct page instead of separately kmalloced struct. Stolen from + struct ptdesc instead of separately kmalloced struct. Stolen from arch/sparc/mm/srmmu.c ... */ typedef struct list_head ptable_desc; @@ -103,9 +103,9 @@ static struct list_head ptable_list[3] = { LIST_HEAD_INIT(ptable_list[2]), }; -#define PD_PTABLE(page) ((ptable_desc *)&(virt_to_page((void *)(page))->lru)) -#define PD_PAGE(ptable) (list_entry(ptable, struct page, lru)) -#define PD_MARKBITS(dp) (*(unsigned int *)&PD_PAGE(dp)->index) +#define PD_PTABLE(ptdesc) ((ptable_desc *)&(virt_to_ptdesc((void *)(ptdesc))->pt_list)) +#define PD_PTDESC(ptable) (list_entry(ptable, struct ptdesc, pt_list)) +#define PD_MARKBITS(dp) (*(unsigned int *)&PD_PTDESC(dp)->pt_index) static const int ptable_shift[3] = { 7+2, /* PGD */ @@ -120,10 +120,10 @@ void __init init_pointer_table(void *table, int type) { ptable_desc *dp; unsigned long ptable = (unsigned long)table; - unsigned long page = ptable & PAGE_MASK; - unsigned int mask = 1U << ((ptable - page)/ptable_size(type)); + unsigned long pt_addr = ptable & PAGE_MASK; + unsigned int mask = 1U << ((ptable - pt_addr)/ptable_size(type)); - dp = PD_PTABLE(page); + dp = PD_PTABLE(pt_addr); if (!(PD_MARKBITS(dp) & mask)) { PD_MARKBITS(dp) = ptable_mask(type); list_add(dp, &ptable_list[type]); @@ -132,14 +132,14 @@ void __init init_pointer_table(void *table, int type) PD_MARKBITS(dp) &= ~mask; pr_debug("init_pointer_table: %lx, %x\n", ptable, PD_MARKBITS(dp)); - /* unreserve the page so it's possible to free that page */ - __ClearPageReserved(PD_PAGE(dp)); - init_page_count(PD_PAGE(dp)); + /* unreserve the ptdesc so it's possible to free that ptdesc */ + __ClearPageReserved(ptdesc_page(PD_PTDESC(dp))); + init_page_count(ptdesc_page(PD_PTDESC(dp))); return; } -void *get_pointer_table(int type) +void *get_pointer_table(struct mm_struct *mm, int type) { ptable_desc *dp = ptable_list[type].next; unsigned int mask = list_empty(&ptable_list[type]) ? 0 : PD_MARKBITS(dp); @@ -147,40 +147,44 @@ void *get_pointer_table(int type) /* * For a pointer table for a user process address space, a - * table is taken from a page allocated for the purpose. Each - * page can hold 8 pointer tables. The page is remapped in + * table is taken from a ptdesc allocated for the purpose. Each + * ptdesc can hold 8 pointer tables. The ptdesc is remapped in * virtual address space to be noncacheable. */ if (mask == 0) { - void *page; + struct ptdesc *ptdesc; ptable_desc *new; + void *pt_addr; - if (!(page = (void *)get_zeroed_page(GFP_KERNEL))) + ptdesc = pagetable_alloc(GFP_KERNEL | __GFP_ZERO, 0); + if (!ptdesc) return NULL; + pt_addr = ptdesc_address(ptdesc); + switch (type) { case TABLE_PTE: /* * m68k doesn't have SPLIT_PTE_PTLOCKS for not having * SMP. */ - pagetable_pte_ctor(virt_to_ptdesc(page)); + pagetable_pte_ctor(mm, ptdesc); break; case TABLE_PMD: - pagetable_pmd_ctor(virt_to_ptdesc(page)); + pagetable_pmd_ctor(mm, ptdesc); break; case TABLE_PGD: - pagetable_pgd_ctor(virt_to_ptdesc(page)); + pagetable_pgd_ctor(ptdesc); break; } - mmu_page_ctor(page); + mmu_page_ctor(pt_addr); - new = PD_PTABLE(page); + new = PD_PTABLE(pt_addr); PD_MARKBITS(new) = ptable_mask(type) - 1; list_add_tail(new, dp); - return (pmd_t *)page; + return (pmd_t *)pt_addr; } for (tmp = 1, off = 0; (mask & tmp) == 0; tmp <<= 1, off += ptable_size(type)) @@ -190,28 +194,27 @@ void *get_pointer_table(int type) /* move to end of list */ list_move_tail(dp, &ptable_list[type]); } - return page_address(PD_PAGE(dp)) + off; + return ptdesc_address(PD_PTDESC(dp)) + off; } int free_pointer_table(void *table, int type) { ptable_desc *dp; unsigned long ptable = (unsigned long)table; - unsigned long page = ptable & PAGE_MASK; - unsigned int mask = 1U << ((ptable - page)/ptable_size(type)); + unsigned long pt_addr = ptable & PAGE_MASK; + unsigned int mask = 1U << ((ptable - pt_addr)/ptable_size(type)); - dp = PD_PTABLE(page); + dp = PD_PTABLE(pt_addr); if (PD_MARKBITS (dp) & mask) panic ("table already free!"); PD_MARKBITS (dp) |= mask; if (PD_MARKBITS(dp) == ptable_mask(type)) { - /* all tables in page are free, free page */ + /* all tables in ptdesc are free, free ptdesc */ list_del(dp); - mmu_page_dtor((void *)page); - pagetable_dtor(virt_to_ptdesc((void *)page)); - free_page (page); + mmu_page_dtor((void *)pt_addr); + pagetable_dtor_free(virt_to_ptdesc((void *)pt_addr)); return 1; } else if (ptable_list[type].next != dp) { /* |