Commit 63e6b854 authored by Nick Piggin's avatar Nick Piggin Committed by Linus Torvalds

[PATCH] convert ia64 to generic nopud header

Convert ia64 architecture over to handle 4 level pagetables.
Signed-off-by: default avatarNick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent a85729c9
...@@ -51,6 +51,7 @@ static int ...@@ -51,6 +51,7 @@ static int
mapped_kernel_page_is_present (unsigned long address) mapped_kernel_page_is_present (unsigned long address)
{ {
pgd_t *pgd; pgd_t *pgd;
pud_t *pud;
pmd_t *pmd; pmd_t *pmd;
pte_t *ptep, pte; pte_t *ptep, pte;
...@@ -58,7 +59,11 @@ mapped_kernel_page_is_present (unsigned long address) ...@@ -58,7 +59,11 @@ mapped_kernel_page_is_present (unsigned long address)
if (pgd_none(*pgd) || pgd_bad(*pgd)) if (pgd_none(*pgd) || pgd_bad(*pgd))
return 0; return 0;
pmd = pmd_offset(pgd, address); pud = pud_offset(pgd, address);
if (pud_none(*pud) || pud_bad(*pud))
return 0;
pmd = pmd_offset(pud, address);
if (pmd_none(*pmd) || pmd_bad(*pmd)) if (pmd_none(*pmd) || pmd_bad(*pmd))
return 0; return 0;
......
...@@ -29,13 +29,17 @@ huge_pte_alloc (struct mm_struct *mm, unsigned long addr) ...@@ -29,13 +29,17 @@ huge_pte_alloc (struct mm_struct *mm, unsigned long addr)
{ {
unsigned long taddr = htlbpage_to_page(addr); unsigned long taddr = htlbpage_to_page(addr);
pgd_t *pgd; pgd_t *pgd;
pud_t *pud;
pmd_t *pmd; pmd_t *pmd;
pte_t *pte = NULL; pte_t *pte = NULL;
pgd = pgd_offset(mm, taddr); pgd = pgd_offset(mm, taddr);
pmd = pmd_alloc(mm, pgd, taddr); pud = pud_alloc(mm, pgd, taddr);
if (pud) {
pmd = pmd_alloc(mm, pud, taddr);
if (pmd) if (pmd)
pte = pte_alloc_map(mm, pmd, taddr); pte = pte_alloc_map(mm, pmd, taddr);
}
return pte; return pte;
} }
...@@ -44,15 +48,19 @@ huge_pte_offset (struct mm_struct *mm, unsigned long addr) ...@@ -44,15 +48,19 @@ huge_pte_offset (struct mm_struct *mm, unsigned long addr)
{ {
unsigned long taddr = htlbpage_to_page(addr); unsigned long taddr = htlbpage_to_page(addr);
pgd_t *pgd; pgd_t *pgd;
pud_t *pud;
pmd_t *pmd; pmd_t *pmd;
pte_t *pte = NULL; pte_t *pte = NULL;
pgd = pgd_offset(mm, taddr); pgd = pgd_offset(mm, taddr);
if (pgd_present(*pgd)) { if (pgd_present(*pgd)) {
pmd = pmd_offset(pgd, taddr); pud = pud_offset(pgd, taddr);
if (pud_present(*pud)) {
pmd = pmd_offset(pud, taddr);
if (pmd_present(*pmd)) if (pmd_present(*pmd))
pte = pte_offset_map(pmd, taddr); pte = pte_offset_map(pmd, taddr);
} }
}
return pte; return pte;
} }
......
...@@ -237,6 +237,7 @@ struct page * ...@@ -237,6 +237,7 @@ struct page *
put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot) put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot)
{ {
pgd_t *pgd; pgd_t *pgd;
pud_t *pud;
pmd_t *pmd; pmd_t *pmd;
pte_t *pte; pte_t *pte;
...@@ -248,7 +249,11 @@ put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot) ...@@ -248,7 +249,11 @@ put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot)
spin_lock(&init_mm.page_table_lock); spin_lock(&init_mm.page_table_lock);
{ {
pmd = pmd_alloc(&init_mm, pgd, address); pud = pud_alloc(&init_mm, pgd, address);
if (!pud)
goto out;
pmd = pmd_alloc(&init_mm, pud, address);
if (!pmd) if (!pmd)
goto out; goto out;
pte = pte_alloc_map(&init_mm, pmd, address); pte = pte_alloc_map(&init_mm, pmd, address);
...@@ -381,6 +386,7 @@ create_mem_map_page_table (u64 start, u64 end, void *arg) ...@@ -381,6 +386,7 @@ create_mem_map_page_table (u64 start, u64 end, void *arg)
struct page *map_start, *map_end; struct page *map_start, *map_end;
int node; int node;
pgd_t *pgd; pgd_t *pgd;
pud_t *pud;
pmd_t *pmd; pmd_t *pmd;
pte_t *pte; pte_t *pte;
...@@ -395,7 +401,11 @@ create_mem_map_page_table (u64 start, u64 end, void *arg) ...@@ -395,7 +401,11 @@ create_mem_map_page_table (u64 start, u64 end, void *arg)
pgd = pgd_offset_k(address); pgd = pgd_offset_k(address);
if (pgd_none(*pgd)) if (pgd_none(*pgd))
pgd_populate(&init_mm, pgd, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE)); pgd_populate(&init_mm, pgd, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE));
pmd = pmd_offset(pgd, address); pud = pud_offset(pgd, address);
if (pud_none(*pud))
pud_populate(&init_mm, pud, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE));
pmd = pmd_offset(pud, address);
if (pmd_none(*pmd)) if (pmd_none(*pmd))
pmd_populate_kernel(&init_mm, pmd, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE)); pmd_populate_kernel(&init_mm, pmd, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE));
......
...@@ -79,12 +79,11 @@ pgd_free (pgd_t *pgd) ...@@ -79,12 +79,11 @@ pgd_free (pgd_t *pgd)
} }
static inline void static inline void
pgd_populate (struct mm_struct *mm, pgd_t *pgd_entry, pmd_t *pmd) pud_populate (struct mm_struct *mm, pud_t *pud_entry, pmd_t *pmd)
{ {
pgd_val(*pgd_entry) = __pa(pmd); pud_val(*pud_entry) = __pa(pmd);
} }
static inline pmd_t* static inline pmd_t*
pmd_alloc_one_fast (struct mm_struct *mm, unsigned long addr) pmd_alloc_one_fast (struct mm_struct *mm, unsigned long addr)
{ {
......
#ifndef _ASM_IA64_PGTABLE_H #ifndef _ASM_IA64_PGTABLE_H
#define _ASM_IA64_PGTABLE_H #define _ASM_IA64_PGTABLE_H
#include <asm-generic/4level-fixup.h>
/* /*
* This file contains the functions and defines necessary to modify and use * This file contains the functions and defines necessary to modify and use
* the IA-64 page table tree. * the IA-64 page table tree.
...@@ -256,11 +254,12 @@ ia64_phys_addr_valid (unsigned long addr) ...@@ -256,11 +254,12 @@ ia64_phys_addr_valid (unsigned long addr)
#define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & _PFN_MASK)) #define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & _PFN_MASK))
#define pmd_page(pmd) virt_to_page((pmd_val(pmd) + PAGE_OFFSET)) #define pmd_page(pmd) virt_to_page((pmd_val(pmd) + PAGE_OFFSET))
#define pgd_none(pgd) (!pgd_val(pgd)) #define pud_none(pud) (!pud_val(pud))
#define pgd_bad(pgd) (!ia64_phys_addr_valid(pgd_val(pgd))) #define pud_bad(pud) (!ia64_phys_addr_valid(pud_val(pud)))
#define pgd_present(pgd) (pgd_val(pgd) != 0UL) #define pud_present(pud) (pud_val(pud) != 0UL)
#define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0UL) #define pud_clear(pudp) (pud_val(*(pudp)) = 0UL)
#define pgd_page(pgd) ((unsigned long) __va(pgd_val(pgd) & _PFN_MASK))
#define pud_page(pud) ((unsigned long) __va(pud_val(pud) & _PFN_MASK))
/* /*
* The following have defined behavior only work if pte_present() is true. * The following have defined behavior only work if pte_present() is true.
...@@ -330,7 +329,7 @@ pgd_offset (struct mm_struct *mm, unsigned long address) ...@@ -330,7 +329,7 @@ pgd_offset (struct mm_struct *mm, unsigned long address)
/* Find an entry in the second-level page table.. */ /* Find an entry in the second-level page table.. */
#define pmd_offset(dir,addr) \ #define pmd_offset(dir,addr) \
((pmd_t *) pgd_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))) ((pmd_t *) pud_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
/* /*
* Find an entry in the third-level page table. This looks more complicated than it * Find an entry in the third-level page table. This looks more complicated than it
...@@ -563,5 +562,6 @@ do { \ ...@@ -563,5 +562,6 @@ do { \
#define __HAVE_ARCH_PTE_SAME #define __HAVE_ARCH_PTE_SAME
#define __HAVE_ARCH_PGD_OFFSET_GATE #define __HAVE_ARCH_PGD_OFFSET_GATE
#include <asm-generic/pgtable.h> #include <asm-generic/pgtable.h>
#include <asm-generic/pgtable-nopud.h>
#endif /* _ASM_IA64_PGTABLE_H */ #endif /* _ASM_IA64_PGTABLE_H */
...@@ -236,4 +236,10 @@ do { \ ...@@ -236,4 +236,10 @@ do { \
__pmd_free_tlb(tlb, ptep); \ __pmd_free_tlb(tlb, ptep); \
} while (0) } while (0)
#define pud_free_tlb(tlb, pudp) \
do { \
tlb->need_flush = 1; \
__pud_free_tlb(tlb, pudp); \
} while (0)
#endif /* _ASM_IA64_TLB_H */ #endif /* _ASM_IA64_TLB_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment