···8787typedef struct { unsigned long pte; } pte_t;8888#define pte_val(x) ((x).pte)8989#endif9090+#define __pte(x) ((pte_t) { (x) } )9191+9292+/*9393+ * For 3-level pagetables we defines these ourselves, for 2-level the9494+ * definitions are supplied by <asm-generic/pgtable-nopmd.h>.9595+ */9696+#ifdef CONFIG_64BIT90979198typedef struct { unsigned long pmd; } pmd_t;9292-typedef struct { unsigned long pgd; } pgd_t;9393-typedef struct { unsigned long pgprot; } pgprot_t;9494-9599#define pmd_val(x) ((x).pmd)9696-#define pgd_val(x) ((x).pgd)9797-#define pgprot_val(x) ((x).pgprot)9898-9999-#define ptep_buddy(x) ((pte_t *)((unsigned long)(x) ^ sizeof(pte_t)))100100-101101-#define __pte(x) ((pte_t) { (x) } )102100#define __pmd(x) ((pmd_t) { (x) } )101101+102102+#endif103103+104104+/*105105+ * Right now we don't support 4-level pagetables, so all pud-related106106+ * definitions come from <asm-generic/pgtable-nopud.h>.107107+ */108108+109109+/*110110+ * Finall the top of the hierarchy, the pgd111111+ */112112+typedef struct { unsigned long pgd; } pgd_t;113113+#define pgd_val(x) ((x).pgd)103114#define __pgd(x) ((pgd_t) { (x) } )115115+116116+/*117117+ * Manipulate page protection bits118118+ */119119+typedef struct { unsigned long pgprot; } pgprot_t;120120+#define pgprot_val(x) ((x).pgprot)104121#define __pgprot(x) ((pgprot_t) { (x) } )122122+123123+/*124124+ * On R4000-style MMUs where a TLB entry is mapping a adjacent even / odd125125+ * pair of pages we only have a single global bit per pair of pages. When126126+ * writing to the TLB make sure we always have the bit set for both pages127127+ * or none. This macro is used to access the `buddy' of the pte we're just128128+ * working on.129129+ */130130+#define ptep_buddy(x) ((pte_t *)((unsigned long)(x) ^ sizeof(pte_t)))105131106132#endif /* !__ASSEMBLY__ */107133
+14-5
include/asm-mips/pgalloc.h
···2626}27272828/*2929+ * Initialize a new pmd table with invalid pointers.3030+ */3131+extern void pmd_init(unsigned long page, unsigned long pagetable);3232+3333+#ifdef CONFIG_64BIT3434+3535+static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)3636+{3737+ set_pud(pud, __pud((unsigned long)pmd));3838+}3939+#endif4040+4141+/*2942 * Initialize a new pgd / pmd table with invalid pointers.3043 */3144extern void pgd_init(unsigned long page);3232-extern void pmd_init(unsigned long page, unsigned long pagetable);33453446static inline pgd_t *pgd_alloc(struct mm_struct *mm)3547{···9886#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))998710088#ifdef CONFIG_32BIT101101-#define pgd_populate(mm, pmd, pte) BUG()1028910390/*10491 * allocating and freeing a pmd is trivial: the 1-entry pmd is10592 * inside the pgd, so has no extra memory associated with it.10693 */107107-#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); })10894#define pmd_free(x) do { } while (0)10995#define __pmd_free_tlb(tlb,x) do { } while (0)9696+11097#endif1119811299#ifdef CONFIG_64BIT113113-114114-#define pgd_populate(mm, pgd, pmd) set_pgd(pgd, __pgd(pmd))115100116101static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)117102{
+12-28
include/asm-mips/pgtable-32.h
···1717#include <asm/cachectl.h>1818#include <asm/fixmap.h>19192020+#include <asm-generic/pgtable-nopmd.h>2121+2022/*2123 * - add_wired_entry() add a fixed TLB entry, and move wired register2224 */···4442 */45434644/* PMD_SHIFT determines the size of the area a second-level page table can map */4747-#ifdef CONFIG_64BIT_PHYS_ADDR4848-#define PMD_SHIFT 214949-#else5050-#define PMD_SHIFT 225151-#endif5245#define PMD_SIZE (1UL << PMD_SHIFT)5346#define PMD_MASK (~(PMD_SIZE-1))54475548/* PGDIR_SHIFT determines what a third-level page table entry can map */5656-#define PGDIR_SHIFT PMD_SHIFT4949+#ifdef CONFIG_64BIT_PHYS_ADDR5050+#define PGDIR_SHIFT 215151+#else5252+#define PGDIR_SHIFT 225353+#endif5754#define PGDIR_SIZE (1UL << PGDIR_SHIFT)5855#define PGDIR_MASK (~(PGDIR_SIZE-1))59566057/*6158 * Entries per page directory level: we use two-level, so6262- * we don't really have any PMD directory physically.5959+ * we don't really have any PUD/PMD directory physically.6360 */6461#ifdef CONFIG_64BIT_PHYS_ADDR6562#define PGD_ORDER 16666-#define PMD_ORDER 06363+#define PUD_ORDER aieeee_attempt_to_allocate_pud6464+#define PMD_ORDER 16765#define PTE_ORDER 06866#else6967#define PGD_ORDER 07070-#define PMD_ORDER 06868+#define PUD_ORDER aieeee_attempt_to_allocate_pud6969+#define PMD_ORDER 17170#define PTE_ORDER 07271#endif73727473#define PTRS_PER_PGD ((PAGE_SIZE << PGD_ORDER) / sizeof(pgd_t))7575-#define PTRS_PER_PMD 17674#define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))77757876#define USER_PTRS_PER_PGD (0x80000000UL/PGDIR_SIZE)···9391#define pte_ERROR(e) \9492 printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))9593#endif9696-#define pmd_ERROR(e) \9797- printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))9894#define pgd_ERROR(e) \9995 printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))10096···119119{120120 pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);121121}122122-123123-/*124124- * The "pgd_xxx()" functions here are trivial for a folded two-level125125- * setup: the pgd is never bad, and a pmd always exists (as it's folded126126- * into the pgd entry)127127- */128128-static inline int pgd_none(pgd_t pgd) { return 0; }129129-static inline int pgd_bad(pgd_t pgd) { return 0; }130130-static inline int pgd_present(pgd_t pgd) { return 1; }131131-static inline void pgd_clear(pgd_t *pgdp) { }132122133123#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)134124#define pte_page(x) pfn_to_page(pte_pfn(x))···155165156166/* to find an entry in a page-table-directory */157167#define pgd_offset(mm,addr) ((mm)->pgd + pgd_index(addr))158158-159159-/* Find an entry in the second-level page table.. */160160-static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)161161-{162162- return (pmd_t *) dir;163163-}164168165169/* Find an entry in the third-level page table.. */166170#define __pte_offset(address) \
+33-24
include/asm-mips/pgtable-64.h
···1616#include <asm/page.h>1717#include <asm/cachectl.h>18181919+#include <asm-generic/pgtable-nopud.h>2020+1921/*2022 * Each address space has 2 4K pages as its page directory, giving 10242123 * (== PTRS_PER_PGD) 8 byte pointers to pmd tables. Each pmd table is a2222- * pair of 4K pages, giving 1024 (== PTRS_PER_PMD) 8 byte pointers to2323- * page tables. Each page table is a single 4K page, giving 512 (==2424- * PTRS_PER_PTE) 8 byte ptes. Each pgde is initialized to point to2525- * invalid_pmd_table, each pmde is initialized to point to2424+ * single 4K page, giving 512 (== PTRS_PER_PMD) 8 byte pointers to page2525+ * tables. Each page table is also a single 4K page, giving 512 (==2626+ * PTRS_PER_PTE) 8 byte ptes. Each pud entry is initialized to point to2727+ * invalid_pmd_table, each pmd entry is initialized to point to2628 * invalid_pte_table, each pte is initialized to 0. When memory is low,2729 * and a pmd table or a page table allocation fails, empty_bad_pmd_table2830 * and empty_bad_page_table is returned back to higher layer code, so···3836 */39374038/* PMD_SHIFT determines the size of the area a second-level page table can map */4141-#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - 3))3939+#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT + PTE_ORDER - 3))4240#define PMD_SIZE (1UL << PMD_SHIFT)4341#define PMD_MASK (~(PMD_SIZE-1))44424543/* PGDIR_SHIFT determines what a third-level page table entry can map */4646-#define PGDIR_SHIFT (PMD_SHIFT + (PAGE_SHIFT + 1 - 3))4444+#define PGDIR_SHIFT (PMD_SHIFT + (PAGE_SHIFT + PMD_ORDER - 3))4745#define PGDIR_SIZE (1UL << PGDIR_SHIFT)4846#define PGDIR_MASK (~(PGDIR_SIZE-1))49475048/*5151- * For 4kB page size we use a 3 level page tree and a 8kB pmd and pgds which4949+ * For 4kB page size we use a 3 level page tree and an 8kB pud, which5250 * permits us mapping 40 bits of virtual address space.5351 *5452 * We used to implement 41 bits by having an order 1 pmd level but that seemed···6765 */6866#ifdef CONFIG_PAGE_SIZE_4KB6967#define PGD_ORDER 16868+#define PUD_ORDER aieeee_attempt_to_allocate_pud7069#define PMD_ORDER 07170#define PTE_ORDER 07271#endif7372#ifdef CONFIG_PAGE_SIZE_8KB7473#define PGD_ORDER 07474+#define PUD_ORDER aieeee_attempt_to_allocate_pud7575#define PMD_ORDER 07676#define PTE_ORDER 07777#endif7878#ifdef CONFIG_PAGE_SIZE_16KB7979#define PGD_ORDER 08080+#define PUD_ORDER aieeee_attempt_to_allocate_pud8081#define PMD_ORDER 08182#define PTE_ORDER 08283#endif8384#ifdef CONFIG_PAGE_SIZE_64KB8485#define PGD_ORDER 08686+#define PUD_ORDER aieeee_attempt_to_allocate_pud8587#define PMD_ORDER 08688#define PTE_ORDER 08789#endif···108102#define pgd_ERROR(e) \109103 printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))110104111111-extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)];112112-extern pte_t empty_bad_page_table[PAGE_SIZE/sizeof(pte_t)];113113-extern pmd_t invalid_pmd_table[2*PAGE_SIZE/sizeof(pmd_t)];114114-extern pmd_t empty_bad_pmd_table[2*PAGE_SIZE/sizeof(pmd_t)];105105+extern pte_t invalid_pte_table[PTRS_PER_PTE];106106+extern pte_t empty_bad_page_table[PTRS_PER_PTE];107107+extern pmd_t invalid_pmd_table[PTRS_PER_PMD];108108+extern pmd_t empty_bad_pmd_table[PTRS_PER_PMD];115109116110/*117111 * Empty pmd entries point to the invalid_pte_table.···136130/*137131 * Empty pgd entries point to the invalid_pmd_table.138132 */139139-static inline int pgd_none(pgd_t pgd)133133+static inline int pud_none(pud_t pud)140134{141141- return pgd_val(pgd) == (unsigned long) invalid_pmd_table;135135+ return pud_val(pud) == (unsigned long) invalid_pmd_table;142136}143137144144-#define pgd_bad(pgd) (pgd_val(pgd) &~ PAGE_MASK)145145-146146-static inline int pgd_present(pgd_t pgd)138138+static inline int pud_bad(pud_t pud)147139{148148- return pgd_val(pgd) != (unsigned long) invalid_pmd_table;140140+ return pud_val(pud) & ~PAGE_MASK;149141}150142151151-static inline void pgd_clear(pgd_t *pgdp)143143+static inline int pud_present(pud_t pud)152144{153153- pgd_val(*pgdp) = ((unsigned long) invalid_pmd_table);145145+ return pud_val(pud) != (unsigned long) invalid_pmd_table;146146+}147147+148148+static inline void pud_clear(pud_t *pudp)149149+{150150+ pud_val(*pudp) = ((unsigned long) invalid_pmd_table);154151}155152156153#define pte_page(x) pfn_to_page((unsigned long)((pte_val(x) >> PAGE_SHIFT)))···171162/* to find an entry in a kernel page-table-directory */172163#define pgd_offset_k(address) pgd_offset(&init_mm, 0)173164174174-#define pgd_index(address) ((address) >> PGDIR_SHIFT)165165+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))175166176167/* to find an entry in a page-table-directory */177168#define pgd_offset(mm,addr) ((mm)->pgd + pgd_index(addr))178169179179-static inline unsigned long pgd_page(pgd_t pgd)170170+static inline unsigned long pud_page(pud_t pud)180171{181181- return pgd_val(pgd);172172+ return pud_val(pud);182173}183174184175/* Find an entry in the second-level page table.. */185185-static inline pmd_t *pmd_offset(pgd_t * dir, unsigned long address)176176+static inline pmd_t *pmd_offset(pud_t * pud, unsigned long address)186177{187187- return (pmd_t *) pgd_page(*dir) +178178+ return (pmd_t *) pud_page(*pud) +188179 ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1));189180}190181
+9-4
include/asm-mips/pgtable.h
···88#ifndef _ASM_PGTABLE_H99#define _ASM_PGTABLE_H10101111-#include <asm-generic/4level-fixup.h>1212-1311#include <linux/config.h>1412#ifdef CONFIG_32BIT1513#include <asm/pgtable-32.h>···146148#endif147149148150/*149149- * (pmds are folded into pgds so this doesn't get actually called,151151+ * (pmds are folded into puds so this doesn't get actually called,150152 * but the define is needed for a generic inline function.)151153 */152154#define set_pmd(pmdptr, pmdval) do { *(pmdptr) = (pmdval); } while(0)153153-#define set_pgd(pgdptr, pgdval) do { *(pgdptr) = (pgdval); } while(0)155155+156156+#ifdef CONFIG_64BIT157157+/*158158+ * (puds are folded into pgds so this doesn't get actually called,159159+ * but the define is needed for a generic inline function.)160160+ */161161+#define set_pud(pudptr, pudval) do { *(pudptr) = (pudval); } while(0)162162+#endif154163155164#define PGD_T_LOG2 ffz(~sizeof(pgd_t))156165#define PMD_T_LOG2 ffz(~sizeof(pmd_t))