diff options
author | Mike Rapoport <rppt@linux.ibm.com> | 2019-12-04 16:53:59 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-12-04 19:44:15 -0800 |
commit | 60e50f34b13e9e40763be12aa55f2144d8da514c (patch) | |
tree | 4a9b2a22edb026d40c30962c91bfe99d5e7c095b | |
parent | f6f7caeb58532db2e46c40eee2d7e8969d5c707e (diff) | |
download | linux-stable-60e50f34b13e9e40763be12aa55f2144d8da514c.tar.gz linux-stable-60e50f34b13e9e40763be12aa55f2144d8da514c.tar.bz2 linux-stable-60e50f34b13e9e40763be12aa55f2144d8da514c.zip |
m68k: mm: use pgtable-nopXd instead of 4level-fixup
m68k has two or three levels of page tables and can use appropriate
pgtable-nopXd and folding of the upper layers.
Replace usage of include/asm-generic/4level-fixup.h and explicit
definitions of __PAGETABLE_PxD_FOLDED in m68k with
include/asm-generic/pgtable-nopmd.h for two-level configurations and
with include/asm-generic/pgtable-nopud.h for three-lelve configurations
and adjust page table manipulation macros and functions accordingly.
[akpm@linux-foundation.org: fix merge glitch]
[geert@linux-m68k.org: more merge glitch fixes]
[akpm@linux-foundation.org: s/bad_pgd/bad_pud/, per Mike]
Link: http://lkml.kernel.org/r/1572938135-31886-6-git-send-email-rppt@kernel.org
Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
Acked-by: Greg Ungerer <gerg@linux-m68k.org>
Cc: Anatoly Pugachev <matorola@gmail.com>
Cc: Anton Ivanov <anton.ivanov@cambridgegreys.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Greentime Hu <green.hu@gmail.com>
Cc: Helge Deller <deller@gmx.de>
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: "Kirill A. Shutemov" <kirill@shutemov.name>
Cc: Mark Salter <msalter@redhat.com>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Michal Simek <monstr@monstr.eu>
Cc: Peter Rosin <peda@axentia.se>
Cc: Richard Weinberger <richard@nod.at>
Cc: Rolf Eike Beer <eike-kernel@sf-tec.de>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Russell King <rmk+kernel@armlinux.org.uk>
Cc: Sam Creasey <sammy@sammy.net>
Cc: Vincent Chen <deanbo422@gmail.com>
Cc: Vineet Gupta <Vineet.Gupta1@synopsys.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/m68k/include/asm/mcf_pgalloc.h | 7 | ||||
-rw-r--r-- | arch/m68k/include/asm/mcf_pgtable.h | 28 | ||||
-rw-r--r-- | arch/m68k/include/asm/mmu_context.h | 12 | ||||
-rw-r--r-- | arch/m68k/include/asm/motorola_pgalloc.h | 4 | ||||
-rw-r--r-- | arch/m68k/include/asm/motorola_pgtable.h | 32 | ||||
-rw-r--r-- | arch/m68k/include/asm/page.h | 9 | ||||
-rw-r--r-- | arch/m68k/include/asm/pgtable_mm.h | 11 | ||||
-rw-r--r-- | arch/m68k/include/asm/sun3_pgalloc.h | 5 | ||||
-rw-r--r-- | arch/m68k/include/asm/sun3_pgtable.h | 18 | ||||
-rw-r--r-- | arch/m68k/kernel/sys_m68k.c | 10 | ||||
-rw-r--r-- | arch/m68k/mm/init.c | 6 | ||||
-rw-r--r-- | arch/m68k/mm/kmap.c | 39 | ||||
-rw-r--r-- | arch/m68k/mm/mcfmmu.c | 16 | ||||
-rw-r--r-- | arch/m68k/mm/motorola.c | 17 | ||||
-rw-r--r-- | arch/m68k/sun3x/dvma.c | 7 |
15 files changed, 129 insertions, 92 deletions
diff --git a/arch/m68k/include/asm/mcf_pgalloc.h b/arch/m68k/include/asm/mcf_pgalloc.h index b34d44d666a4..82ec54c2eaa4 100644 --- a/arch/m68k/include/asm/mcf_pgalloc.h +++ b/arch/m68k/include/asm/mcf_pgalloc.h @@ -28,9 +28,6 @@ extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address) return (pmd_t *) pgd; } -#define pmd_alloc_one_fast(mm, address) ({ BUG(); ((pmd_t *)1); }) -#define pmd_alloc_one(mm, address) ({ BUG(); ((pmd_t *)2); }) - #define pmd_populate(mm, pmd, page) (pmd_val(*pmd) = \ (unsigned long)(page_address(page))) @@ -45,8 +42,6 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page, __free_page(page); } -#define __pmd_free_tlb(tlb, pmd, address) do { } while (0) - static inline struct page *pte_alloc_one(struct mm_struct *mm) { struct page *page = alloc_pages(GFP_DMA, 0); @@ -100,6 +95,4 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) return new_pgd; } -#define pgd_populate(mm, pmd, pte) BUG() - #endif /* M68K_MCF_PGALLOC_H */ diff --git a/arch/m68k/include/asm/mcf_pgtable.h b/arch/m68k/include/asm/mcf_pgtable.h index 5d5502cb2b2d..b9f45aeded25 100644 --- a/arch/m68k/include/asm/mcf_pgtable.h +++ b/arch/m68k/include/asm/mcf_pgtable.h @@ -198,17 +198,9 @@ static inline int pmd_bad2(pmd_t *pmd) { return 0; } #define pmd_present(pmd) (!pmd_none2(&(pmd))) static inline void pmd_clear(pmd_t *pmdp) { pmd_val(*pmdp) = 0; } -static inline int pgd_none(pgd_t pgd) { return 0; } -static inline int pgd_bad(pgd_t pgd) { return 0; } -static inline int pgd_present(pgd_t pgd) { return 1; } -static inline void pgd_clear(pgd_t *pgdp) {} - #define pte_ERROR(e) \ printk(KERN_ERR "%s:%d: bad pte %08lx.\n", \ __FILE__, __LINE__, pte_val(e)) -#define pmd_ERROR(e) \ - printk(KERN_ERR "%s:%d: bad pmd %08lx.\n", \ - __FILE__, __LINE__, pmd_val(e)) #define pgd_ERROR(e) \ printk(KERN_ERR "%s:%d: bad pgd %08lx.\n", \ __FILE__, __LINE__, pgd_val(e)) @@ -340,14 +332,6 @@ extern pgd_t kernel_pg_dir[PTRS_PER_PGD]; #define pgd_offset_k(address) pgd_offset(&init_mm, address) /* - * Find an entry in the second-level pagetable. - */ -static inline pmd_t *pmd_offset(pgd_t *pgd, unsigned long address) -{ - return (pmd_t *) pgd; -} - -/* * Find an entry in the third-level pagetable. */ #define __pte_offset(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) @@ -360,12 +344,16 @@ static inline pmd_t *pmd_offset(pgd_t *pgd, unsigned long address) static inline void nocache_page(void *vaddr) { pgd_t *dir; + p4d_t *p4dp; + pud_t *pudp; pmd_t *pmdp; pte_t *ptep; unsigned long addr = (unsigned long) vaddr; dir = pgd_offset_k(addr); - pmdp = pmd_offset(dir, addr); + p4dp = p4d_offset(dir, addr); + pudp = pud_offset(p4dp, addr); + pmdp = pmd_offset(pudp, addr); ptep = pte_offset_kernel(pmdp, addr); *ptep = pte_mknocache(*ptep); } @@ -376,12 +364,16 @@ static inline void nocache_page(void *vaddr) static inline void cache_page(void *vaddr) { pgd_t *dir; + p4d_t *p4dp; + pud_t *pudp; pmd_t *pmdp; pte_t *ptep; unsigned long addr = (unsigned long) vaddr; dir = pgd_offset_k(addr); - pmdp = pmd_offset(dir, addr); + p4dp = p4d_offset(dir, addr); + pudp = pud_offset(p4dp, addr); + pmdp = pmd_offset(pudp, addr); ptep = pte_offset_kernel(pmdp, addr); *ptep = pte_mkcache(*ptep); } diff --git a/arch/m68k/include/asm/mmu_context.h b/arch/m68k/include/asm/mmu_context.h index f5b1852b4663..cac9f289d1f6 100644 --- a/arch/m68k/include/asm/mmu_context.h +++ b/arch/m68k/include/asm/mmu_context.h @@ -100,6 +100,8 @@ static inline void load_ksp_mmu(struct task_struct *task) struct mm_struct *mm; int asid; pgd_t *pgd; + p4d_t *p4d; + pud_t *pud; pmd_t *pmd; pte_t *pte; unsigned long mmuar; @@ -127,7 +129,15 @@ static inline void load_ksp_mmu(struct task_struct *task) if (pgd_none(*pgd)) goto bug; - pmd = pmd_offset(pgd, mmuar); + p4d = p4d_offset(pgd, mmuar); + if (p4d_none(*p4d)) + goto bug; + + pud = pud_offset(p4d, mmuar); + if (pud_none(*pud)) + goto bug; + + pmd = pmd_offset(pud, mmuar); if (pmd_none(*pmd)) goto bug; diff --git a/arch/m68k/include/asm/motorola_pgalloc.h b/arch/m68k/include/asm/motorola_pgalloc.h index acab315c851f..ff9cc401ffd1 100644 --- a/arch/m68k/include/asm/motorola_pgalloc.h +++ b/arch/m68k/include/asm/motorola_pgalloc.h @@ -106,9 +106,9 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t page } #define pmd_pgtable(pmd) pmd_page(pmd) -static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd) +static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) { - pgd_set(pgd, pmd); + pud_set(pud, pmd); } #endif /* _MOTOROLA_PGALLOC_H */ diff --git a/arch/m68k/include/asm/motorola_pgtable.h b/arch/m68k/include/asm/motorola_pgtable.h index 7f66a7bad7a5..62bedc61f110 100644 --- a/arch/m68k/include/asm/motorola_pgtable.h +++ b/arch/m68k/include/asm/motorola_pgtable.h @@ -117,14 +117,14 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep) } } -static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp) +static inline void pud_set(pud_t *pudp, pmd_t *pmdp) { - pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | __pa(pmdp); + pud_val(*pudp) = _PAGE_TABLE | _PAGE_ACCESSED | __pa(pmdp); } #define __pte_page(pte) ((unsigned long)__va(pte_val(pte) & PAGE_MASK)) #define __pmd_page(pmd) ((unsigned long)__va(pmd_val(pmd) & _TABLE_MASK)) -#define __pgd_page(pgd) ((unsigned long)__va(pgd_val(pgd) & _TABLE_MASK)) +#define pud_page_vaddr(pud) ((unsigned long)__va(pud_val(pud) & _TABLE_MASK)) #define pte_none(pte) (!pte_val(pte)) @@ -147,11 +147,11 @@ static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp) #define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd))) -#define pgd_none(pgd) (!pgd_val(pgd)) -#define pgd_bad(pgd) ((pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE) -#define pgd_present(pgd) (pgd_val(pgd) & _PAGE_TABLE) -#define pgd_clear(pgdp) ({ pgd_val(*pgdp) = 0; }) -#define pgd_page(pgd) (mem_map + ((unsigned long)(__va(pgd_val(pgd)) - PAGE_OFFSET) >> PAGE_SHIFT)) +#define pud_none(pud) (!pud_val(pud)) +#define pud_bad(pud) ((pud_val(pud) & _DESCTYPE_MASK) != _PAGE_TABLE) +#define pud_present(pud) (pud_val(pud) & _PAGE_TABLE) +#define pud_clear(pudp) ({ pud_val(*pudp) = 0; }) +#define pud_page(pud) (mem_map + ((unsigned long)(__va(pud_val(pud)) - PAGE_OFFSET) >> PAGE_SHIFT)) #define pte_ERROR(e) \ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) @@ -209,9 +209,9 @@ static inline pgd_t *pgd_offset_k(unsigned long address) /* Find an entry in the second-level page table.. */ -static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address) +static inline pmd_t *pmd_offset(pud_t *dir, unsigned long address) { - return (pmd_t *)__pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1)); + return (pmd_t *)pud_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1)); } /* Find an entry in the third-level page table.. */ @@ -239,11 +239,15 @@ static inline void nocache_page(void *vaddr) if (CPU_IS_040_OR_060) { pgd_t *dir; + p4d_t *p4dp; + pud_t *pudp; pmd_t *pmdp; pte_t *ptep; dir = pgd_offset_k(addr); - pmdp = pmd_offset(dir, addr); + p4dp = p4d_offset(dir, addr); + pudp = pud_offset(p4dp, addr); + pmdp = pmd_offset(pudp, addr); ptep = pte_offset_kernel(pmdp, addr); *ptep = pte_mknocache(*ptep); } @@ -255,11 +259,15 @@ static inline void cache_page(void *vaddr) if (CPU_IS_040_OR_060) { pgd_t *dir; + p4d_t *p4dp; + pud_t *pudp; pmd_t *pmdp; pte_t *ptep; dir = pgd_offset_k(addr); - pmdp = pmd_offset(dir, addr); + p4dp = p4d_offset(dir, addr); + pudp = pud_offset(p4dp, addr); + pmdp = pmd_offset(pudp, addr); ptep = pte_offset_kernel(pmdp, addr); *ptep = pte_mkcache(*ptep); } diff --git a/arch/m68k/include/asm/page.h b/arch/m68k/include/asm/page.h index 700d8195880c..05e1e1e77a9a 100644 --- a/arch/m68k/include/asm/page.h +++ b/arch/m68k/include/asm/page.h @@ -21,19 +21,22 @@ /* * These are used to make use of C type-checking.. */ -typedef struct { unsigned long pte; } pte_t; +#if !defined(CONFIG_MMU) || CONFIG_PGTABLE_LEVELS == 3 typedef struct { unsigned long pmd[16]; } pmd_t; +#define pmd_val(x) ((&x)->pmd[0]) +#define __pmd(x) ((pmd_t) { { (x) }, }) +#endif + +typedef struct { unsigned long pte; } pte_t; typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgprot; } pgprot_t; typedef struct page *pgtable_t; #define pte_val(x) ((x).pte) -#define pmd_val(x) ((&x)->pmd[0]) #define pgd_val(x) ((x).pgd) #define pgprot_val(x) ((x).pgprot) #define __pte(x) ((pte_t) { (x) } ) -#define __pmd(x) ((pmd_t) { { (x) }, }) #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) diff --git a/arch/m68k/include/asm/pgtable_mm.h b/arch/m68k/include/asm/pgtable_mm.h index 646c174fff99..2bf5c3501e78 100644 --- a/arch/m68k/include/asm/pgtable_mm.h +++ b/arch/m68k/include/asm/pgtable_mm.h @@ -2,7 +2,12 @@ #ifndef _M68K_PGTABLE_H #define _M68K_PGTABLE_H -#include <asm-generic/4level-fixup.h> + +#if defined(CONFIG_SUN3) || defined(CONFIG_COLDFIRE) +#include <asm-generic/pgtable-nopmd.h> +#else +#include <asm-generic/pgtable-nopud.h> +#endif #include <asm/setup.h> @@ -30,9 +35,7 @@ /* PMD_SHIFT determines the size of the area a second-level page table can map */ -#ifdef CONFIG_SUN3 -#define PMD_SHIFT 17 -#else +#if CONFIG_PGTABLE_LEVELS == 3 #define PMD_SHIFT 22 #endif #define PMD_SIZE (1UL << PMD_SHIFT) diff --git a/arch/m68k/include/asm/sun3_pgalloc.h b/arch/m68k/include/asm/sun3_pgalloc.h index 856121122b91..11b95dadf7c0 100644 --- a/arch/m68k/include/asm/sun3_pgalloc.h +++ b/arch/m68k/include/asm/sun3_pgalloc.h @@ -17,8 +17,6 @@ extern const char bad_pmd_string[]; -#define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) - #define __pte_free_tlb(tlb,pte,addr) \ do { \ pgtable_pte_page_dtor(pte); \ @@ -41,7 +39,6 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t page * inside the pgd, so has no extra memory associated with it. */ #define pmd_free(mm, x) do { } while (0) -#define __pmd_free_tlb(tlb, x, addr) do { } while (0) static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) { @@ -58,6 +55,4 @@ static inline pgd_t * pgd_alloc(struct mm_struct *mm) return new_pgd; } -#define pgd_populate(mm, pmd, pte) BUG() - #endif /* SUN3_PGALLOC_H */ diff --git a/arch/m68k/include/asm/sun3_pgtable.h b/arch/m68k/include/asm/sun3_pgtable.h index c987d50866b4..bc4155264810 100644 --- a/arch/m68k/include/asm/sun3_pgtable.h +++ b/arch/m68k/include/asm/sun3_pgtable.h @@ -110,11 +110,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define pmd_set(pmdp,ptep) do {} while (0) -static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp) -{ - pgd_val(*pgdp) = virt_to_phys(pmdp); -} - #define __pte_page(pte) \ ((unsigned long) __va ((pte_val (pte) & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT)) #define __pmd_page(pmd) \ @@ -145,16 +140,9 @@ static inline int pmd_present2 (pmd_t *pmd) { return pmd_val (*pmd) & SUN3_PMD_V #define pmd_present(pmd) (!pmd_none2(&(pmd))) static inline void pmd_clear (pmd_t *pmdp) { pmd_val (*pmdp) = 0; } -static inline int pgd_none (pgd_t pgd) { return 0; } -static inline int pgd_bad (pgd_t pgd) { return 0; } -static inline int pgd_present (pgd_t pgd) { return 1; } -static inline void pgd_clear (pgd_t *pgdp) {} - #define pte_ERROR(e) \ pr_err("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) -#define pmd_ERROR(e) \ - pr_err("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) #define pgd_ERROR(e) \ pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) @@ -194,12 +182,6 @@ extern pgd_t kernel_pg_dir[PTRS_PER_PGD]; /* Find an entry in a kernel pagetable directory. */ #define pgd_offset_k(address) pgd_offset(&init_mm, address) -/* Find an entry in the second-level pagetable. */ -static inline pmd_t *pmd_offset (pgd_t *pgd, unsigned long address) -{ - return (pmd_t *) pgd; -} - /* Find an entry in the third-level pagetable. */ #define pte_index(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE-1)) #define pte_offset_kernel(pmd, address) ((pte_t *) __pmd_page(*pmd) + pte_index(address)) diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 6363ec83a290..18a4de7d5934 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c @@ -465,6 +465,8 @@ sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, for (;;) { struct mm_struct *mm = current->mm; pgd_t *pgd; + p4d_t *p4d; + pud_t *pud; pmd_t *pmd; pte_t *pte; spinlock_t *ptl; @@ -474,7 +476,13 @@ sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, pgd = pgd_offset(mm, (unsigned long)mem); if (!pgd_present(*pgd)) goto bad_access; - pmd = pmd_offset(pgd, (unsigned long)mem); + p4d = p4d_offset(pgd, (unsigned long)mem); + if (!p4d_present(*p4d)) + goto bad_access; + pud = pud_offset(p4d, (unsigned long)mem); + if (!pud_present(*pud)) + goto bad_access; + pmd = pmd_offset(pud, (unsigned long)mem); if (!pmd_present(*pmd)) goto bad_access; pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl); diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c index 778cacb7d57b..27c453f4fffe 100644 --- a/arch/m68k/mm/init.c +++ b/arch/m68k/mm/init.c @@ -130,8 +130,10 @@ static inline void init_pointer_tables(void) /* insert pointer tables allocated so far into the tablelist */ init_pointer_table((unsigned long)kernel_pg_dir); for (i = 0; i < PTRS_PER_PGD; i++) { - if (pgd_present(kernel_pg_dir[i])) - init_pointer_table(__pgd_page(kernel_pg_dir[i])); + pud_t *pud = (pud_t *)(&kernel_pg_dir[i]); + + if (pud_present(*pud)) + init_pointer_table(pgd_page_vaddr(kernel_pg_dir[i])); } /* insert also pointer table that we used to unmap the zero page */ diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c index 23f9466aabb5..120030ad8dc4 100644 --- a/arch/m68k/mm/kmap.c +++ b/arch/m68k/mm/kmap.c @@ -63,18 +63,23 @@ static void __free_io_area(void *addr, unsigned long size) { unsigned long virtaddr = (unsigned long)addr; pgd_t *pgd_dir; + p4d_t *p4d_dir; + pud_t *pud_dir; pmd_t *pmd_dir; pte_t *pte_dir; while ((long)size > 0) { pgd_dir = pgd_offset_k(virtaddr); - if (pgd_bad(*pgd_dir)) { - printk("iounmap: bad pgd(%08lx)\n", pgd_val(*pgd_dir)); - pgd_clear(pgd_dir); + p4d_dir = p4d_offset(pgd_dir, virtaddr); + pud_dir = pud_offset(p4d_dir, virtaddr); + if (pud_bad(*pud_dir)) { + printk("iounmap: bad pud(%08lx)\n", pud_val(*pud_dir)); + pud_clear(pud_dir); return; } - pmd_dir = pmd_offset(pgd_dir, virtaddr); + pmd_dir = pmd_offset(pud_dir, virtaddr); +#if CONFIG_PGTABLE_LEVELS == 3 if (CPU_IS_020_OR_030) { int pmd_off = (virtaddr/PTRTREESIZE) & 15; int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK; @@ -87,6 +92,7 @@ static void __free_io_area(void *addr, unsigned long size) } else if (pmd_type == 0) continue; } +#endif if (pmd_bad(*pmd_dir)) { printk("iounmap: bad pmd (%08lx)\n", pmd_val(*pmd_dir)); @@ -159,6 +165,8 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cachefla unsigned long virtaddr, retaddr; long offset; pgd_t *pgd_dir; + p4d_t *p4d_dir; + pud_t *pud_dir; pmd_t *pmd_dir; pte_t *pte_dir; @@ -245,18 +253,23 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cachefla printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr); #endif pgd_dir = pgd_offset_k(virtaddr); - pmd_dir = pmd_alloc(&init_mm, pgd_dir, virtaddr); + p4d_dir = p4d_offset(pgd_dir, virtaddr); + pud_dir = pud_offset(p4d_dir, virtaddr); + pmd_dir = pmd_alloc(&init_mm, pud_dir, virtaddr); if (!pmd_dir) { printk("ioremap: no mem for pmd_dir\n"); return NULL; } +#if CONFIG_PGTABLE_LEVELS == 3 if (CPU_IS_020_OR_030) { pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr; physaddr += PTRTREESIZE; virtaddr += PTRTREESIZE; size -= PTRTREESIZE; - } else { + } else +#endif + { pte_dir = pte_alloc_kernel(pmd_dir, virtaddr); if (!pte_dir) { printk("ioremap: no mem for pte_dir\n"); @@ -307,6 +320,8 @@ void kernel_set_cachemode(void *addr, unsigned long size, int cmode) { unsigned long virtaddr = (unsigned long)addr; pgd_t *pgd_dir; + p4d_t *p4d_dir; + pud_t *pud_dir; pmd_t *pmd_dir; pte_t *pte_dir; @@ -341,13 +356,16 @@ void kernel_set_cachemode(void *addr, unsigned long size, int cmode) while ((long)size > 0) { pgd_dir = pgd_offset_k(virtaddr); - if (pgd_bad(*pgd_dir)) { - printk("iocachemode: bad pgd(%08lx)\n", pgd_val(*pgd_dir)); - pgd_clear(pgd_dir); + p4d_dir = p4d_offset(pgd_dir, virtaddr); + pud_dir = pud_offset(p4d_dir, virtaddr); + if (pud_bad(*pud_dir)) { + printk("iocachemode: bad pud(%08lx)\n", pud_val(*pud_dir)); + pud_clear(pud_dir); return; } - pmd_dir = pmd_offset(pgd_dir, virtaddr); + pmd_dir = pmd_offset(pud_dir, virtaddr); +#if CONFIG_PGTABLE_LEVELS == 3 if (CPU_IS_020_OR_030) { int pmd_off = (virtaddr/PTRTREESIZE) & 15; @@ -359,6 +377,7 @@ void kernel_set_cachemode(void *addr, unsigned long size, int cmode) continue; } } +#endif if (pmd_bad(*pmd_dir)) { printk("iocachemode: bad pmd (%08lx)\n", pmd_val(*pmd_dir)); diff --git a/arch/m68k/mm/mcfmmu.c b/arch/m68k/mm/mcfmmu.c index 6cb1e41d58d0..0ea375607767 100644 --- a/arch/m68k/mm/mcfmmu.c +++ b/arch/m68k/mm/mcfmmu.c @@ -92,6 +92,8 @@ int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb, int extension_word) unsigned long flags, mmuar, mmutr; struct mm_struct *mm; pgd_t *pgd; + p4d_t *p4d; + pud_t *pud; pmd_t *pmd; pte_t *pte; int asid; @@ -113,7 +115,19 @@ int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb, int extension_word) return -1; } - pmd = pmd_offset(pgd, mmuar); + p4d = p4d_offset(pgd, mmuar); + if (p4d_none(*p4d)) { + local_irq_restore(flags); + return -1; + } + + pud = pud_offset(p4d, mmuar); + if (pud_none(*pud)) { + local_irq_restore(flags); + return -1; + } + + pmd = pmd_offset(pud, mmuar); if (pmd_none(*pmd)) { local_irq_restore(flags); return -1; diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c index 356601bf96d9..4857985b8080 100644 --- a/arch/m68k/mm/motorola.c +++ b/arch/m68k/mm/motorola.c @@ -82,9 +82,11 @@ static pmd_t * __init kernel_ptr_table(void) */ last = (unsigned long)kernel_pg_dir; for (i = 0; i < PTRS_PER_PGD; i++) { - if (!pgd_present(kernel_pg_dir[i])) + pud_t *pud = (pud_t *)(&kernel_pg_dir[i]); + + if (!pud_present(*pud)) continue; - pmd = __pgd_page(kernel_pg_dir[i]); + pmd = pgd_page_vaddr(kernel_pg_dir[i]); if (pmd > last) last = pmd; } @@ -118,6 +120,8 @@ static void __init map_node(int node) #define ROOTTREESIZE (32*1024*1024) unsigned long physaddr, virtaddr, size; pgd_t *pgd_dir; + p4d_t *p4d_dir; + pud_t *pud_dir; pmd_t *pmd_dir; pte_t *pte_dir; @@ -149,14 +153,16 @@ static void __init map_node(int node) continue; } } - if (!pgd_present(*pgd_dir)) { + p4d_dir = p4d_offset(pgd_dir, virtaddr); + pud_dir = pud_offset(p4d_dir, virtaddr); + if (!pud_present(*pud_dir)) { pmd_dir = kernel_ptr_table(); #ifdef DEBUG printk ("[new pointer %p]", pmd_dir); #endif - pgd_set(pgd_dir, pmd_dir); + pud_set(pud_dir, pmd_dir); } else - pmd_dir = pmd_offset(pgd_dir, virtaddr); + pmd_dir = pmd_offset(pud_dir, virtaddr); if (CPU_IS_020_OR_030) { if (virtaddr) { @@ -304,4 +310,3 @@ void __init paging_init(void) node_set_state(i, N_NORMAL_MEMORY); } } - diff --git a/arch/m68k/sun3x/dvma.c b/arch/m68k/sun3x/dvma.c index 89e630e66555..c4b8aa1d80f4 100644 --- a/arch/m68k/sun3x/dvma.c +++ b/arch/m68k/sun3x/dvma.c @@ -80,6 +80,8 @@ inline int dvma_map_cpu(unsigned long kaddr, unsigned long vaddr, int len) { pgd_t *pgd; + p4d_t *p4d; + pud_t *pud; unsigned long end; int ret = 0; @@ -90,12 +92,14 @@ inline int dvma_map_cpu(unsigned long kaddr, pr_debug("dvma: mapping kern %08lx to virt %08lx\n", kaddr, vaddr); pgd = pgd_offset_k(vaddr); + p4d = p4d_offset(pgd, vaddr); + pud = pud_offset(p4d, vaddr); do { pmd_t *pmd; unsigned long end2; - if((pmd = pmd_alloc(&init_mm, pgd, vaddr)) == NULL) { + if((pmd = pmd_alloc(&init_mm, pud, vaddr)) == NULL) { ret = -ENOMEM; goto out; } @@ -196,4 +200,3 @@ void dvma_unmap_iommu(unsigned long baddr, int len) } } - |