Linux-parisc archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK
@ 2019-10-23  9:28 Mike Rapoport
  2019-10-23  9:28 ` [PATCH 01/12] alpha: use pgtable-nop4d instead of 4level-fixup Mike Rapoport
                   ` (12 more replies)
  0 siblings, 13 replies; 31+ messages in thread
From: Mike Rapoport @ 2019-10-23  9:28 UTC (permalink / raw)
  To: linux-mm
  Cc: Andrew Morton, Anton Ivanov, Arnd Bergmann, David S. Miller,
	Geert Uytterhoeven, Greentime Hu, Greg Ungerer, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, Mike Rapoport, linux-alpha, linux-arch,
	linux-arm-kernel, linux-c6x-dev, linux-kernel, linux-m68k,
	linux-parisc, linux-um, sparclinux, Mike Rapoport

From: Mike Rapoport <rppt@linux.ibm.com>

Hi,

These patches convert several architectures to use page table folding and
remove __ARCH_HAS_4LEVEL_HACK along with include/asm-generic/4level-fixup.h.

For the nommu configurations the folding is already implemented by the
generic code so the only change was to use the appropriate header file.

As for the rest, the changes are mostly about mechanical replacement of
pgd accessors with pud/pmd ones and the addition of higher levels to page
table traversals.

With Vineet's patches from "elide extraneous generated code for folded
p4d/pud/pmd" series [1] there is a small shrink of the kernel size of about
-0.01% for the defconfig build. 

The set is boot-tested on UML, qemu-{alpha,sparc} and aranym.

[1] https://lore.kernel.org/lkml/20191016162400.14796-1-vgupta@synopsys.com

Mike Rapoport (12):
  alpha: use pgtable-nop4d instead of 4level-fixup
  arm: nommu: use pgtable-nopud instead of 4level-fixup
  c6x: use pgtable-nopud instead of 4level-fixup
  m68k: nommu: use pgtable-nopud instead of 4level-fixup
  m68k: mm: use pgtable-nopXd instead of 4level-fixup
  microblaze: use pgtable-nopmd instead of 4level-fixup
  nds32: use pgtable-nopmd instead of 4level-fixup
  parisc: use pgtable-nopXd instead of 4level-fixup
  sparc32: use pgtable-nopud instead of 4level-fixup
  um: remove unused pxx_offset_proc() and addr_pte() functions
  um: add support for folded p4d page tables
  mm: remove __ARCH_HAS_4LEVEL_HACK and include/asm-generic/4level-fixup.h

 arch/alpha/include/asm/pgalloc.h         |  4 +-
 arch/alpha/include/asm/pgtable.h         | 24 ++++-----
 arch/alpha/mm/init.c                     | 12 +++--
 arch/arm/include/asm/pgtable.h           |  2 +-
 arch/c6x/include/asm/pgtable.h           |  2 +-
 arch/m68k/include/asm/mcf_pgalloc.h      |  7 ---
 arch/m68k/include/asm/mcf_pgtable.h      | 28 ++++-------
 arch/m68k/include/asm/mmu_context.h      | 12 ++++-
 arch/m68k/include/asm/motorola_pgalloc.h |  4 +-
 arch/m68k/include/asm/motorola_pgtable.h | 32 +++++++-----
 arch/m68k/include/asm/page.h             |  9 ++--
 arch/m68k/include/asm/pgtable_mm.h       | 11 +++--
 arch/m68k/include/asm/pgtable_no.h       |  2 +-
 arch/m68k/include/asm/sun3_pgalloc.h     |  5 --
 arch/m68k/include/asm/sun3_pgtable.h     | 18 -------
 arch/m68k/kernel/sys_m68k.c              | 10 +++-
 arch/m68k/mm/init.c                      |  6 ++-
 arch/m68k/mm/kmap.c                      | 36 ++++++++++----
 arch/m68k/mm/mcfmmu.c                    | 16 +++++-
 arch/m68k/mm/motorola.c                  | 17 ++++---
 arch/microblaze/include/asm/page.h       |  3 --
 arch/microblaze/include/asm/pgalloc.h    | 16 ------
 arch/microblaze/include/asm/pgtable.h    | 32 +-----------
 arch/microblaze/kernel/signal.c          | 10 ++--
 arch/microblaze/mm/init.c                |  7 ++-
 arch/microblaze/mm/pgtable.c             | 13 ++++-
 arch/nds32/include/asm/page.h            |  3 --
 arch/nds32/include/asm/pgalloc.h         |  3 --
 arch/nds32/include/asm/pgtable.h         | 12 +----
 arch/nds32/include/asm/tlb.h             |  1 -
 arch/nds32/kernel/pm.c                   |  4 +-
 arch/nds32/mm/fault.c                    | 16 ++++--
 arch/nds32/mm/init.c                     | 11 +++--
 arch/nds32/mm/mm-nds32.c                 |  6 ++-
 arch/nds32/mm/proc.c                     | 26 ++++++----
 arch/parisc/include/asm/page.h           | 30 ++++++-----
 arch/parisc/include/asm/pgalloc.h        | 41 ++++++---------
 arch/parisc/include/asm/pgtable.h        | 52 ++++++++++---------
 arch/parisc/include/asm/tlb.h            |  2 +
 arch/parisc/kernel/cache.c               | 13 +++--
 arch/parisc/kernel/pci-dma.c             |  9 +++-
 arch/parisc/mm/fixmap.c                  | 10 ++--
 arch/sparc/include/asm/pgalloc_32.h      |  6 +--
 arch/sparc/include/asm/pgtable_32.h      | 28 +++++------
 arch/sparc/mm/fault_32.c                 | 11 ++++-
 arch/sparc/mm/highmem.c                  |  6 ++-
 arch/sparc/mm/io-unit.c                  |  6 ++-
 arch/sparc/mm/iommu.c                    |  6 ++-
 arch/sparc/mm/srmmu.c                    | 51 ++++++++++++++-----
 arch/um/include/asm/pgtable-2level.h     |  1 -
 arch/um/include/asm/pgtable-3level.h     |  1 -
 arch/um/include/asm/pgtable.h            |  3 ++
 arch/um/kernel/mem.c                     | 25 +++++++++-
 arch/um/kernel/skas/mmu.c                | 12 ++++-
 arch/um/kernel/skas/uaccess.c            |  7 ++-
 arch/um/kernel/tlb.c                     | 85 +++++++++++++++++++-------------
 arch/um/kernel/trap.c                    |  4 +-
 include/asm-generic/4level-fixup.h       | 40 ---------------
 include/asm-generic/tlb.h                |  2 -
 include/linux/mm.h                       | 10 ++--
 mm/memory.c                              |  8 ---
 61 files changed, 481 insertions(+), 408 deletions(-)
 delete mode 100644 include/asm-generic/4level-fixup.h

-- 
2.7.4


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 01/12] alpha: use pgtable-nop4d instead of 4level-fixup
  2019-10-23  9:28 [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK Mike Rapoport
@ 2019-10-23  9:28 ` Mike Rapoport
  2019-10-23  9:28 ` [PATCH 02/12] arm: nommu: use pgtable-nopud " Mike Rapoport
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 31+ messages in thread
From: Mike Rapoport @ 2019-10-23  9:28 UTC (permalink / raw)
  To: linux-mm
  Cc: Andrew Morton, Anton Ivanov, Arnd Bergmann, David S. Miller,
	Geert Uytterhoeven, Greentime Hu, Greg Ungerer, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, Mike Rapoport, linux-alpha, linux-arch,
	linux-arm-kernel, linux-c6x-dev, linux-kernel, linux-m68k,
	linux-parisc, linux-um, sparclinux, Mike Rapoport

From: Mike Rapoport <rppt@linux.ibm.com>

It is not likely alpha will have 5-level page tables.

Replace usage of include/asm-generic/4level-fixup.h and implied
__ARCH_HAS_4LEVEL_HACK with include/asm-generic/pgtable-nop4d.h and adjust
page table manipulation macros and functions accordingly.

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
 arch/alpha/include/asm/pgalloc.h |  4 ++--
 arch/alpha/include/asm/pgtable.h | 24 ++++++++++++------------
 arch/alpha/mm/init.c             | 12 ++++++++----
 3 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/arch/alpha/include/asm/pgalloc.h b/arch/alpha/include/asm/pgalloc.h
index eb91f1e..a1a29f6 100644
--- a/arch/alpha/include/asm/pgalloc.h
+++ b/arch/alpha/include/asm/pgalloc.h
@@ -27,9 +27,9 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
 }
 
 static inline void
-pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
+pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
 {
-	pgd_set(pgd, pmd);
+	pud_set(pud, pmd);
 }
 
 extern pgd_t *pgd_alloc(struct mm_struct *mm);
diff --git a/arch/alpha/include/asm/pgtable.h b/arch/alpha/include/asm/pgtable.h
index 065b57f..299791c 100644
--- a/arch/alpha/include/asm/pgtable.h
+++ b/arch/alpha/include/asm/pgtable.h
@@ -2,7 +2,7 @@
 #ifndef _ALPHA_PGTABLE_H
 #define _ALPHA_PGTABLE_H
 
-#include <asm-generic/4level-fixup.h>
+#include <asm-generic/pgtable-nopud.h>
 
 /*
  * This file contains the functions and defines necessary to modify and use
@@ -226,8 +226,8 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
 { pmd_val(*pmdp) = _PAGE_TABLE | ((((unsigned long) ptep) - PAGE_OFFSET) << (32-PAGE_SHIFT)); }
 
-extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
-{ pgd_val(*pgdp) = _PAGE_TABLE | ((((unsigned long) pmdp) - PAGE_OFFSET) << (32-PAGE_SHIFT)); }
+extern inline void pud_set(pud_t * pudp, pmd_t * pmdp)
+{ pud_val(*pudp) = _PAGE_TABLE | ((((unsigned long) pmdp) - PAGE_OFFSET) << (32-PAGE_SHIFT)); }
 
 
 extern inline unsigned long
@@ -238,11 +238,11 @@ pmd_page_vaddr(pmd_t pmd)
 
 #ifndef CONFIG_DISCONTIGMEM
 #define pmd_page(pmd)	(mem_map + ((pmd_val(pmd) & _PFN_MASK) >> 32))
-#define pgd_page(pgd)	(mem_map + ((pgd_val(pgd) & _PFN_MASK) >> 32))
+#define pud_page(pud)	(mem_map + ((pud_val(pud) & _PFN_MASK) >> 32))
 #endif
 
-extern inline unsigned long pgd_page_vaddr(pgd_t pgd)
-{ return PAGE_OFFSET + ((pgd_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT)); }
+extern inline unsigned long pud_page_vaddr(pud_t pgd)
+{ return PAGE_OFFSET + ((pud_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT)); }
 
 extern inline int pte_none(pte_t pte)		{ return !pte_val(pte); }
 extern inline int pte_present(pte_t pte)	{ return pte_val(pte) & _PAGE_VALID; }
@@ -256,10 +256,10 @@ extern inline int pmd_bad(pmd_t pmd)		{ return (pmd_val(pmd) & ~_PFN_MASK) != _P
 extern inline int pmd_present(pmd_t pmd)	{ return pmd_val(pmd) & _PAGE_VALID; }
 extern inline void pmd_clear(pmd_t * pmdp)	{ pmd_val(*pmdp) = 0; }
 
-extern inline int pgd_none(pgd_t pgd)		{ return !pgd_val(pgd); }
-extern inline int pgd_bad(pgd_t pgd)		{ return (pgd_val(pgd) & ~_PFN_MASK) != _PAGE_TABLE; }
-extern inline int pgd_present(pgd_t pgd)	{ return pgd_val(pgd) & _PAGE_VALID; }
-extern inline void pgd_clear(pgd_t * pgdp)	{ pgd_val(*pgdp) = 0; }
+extern inline int pud_none(pud_t pud)		{ return !pud_val(pud); }
+extern inline int pud_bad(pud_t pud)		{ return (pud_val(pud) & ~_PFN_MASK) != _PAGE_TABLE; }
+extern inline int pud_present(pud_t pud)	{ return pud_val(pud) & _PAGE_VALID; }
+extern inline void pud_clear(pud_t * pudp)	{ pud_val(*pudp) = 0; }
 
 /*
  * The following only work if pte_present() is true.
@@ -301,9 +301,9 @@ extern inline pte_t pte_mkspecial(pte_t pte)	{ return pte; }
  */
 
 /* Find an entry in the second-level page table.. */
-extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
+extern inline pmd_t * pmd_offset(pud_t * dir, unsigned long address)
 {
-	pmd_t *ret = (pmd_t *) pgd_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1));
+	pmd_t *ret = (pmd_t *) pud_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1));
 	smp_read_barrier_depends(); /* see above */
 	return ret;
 }
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index e2cbec3..12e218d 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -146,6 +146,8 @@ callback_init(void * kernel_end)
 {
 	struct crb_struct * crb;
 	pgd_t *pgd;
+	p4d_t *p4d;
+	pud_t *pud;
 	pmd_t *pmd;
 	void *two_pages;
 
@@ -184,8 +186,10 @@ callback_init(void * kernel_end)
 	memset(two_pages, 0, 2*PAGE_SIZE);
 
 	pgd = pgd_offset_k(VMALLOC_START);
-	pgd_set(pgd, (pmd_t *)two_pages);
-	pmd = pmd_offset(pgd, VMALLOC_START);
+	p4d = p4d_offset(pgd, VMALLOC_START);
+	pud = pud_offset(p4d, VMALLOC_START);
+	pud_set(pud, (pmd_t *)two_pages);
+	pmd = pmd_offset(pud, VMALLOC_START);
 	pmd_set(pmd, (pte_t *)(two_pages + PAGE_SIZE));
 
 	if (alpha_using_srm) {
@@ -214,9 +218,9 @@ callback_init(void * kernel_end)
 				/* Newer consoles (especially on larger
 				   systems) may require more pages of
 				   PTEs. Grab additional pages as needed. */
-				if (pmd != pmd_offset(pgd, vaddr)) {
+				if (pmd != pmd_offset(pud, vaddr)) {
 					memset(kernel_end, 0, PAGE_SIZE);
-					pmd = pmd_offset(pgd, vaddr);
+					pmd = pmd_offset(pud, vaddr);
 					pmd_set(pmd, (pte_t *)kernel_end);
 					kernel_end += PAGE_SIZE;
 				}
-- 
2.7.4


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 02/12] arm: nommu: use pgtable-nopud instead of 4level-fixup
  2019-10-23  9:28 [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK Mike Rapoport
  2019-10-23  9:28 ` [PATCH 01/12] alpha: use pgtable-nop4d instead of 4level-fixup Mike Rapoport
@ 2019-10-23  9:28 ` " Mike Rapoport
  2019-10-23  9:40   ` Russell King - ARM Linux admin
  2019-10-23  9:28 ` [PATCH 03/12] c6x: " Mike Rapoport
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 31+ messages in thread
From: Mike Rapoport @ 2019-10-23  9:28 UTC (permalink / raw)
  To: linux-mm
  Cc: Andrew Morton, Anton Ivanov, Arnd Bergmann, David S. Miller,
	Geert Uytterhoeven, Greentime Hu, Greg Ungerer, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, Mike Rapoport, linux-alpha, linux-arch,
	linux-arm-kernel, linux-c6x-dev, linux-kernel, linux-m68k,
	linux-parisc, linux-um, sparclinux, Mike Rapoport

From: Mike Rapoport <rppt@linux.ibm.com>

The generic nommu implementation of page table manipulation takes care of
folding of the upper levels and does not require fixups.

Simply replace of include/asm-generic/4level-fixup.h with
include/asm-generic/pgtable-nopud.h.

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
 arch/arm/include/asm/pgtable.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 3ae120c..eabcb48 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -12,7 +12,7 @@
 
 #ifndef CONFIG_MMU
 
-#include <asm-generic/4level-fixup.h>
+#include <asm-generic/pgtable-nopud.h>
 #include <asm/pgtable-nommu.h>
 
 #else
-- 
2.7.4


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 03/12] c6x: use pgtable-nopud instead of 4level-fixup
  2019-10-23  9:28 [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK Mike Rapoport
  2019-10-23  9:28 ` [PATCH 01/12] alpha: use pgtable-nop4d instead of 4level-fixup Mike Rapoport
  2019-10-23  9:28 ` [PATCH 02/12] arm: nommu: use pgtable-nopud " Mike Rapoport
@ 2019-10-23  9:28 ` " Mike Rapoport
  2019-10-23  9:28 ` [PATCH 04/12] m68k: nommu: " Mike Rapoport
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 31+ messages in thread
From: Mike Rapoport @ 2019-10-23  9:28 UTC (permalink / raw)
  To: linux-mm
  Cc: Andrew Morton, Anton Ivanov, Arnd Bergmann, David S. Miller,
	Geert Uytterhoeven, Greentime Hu, Greg Ungerer, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, Mike Rapoport, linux-alpha, linux-arch,
	linux-arm-kernel, linux-c6x-dev, linux-kernel, linux-m68k,
	linux-parisc, linux-um, sparclinux, Mike Rapoport

From: Mike Rapoport <rppt@linux.ibm.com>

c6x is a nommu architecture and does not require fixup for upper layers of
the page tables because it is already handled by the generic nommu
implementation.

Replace usage of include/asm-generic/4level-fixup.h with
include/asm-generic/pgtable-nopud.h

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
 arch/c6x/include/asm/pgtable.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/c6x/include/asm/pgtable.h b/arch/c6x/include/asm/pgtable.h
index 0b6919c..197c473 100644
--- a/arch/c6x/include/asm/pgtable.h
+++ b/arch/c6x/include/asm/pgtable.h
@@ -8,7 +8,7 @@
 #ifndef _ASM_C6X_PGTABLE_H
 #define _ASM_C6X_PGTABLE_H
 
-#include <asm-generic/4level-fixup.h>
+#include <asm-generic/pgtable-nopud.h>
 
 #include <asm/setup.h>
 #include <asm/page.h>
-- 
2.7.4


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 04/12] m68k: nommu: use pgtable-nopud instead of 4level-fixup
  2019-10-23  9:28 [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK Mike Rapoport
                   ` (2 preceding siblings ...)
  2019-10-23  9:28 ` [PATCH 03/12] c6x: " Mike Rapoport
@ 2019-10-23  9:28 ` " Mike Rapoport
  2019-10-24  4:09   ` Greg Ungerer
  2019-10-23  9:28 ` [PATCH 05/12] m68k: mm: use pgtable-nopXd " Mike Rapoport
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 31+ messages in thread
From: Mike Rapoport @ 2019-10-23  9:28 UTC (permalink / raw)
  To: linux-mm
  Cc: Andrew Morton, Anton Ivanov, Arnd Bergmann, David S. Miller,
	Geert Uytterhoeven, Greentime Hu, Greg Ungerer, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, Mike Rapoport, linux-alpha, linux-arch,
	linux-arm-kernel, linux-c6x-dev, linux-kernel, linux-m68k,
	linux-parisc, linux-um, sparclinux, Mike Rapoport

From: Mike Rapoport <rppt@linux.ibm.com>

The generic nommu implementation of page table manipulation takes care of
folding of the upper levels and does not require fixups.

Simply replace of include/asm-generic/4level-fixup.h with
include/asm-generic/pgtable-nopud.h.

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
 arch/m68k/include/asm/pgtable_no.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/m68k/include/asm/pgtable_no.h b/arch/m68k/include/asm/pgtable_no.h
index c18165b..ccc4568 100644
--- a/arch/m68k/include/asm/pgtable_no.h
+++ b/arch/m68k/include/asm/pgtable_no.h
@@ -2,7 +2,7 @@
 #ifndef _M68KNOMMU_PGTABLE_H
 #define _M68KNOMMU_PGTABLE_H
 
-#include <asm-generic/4level-fixup.h>
+#include <asm-generic/pgtable-nopud.h>
 
 /*
  * (C) Copyright 2000-2002, Greg Ungerer <gerg@snapgear.com>
-- 
2.7.4


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 05/12] m68k: mm: use pgtable-nopXd instead of 4level-fixup
  2019-10-23  9:28 [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK Mike Rapoport
                   ` (3 preceding siblings ...)
  2019-10-23  9:28 ` [PATCH 04/12] m68k: nommu: " Mike Rapoport
@ 2019-10-23  9:28 ` " Mike Rapoport
  2019-10-24  4:12   ` Greg Ungerer
  2019-10-25  5:52   ` kbuild test robot
  2019-10-23  9:28 ` [PATCH 06/12] microblaze: use pgtable-nopmd " Mike Rapoport
                   ` (7 subsequent siblings)
  12 siblings, 2 replies; 31+ messages in thread
From: Mike Rapoport @ 2019-10-23  9:28 UTC (permalink / raw)
  To: linux-mm
  Cc: Andrew Morton, Anton Ivanov, Arnd Bergmann, David S. Miller,
	Geert Uytterhoeven, Greentime Hu, Greg Ungerer, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, Mike Rapoport, linux-alpha, linux-arch,
	linux-arm-kernel, linux-c6x-dev, linux-kernel, linux-m68k,
	linux-parisc, linux-um, sparclinux, Mike Rapoport

From: Mike Rapoport <rppt@linux.ibm.com>

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-nopmd.h for three-lelve configurations and
adjust page table manipulation macros and functions accordingly.

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
 arch/m68k/include/asm/mcf_pgalloc.h      |  7 -------
 arch/m68k/include/asm/mcf_pgtable.h      | 28 +++++++++----------------
 arch/m68k/include/asm/mmu_context.h      | 12 ++++++++++-
 arch/m68k/include/asm/motorola_pgalloc.h |  4 ++--
 arch/m68k/include/asm/motorola_pgtable.h | 32 +++++++++++++++++-----------
 arch/m68k/include/asm/page.h             |  9 +++++---
 arch/m68k/include/asm/pgtable_mm.h       | 11 ++++++----
 arch/m68k/include/asm/sun3_pgalloc.h     |  5 -----
 arch/m68k/include/asm/sun3_pgtable.h     | 18 ----------------
 arch/m68k/kernel/sys_m68k.c              | 10 ++++++++-
 arch/m68k/mm/init.c                      |  6 ++++--
 arch/m68k/mm/kmap.c                      | 36 ++++++++++++++++++++++++--------
 arch/m68k/mm/mcfmmu.c                    | 16 +++++++++++++-
 arch/m68k/mm/motorola.c                  | 17 +++++++++------
 14 files changed, 122 insertions(+), 89 deletions(-)

diff --git a/arch/m68k/include/asm/mcf_pgalloc.h b/arch/m68k/include/asm/mcf_pgalloc.h
index b34d44d..82ec54c 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 5d5502c..b9f45ae 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 f5b1852..cac9f28 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 acab315..ff9cc40 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 7f66a7b..62bedc6 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 700d819..c00b67a 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 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 646c174f..2bf5c35 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 8561211..11b95da 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 c987d50..bc41552 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 6363ec8..18a4de7 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 778cacb..27c453f 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 40a3b32..9f687da 100644
--- a/arch/m68k/mm/kmap.c
+++ b/arch/m68k/mm/kmap.c
@@ -110,6 +110,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;
 
@@ -196,17 +198,21 @@ 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 (CPU_IS_020_OR_030) {
+#if CONFIG_PGTABLE_LEVELS == 3
 			pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr;
 			physaddr += PTRTREESIZE;
 			virtaddr += PTRTREESIZE;
 			size -= PTRTREESIZE;
+#endif
 		} else {
 			pte_dir = pte_alloc_kernel(pmd_dir, virtaddr);
 			if (!pte_dir) {
@@ -258,19 +264,24 @@ void __iounmap(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 pgd(%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 (CPU_IS_020_OR_030) {
+#if CONFIG_PGTABLE_LEVELS == 3
 			int pmd_off = (virtaddr/PTRTREESIZE) & 15;
 			int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK;
 
@@ -281,6 +292,7 @@ void __iounmap(void *addr, unsigned long size)
 				continue;
 			} else if (pmd_type == 0)
 				continue;
+#endif
 		}
 
 		if (pmd_bad(*pmd_dir)) {
@@ -307,6 +319,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,14 +355,17 @@ 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 (CPU_IS_020_OR_030) {
+#if CONFIG_PGTABLE_LEVELS == 3
 			int pmd_off = (virtaddr/PTRTREESIZE) & 15;
 
 			if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) {
@@ -358,6 +375,7 @@ void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
 				size -= PTRTREESIZE;
 				continue;
 			}
+#endif
 		}
 
 		if (pmd_bad(*pmd_dir)) {
diff --git a/arch/m68k/mm/mcfmmu.c b/arch/m68k/mm/mcfmmu.c
index 6cb1e41..0ea3756 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 356601b..4857985 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);
 	}
 }
-
-- 
2.7.4


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 06/12] microblaze: use pgtable-nopmd instead of 4level-fixup
  2019-10-23  9:28 [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK Mike Rapoport
                   ` (4 preceding siblings ...)
  2019-10-23  9:28 ` [PATCH 05/12] m68k: mm: use pgtable-nopXd " Mike Rapoport
@ 2019-10-23  9:28 ` " Mike Rapoport
  2019-10-25  2:17   ` kbuild test robot
  2019-10-25  8:24   ` Michal Simek
  2019-10-23  9:28 ` [PATCH 07/12] nds32: " Mike Rapoport
                   ` (6 subsequent siblings)
  12 siblings, 2 replies; 31+ messages in thread
From: Mike Rapoport @ 2019-10-23  9:28 UTC (permalink / raw)
  To: linux-mm
  Cc: Andrew Morton, Anton Ivanov, Arnd Bergmann, David S. Miller,
	Geert Uytterhoeven, Greentime Hu, Greg Ungerer, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, Mike Rapoport, linux-alpha, linux-arch,
	linux-arm-kernel, linux-c6x-dev, linux-kernel, linux-m68k,
	linux-parisc, linux-um, sparclinux, Mike Rapoport

From: Mike Rapoport <rppt@linux.ibm.com>

microblaze has only two-level page tables and can use pgtable-nopmd and
folding of the upper layers.

Replace usage of include/asm-generic/4level-fixup.h and explicit definition
of __PAGETABLE_PMD_FOLDED in microblaze with
include/asm-generic/pgtable-nopmd.h and adjust page table manipulation
macros and functions accordingly.

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
 arch/microblaze/include/asm/page.h    |  3 ---
 arch/microblaze/include/asm/pgalloc.h | 16 ----------------
 arch/microblaze/include/asm/pgtable.h | 32 ++------------------------------
 arch/microblaze/kernel/signal.c       | 10 +++++++---
 arch/microblaze/mm/init.c             |  7 +++++--
 arch/microblaze/mm/pgtable.c          | 13 +++++++++++--
 6 files changed, 25 insertions(+), 56 deletions(-)

diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h
index d506bb0..f4b44b2 100644
--- a/arch/microblaze/include/asm/page.h
+++ b/arch/microblaze/include/asm/page.h
@@ -90,7 +90,6 @@ typedef struct { unsigned long	pte; }		pte_t;
 typedef struct { unsigned long	pgprot; }	pgprot_t;
 /* FIXME this can depend on linux kernel version */
 #   ifdef CONFIG_MMU
-typedef struct { unsigned long pmd; } pmd_t;
 typedef struct { unsigned long pgd; } pgd_t;
 #   else /* CONFIG_MMU */
 typedef struct { unsigned long	ste[64]; }	pmd_t;
@@ -103,7 +102,6 @@ typedef struct { p4d_t		pge[1]; }	pgd_t;
 # define pgprot_val(x)	((x).pgprot)
 
 #   ifdef CONFIG_MMU
-#   define pmd_val(x)      ((x).pmd)
 #   define pgd_val(x)      ((x).pgd)
 #   else  /* CONFIG_MMU */
 #   define pmd_val(x)	((x).ste[0])
@@ -112,7 +110,6 @@ typedef struct { p4d_t		pge[1]; }	pgd_t;
 #   endif  /* CONFIG_MMU */
 
 # 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/microblaze/include/asm/pgalloc.h b/arch/microblaze/include/asm/pgalloc.h
index 7ecb05b..fcf1e23 100644
--- a/arch/microblaze/include/asm/pgalloc.h
+++ b/arch/microblaze/include/asm/pgalloc.h
@@ -41,13 +41,6 @@ static inline void free_pgd(pgd_t *pgd)
 
 #define pmd_pgtable(pmd)	pmd_page(pmd)
 
-/*
- * We don't have any real pmd's, and this code never triggers because
- * the pgd will always be present..
- */
-#define pmd_alloc_one_fast(mm, address)	({ BUG(); ((pmd_t *)1); })
-#define pmd_alloc_one(mm, address)	({ BUG(); ((pmd_t *)2); })
-
 extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm);
 
 #define __pte_free_tlb(tlb, pte, addr)	pte_free((tlb)->mm, (pte))
@@ -58,15 +51,6 @@ extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm);
 #define pmd_populate_kernel(mm, pmd, pte) \
 		(pmd_val(*(pmd)) = (unsigned long) (pte))
 
-/*
- * We don't have any real pmd's, and this code never triggers because
- * the pgd will always be present..
- */
-#define pmd_alloc_one(mm, address)	({ BUG(); ((pmd_t *)2); })
-#define pmd_free(mm, x)			do { } while (0)
-#define __pmd_free_tlb(tlb, x, addr)	pmd_free((tlb)->mm, x)
-#define pgd_populate(mm, pmd, pte)	BUG()
-
 #endif /* CONFIG_MMU */
 
 #endif /* _ASM_MICROBLAZE_PGALLOC_H */
diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h
index 954b69a..2def331 100644
--- a/arch/microblaze/include/asm/pgtable.h
+++ b/arch/microblaze/include/asm/pgtable.h
@@ -59,9 +59,7 @@ extern int mem_init_done;
 
 #else /* CONFIG_MMU */
 
-#include <asm-generic/4level-fixup.h>
-
-#define __PAGETABLE_PMD_FOLDED 1
+#include <asm-generic/pgtable-nopmd.h>
 
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
@@ -138,13 +136,8 @@ static inline pte_t pte_mkspecial(pte_t pte)	{ return pte; }
  *
  */
 
-/* PMD_SHIFT determines the size of the area mapped by the PTE pages */
-#define PMD_SHIFT	(PAGE_SHIFT + PTE_SHIFT)
-#define PMD_SIZE	(1UL << PMD_SHIFT)
-#define PMD_MASK	(~(PMD_SIZE-1))
-
 /* PGDIR_SHIFT determines what a top-level page table entry can map */
-#define PGDIR_SHIFT	PMD_SHIFT
+#define PGDIR_SHIFT	(PAGE_SHIFT + PTE_SHIFT)
 #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
@@ -165,9 +158,6 @@ static inline pte_t pte_mkspecial(pte_t pte)	{ return pte; }
 #define pte_ERROR(e) \
 	printk(KERN_ERR "%s:%d: bad pte "PTE_FMT".\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))
@@ -314,18 +304,6 @@ extern unsigned long empty_zero_page[1024];
 
 #ifndef __ASSEMBLY__
 /*
- * The "pgd_xxx()" functions here are trivial for a folded two-level
- * setup: the pgd is never bad, and a pmd always exists (as it's folded
- * into the pgd entry)
- */
-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; }
-#define pgd_clear(xp)				do { } while (0)
-#define pgd_page(pgd) \
-	((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
-
-/*
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
  */
@@ -479,12 +457,6 @@ static inline void ptep_mkdirty(struct mm_struct *mm,
 #define pgd_index(address)	 ((address) >> PGDIR_SHIFT)
 #define pgd_offset(mm, address)	 ((mm)->pgd + pgd_index(address))
 
-/* Find an entry in the second-level page table.. */
-static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
-{
-	return (pmd_t *) dir;
-}
-
 /* Find an entry in the third-level page table.. */
 #define pte_index(address)		\
 	(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index cdd4feb..c9125c3 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -160,6 +160,9 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 	int err = 0, sig = ksig->sig;
 	unsigned long address = 0;
 #ifdef CONFIG_MMU
+	pgd_t *pgdp;
+	p4d_t *p4dp;
+	pud_t *pudp;
 	pmd_t *pmdp;
 	pte_t *ptep;
 #endif
@@ -195,9 +198,10 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 
 	address = ((unsigned long)frame->tramp);
 #ifdef CONFIG_MMU
-	pmdp = pmd_offset(pud_offset(
-			pgd_offset(current->mm, address),
-					address), address);
+	pgdp = pgd_offset(current->mm, address);
+	p4dp = p4d_offset(pgdp, address);
+	pudp = pud_offset(p4dp, address);
+	pmdp = pmd_offset(pudp, address);
 
 	preempt_disable();
 	ptep = pte_offset_map(pmdp, address);
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
index a015a95..050fc62 100644
--- a/arch/microblaze/mm/init.c
+++ b/arch/microblaze/mm/init.c
@@ -53,8 +53,11 @@ EXPORT_SYMBOL(kmap_prot);
 
 static inline pte_t *virt_to_kpte(unsigned long vaddr)
 {
-	return pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr),
-			vaddr), vaddr);
+	pgd_t *pgd = pgd_offset_k(vaddr);
+	p4d_t *p4d = p4d_offset(pgd, vaddr);
+	pud_t *pud = pud_offset(p4d, vaddr);
+
+	return pte_offset_kernel(pmd_offset(pud, vaddr), vaddr);
 }
 
 static void __init highmem_init(void)
diff --git a/arch/microblaze/mm/pgtable.c b/arch/microblaze/mm/pgtable.c
index 010bb9c..68c26ca 100644
--- a/arch/microblaze/mm/pgtable.c
+++ b/arch/microblaze/mm/pgtable.c
@@ -134,11 +134,16 @@ EXPORT_SYMBOL(iounmap);
 
 int map_page(unsigned long va, phys_addr_t pa, int flags)
 {
+	p4d_t *p4d;
+	pud_t *pud;
 	pmd_t *pd;
 	pte_t *pg;
 	int err = -ENOMEM;
+
 	/* Use upper 10 bits of VA to index the first level map */
-	pd = pmd_offset(pgd_offset_k(va), va);
+	p4d = p4d_offset(pgd_offset_k(va), va);
+	pud = pud_offset(p4d, va);
+	pd = pmd_offset(pud, va);
 	/* Use middle 10 bits of VA to index the second-level map */
 	pg = pte_alloc_kernel(pd, va); /* from powerpc - pgtable.c */
 	/* pg = pte_alloc_kernel(&init_mm, pd, va); */
@@ -188,13 +193,17 @@ void __init mapin_ram(void)
 static int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep)
 {
 	pgd_t	*pgd;
+	p4d_t	*p4d;
+	pud_t	*pud;
 	pmd_t	*pmd;
 	pte_t	*pte;
 	int     retval = 0;
 
 	pgd = pgd_offset(mm, addr & PAGE_MASK);
 	if (pgd) {
-		pmd = pmd_offset(pgd, addr & PAGE_MASK);
+		p4d = p4d_offset(pgd, addr & PAGE_MASK);
+		pud = pud_offset(p4d, addr & PAGE_MASK);
+		pmd = pmd_offset(pud, addr & PAGE_MASK);
 		if (pmd_present(*pmd)) {
 			pte = pte_offset_kernel(pmd, addr & PAGE_MASK);
 			if (pte) {
-- 
2.7.4


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 07/12] nds32: use pgtable-nopmd instead of 4level-fixup
  2019-10-23  9:28 [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK Mike Rapoport
                   ` (5 preceding siblings ...)
  2019-10-23  9:28 ` [PATCH 06/12] microblaze: use pgtable-nopmd " Mike Rapoport
@ 2019-10-23  9:28 ` " Mike Rapoport
  2019-10-23  9:28 ` [PATCH 08/12] parisc: use pgtable-nopXd " Mike Rapoport
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 31+ messages in thread
From: Mike Rapoport @ 2019-10-23  9:28 UTC (permalink / raw)
  To: linux-mm
  Cc: Andrew Morton, Anton Ivanov, Arnd Bergmann, David S. Miller,
	Geert Uytterhoeven, Greentime Hu, Greg Ungerer, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, Mike Rapoport, linux-alpha, linux-arch,
	linux-arm-kernel, linux-c6x-dev, linux-kernel, linux-m68k,
	linux-parisc, linux-um, sparclinux, Mike Rapoport

From: Mike Rapoport <rppt@linux.ibm.com>

nds32 has only two-level page tables and can use pgtable-nopmd and folding
of the upper layers.

Replace usage of include/asm-generic/4level-fixup.h and explicit definition
of __PAGETABLE_PMD_FOLDED in nds32 with include/asm-generic/pgtable-nopmd.h
and adjust page table manipulation macros and functions accordingly.

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
 arch/nds32/include/asm/page.h    |  3 ---
 arch/nds32/include/asm/pgalloc.h |  3 ---
 arch/nds32/include/asm/pgtable.h | 12 +-----------
 arch/nds32/include/asm/tlb.h     |  1 -
 arch/nds32/kernel/pm.c           |  4 +++-
 arch/nds32/mm/fault.c            | 16 +++++++++++++---
 arch/nds32/mm/init.c             | 11 ++++++++---
 arch/nds32/mm/mm-nds32.c         |  6 +++++-
 arch/nds32/mm/proc.c             | 26 +++++++++++++++++---------
 9 files changed, 47 insertions(+), 35 deletions(-)

diff --git a/arch/nds32/include/asm/page.h b/arch/nds32/include/asm/page.h
index 8feb1fa..86b3201 100644
--- a/arch/nds32/include/asm/page.h
+++ b/arch/nds32/include/asm/page.h
@@ -41,17 +41,14 @@ void clear_page(void *page);
 void copy_page(void *to, void *from);
 
 typedef unsigned long pte_t;
-typedef unsigned long pmd_t;
 typedef unsigned long pgd_t;
 typedef unsigned long pgprot_t;
 
 #define pte_val(x)      (x)
-#define pmd_val(x)      (x)
 #define pgd_val(x)	(x)
 #define pgprot_val(x)   (x)
 
 #define __pte(x)        (x)
-#define __pmd(x)        (x)
 #define __pgd(x)        (x)
 #define __pgprot(x)     (x)
 
diff --git a/arch/nds32/include/asm/pgalloc.h b/arch/nds32/include/asm/pgalloc.h
index 37125e6..85c1173 100644
--- a/arch/nds32/include/asm/pgalloc.h
+++ b/arch/nds32/include/asm/pgalloc.h
@@ -15,9 +15,6 @@
 /*
  * Since we have only two-level page tables, these are trivial
  */
-#define pmd_alloc_one(mm, addr)		({ BUG(); ((pmd_t *)2); })
-#define pmd_free(mm, pmd)			do { } while (0)
-#define pgd_populate(mm, pmd, pte)	BUG()
 #define pmd_pgtable(pmd) pmd_page(pmd)
 
 extern pgd_t *pgd_alloc(struct mm_struct *mm);
diff --git a/arch/nds32/include/asm/pgtable.h b/arch/nds32/include/asm/pgtable.h
index 0588ec9..a80b9c6 100644
--- a/arch/nds32/include/asm/pgtable.h
+++ b/arch/nds32/include/asm/pgtable.h
@@ -4,8 +4,7 @@
 #ifndef _ASMNDS32_PGTABLE_H
 #define _ASMNDS32_PGTABLE_H
 
-#define __PAGETABLE_PMD_FOLDED 1
-#include <asm-generic/4level-fixup.h>
+#include <asm-generic/pgtable-nopmd.h>
 #include <linux/sizes.h>
 
 #include <asm/memory.h>
@@ -19,26 +18,20 @@
 #ifdef CONFIG_ANDES_PAGE_SIZE_4KB
 #define PGDIR_SHIFT      22
 #define PTRS_PER_PGD     1024
-#define PMD_SHIFT        22
-#define PTRS_PER_PMD     1
 #define PTRS_PER_PTE     1024
 #endif
 
 #ifdef CONFIG_ANDES_PAGE_SIZE_8KB
 #define PGDIR_SHIFT      24
 #define PTRS_PER_PGD     256
-#define PMD_SHIFT        24
-#define PTRS_PER_PMD     1
 #define PTRS_PER_PTE     2048
 #endif
 
 #ifndef __ASSEMBLY__
 extern void __pte_error(const char *file, int line, unsigned long val);
-extern void __pmd_error(const char *file, int line, unsigned long val);
 extern void __pgd_error(const char *file, int line, unsigned long val);
 
 #define pte_ERROR(pte)		__pte_error(__FILE__, __LINE__, pte_val(pte))
-#define pmd_ERROR(pmd)		__pmd_error(__FILE__, __LINE__, pmd_val(pmd))
 #define pgd_ERROR(pgd)		__pgd_error(__FILE__, __LINE__, pgd_val(pgd))
 #endif /* !__ASSEMBLY__ */
 
@@ -366,9 +359,6 @@ static inline pmd_t __mk_pmd(pte_t * ptep, unsigned long prot)
 /* to find an entry in a kernel page-table-directory */
 #define pgd_offset_k(addr)      pgd_offset(&init_mm, addr)
 
-/* Find an entry in the second-level page table.. */
-#define pmd_offset(dir, addr)	((pmd_t *)(dir))
-
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
 	const unsigned long mask = 0xfff;
diff --git a/arch/nds32/include/asm/tlb.h b/arch/nds32/include/asm/tlb.h
index a8aff1c..6726038 100644
--- a/arch/nds32/include/asm/tlb.h
+++ b/arch/nds32/include/asm/tlb.h
@@ -7,6 +7,5 @@
 #include <asm-generic/tlb.h>
 
 #define __pte_free_tlb(tlb, pte, addr)	pte_free((tlb)->mm, pte)
-#define __pmd_free_tlb(tlb, pmd, addr)	pmd_free((tln)->mm, pmd)
 
 #endif
diff --git a/arch/nds32/kernel/pm.c b/arch/nds32/kernel/pm.c
index ffa8040..e25700e 100644
--- a/arch/nds32/kernel/pm.c
+++ b/arch/nds32/kernel/pm.c
@@ -14,6 +14,7 @@ unsigned int *phy_addr_sp_tmp;
 static void nds32_suspend2ram(void)
 {
 	pgd_t *pgdv;
+	p4d_t *p4dv;
 	pud_t *pudv;
 	pmd_t *pmdv;
 	pte_t *ptev;
@@ -21,7 +22,8 @@ static void nds32_suspend2ram(void)
 	pgdv = (pgd_t *)__va((__nds32__mfsr(NDS32_SR_L1_PPTB) &
 		L1_PPTB_mskBASE)) + pgd_index((unsigned int)cpu_resume);
 
-	pudv = pud_offset(pgdv, (unsigned int)cpu_resume);
+	p4dv = p4d_offset(pgdv, (unsigned int)cpu_resume);
+	pudv = pud_offset(p4dv, (unsigned int)cpu_resume);
 	pmdv = pmd_offset(pudv, (unsigned int)cpu_resume);
 	ptev = pte_offset_map(pmdv, (unsigned int)cpu_resume);
 
diff --git a/arch/nds32/mm/fault.c b/arch/nds32/mm/fault.c
index 064ae5d..906dfb2 100644
--- a/arch/nds32/mm/fault.c
+++ b/arch/nds32/mm/fault.c
@@ -31,6 +31,8 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
 	pr_alert("[%08lx] *pgd=%08lx", addr, pgd_val(*pgd));
 
 	do {
+		p4d_t *p4d;
+		pud_t *pud;
 		pmd_t *pmd;
 
 		if (pgd_none(*pgd))
@@ -41,7 +43,9 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
 			break;
 		}
 
-		pmd = pmd_offset(pgd, addr);
+		p4d = p4d_offset(pgd, addr);
+		pud = pud_offset(p4d, addr);
+		pmd = pmd_offset(pud, addr);
 #if PTRS_PER_PMD != 1
 		pr_alert(", *pmd=%08lx", pmd_val(*pmd));
 #endif
@@ -359,6 +363,7 @@ void do_page_fault(unsigned long entry, unsigned long addr,
 
 		unsigned int index = pgd_index(addr);
 		pgd_t *pgd, *pgd_k;
+		p4d_t *p4d, *p4d_k;
 		pud_t *pud, *pud_k;
 		pmd_t *pmd, *pmd_k;
 		pte_t *pte_k;
@@ -369,8 +374,13 @@ void do_page_fault(unsigned long entry, unsigned long addr,
 		if (!pgd_present(*pgd_k))
 			goto no_context;
 
-		pud = pud_offset(pgd, addr);
-		pud_k = pud_offset(pgd_k, addr);
+		p4d = p4d_offset(pgd, addr);
+		p4d_k = p4d_offset(pgd_k, addr);
+		if (!p4d_present(*p4d_k))
+			goto no_context;
+
+		pud = pud_offset(p4d, addr);
+		pud_k = pud_offset(p4d_k, addr);
 		if (!pud_present(*pud_k))
 			goto no_context;
 
diff --git a/arch/nds32/mm/init.c b/arch/nds32/mm/init.c
index 55703b0..0be3833f 100644
--- a/arch/nds32/mm/init.c
+++ b/arch/nds32/mm/init.c
@@ -54,6 +54,7 @@ static void __init map_ram(void)
 {
 	unsigned long v, p, e;
 	pgd_t *pge;
+	p4d_t *p4e;
 	pud_t *pue;
 	pmd_t *pme;
 	pte_t *pte;
@@ -69,7 +70,8 @@ static void __init map_ram(void)
 
 	while (p < e) {
 		int j;
-		pue = pud_offset(pge, v);
+		p4e = p4d_offset(pge, v);
+		pue = pud_offset(p4e, v);
 		pme = pmd_offset(pue, v);
 
 		if ((u32) pue != (u32) pge || (u32) pme != (u32) pge) {
@@ -100,6 +102,7 @@ static void __init fixedrange_init(void)
 {
 	unsigned long vaddr;
 	pgd_t *pgd;
+	p4d_t *p4d;
 	pud_t *pud;
 	pmd_t *pmd;
 #ifdef CONFIG_HIGHMEM
@@ -111,7 +114,8 @@ static void __init fixedrange_init(void)
 	 */
 	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1);
 	pgd = swapper_pg_dir + pgd_index(vaddr);
-	pud = pud_offset(pgd, vaddr);
+	p4d = p4d_offset(pgd, vaddr);
+	pud = pud_offset(p4d, vaddr);
 	pmd = pmd_offset(pud, vaddr);
 	fixmap_pmd_p = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
 	if (!fixmap_pmd_p)
@@ -126,7 +130,8 @@ static void __init fixedrange_init(void)
 	vaddr = PKMAP_BASE;
 
 	pgd = swapper_pg_dir + pgd_index(vaddr);
-	pud = pud_offset(pgd, vaddr);
+	p4d = p4d_offset(pgd, vaddr);
+	pud = pud_offset(p4d, vaddr);
 	pmd = pmd_offset(pud, vaddr);
 	pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
 	if (!pte)
diff --git a/arch/nds32/mm/mm-nds32.c b/arch/nds32/mm/mm-nds32.c
index 3b43798..8503bee 100644
--- a/arch/nds32/mm/mm-nds32.c
+++ b/arch/nds32/mm/mm-nds32.c
@@ -74,6 +74,8 @@ void setup_mm_for_reboot(char mode)
 {
 	unsigned long pmdval;
 	pgd_t *pgd;
+	p4d_t *p4d;
+	pud_t *pud;
 	pmd_t *pmd;
 	int i;
 
@@ -84,7 +86,9 @@ void setup_mm_for_reboot(char mode)
 
 	for (i = 0; i < USER_PTRS_PER_PGD; i++) {
 		pmdval = (i << PGDIR_SHIFT);
-		pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT);
+		p4d = p4d_offset(pgd, i << PGDIR_SHIFT);
+		pud = pud_offset(p4d, i << PGDIR_SHIFT);
+		pmd = pmd_offset(pud + i, i << PGDIR_SHIFT);
 		set_pmd(pmd, __pmd(pmdval));
 	}
 }
diff --git a/arch/nds32/mm/proc.c b/arch/nds32/mm/proc.c
index ba80992..837ae77 100644
--- a/arch/nds32/mm/proc.c
+++ b/arch/nds32/mm/proc.c
@@ -16,10 +16,14 @@ extern struct cache_info L1_cache_info[2];
 
 int va_kernel_present(unsigned long addr)
 {
+	p4d_t *p4d;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *ptep, pte;
 
-	pmd = pmd_offset(pgd_offset_k(addr), addr);
+	p4d = p4d_offset(pgd_offset_k(addr), addr);
+	pud = pud_offset(p4d, addr);
+	pmd = pmd_offset(pud, addr);
 	if (!pmd_none(*pmd)) {
 		ptep = pte_offset_map(pmd, addr);
 		pte = *ptep;
@@ -32,20 +36,24 @@ int va_kernel_present(unsigned long addr)
 pte_t va_present(struct mm_struct * mm, unsigned long addr)
 {
 	pgd_t *pgd;
+	p4d_t *p4d;
 	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *ptep, pte;
 
 	pgd = pgd_offset(mm, addr);
 	if (!pgd_none(*pgd)) {
-		pud = pud_offset(pgd, addr);
-		if (!pud_none(*pud)) {
-			pmd = pmd_offset(pud, addr);
-			if (!pmd_none(*pmd)) {
-				ptep = pte_offset_map(pmd, addr);
-				pte = *ptep;
-				if (pte_present(pte))
-					return pte;
+		p4d = p4d_offset(pgd, addr);
+		if (!p4d_none(*p4d)) {
+			pud = pud_offset(p4d, addr);
+			if (!pud_none(*pud)) {
+				pmd = pmd_offset(pud, addr);
+				if (!pmd_none(*pmd)) {
+					ptep = pte_offset_map(pmd, addr);
+					pte = *ptep;
+					if (pte_present(pte))
+						return pte;
+				}
 			}
 		}
 	}
-- 
2.7.4


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 08/12] parisc: use pgtable-nopXd instead of 4level-fixup
  2019-10-23  9:28 [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK Mike Rapoport
                   ` (6 preceding siblings ...)
  2019-10-23  9:28 ` [PATCH 07/12] nds32: " Mike Rapoport
@ 2019-10-23  9:28 ` " Mike Rapoport
  2019-10-23 10:20   ` Rolf Eike Beer
                     ` (2 more replies)
  2019-10-23  9:28 ` [PATCH 09/12] sparc32: use pgtable-nopud " Mike Rapoport
                   ` (4 subsequent siblings)
  12 siblings, 3 replies; 31+ messages in thread
From: Mike Rapoport @ 2019-10-23  9:28 UTC (permalink / raw)
  To: linux-mm
  Cc: Andrew Morton, Anton Ivanov, Arnd Bergmann, David S. Miller,
	Geert Uytterhoeven, Greentime Hu, Greg Ungerer, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, Mike Rapoport, linux-alpha, linux-arch,
	linux-arm-kernel, linux-c6x-dev, linux-kernel, linux-m68k,
	linux-parisc, linux-um, sparclinux, Mike Rapoport

From: Mike Rapoport <rppt@linux.ibm.com>

parisc 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 parisc with
include/asm-generic/pgtable-nopmd.h for two-level configurations and with
include/asm-generic/pgtable-nopmd.h for three-lelve configurations and
adjust page table manipulation macros and functions accordingly.

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
 arch/parisc/include/asm/page.h    | 30 +++++++++++++---------
 arch/parisc/include/asm/pgalloc.h | 41 +++++++++++-------------------
 arch/parisc/include/asm/pgtable.h | 52 +++++++++++++++++++--------------------
 arch/parisc/include/asm/tlb.h     |  2 ++
 arch/parisc/kernel/cache.c        | 13 ++++++----
 arch/parisc/kernel/pci-dma.c      |  9 +++++--
 arch/parisc/mm/fixmap.c           | 10 +++++---
 7 files changed, 81 insertions(+), 76 deletions(-)

diff --git a/arch/parisc/include/asm/page.h b/arch/parisc/include/asm/page.h
index 93caf17..1d339ee 100644
--- a/arch/parisc/include/asm/page.h
+++ b/arch/parisc/include/asm/page.h
@@ -42,48 +42,54 @@ typedef struct { unsigned long pte; } pte_t; /* either 32 or 64bit */
 
 /* NOTE: even on 64 bits, these entries are __u32 because we allocate
  * the pmd and pgd in ZONE_DMA (i.e. under 4GB) */
-typedef struct { __u32 pmd; } pmd_t;
 typedef struct { __u32 pgd; } pgd_t;
 typedef struct { unsigned long pgprot; } pgprot_t;
 
-#define pte_val(x)	((x).pte)
-/* These do not work lvalues, so make sure we don't use them as such. */
+#if CONFIG_PGTABLE_LEVELS == 3
+typedef struct { __u32 pmd; } pmd_t;
+#define __pmd(x)	((pmd_t) { (x) } )
+/* pXd_val() do not work lvalues, so make sure we don't use them as such. */
 #define pmd_val(x)	((x).pmd + 0)
+#endif
+
+#define pte_val(x)	((x).pte)
 #define pgd_val(x)	((x).pgd + 0)
 #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) } )
 
-#define __pmd_val_set(x,n) (x).pmd = (n)
-#define __pgd_val_set(x,n) (x).pgd = (n)
-
 #else
 /*
  * .. while these make it easier on the compiler
  */
 typedef unsigned long pte_t;
+
+#if CONFIG_PGTABLE_LEVELS == 3
 typedef         __u32 pmd_t;
+#define pmd_val(x)      (x)
+#define __pmd(x)	(x)
+#endif
+
 typedef         __u32 pgd_t;
 typedef unsigned long pgprot_t;
 
 #define pte_val(x)      (x)
-#define pmd_val(x)      (x)
 #define pgd_val(x)      (x)
 #define pgprot_val(x)   (x)
 
 #define __pte(x)        (x)
-#define __pmd(x)	(x)
 #define __pgd(x)        (x)
 #define __pgprot(x)     (x)
 
-#define __pmd_val_set(x,n) (x) = (n)
-#define __pgd_val_set(x,n) (x) = (n)
-
 #endif /* STRICT_MM_TYPECHECKS */
 
+#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
+#if CONFIG_PGTABLE_LEVELS == 3
+#define set_pud(pudptr, pudval) (*(pudptr) = (pudval))
+#endif
+
 typedef struct page *pgtable_t;
 
 typedef struct __physmem_range {
diff --git a/arch/parisc/include/asm/pgalloc.h b/arch/parisc/include/asm/pgalloc.h
index d98647c..9ac74da 100644
--- a/arch/parisc/include/asm/pgalloc.h
+++ b/arch/parisc/include/asm/pgalloc.h
@@ -34,13 +34,13 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 		/* Populate first pmd with allocated memory.  We mark it
 		 * with PxD_FLAG_ATTACHED as a signal to the system that this
 		 * pmd entry may not be cleared. */
-		__pgd_val_set(*actual_pgd, (PxD_FLAG_PRESENT | 
-				        PxD_FLAG_VALID | 
-					PxD_FLAG_ATTACHED) 
-			+ (__u32)(__pa((unsigned long)pgd) >> PxD_VALUE_SHIFT));
+		set_pgd(actual_pgd, __pgd((PxD_FLAG_PRESENT |
+				        PxD_FLAG_VALID |
+					PxD_FLAG_ATTACHED)
+			+ (__u32)(__pa((unsigned long)pgd) >> PxD_VALUE_SHIFT)));
 		/* The first pmd entry also is marked with PxD_FLAG_ATTACHED as
 		 * a signal that this pmd may not be freed */
-		__pgd_val_set(*pgd, PxD_FLAG_ATTACHED);
+		set_pgd(pgd, __pgd(PxD_FLAG_ATTACHED));
 #endif
 	}
 	spin_lock_init(pgd_spinlock(actual_pgd));
@@ -59,10 +59,10 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 
 /* Three Level Page Table Support for pmd's */
 
-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_val_set(*pgd, (PxD_FLAG_PRESENT | PxD_FLAG_VALID) +
-		        (__u32)(__pa((unsigned long)pmd) >> PxD_VALUE_SHIFT));
+	set_pud(pud, __pud((PxD_FLAG_PRESENT | PxD_FLAG_VALID) +
+			(__u32)(__pa((unsigned long)pmd) >> PxD_VALUE_SHIFT)));
 }
 
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
@@ -88,19 +88,6 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
 	free_pages((unsigned long)pmd, PMD_ORDER);
 }
 
-#else
-
-/* Two Level Page Table Support for pmd's */
-
-/*
- * allocating and freeing a pmd is trivial: the 1-entry pmd is
- * inside the pgd, so has no extra memory associated with it.
- */
-
-#define pmd_alloc_one(mm, addr)		({ BUG(); ((pmd_t *)2); })
-#define pmd_free(mm, x)			do { } while (0)
-#define pgd_populate(mm, pmd, pte)	BUG()
-
 #endif
 
 static inline void
@@ -110,14 +97,14 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
 	/* preserve the gateway marker if this is the beginning of
 	 * the permanent pmd */
 	if(pmd_flag(*pmd) & PxD_FLAG_ATTACHED)
-		__pmd_val_set(*pmd, (PxD_FLAG_PRESENT |
-				 PxD_FLAG_VALID |
-				 PxD_FLAG_ATTACHED) 
-			+ (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT));
+		set_pmd(pmd, __pmd((PxD_FLAG_PRESENT |
+				PxD_FLAG_VALID |
+				PxD_FLAG_ATTACHED)
+			+ (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT)));
 	else
 #endif
-		__pmd_val_set(*pmd, (PxD_FLAG_PRESENT | PxD_FLAG_VALID) 
-			+ (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT));
+		set_pmd(pmd, __pmd((PxD_FLAG_PRESENT | PxD_FLAG_VALID)
+			+ (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT)));
 }
 
 #define pmd_populate(mm, pmd, pte_page) \
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
index 4ac374b..f0a3659 100644
--- a/arch/parisc/include/asm/pgtable.h
+++ b/arch/parisc/include/asm/pgtable.h
@@ -3,7 +3,12 @@
 #define _PARISC_PGTABLE_H
 
 #include <asm/page.h>
-#include <asm-generic/4level-fixup.h>
+
+#if CONFIG_PGTABLE_LEVELS == 3
+#include <asm-generic/pgtable-nopud.h>
+#elif CONFIG_PGTABLE_LEVELS == 2
+#include <asm-generic/pgtable-nopmd.h>
+#endif
 
 #include <asm/fixmap.h>
 
@@ -101,8 +106,10 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
 
 #define pte_ERROR(e) \
 	printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+#if CONFIG_PGTABLE_LEVELS == 3
 #define pmd_ERROR(e) \
 	printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, (unsigned long)pmd_val(e))
+#endif
 #define pgd_ERROR(e) \
 	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e))
 
@@ -132,19 +139,18 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
 #define PTRS_PER_PTE    (1UL << BITS_PER_PTE)
 
 /* Definitions for 2nd level */
+#if CONFIG_PGTABLE_LEVELS == 3
 #define PMD_SHIFT       (PLD_SHIFT + BITS_PER_PTE)
 #define PMD_SIZE	(1UL << PMD_SHIFT)
 #define PMD_MASK	(~(PMD_SIZE-1))
-#if CONFIG_PGTABLE_LEVELS == 3
 #define BITS_PER_PMD	(PAGE_SHIFT + PMD_ORDER - BITS_PER_PMD_ENTRY)
+#define PTRS_PER_PMD    (1UL << BITS_PER_PMD)
 #else
-#define __PAGETABLE_PMD_FOLDED 1
 #define BITS_PER_PMD	0
 #endif
-#define PTRS_PER_PMD    (1UL << BITS_PER_PMD)
 
 /* Definitions for 1st level */
-#define PGDIR_SHIFT	(PMD_SHIFT + BITS_PER_PMD)
+#define PGDIR_SHIFT	(PLD_SHIFT + BITS_PER_PTE + BITS_PER_PMD)
 #if (PGDIR_SHIFT + PAGE_SHIFT + PGD_ORDER - BITS_PER_PGD_ENTRY) > BITS_PER_LONG
 #define BITS_PER_PGD	(BITS_PER_LONG - PGDIR_SHIFT)
 #else
@@ -317,6 +323,8 @@ extern unsigned long *empty_zero_page;
 
 #define pmd_flag(x)	(pmd_val(x) & PxD_FLAG_MASK)
 #define pmd_address(x)	((unsigned long)(pmd_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT)
+#define pud_flag(x)	(pud_val(x) & PxD_FLAG_MASK)
+#define pud_address(x)	((unsigned long)(pud_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT)
 #define pgd_flag(x)	(pgd_val(x) & PxD_FLAG_MASK)
 #define pgd_address(x)	((unsigned long)(pgd_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT)
 
@@ -334,42 +342,32 @@ static inline void pmd_clear(pmd_t *pmd) {
 	if (pmd_flag(*pmd) & PxD_FLAG_ATTACHED)
 		/* This is the entry pointing to the permanent pmd
 		 * attached to the pgd; cannot clear it */
-		__pmd_val_set(*pmd, PxD_FLAG_ATTACHED);
+		set_pmd(pmd, __pmd(PxD_FLAG_ATTACHED));
 	else
 #endif
-		__pmd_val_set(*pmd,  0);
+		set_pmd(pmd,  __pmd(0));
 }
 
 
 
 #if CONFIG_PGTABLE_LEVELS == 3
-#define pgd_page_vaddr(pgd) ((unsigned long) __va(pgd_address(pgd)))
-#define pgd_page(pgd)	virt_to_page((void *)pgd_page_vaddr(pgd))
+#define pud_page_vaddr(pud) ((unsigned long) __va(pud_address(pud)))
+#define pud_page(pud)	virt_to_page((void *)pud_page_vaddr(pud))
 
 /* For 64 bit we have three level tables */
 
-#define pgd_none(x)     (!pgd_val(x))
-#define pgd_bad(x)      (!(pgd_flag(x) & PxD_FLAG_VALID))
-#define pgd_present(x)  (pgd_flag(x) & PxD_FLAG_PRESENT)
-static inline void pgd_clear(pgd_t *pgd) {
+#define pud_none(x)     (!pud_val(x))
+#define pud_bad(x)      (!(pud_flag(x) & PxD_FLAG_VALID))
+#define pud_present(x)  (pud_flag(x) & PxD_FLAG_PRESENT)
+static inline void pud_clear(pud_t *pud) {
 #if CONFIG_PGTABLE_LEVELS == 3
-	if(pgd_flag(*pgd) & PxD_FLAG_ATTACHED)
-		/* This is the permanent pmd attached to the pgd; cannot
+	if(pud_flag(*pud) & PxD_FLAG_ATTACHED)
+		/* This is the permanent pmd attached to the pud; cannot
 		 * free it */
 		return;
 #endif
-	__pgd_val_set(*pgd, 0);
+	set_pud(pud, __pud(0));
 }
-#else
-/*
- * The "pgd_xxx()" functions here are trivial for a folded two-level
- * setup: the pgd is never bad, and a pmd always exists (as it's folded
- * into the pgd entry)
- */
-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)	{ }
 #endif
 
 /*
@@ -452,7 +450,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 #if CONFIG_PGTABLE_LEVELS == 3
 #define pmd_index(addr)         (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
 #define pmd_offset(dir,address) \
-((pmd_t *) pgd_page_vaddr(*(dir)) + pmd_index(address))
+((pmd_t *) pud_page_vaddr(*(dir)) + pmd_index(address))
 #else
 #define pmd_offset(dir,addr) ((pmd_t *) dir)
 #endif
diff --git a/arch/parisc/include/asm/tlb.h b/arch/parisc/include/asm/tlb.h
index 8c0446b..44235f3 100644
--- a/arch/parisc/include/asm/tlb.h
+++ b/arch/parisc/include/asm/tlb.h
@@ -4,7 +4,9 @@
 
 #include <asm-generic/tlb.h>
 
+#if CONFIG_PGTABLE_LEVELS == 3
 #define __pmd_free_tlb(tlb, pmd, addr)	pmd_free((tlb)->mm, pmd)
+#endif
 #define __pte_free_tlb(tlb, pte, addr)	pte_free((tlb)->mm, pte)
 
 #endif
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index a82b3ea..7b2e0ab 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -534,11 +534,14 @@ static inline pte_t *get_ptep(pgd_t *pgd, unsigned long addr)
 	pte_t *ptep = NULL;
 
 	if (!pgd_none(*pgd)) {
-		pud_t *pud = pud_offset(pgd, addr);
-		if (!pud_none(*pud)) {
-			pmd_t *pmd = pmd_offset(pud, addr);
-			if (!pmd_none(*pmd))
-				ptep = pte_offset_map(pmd, addr);
+		p4d_t *p4d = p4d_offset(pgd, addr);
+		if (!p4d_none(*p4d)) {
+			pud_t *pud = pud_offset(p4d, addr);
+			if (!pud_none(*pud)) {
+				pmd_t *pmd = pmd_offset(pud, addr);
+				if (!pmd_none(*pmd))
+					ptep = pte_offset_map(pmd, addr);
+			}
 		}
 	}
 	return ptep;
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
index ca35d9a..8859c71 100644
--- a/arch/parisc/kernel/pci-dma.c
+++ b/arch/parisc/kernel/pci-dma.c
@@ -133,9 +133,14 @@ static inline int map_uncached_pages(unsigned long vaddr, unsigned long size,
 
 	dir = pgd_offset_k(vaddr);
 	do {
+		p4d_t *p4d;
+		pud_t *pud;
 		pmd_t *pmd;
-		
-		pmd = pmd_alloc(NULL, dir, vaddr);
+
+		p4d = p4d_offset(dir, vaddr);
+		pud = pud_offset(p4d, vaddr);
+		pmd = pmd_alloc(NULL, pud, vaddr);
+
 		if (!pmd)
 			return -ENOMEM;
 		if (map_pmd_uncached(pmd, vaddr, end - vaddr, &paddr))
diff --git a/arch/parisc/mm/fixmap.c b/arch/parisc/mm/fixmap.c
index 474cd24..e2d8b0a 100644
--- a/arch/parisc/mm/fixmap.c
+++ b/arch/parisc/mm/fixmap.c
@@ -14,11 +14,13 @@ void notrace set_fixmap(enum fixed_addresses idx, phys_addr_t phys)
 {
 	unsigned long vaddr = __fix_to_virt(idx);
 	pgd_t *pgd = pgd_offset_k(vaddr);
-	pmd_t *pmd = pmd_offset(pgd, vaddr);
+	p4d_t *p4d = p4d_offset(pgd, vaddr);
+	pud_t *pud = pud_offset(p4d, vaddr);
+	pmd_t *pmd = pmd_offset(pud, vaddr);
 	pte_t *pte;
 
 	if (pmd_none(*pmd))
-		pmd = pmd_alloc(NULL, pgd, vaddr);
+		pmd = pmd_alloc(NULL, pud, vaddr);
 
 	pte = pte_offset_kernel(pmd, vaddr);
 	if (pte_none(*pte))
@@ -32,7 +34,9 @@ void notrace clear_fixmap(enum fixed_addresses idx)
 {
 	unsigned long vaddr = __fix_to_virt(idx);
 	pgd_t *pgd = pgd_offset_k(vaddr);
-	pmd_t *pmd = pmd_offset(pgd, vaddr);
+	p4d_t *p4d = p4d_offset(pgd, vaddr);
+	pud_t *pud = pud_offset(p4d, vaddr);
+	pmd_t *pmd = pmd_offset(pud, vaddr);
 	pte_t *pte = pte_offset_kernel(pmd, vaddr);
 
 	if (WARN_ON(pte_none(*pte)))
-- 
2.7.4


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 09/12] sparc32: use pgtable-nopud instead of 4level-fixup
  2019-10-23  9:28 [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK Mike Rapoport
                   ` (7 preceding siblings ...)
  2019-10-23  9:28 ` [PATCH 08/12] parisc: use pgtable-nopXd " Mike Rapoport
@ 2019-10-23  9:28 ` " Mike Rapoport
  2019-10-23 19:59   ` [PATCH v2 " Mike Rapoport
  2019-10-23  9:28 ` [PATCH 10/12] um: remove unused pxx_offset_proc() and addr_pte() functions Mike Rapoport
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 31+ messages in thread
From: Mike Rapoport @ 2019-10-23  9:28 UTC (permalink / raw)
  To: linux-mm
  Cc: Andrew Morton, Anton Ivanov, Arnd Bergmann, David S. Miller,
	Geert Uytterhoeven, Greentime Hu, Greg Ungerer, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, Mike Rapoport, linux-alpha, linux-arch,
	linux-arm-kernel, linux-c6x-dev, linux-kernel, linux-m68k,
	linux-parisc, linux-um, sparclinux, Mike Rapoport

From: Mike Rapoport <rppt@linux.ibm.com>

32-bit version of sparc has three-level page tables and can use
pgtable-nopud and folding of the upper layers.

Replace usage of include/asm-generic/4level-fixup.h with
include/asm-generic/pgtable-nopud.h and adjust page table manipulation
macros and functions accordingly.

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
 arch/sparc/include/asm/pgalloc_32.h |  6 ++---
 arch/sparc/include/asm/pgtable_32.h | 28 ++++++++++----------
 arch/sparc/mm/fault_32.c            | 11 ++++++--
 arch/sparc/mm/highmem.c             |  6 ++++-
 arch/sparc/mm/io-unit.c             |  6 ++++-
 arch/sparc/mm/iommu.c               |  6 ++++-
 arch/sparc/mm/srmmu.c               | 51 +++++++++++++++++++++++++++++--------
 7 files changed, 81 insertions(+), 33 deletions(-)

diff --git a/arch/sparc/include/asm/pgalloc_32.h b/arch/sparc/include/asm/pgalloc_32.h
index 10538a4..eae0c92 100644
--- a/arch/sparc/include/asm/pgalloc_32.h
+++ b/arch/sparc/include/asm/pgalloc_32.h
@@ -26,14 +26,14 @@ static inline void free_pgd_fast(pgd_t *pgd)
 #define pgd_free(mm, pgd)	free_pgd_fast(pgd)
 #define pgd_alloc(mm)	get_pgd_fast()
 
-static inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
+static inline void pud_set(pud_t * pudp, pmd_t * pmdp)
 {
 	unsigned long pa = __nocache_pa(pmdp);
 
-	set_pte((pte_t *)pgdp, __pte((SRMMU_ET_PTD | (pa >> 4))));
+	set_pte((pte_t *)pudp, __pte((SRMMU_ET_PTD | (pa >> 4))));
 }
 
-#define pgd_populate(MM, PGD, PMD)      pgd_set(PGD, PMD)
+#define pud_populate(MM, PGD, PMD)      pud_set(PGD, PMD)
 
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm,
 				   unsigned long address)
diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index 31da448..6d6f44c 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -12,7 +12,7 @@
 #include <linux/const.h>
 
 #ifndef __ASSEMBLY__
-#include <asm-generic/4level-fixup.h>
+#include <asm-generic/pgtable-nopud.h>
 
 #include <linux/spinlock.h>
 #include <linux/mm_types.h>
@@ -132,12 +132,12 @@ static inline struct page *pmd_page(pmd_t pmd)
 	return pfn_to_page((pmd_val(pmd) & SRMMU_PTD_PMASK) >> (PAGE_SHIFT-4));
 }
 
-static inline unsigned long pgd_page_vaddr(pgd_t pgd)
+static inline unsigned long pud_page_vaddr(pud_t pud)
 {
-	if (srmmu_device_memory(pgd_val(pgd))) {
+	if (srmmu_device_memory(pud_val(pud))) {
 		return ~0;
 	} else {
-		unsigned long v = pgd_val(pgd) & SRMMU_PTD_PMASK;
+		unsigned long v = pud_val(pud) & SRMMU_PTD_PMASK;
 		return (unsigned long)__nocache_va(v << 4);
 	}
 }
@@ -184,24 +184,24 @@ static inline void pmd_clear(pmd_t *pmdp)
 		set_pte((pte_t *)&pmdp->pmdv[i], __pte(0));
 }
 
-static inline int pgd_none(pgd_t pgd)          
+static inline int pud_none(pud_t pud)
 {
-	return !(pgd_val(pgd) & 0xFFFFFFF);
+	return !(pud_val(pud) & 0xFFFFFFF);
 }
 
-static inline int pgd_bad(pgd_t pgd)
+static inline int pud_bad(pud_t pud)
 {
-	return (pgd_val(pgd) & SRMMU_ET_MASK) != SRMMU_ET_PTD;
+	return (pud_val(pud) & SRMMU_ET_MASK) != SRMMU_ET_PTD;
 }
 
-static inline int pgd_present(pgd_t pgd)
+static inline int pud_present(pud_t pud)
 {
-	return ((pgd_val(pgd) & SRMMU_ET_MASK) == SRMMU_ET_PTD);
+	return ((pud_val(pud) & SRMMU_ET_MASK) == SRMMU_ET_PTD);
 }
 
-static inline void pgd_clear(pgd_t *pgdp)
+static inline void pud_clear(pud_t *pudp)
 {
-	set_pte((pte_t *)pgdp, __pte(0));
+	set_pte((pte_t *)pudp, __pte(0));
 }
 
 /*
@@ -319,9 +319,9 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 #define pgd_offset_k(address) pgd_offset(&init_mm, 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_vaddr(*dir) +
+	return (pmd_t *) pud_page_vaddr(*dir) +
 		((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
 }
 
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
index 8d69de1..89976c9 100644
--- a/arch/sparc/mm/fault_32.c
+++ b/arch/sparc/mm/fault_32.c
@@ -351,6 +351,8 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
 		 */
 		int offset = pgd_index(address);
 		pgd_t *pgd, *pgd_k;
+		p4d_t *p4d, *p4d_k;
+		pud_t *pud, *pud_k;
 		pmd_t *pmd, *pmd_k;
 
 		pgd = tsk->active_mm->pgd + offset;
@@ -363,8 +365,13 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
 			return;
 		}
 
-		pmd = pmd_offset(pgd, address);
-		pmd_k = pmd_offset(pgd_k, address);
+		p4d = p4d_offset(pgd, address);
+		pud = pud_offset(p4d, address);
+		pmd = pmd_offset(pud, address);
+
+		p4d_k = p4d_offset(pgd_k, address);
+		pud_k = pud_offset(p4d_k, address);
+		pmd_k = pmd_offset(pud_k, address);
 
 		if (pmd_present(*pmd) || !pmd_present(*pmd_k))
 			goto bad_area_nosemaphore;
diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c
index 86bc2a5..d4a80ad 100644
--- a/arch/sparc/mm/highmem.c
+++ b/arch/sparc/mm/highmem.c
@@ -39,10 +39,14 @@ static pte_t *kmap_pte;
 void __init kmap_init(void)
 {
 	unsigned long address;
+	p4d_t *p4d;
+	pud_t *pud;
 	pmd_t *dir;
 
 	address = __fix_to_virt(FIX_KMAP_BEGIN);
-	dir = pmd_offset(pgd_offset_k(address), address);
+	p4d = p4d_offset(pgd_offset_k(address), address);
+	pud = pud_offset(p4d, address);
+	dir = pmd_offset(pud, address);
 
         /* cache the first kmap pte */
         kmap_pte = pte_offset_kernel(dir, address);
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index f770ee7..33a0fac 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -239,12 +239,16 @@ static void *iounit_alloc(struct device *dev, size_t len,
 		page = va;
 		{
 			pgd_t *pgdp;
+			p4d_t *p4dp;
+			pud_t *pudp;
 			pmd_t *pmdp;
 			pte_t *ptep;
 			long i;
 
 			pgdp = pgd_offset(&init_mm, addr);
-			pmdp = pmd_offset(pgdp, addr);
+			p4dp = p4d_offset(pgdp, addr);
+			pudp = pud_offset(p4dp, addr);
+			pmdp = pmd_offset(pudp, addr);
 			ptep = pte_offset_map(pmdp, addr);
 
 			set_pte(ptep, mk_pte(virt_to_page(page), dvma_prot));
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 71ac353..4d3c699 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -343,6 +343,8 @@ static void *sbus_iommu_alloc(struct device *dev, size_t len,
 		page = va;
 		{
 			pgd_t *pgdp;
+			p4d_t *p4dp;
+			pud_t *pudp;
 			pmd_t *pmdp;
 			pte_t *ptep;
 
@@ -354,7 +356,9 @@ static void *sbus_iommu_alloc(struct device *dev, size_t len,
 				__flush_page_to_ram(page);
 
 			pgdp = pgd_offset(&init_mm, addr);
-			pmdp = pmd_offset(pgdp, addr);
+			p4dp = p4d_offset(pgdp, addr);
+			pudp = pud_offset(p4dp, addr);
+			pmdp = pmd_offset(pudp, addr);
 			ptep = pte_offset_map(pmdp, addr);
 
 			set_pte(ptep, mk_pte(virt_to_page(page), dvma_prot));
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index cc3ad64..eb95407 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -296,6 +296,8 @@ static void __init srmmu_nocache_init(void)
 	void *srmmu_nocache_bitmap;
 	unsigned int bitmap_bits;
 	pgd_t *pgd;
+	p4d_t *p4d;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 	unsigned long paddr, vaddr;
@@ -329,6 +331,8 @@ static void __init srmmu_nocache_init(void)
 
 	while (vaddr < srmmu_nocache_end) {
 		pgd = pgd_offset_k(vaddr);
+		p4d = p4d_offset(__nocache_fix(pgd), vaddr);
+		pud = pud_offset(__nocache_fix(p4d), vaddr);
 		pmd = pmd_offset(__nocache_fix(pgd), vaddr);
 		pte = pte_offset_kernel(__nocache_fix(pmd), vaddr);
 
@@ -516,13 +520,17 @@ static inline void srmmu_mapioaddr(unsigned long physaddr,
 				   unsigned long virt_addr, int bus_type)
 {
 	pgd_t *pgdp;
+	p4d_t *p4dp;
+	pud_t *pudp;
 	pmd_t *pmdp;
 	pte_t *ptep;
 	unsigned long tmp;
 
 	physaddr &= PAGE_MASK;
 	pgdp = pgd_offset_k(virt_addr);
-	pmdp = pmd_offset(pgdp, virt_addr);
+	p4dp = p4d_offset(pgdp, virt_addr);
+	pudp = pud_offset(p4dp, virt_addr);
+	pmdp = pmd_offset(pudp, virt_addr);
 	ptep = pte_offset_kernel(pmdp, virt_addr);
 	tmp = (physaddr >> 4) | SRMMU_ET_PTE;
 
@@ -551,11 +559,16 @@ void srmmu_mapiorange(unsigned int bus, unsigned long xpa,
 static inline void srmmu_unmapioaddr(unsigned long virt_addr)
 {
 	pgd_t *pgdp;
+	p4d_t *p4dp;
+	pud_t *pudp;
 	pmd_t *pmdp;
 	pte_t *ptep;
 
+
 	pgdp = pgd_offset_k(virt_addr);
-	pmdp = pmd_offset(pgdp, virt_addr);
+	p4dp = p4d_offset(pgdp, virt_addr);
+	pudp = pud_offset(p4dp, virt_addr);
+	pmdp = pmd_offset(pudp, virt_addr);
 	ptep = pte_offset_kernel(pmdp, virt_addr);
 
 	/* No need to flush uncacheable page. */
@@ -693,20 +706,24 @@ static void __init srmmu_early_allocate_ptable_skeleton(unsigned long start,
 							unsigned long end)
 {
 	pgd_t *pgdp;
+	p4d_t *p4dp;
+	pud_t *pudp;
 	pmd_t *pmdp;
 	pte_t *ptep;
 
 	while (start < end) {
 		pgdp = pgd_offset_k(start);
-		if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
+		p4dp = p4d_offset(__nocache_fix(pgdp), start);
+		pudp = pud_offset(__nocache_fix(p4dp), start);
+		if (pud_none(*(pud_t *)__nocache_fix(pudp))) {
 			pmdp = __srmmu_get_nocache(
 			    SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
 			if (pmdp == NULL)
 				early_pgtable_allocfail("pmd");
 			memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE);
-			pgd_set(__nocache_fix(pgdp), pmdp);
+			pud_set(__nocache_fix(pudp), pmdp);
 		}
-		pmdp = pmd_offset(__nocache_fix(pgdp), start);
+		pmdp = pmd_offset(__nocache_fix(pudp), start);
 		if (srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
 			ptep = __srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
 			if (ptep == NULL)
@@ -724,19 +741,23 @@ static void __init srmmu_allocate_ptable_skeleton(unsigned long start,
 						  unsigned long end)
 {
 	pgd_t *pgdp;
+	p4d_t *p4dp;
+	pud_t *pudp;
 	pmd_t *pmdp;
 	pte_t *ptep;
 
 	while (start < end) {
 		pgdp = pgd_offset_k(start);
-		if (pgd_none(*pgdp)) {
+		p4dp = p4d_offset(pgdp, start);
+		pudp = pud_offset(p4dp, start);
+		if (pud_none(*pudp)) {
 			pmdp = __srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
 			if (pmdp == NULL)
 				early_pgtable_allocfail("pmd");
 			memset(pmdp, 0, SRMMU_PMD_TABLE_SIZE);
-			pgd_set(pgdp, pmdp);
+			pud_set((pud_t *)pgdp, pmdp);
 		}
-		pmdp = pmd_offset(pgdp, start);
+		pmdp = pmd_offset(pudp, start);
 		if (srmmu_pmd_none(*pmdp)) {
 			ptep = __srmmu_get_nocache(PTE_SIZE,
 							     PTE_SIZE);
@@ -779,6 +800,8 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start,
 	unsigned long probed;
 	unsigned long addr;
 	pgd_t *pgdp;
+	p4d_t *p4dp;
+	pud_t *pudp;
 	pmd_t *pmdp;
 	pte_t *ptep;
 	int what; /* 0 = normal-pte, 1 = pmd-level pte, 2 = pgd-level pte */
@@ -810,18 +833,20 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start,
 		}
 
 		pgdp = pgd_offset_k(start);
+		p4dp = p4d_offset(__nocache_fix(pgdp), start);
+		pudp = pud_offset(__nocache_fix(p4dp), start);
 		if (what == 2) {
 			*(pgd_t *)__nocache_fix(pgdp) = __pgd(probed);
 			start += SRMMU_PGDIR_SIZE;
 			continue;
 		}
-		if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
+		if (pud_none(*(pud_t *)__nocache_fix(pudp))) {
 			pmdp = __srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE,
 						   SRMMU_PMD_TABLE_SIZE);
 			if (pmdp == NULL)
 				early_pgtable_allocfail("pmd");
 			memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE);
-			pgd_set(__nocache_fix(pgdp), pmdp);
+			pud_set(__nocache_fix(pudp), pmdp);
 		}
 		pmdp = pmd_offset(__nocache_fix(pgdp), start);
 		if (srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
@@ -906,6 +931,8 @@ void __init srmmu_paging_init(void)
 	phandle cpunode;
 	char node_str[128];
 	pgd_t *pgd;
+	p4d_t *p4d;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 	unsigned long pages_avail;
@@ -967,7 +994,9 @@ void __init srmmu_paging_init(void)
 	srmmu_allocate_ptable_skeleton(PKMAP_BASE, PKMAP_END);
 
 	pgd = pgd_offset_k(PKMAP_BASE);
-	pmd = pmd_offset(pgd, PKMAP_BASE);
+	p4d = p4d_offset(pgd, PKMAP_BASE);
+	pud = pud_offset(p4d, PKMAP_BASE);
+	pmd = pmd_offset(pud, PKMAP_BASE);
 	pte = pte_offset_kernel(pmd, PKMAP_BASE);
 	pkmap_page_table = pte;
 
-- 
2.7.4


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 10/12] um: remove unused pxx_offset_proc() and addr_pte() functions
  2019-10-23  9:28 [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK Mike Rapoport
                   ` (8 preceding siblings ...)
  2019-10-23  9:28 ` [PATCH 09/12] sparc32: use pgtable-nopud " Mike Rapoport
@ 2019-10-23  9:28 ` Mike Rapoport
  2019-10-23  9:29 ` [PATCH 11/12] um: add support for folded p4d page tables Mike Rapoport
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 31+ messages in thread
From: Mike Rapoport @ 2019-10-23  9:28 UTC (permalink / raw)
  To: linux-mm
  Cc: Andrew Morton, Anton Ivanov, Arnd Bergmann, David S. Miller,
	Geert Uytterhoeven, Greentime Hu, Greg Ungerer, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, Mike Rapoport, linux-alpha, linux-arch,
	linux-arm-kernel, linux-c6x-dev, linux-kernel, linux-m68k,
	linux-parisc, linux-um, sparclinux, Mike Rapoport

From: Mike Rapoport <rppt@linux.ibm.com>

The pxx_offset_proc() and addr_pte() functions are never used.
Remove them.

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
 arch/um/kernel/tlb.c | 29 -----------------------------
 1 file changed, 29 deletions(-)

diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index b7eaf65..8425a22 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -490,35 +490,6 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
 	force_sig(SIGKILL);
 }
 
-pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
-{
-	return pgd_offset(mm, address);
-}
-
-pud_t *pud_offset_proc(pgd_t *pgd, unsigned long address)
-{
-	return pud_offset(pgd, address);
-}
-
-pmd_t *pmd_offset_proc(pud_t *pud, unsigned long address)
-{
-	return pmd_offset(pud, address);
-}
-
-pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
-{
-	return pte_offset_kernel(pmd, address);
-}
-
-pte_t *addr_pte(struct task_struct *task, unsigned long addr)
-{
-	pgd_t *pgd = pgd_offset(task->mm, addr);
-	pud_t *pud = pud_offset(pgd, addr);
-	pmd_t *pmd = pmd_offset(pud, addr);
-
-	return pte_offset_map(pmd, addr);
-}
-
 void flush_tlb_all(void)
 {
 	/*
-- 
2.7.4


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 11/12] um: add support for folded p4d page tables
  2019-10-23  9:28 [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK Mike Rapoport
                   ` (9 preceding siblings ...)
  2019-10-23  9:28 ` [PATCH 10/12] um: remove unused pxx_offset_proc() and addr_pte() functions Mike Rapoport
@ 2019-10-23  9:29 ` Mike Rapoport
  2019-10-23  9:29 ` [PATCH 12/12] mm: remove __ARCH_HAS_4LEVEL_HACK and include/asm-generic/4level-fixup.h Mike Rapoport
  2019-10-23 10:25 ` [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK Linus Torvalds
  12 siblings, 0 replies; 31+ messages in thread
From: Mike Rapoport @ 2019-10-23  9:29 UTC (permalink / raw)
  To: linux-mm
  Cc: Andrew Morton, Anton Ivanov, Arnd Bergmann, David S. Miller,
	Geert Uytterhoeven, Greentime Hu, Greg Ungerer, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, Mike Rapoport, linux-alpha, linux-arch,
	linux-arm-kernel, linux-c6x-dev, linux-kernel, linux-m68k,
	linux-parisc, linux-um, sparclinux, Mike Rapoport

From: Mike Rapoport <rppt@linux.ibm.com>

The UML port uses 4 and 5 level fixups to support higher level page table
directories in the generic VM code.

Implement primitives necessary for the 4th level folding and add walks of
p4d level where appropriate.

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
 arch/um/include/asm/pgtable-2level.h |  1 -
 arch/um/include/asm/pgtable-3level.h |  1 -
 arch/um/include/asm/pgtable.h        |  3 ++
 arch/um/kernel/mem.c                 | 25 ++++++++++++++--
 arch/um/kernel/skas/mmu.c            | 12 ++++++--
 arch/um/kernel/skas/uaccess.c        |  7 ++++-
 arch/um/kernel/tlb.c                 | 56 ++++++++++++++++++++++++++++++++----
 arch/um/kernel/trap.c                |  4 ++-
 8 files changed, 95 insertions(+), 14 deletions(-)

diff --git a/arch/um/include/asm/pgtable-2level.h b/arch/um/include/asm/pgtable-2level.h
index 32b3d26..32106d3 100644
--- a/arch/um/include/asm/pgtable-2level.h
+++ b/arch/um/include/asm/pgtable-2level.h
@@ -8,7 +8,6 @@
 #ifndef __UM_PGTABLE_2LEVEL_H
 #define __UM_PGTABLE_2LEVEL_H
 
-#define __ARCH_USE_5LEVEL_HACK
 #include <asm-generic/pgtable-nopmd.h>
 
 /* PGDIR_SHIFT determines what a third-level page table entry can map */
diff --git a/arch/um/include/asm/pgtable-3level.h b/arch/um/include/asm/pgtable-3level.h
index 9812269..8a3b689 100644
--- a/arch/um/include/asm/pgtable-3level.h
+++ b/arch/um/include/asm/pgtable-3level.h
@@ -7,7 +7,6 @@
 #ifndef __UM_PGTABLE_3LEVEL_H
 #define __UM_PGTABLE_3LEVEL_H
 
-#define __ARCH_USE_5LEVEL_HACK
 #include <asm-generic/pgtable-nopud.h>
 
 /* PGDIR_SHIFT determines what a third-level page table entry can map */
diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h
index 36a44d5..2daa58d 100644
--- a/arch/um/include/asm/pgtable.h
+++ b/arch/um/include/asm/pgtable.h
@@ -106,6 +106,9 @@ extern unsigned long end_iomem;
 #define pud_newpage(x)  (pud_val(x) & _PAGE_NEWPAGE)
 #define pud_mkuptodate(x) (pud_val(x) &= ~_PAGE_NEWPAGE)
 
+#define p4d_newpage(x)  (p4d_val(x) & _PAGE_NEWPAGE)
+#define p4d_mkuptodate(x) (p4d_val(x) &= ~_PAGE_NEWPAGE)
+
 #define pmd_page(pmd) phys_to_page(pmd_val(pmd) & PAGE_MASK)
 
 #define pte_page(x) pfn_to_page(pte_pfn(x))
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 417ff64..6fd17bc 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -92,10 +92,26 @@ static void __init one_md_table_init(pud_t *pud)
 #endif
 }
 
+static void __init one_pud_table_init(p4d_t *p4d)
+{
+#if CONFIG_PGTABLE_LEVELS > 3
+	pud_t *pud_table = (pud_t *) memblock_alloc_low(PAGE_SIZE, PAGE_SIZE);
+
+	if (!pud_table)
+		panic("%s: Failed to allocate %lu bytes align=%lx\n",
+		      __func__, PAGE_SIZE, PAGE_SIZE);
+
+	set_p4d(p4d, __p4d(_KERNPG_TABLE + (unsigned long) __pa(pud_table)));
+	if (pud_table != pud_offset(p4d, 0))
+		BUG();
+#endif
+}
+
 static void __init fixrange_init(unsigned long start, unsigned long end,
 				 pgd_t *pgd_base)
 {
 	pgd_t *pgd;
+	p4d_t *p4d;
 	pud_t *pud;
 	pmd_t *pmd;
 	int i, j;
@@ -107,7 +123,10 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
 	pgd = pgd_base + i;
 
 	for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
-		pud = pud_offset(pgd, vaddr);
+		p4d = p4d_offset(pgd, vaddr);
+		if (p4d_none(*p4d))
+			one_pud_table_init(p4d);
+		pud = pud_offset(p4d, vaddr);
 		if (pud_none(*pud))
 			one_md_table_init(pud);
 		pmd = pmd_offset(pud, vaddr);
@@ -124,6 +143,7 @@ static void __init fixaddr_user_init( void)
 #ifdef CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA
 	long size = FIXADDR_USER_END - FIXADDR_USER_START;
 	pgd_t *pgd;
+	p4d_t *p4d;
 	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
@@ -144,7 +164,8 @@ static void __init fixaddr_user_init( void)
 	for ( ; size > 0; size -= PAGE_SIZE, vaddr += PAGE_SIZE,
 		      p += PAGE_SIZE) {
 		pgd = swapper_pg_dir + pgd_index(vaddr);
-		pud = pud_offset(pgd, vaddr);
+		p4d = p4d_offset(pgd, vaddr);
+		pud = pud_offset(p4d, vaddr);
 		pmd = pmd_offset(pud, vaddr);
 		pte = pte_offset_kernel(pmd, vaddr);
 		pte_set_val(*pte, p, PAGE_READONLY);
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index b5e3d91..3f0d9a5 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -19,15 +19,21 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
 			 unsigned long kernel)
 {
 	pgd_t *pgd;
+	p4d_t *p4d;
 	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 
 	pgd = pgd_offset(mm, proc);
-	pud = pud_alloc(mm, pgd, proc);
-	if (!pud)
+
+	p4d = p4d_alloc(mm, pgd, proc);
+	if (!p4d)
 		goto out;
 
+	pud = pud_alloc(mm, p4d, proc);
+	if (!pud)
+		goto out_pud;
+
 	pmd = pmd_alloc(mm, pud, proc);
 	if (!pmd)
 		goto out_pmd;
@@ -44,6 +50,8 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
 	pmd_free(mm, pmd);
  out_pmd:
 	pud_free(mm, pud);
+ out_pud:
+	p4d_free(mm, p4d);
  out:
 	return -ENOMEM;
 }
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index 3236052..d617f8d 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -17,6 +17,7 @@
 pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pgd;
+	p4d_t *p4d;
 	pud_t *pud;
 	pmd_t *pmd;
 
@@ -27,7 +28,11 @@ pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr)
 	if (!pgd_present(*pgd))
 		return NULL;
 
-	pud = pud_offset(pgd, addr);
+	p4d = p4d_offset(pgd, addr);
+	if (!p4d_present(*p4d))
+		return NULL;
+
+	pud = pud_offset(p4d, addr);
 	if (!pud_present(*pud))
 		return NULL;
 
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index 8425a22..80a358c 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -277,7 +277,7 @@ static inline int update_pmd_range(pud_t *pud, unsigned long addr,
 	return ret;
 }
 
-static inline int update_pud_range(pgd_t *pgd, unsigned long addr,
+static inline int update_pud_range(p4d_t *p4d, unsigned long addr,
 				   unsigned long end,
 				   struct host_vm_change *hvc)
 {
@@ -285,7 +285,7 @@ static inline int update_pud_range(pgd_t *pgd, unsigned long addr,
 	unsigned long next;
 	int ret = 0;
 
-	pud = pud_offset(pgd, addr);
+	pud = pud_offset(p4d, addr);
 	do {
 		next = pud_addr_end(addr, end);
 		if (!pud_present(*pud)) {
@@ -299,6 +299,28 @@ static inline int update_pud_range(pgd_t *pgd, unsigned long addr,
 	return ret;
 }
 
+static inline int update_p4d_range(pgd_t *pgd, unsigned long addr,
+				   unsigned long end,
+				   struct host_vm_change *hvc)
+{
+	p4d_t *p4d;
+	unsigned long next;
+	int ret = 0;
+
+	p4d = p4d_offset(pgd, addr);
+	do {
+		next = p4d_addr_end(addr, end);
+		if (!p4d_present(*p4d)) {
+			if (hvc->force || p4d_newpage(*p4d)) {
+				ret = add_munmap(addr, next - addr, hvc);
+				p4d_mkuptodate(*p4d);
+			}
+		} else
+			ret = update_pud_range(p4d, addr, next, hvc);
+	} while (p4d++, addr = next, ((addr < end) && !ret));
+	return ret;
+}
+
 void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
 		      unsigned long end_addr, int force)
 {
@@ -316,8 +338,8 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
 				ret = add_munmap(addr, next - addr, &hvc);
 				pgd_mkuptodate(*pgd);
 			}
-		}
-		else ret = update_pud_range(pgd, addr, next, &hvc);
+		} else
+			ret = update_p4d_range(pgd, addr, next, &hvc);
 	} while (pgd++, addr = next, ((addr < end_addr) && !ret));
 
 	if (!ret)
@@ -338,6 +360,7 @@ static int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
 {
 	struct mm_struct *mm;
 	pgd_t *pgd;
+	p4d_t *p4d;
 	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
@@ -364,7 +387,23 @@ static int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
 			continue;
 		}
 
-		pud = pud_offset(pgd, addr);
+		p4d = p4d_offset(pgd, addr);
+		if (!p4d_present(*p4d)) {
+			last = ADD_ROUND(addr, P4D_SIZE);
+			if (last > end)
+				last = end;
+			if (p4d_newpage(*p4d)) {
+				updated = 1;
+				err = add_munmap(addr, last - addr, &hvc);
+				if (err < 0)
+					panic("munmap failed, errno = %d\n",
+					      -err);
+			}
+			addr = last;
+			continue;
+		}
+
+		pud = pud_offset(p4d, addr);
 		if (!pud_present(*pud)) {
 			last = ADD_ROUND(addr, PUD_SIZE);
 			if (last > end)
@@ -424,6 +463,7 @@ static int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
 {
 	pgd_t *pgd;
+	p4d_t *p4d;
 	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
@@ -437,7 +477,11 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
 	if (!pgd_present(*pgd))
 		goto kill;
 
-	pud = pud_offset(pgd, address);
+	p4d = p4d_offset(pgd, address);
+	if (!p4d_present(*p4d))
+		goto kill;
+
+	pud = pud_offset(p4d, address);
 	if (!pud_present(*pud))
 		goto kill;
 
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index e62296c..8185530 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -28,6 +28,7 @@ int handle_page_fault(unsigned long address, unsigned long ip,
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
 	pgd_t *pgd;
+	p4d_t *p4d;
 	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
@@ -104,7 +105,8 @@ int handle_page_fault(unsigned long address, unsigned long ip,
 		}
 
 		pgd = pgd_offset(mm, address);
-		pud = pud_offset(pgd, address);
+		p4d = p4d_offset(pgd, address);
+		pud = pud_offset(p4d, address);
 		pmd = pmd_offset(pud, address);
 		pte = pte_offset_kernel(pmd, address);
 	} while (!pte_present(*pte));
-- 
2.7.4


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 12/12] mm: remove __ARCH_HAS_4LEVEL_HACK and include/asm-generic/4level-fixup.h
  2019-10-23  9:28 [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK Mike Rapoport
                   ` (10 preceding siblings ...)
  2019-10-23  9:29 ` [PATCH 11/12] um: add support for folded p4d page tables Mike Rapoport
@ 2019-10-23  9:29 ` Mike Rapoport
  2019-10-23 10:25 ` [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK Linus Torvalds
  12 siblings, 0 replies; 31+ messages in thread
From: Mike Rapoport @ 2019-10-23  9:29 UTC (permalink / raw)
  To: linux-mm
  Cc: Andrew Morton, Anton Ivanov, Arnd Bergmann, David S. Miller,
	Geert Uytterhoeven, Greentime Hu, Greg Ungerer, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, Mike Rapoport, linux-alpha, linux-arch,
	linux-arm-kernel, linux-c6x-dev, linux-kernel, linux-m68k,
	linux-parisc, linux-um, sparclinux, Mike Rapoport

From: Mike Rapoport <rppt@linux.ibm.com>

There are no architectures that use include/asm-generic/4level-fixup.h
therefore it can be removed along with __ARCH_HAS_4LEVEL_HACK define.

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
 include/asm-generic/4level-fixup.h | 40 --------------------------------------
 include/asm-generic/tlb.h          |  2 --
 include/linux/mm.h                 | 10 +++++-----
 mm/memory.c                        |  8 --------
 4 files changed, 5 insertions(+), 55 deletions(-)
 delete mode 100644 include/asm-generic/4level-fixup.h

diff --git a/include/asm-generic/4level-fixup.h b/include/asm-generic/4level-fixup.h
deleted file mode 100644
index e3667c9..0000000
--- a/include/asm-generic/4level-fixup.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _4LEVEL_FIXUP_H
-#define _4LEVEL_FIXUP_H
-
-#define __ARCH_HAS_4LEVEL_HACK
-#define __PAGETABLE_PUD_FOLDED 1
-
-#define PUD_SHIFT			PGDIR_SHIFT
-#define PUD_SIZE			PGDIR_SIZE
-#define PUD_MASK			PGDIR_MASK
-#define PTRS_PER_PUD			1
-
-#define pud_t				pgd_t
-
-#define pmd_alloc(mm, pud, address) \
-	((unlikely(pgd_none(*(pud))) && __pmd_alloc(mm, pud, address))? \
- 		NULL: pmd_offset(pud, address))
-
-#define pud_offset(pgd, start)		(pgd)
-#define pud_none(pud)			0
-#define pud_bad(pud)			0
-#define pud_present(pud)		1
-#define pud_ERROR(pud)			do { } while (0)
-#define pud_clear(pud)			pgd_clear(pud)
-#define pud_val(pud)			pgd_val(pud)
-#define pud_populate(mm, pud, pmd)	pgd_populate(mm, pud, pmd)
-#define pud_page(pud)			pgd_page(pud)
-#define pud_page_vaddr(pud)		pgd_page_vaddr(pud)
-
-#undef pud_free_tlb
-#define pud_free_tlb(tlb, x, addr)	do { } while (0)
-#define pud_free(mm, x)			do { } while (0)
-#define __pud_free_tlb(tlb, x, addr)	do { } while (0)
-
-#undef  pud_addr_end
-#define pud_addr_end(addr, end)		(end)
-
-#include <asm-generic/5level-fixup.h>
-
-#endif
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index 04c0644..5e0c2d0 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -584,7 +584,6 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm
 	} while (0)
 #endif
 
-#ifndef __ARCH_HAS_4LEVEL_HACK
 #ifndef pud_free_tlb
 #define pud_free_tlb(tlb, pudp, address)			\
 	do {							\
@@ -594,7 +593,6 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm
 		__pud_free_tlb(tlb, pudp, address);		\
 	} while (0)
 #endif
-#endif
 
 #ifndef __ARCH_HAS_5LEVEL_HACK
 #ifndef p4d_free_tlb
diff --git a/include/linux/mm.h b/include/linux/mm.h
index cc29227..477b52a 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1850,12 +1850,12 @@ static inline void mm_dec_nr_ptes(struct mm_struct *mm) {}
 int __pte_alloc(struct mm_struct *mm, pmd_t *pmd);
 int __pte_alloc_kernel(pmd_t *pmd);
 
+#if defined(CONFIG_MMU)
+
 /*
- * The following ifdef needed to get the 4level-fixup.h header to work.
- * Remove it when 4level-fixup.h has been removed.
+ * The following ifdef needed to get the 5level-fixup.h header to work.
+ * Remove it when 5level-fixup.h has been removed.
  */
-#if defined(CONFIG_MMU) && !defined(__ARCH_HAS_4LEVEL_HACK)
-
 #ifndef __ARCH_HAS_5LEVEL_HACK
 static inline p4d_t *p4d_alloc(struct mm_struct *mm, pgd_t *pgd,
 		unsigned long address)
@@ -1877,7 +1877,7 @@ static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long a
 	return (unlikely(pud_none(*pud)) && __pmd_alloc(mm, pud, address))?
 		NULL: pmd_offset(pud, address);
 }
-#endif /* CONFIG_MMU && !__ARCH_HAS_4LEVEL_HACK */
+#endif /* CONFIG_MMU */
 
 #if USE_SPLIT_PTE_PTLOCKS
 #if ALLOC_SPLIT_PTLOCKS
diff --git a/mm/memory.c b/mm/memory.c
index b1ca51a..50300f0 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4095,19 +4095,11 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
 	smp_wmb(); /* See comment in __pte_alloc */
 
 	ptl = pud_lock(mm, pud);
-#ifndef __ARCH_HAS_4LEVEL_HACK
 	if (!pud_present(*pud)) {
 		mm_inc_nr_pmds(mm);
 		pud_populate(mm, pud, new);
 	} else	/* Another has populated it */
 		pmd_free(mm, new);
-#else
-	if (!pgd_present(*pud)) {
-		mm_inc_nr_pmds(mm);
-		pgd_populate(mm, pud, new);
-	} else /* Another has populated it */
-		pmd_free(mm, new);
-#endif /* __ARCH_HAS_4LEVEL_HACK */
 	spin_unlock(ptl);
 	return 0;
 }
-- 
2.7.4


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 02/12] arm: nommu: use pgtable-nopud instead of 4level-fixup
  2019-10-23  9:28 ` [PATCH 02/12] arm: nommu: use pgtable-nopud " Mike Rapoport
@ 2019-10-23  9:40   ` Russell King - ARM Linux admin
  0 siblings, 0 replies; 31+ messages in thread
From: Russell King - ARM Linux admin @ 2019-10-23  9:40 UTC (permalink / raw)
  To: Mike Rapoport
  Cc: linux-mm, Andrew Morton, Anton Ivanov, Arnd Bergmann,
	David S. Miller, Geert Uytterhoeven, Greentime Hu, Greg Ungerer,
	Helge Deller, James E.J. Bottomley, Jeff Dike,
	Kirill A. Shutemov, Linus Torvalds, Mark Salter, Matt Turner,
	Michal Simek, Richard Weinberger, Sam Creasey, Vincent Chen,
	Vineet Gupta, linux-alpha, linux-arch, linux-arm-kernel,
	linux-c6x-dev, linux-kernel, linux-m68k, linux-parisc, linux-um,
	sparclinux, Mike Rapoport

On Wed, Oct 23, 2019 at 12:28:51PM +0300, Mike Rapoport wrote:
> From: Mike Rapoport <rppt@linux.ibm.com>
> 
> The generic nommu implementation of page table manipulation takes care of
> folding of the upper levels and does not require fixups.
> 
> Simply replace of include/asm-generic/4level-fixup.h with
> include/asm-generic/pgtable-nopud.h.
> 
> Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>

Acked-by: Russell King <rmk+kernel@armlinux.org.uk>

Thanks.

> ---
>  arch/arm/include/asm/pgtable.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
> index 3ae120c..eabcb48 100644
> --- a/arch/arm/include/asm/pgtable.h
> +++ b/arch/arm/include/asm/pgtable.h
> @@ -12,7 +12,7 @@
>  
>  #ifndef CONFIG_MMU
>  
> -#include <asm-generic/4level-fixup.h>
> +#include <asm-generic/pgtable-nopud.h>
>  #include <asm/pgtable-nommu.h>
>  
>  #else
> -- 
> 2.7.4
> 
> 

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 08/12] parisc: use pgtable-nopXd instead of 4level-fixup
  2019-10-23  9:28 ` [PATCH 08/12] parisc: use pgtable-nopXd " Mike Rapoport
@ 2019-10-23 10:20   ` Rolf Eike Beer
  2019-10-24  8:51     ` Mike Rapoport
  2019-10-24  9:35   ` Peter Rosin
  2019-10-24 12:02   ` Helge Deller
  2 siblings, 1 reply; 31+ messages in thread
From: Rolf Eike Beer @ 2019-10-23 10:20 UTC (permalink / raw)
  To: Mike Rapoport
  Cc: linux-mm, Andrew Morton, Anton Ivanov, Arnd Bergmann,
	David S. Miller, Geert Uytterhoeven, Greentime Hu, Greg Ungerer,
	Helge Deller, James E.J. Bottomley, Jeff Dike,
	Kirill A. Shutemov, Linus Torvalds, Mark Salter, Matt Turner,
	Michal Simek, Richard Weinberger, Russell King, Sam Creasey,
	Vincent Chen, Vineet Gupta, linux-alpha, linux-arch,
	linux-arm-kernel, linux-c6x-dev, linux-kernel, linux-m68k,
	linux-parisc, linux-um, sparclinux, Mike Rapoport,
	linux-parisc-owner

> diff --git a/arch/parisc/include/asm/page.h 
> b/arch/parisc/include/asm/page.h
> index 93caf17..1d339ee 100644
> --- a/arch/parisc/include/asm/page.h
> +++ b/arch/parisc/include/asm/page.h
> @@ -42,48 +42,54 @@ typedef struct { unsigned long pte; } pte_t; /*
> either 32 or 64bit */
> 
>  /* NOTE: even on 64 bits, these entries are __u32 because we allocate
>   * the pmd and pgd in ZONE_DMA (i.e. under 4GB) */
> -typedef struct { __u32 pmd; } pmd_t;
>  typedef struct { __u32 pgd; } pgd_t;
>  typedef struct { unsigned long pgprot; } pgprot_t;
> 
> -#define pte_val(x)	((x).pte)
> -/* These do not work lvalues, so make sure we don't use them as such. 
> */
> +#if CONFIG_PGTABLE_LEVELS == 3
> +typedef struct { __u32 pmd; } pmd_t;
> +#define __pmd(x)	((pmd_t) { (x) } )
> +/* pXd_val() do not work lvalues, so make sure we don't use them as 
> such. */

For me it sounds like there is something missing, maybe an "as" before 
lvalues?
And it was "These", so plural, and now it is singular, so do -> does?

Eike

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK
  2019-10-23  9:28 [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK Mike Rapoport
                   ` (11 preceding siblings ...)
  2019-10-23  9:29 ` [PATCH 12/12] mm: remove __ARCH_HAS_4LEVEL_HACK and include/asm-generic/4level-fixup.h Mike Rapoport
@ 2019-10-23 10:25 ` Linus Torvalds
  12 siblings, 0 replies; 31+ messages in thread
From: Linus Torvalds @ 2019-10-23 10:25 UTC (permalink / raw)
  To: Mike Rapoport
  Cc: Linux-MM, Andrew Morton, Anton Ivanov, Arnd Bergmann,
	David S. Miller, Geert Uytterhoeven, Greentime Hu, Greg Ungerer,
	Helge Deller, James E.J. Bottomley, Jeff Dike,
	Kirill A. Shutemov, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, alpha, linux-arch, Linux ARM, linux-c6x-dev,
	Linux Kernel Mailing List, linux-m68k, linux-parisc, linux-um,
	sparclinux, Mike Rapoport

On Wed, Oct 23, 2019 at 5:29 AM Mike Rapoport <rppt@kernel.org> wrote:
>
> These patches convert several architectures to use page table folding and
> remove __ARCH_HAS_4LEVEL_HACK along with include/asm-generic/4level-fixup.h.

Thanks for doing this.

The patches look sane from a quick scan, and it's definitely the right
thing to do. So ack on my part, but obviously testing the different
architectures would be a really good thing...

                Linus

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 09/12] sparc32: use pgtable-nopud instead of 4level-fixup
  2019-10-23  9:28 ` [PATCH 09/12] sparc32: use pgtable-nopud " Mike Rapoport
@ 2019-10-23 19:59   ` " Mike Rapoport
  2019-10-23 21:21     ` David Miller
  0 siblings, 1 reply; 31+ messages in thread
From: Mike Rapoport @ 2019-10-23 19:59 UTC (permalink / raw)
  To: linux-mm
  Cc: Andrew Morton, Anton Ivanov, Arnd Bergmann, David S. Miller,
	Geert Uytterhoeven, Greentime Hu, Greg Ungerer, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, linux-alpha, linux-arch, linux-arm-kernel,
	linux-c6x-dev, linux-kernel, linux-m68k, linux-parisc, linux-um,
	sparclinux, Mike Rapoport

I've just discovered that I've booted qemu-sparc with the wrong kernel and
this patch crashes miserably :(

The better version that does allow qemu-sparc to boot with folded page
tables is below:


From a90e1d157b7f8786a4276ffc8553f2167c8bc0e7 Mon Sep 17 00:00:00 2001
From: Mike Rapoport <rppt@linux.ibm.com>
Date: Tue, 1 Oct 2019 17:14:38 +0300
Subject: [PATCH v2] sparc32: use pgtable-nopud instead of 4level-fixup

32-bit version of sparc has three-level page tables and can use
pgtable-nopud and folding of the upper layers.

Replace usage of include/asm-generic/4level-fixup.h with
include/asm-generic/pgtable-nopud.h and adjust page table manipulation
macros and functions accordingly.

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
 arch/sparc/include/asm/pgalloc_32.h |  6 ++---
 arch/sparc/include/asm/pgtable_32.h | 28 ++++++++++----------
 arch/sparc/mm/fault_32.c            | 11 ++++++--
 arch/sparc/mm/highmem.c             |  6 ++++-
 arch/sparc/mm/io-unit.c             |  6 ++++-
 arch/sparc/mm/iommu.c               |  6 ++++-
 arch/sparc/mm/srmmu.c               | 51 +++++++++++++++++++++++++++++--------
 7 files changed, 81 insertions(+), 33 deletions(-)

diff --git a/arch/sparc/include/asm/pgalloc_32.h b/arch/sparc/include/asm/pgalloc_32.h
index 10538a4..eae0c92 100644
--- a/arch/sparc/include/asm/pgalloc_32.h
+++ b/arch/sparc/include/asm/pgalloc_32.h
@@ -26,14 +26,14 @@ static inline void free_pgd_fast(pgd_t *pgd)
 #define pgd_free(mm, pgd)	free_pgd_fast(pgd)
 #define pgd_alloc(mm)	get_pgd_fast()
 
-static inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
+static inline void pud_set(pud_t * pudp, pmd_t * pmdp)
 {
 	unsigned long pa = __nocache_pa(pmdp);
 
-	set_pte((pte_t *)pgdp, __pte((SRMMU_ET_PTD | (pa >> 4))));
+	set_pte((pte_t *)pudp, __pte((SRMMU_ET_PTD | (pa >> 4))));
 }
 
-#define pgd_populate(MM, PGD, PMD)      pgd_set(PGD, PMD)
+#define pud_populate(MM, PGD, PMD)      pud_set(PGD, PMD)
 
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm,
 				   unsigned long address)
diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index 31da448..6d6f44c 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -12,7 +12,7 @@
 #include <linux/const.h>
 
 #ifndef __ASSEMBLY__
-#include <asm-generic/4level-fixup.h>
+#include <asm-generic/pgtable-nopud.h>
 
 #include <linux/spinlock.h>
 #include <linux/mm_types.h>
@@ -132,12 +132,12 @@ static inline struct page *pmd_page(pmd_t pmd)
 	return pfn_to_page((pmd_val(pmd) & SRMMU_PTD_PMASK) >> (PAGE_SHIFT-4));
 }
 
-static inline unsigned long pgd_page_vaddr(pgd_t pgd)
+static inline unsigned long pud_page_vaddr(pud_t pud)
 {
-	if (srmmu_device_memory(pgd_val(pgd))) {
+	if (srmmu_device_memory(pud_val(pud))) {
 		return ~0;
 	} else {
-		unsigned long v = pgd_val(pgd) & SRMMU_PTD_PMASK;
+		unsigned long v = pud_val(pud) & SRMMU_PTD_PMASK;
 		return (unsigned long)__nocache_va(v << 4);
 	}
 }
@@ -184,24 +184,24 @@ static inline void pmd_clear(pmd_t *pmdp)
 		set_pte((pte_t *)&pmdp->pmdv[i], __pte(0));
 }
 
-static inline int pgd_none(pgd_t pgd)          
+static inline int pud_none(pud_t pud)
 {
-	return !(pgd_val(pgd) & 0xFFFFFFF);
+	return !(pud_val(pud) & 0xFFFFFFF);
 }
 
-static inline int pgd_bad(pgd_t pgd)
+static inline int pud_bad(pud_t pud)
 {
-	return (pgd_val(pgd) & SRMMU_ET_MASK) != SRMMU_ET_PTD;
+	return (pud_val(pud) & SRMMU_ET_MASK) != SRMMU_ET_PTD;
 }
 
-static inline int pgd_present(pgd_t pgd)
+static inline int pud_present(pud_t pud)
 {
-	return ((pgd_val(pgd) & SRMMU_ET_MASK) == SRMMU_ET_PTD);
+	return ((pud_val(pud) & SRMMU_ET_MASK) == SRMMU_ET_PTD);
 }
 
-static inline void pgd_clear(pgd_t *pgdp)
+static inline void pud_clear(pud_t *pudp)
 {
-	set_pte((pte_t *)pgdp, __pte(0));
+	set_pte((pte_t *)pudp, __pte(0));
 }
 
 /*
@@ -319,9 +319,9 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 #define pgd_offset_k(address) pgd_offset(&init_mm, 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_vaddr(*dir) +
+	return (pmd_t *) pud_page_vaddr(*dir) +
 		((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
 }
 
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
index 8d69de1..89976c9 100644
--- a/arch/sparc/mm/fault_32.c
+++ b/arch/sparc/mm/fault_32.c
@@ -351,6 +351,8 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
 		 */
 		int offset = pgd_index(address);
 		pgd_t *pgd, *pgd_k;
+		p4d_t *p4d, *p4d_k;
+		pud_t *pud, *pud_k;
 		pmd_t *pmd, *pmd_k;
 
 		pgd = tsk->active_mm->pgd + offset;
@@ -363,8 +365,13 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
 			return;
 		}
 
-		pmd = pmd_offset(pgd, address);
-		pmd_k = pmd_offset(pgd_k, address);
+		p4d = p4d_offset(pgd, address);
+		pud = pud_offset(p4d, address);
+		pmd = pmd_offset(pud, address);
+
+		p4d_k = p4d_offset(pgd_k, address);
+		pud_k = pud_offset(p4d_k, address);
+		pmd_k = pmd_offset(pud_k, address);
 
 		if (pmd_present(*pmd) || !pmd_present(*pmd_k))
 			goto bad_area_nosemaphore;
diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c
index 86bc2a5..d4a80ad 100644
--- a/arch/sparc/mm/highmem.c
+++ b/arch/sparc/mm/highmem.c
@@ -39,10 +39,14 @@ static pte_t *kmap_pte;
 void __init kmap_init(void)
 {
 	unsigned long address;
+	p4d_t *p4d;
+	pud_t *pud;
 	pmd_t *dir;
 
 	address = __fix_to_virt(FIX_KMAP_BEGIN);
-	dir = pmd_offset(pgd_offset_k(address), address);
+	p4d = p4d_offset(pgd_offset_k(address), address);
+	pud = pud_offset(p4d, address);
+	dir = pmd_offset(pud, address);
 
         /* cache the first kmap pte */
         kmap_pte = pte_offset_kernel(dir, address);
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index f770ee7..33a0fac 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -239,12 +239,16 @@ static void *iounit_alloc(struct device *dev, size_t len,
 		page = va;
 		{
 			pgd_t *pgdp;
+			p4d_t *p4dp;
+			pud_t *pudp;
 			pmd_t *pmdp;
 			pte_t *ptep;
 			long i;
 
 			pgdp = pgd_offset(&init_mm, addr);
-			pmdp = pmd_offset(pgdp, addr);
+			p4dp = p4d_offset(pgdp, addr);
+			pudp = pud_offset(p4dp, addr);
+			pmdp = pmd_offset(pudp, addr);
 			ptep = pte_offset_map(pmdp, addr);
 
 			set_pte(ptep, mk_pte(virt_to_page(page), dvma_prot));
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 71ac353..4d3c699 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -343,6 +343,8 @@ static void *sbus_iommu_alloc(struct device *dev, size_t len,
 		page = va;
 		{
 			pgd_t *pgdp;
+			p4d_t *p4dp;
+			pud_t *pudp;
 			pmd_t *pmdp;
 			pte_t *ptep;
 
@@ -354,7 +356,9 @@ static void *sbus_iommu_alloc(struct device *dev, size_t len,
 				__flush_page_to_ram(page);
 
 			pgdp = pgd_offset(&init_mm, addr);
-			pmdp = pmd_offset(pgdp, addr);
+			p4dp = p4d_offset(pgdp, addr);
+			pudp = pud_offset(p4dp, addr);
+			pmdp = pmd_offset(pudp, addr);
 			ptep = pte_offset_map(pmdp, addr);
 
 			set_pte(ptep, mk_pte(virt_to_page(page), dvma_prot));
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index cc3ad64..f56c3c9 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -296,6 +296,8 @@ static void __init srmmu_nocache_init(void)
 	void *srmmu_nocache_bitmap;
 	unsigned int bitmap_bits;
 	pgd_t *pgd;
+	p4d_t *p4d;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 	unsigned long paddr, vaddr;
@@ -329,6 +331,8 @@ static void __init srmmu_nocache_init(void)
 
 	while (vaddr < srmmu_nocache_end) {
 		pgd = pgd_offset_k(vaddr);
+		p4d = p4d_offset(__nocache_fix(pgd), vaddr);
+		pud = pud_offset(__nocache_fix(p4d), vaddr);
 		pmd = pmd_offset(__nocache_fix(pgd), vaddr);
 		pte = pte_offset_kernel(__nocache_fix(pmd), vaddr);
 
@@ -516,13 +520,17 @@ static inline void srmmu_mapioaddr(unsigned long physaddr,
 				   unsigned long virt_addr, int bus_type)
 {
 	pgd_t *pgdp;
+	p4d_t *p4dp;
+	pud_t *pudp;
 	pmd_t *pmdp;
 	pte_t *ptep;
 	unsigned long tmp;
 
 	physaddr &= PAGE_MASK;
 	pgdp = pgd_offset_k(virt_addr);
-	pmdp = pmd_offset(pgdp, virt_addr);
+	p4dp = p4d_offset(pgdp, virt_addr);
+	pudp = pud_offset(p4dp, virt_addr);
+	pmdp = pmd_offset(pudp, virt_addr);
 	ptep = pte_offset_kernel(pmdp, virt_addr);
 	tmp = (physaddr >> 4) | SRMMU_ET_PTE;
 
@@ -551,11 +559,16 @@ void srmmu_mapiorange(unsigned int bus, unsigned long xpa,
 static inline void srmmu_unmapioaddr(unsigned long virt_addr)
 {
 	pgd_t *pgdp;
+	p4d_t *p4dp;
+	pud_t *pudp;
 	pmd_t *pmdp;
 	pte_t *ptep;
 
+
 	pgdp = pgd_offset_k(virt_addr);
-	pmdp = pmd_offset(pgdp, virt_addr);
+	p4dp = p4d_offset(pgdp, virt_addr);
+	pudp = pud_offset(p4dp, virt_addr);
+	pmdp = pmd_offset(pudp, virt_addr);
 	ptep = pte_offset_kernel(pmdp, virt_addr);
 
 	/* No need to flush uncacheable page. */
@@ -693,20 +706,24 @@ static void __init srmmu_early_allocate_ptable_skeleton(unsigned long start,
 							unsigned long end)
 {
 	pgd_t *pgdp;
+	p4d_t *p4dp;
+	pud_t *pudp;
 	pmd_t *pmdp;
 	pte_t *ptep;
 
 	while (start < end) {
 		pgdp = pgd_offset_k(start);
-		if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
+		p4dp = p4d_offset(pgdp, start);
+		pudp = pud_offset(p4dp, start);
+		if (pud_none(*(pud_t *)__nocache_fix(pudp))) {
 			pmdp = __srmmu_get_nocache(
 			    SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
 			if (pmdp == NULL)
 				early_pgtable_allocfail("pmd");
 			memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE);
-			pgd_set(__nocache_fix(pgdp), pmdp);
+			pud_set(__nocache_fix(pudp), pmdp);
 		}
-		pmdp = pmd_offset(__nocache_fix(pgdp), start);
+		pmdp = pmd_offset(__nocache_fix(pudp), start);
 		if (srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
 			ptep = __srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
 			if (ptep == NULL)
@@ -724,19 +741,23 @@ static void __init srmmu_allocate_ptable_skeleton(unsigned long start,
 						  unsigned long end)
 {
 	pgd_t *pgdp;
+	p4d_t *p4dp;
+	pud_t *pudp;
 	pmd_t *pmdp;
 	pte_t *ptep;
 
 	while (start < end) {
 		pgdp = pgd_offset_k(start);
-		if (pgd_none(*pgdp)) {
+		p4dp = p4d_offset(pgdp, start);
+		pudp = pud_offset(p4dp, start);
+		if (pud_none(*pudp)) {
 			pmdp = __srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
 			if (pmdp == NULL)
 				early_pgtable_allocfail("pmd");
 			memset(pmdp, 0, SRMMU_PMD_TABLE_SIZE);
-			pgd_set(pgdp, pmdp);
+			pud_set((pud_t *)pgdp, pmdp);
 		}
-		pmdp = pmd_offset(pgdp, start);
+		pmdp = pmd_offset(pudp, start);
 		if (srmmu_pmd_none(*pmdp)) {
 			ptep = __srmmu_get_nocache(PTE_SIZE,
 							     PTE_SIZE);
@@ -779,6 +800,8 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start,
 	unsigned long probed;
 	unsigned long addr;
 	pgd_t *pgdp;
+	p4d_t *p4dp;
+	pud_t *pudp;
 	pmd_t *pmdp;
 	pte_t *ptep;
 	int what; /* 0 = normal-pte, 1 = pmd-level pte, 2 = pgd-level pte */
@@ -810,18 +833,20 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start,
 		}
 
 		pgdp = pgd_offset_k(start);
+		p4dp = p4d_offset(pgdp, start);
+		pudp = pud_offset(p4dp, start);
 		if (what == 2) {
 			*(pgd_t *)__nocache_fix(pgdp) = __pgd(probed);
 			start += SRMMU_PGDIR_SIZE;
 			continue;
 		}
-		if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
+		if (pud_none(*(pud_t *)__nocache_fix(pudp))) {
 			pmdp = __srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE,
 						   SRMMU_PMD_TABLE_SIZE);
 			if (pmdp == NULL)
 				early_pgtable_allocfail("pmd");
 			memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE);
-			pgd_set(__nocache_fix(pgdp), pmdp);
+			pud_set(__nocache_fix(pudp), pmdp);
 		}
 		pmdp = pmd_offset(__nocache_fix(pgdp), start);
 		if (srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
@@ -906,6 +931,8 @@ void __init srmmu_paging_init(void)
 	phandle cpunode;
 	char node_str[128];
 	pgd_t *pgd;
+	p4d_t *p4d;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 	unsigned long pages_avail;
@@ -967,7 +994,9 @@ void __init srmmu_paging_init(void)
 	srmmu_allocate_ptable_skeleton(PKMAP_BASE, PKMAP_END);
 
 	pgd = pgd_offset_k(PKMAP_BASE);
-	pmd = pmd_offset(pgd, PKMAP_BASE);
+	p4d = p4d_offset(pgd, PKMAP_BASE);
+	pud = pud_offset(p4d, PKMAP_BASE);
+	pmd = pmd_offset(pud, PKMAP_BASE);
 	pte = pte_offset_kernel(pmd, PKMAP_BASE);
 	pkmap_page_table = pte;
 
-- 
2.7.4


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 09/12] sparc32: use pgtable-nopud instead of 4level-fixup
  2019-10-23 19:59   ` [PATCH v2 " Mike Rapoport
@ 2019-10-23 21:21     ` David Miller
  0 siblings, 0 replies; 31+ messages in thread
From: David Miller @ 2019-10-23 21:21 UTC (permalink / raw)
  To: rppt
  Cc: linux-mm, akpm, anton.ivanov, arnd, geert, green.hu, gerg,
	deller, James.Bottomley, jdike, kirill, torvalds, msalter,
	mattst88, monstr, richard, linux, sammy, deanbo422,
	Vineet.Gupta1, linux-alpha, linux-arch, linux-arm-kernel,
	linux-c6x-dev, linux-kernel, linux-m68k, linux-parisc, linux-um,
	sparclinux, rppt

From: Mike Rapoport <rppt@kernel.org>
Date: Wed, 23 Oct 2019 22:59:00 +0300

> I've just discovered that I've booted qemu-sparc with the wrong kernel and
> this patch crashes miserably :(
> 
> The better version that does allow qemu-sparc to boot with folded page
> tables is below:
> 
> 
> From a90e1d157b7f8786a4276ffc8553f2167c8bc0e7 Mon Sep 17 00:00:00 2001
> From: Mike Rapoport <rppt@linux.ibm.com>
> Date: Tue, 1 Oct 2019 17:14:38 +0300
> Subject: [PATCH v2] sparc32: use pgtable-nopud instead of 4level-fixup
> 
> 32-bit version of sparc has three-level page tables and can use
> pgtable-nopud and folding of the upper layers.
> 
> Replace usage of include/asm-generic/4level-fixup.h with
> include/asm-generic/pgtable-nopud.h and adjust page table manipulation
> macros and functions accordingly.
> 
> Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>

Acked-by: David S. Miller <davem@davemloft.net>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 04/12] m68k: nommu: use pgtable-nopud instead of 4level-fixup
  2019-10-23  9:28 ` [PATCH 04/12] m68k: nommu: " Mike Rapoport
@ 2019-10-24  4:09   ` Greg Ungerer
  2019-10-24  5:35     ` Mike Rapoport
  0 siblings, 1 reply; 31+ messages in thread
From: Greg Ungerer @ 2019-10-24  4:09 UTC (permalink / raw)
  To: Mike Rapoport, linux-mm
  Cc: Andrew Morton, Anton Ivanov, Arnd Bergmann, David S. Miller,
	Geert Uytterhoeven, Greentime Hu, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, linux-alpha, linux-arch, linux-arm-kernel,
	linux-c6x-dev, linux-kernel, linux-m68k, linux-parisc, linux-um,
	sparclinux, Mike Rapoport

Hi Mike,

On 23/10/19 7:28 pm, Mike Rapoport wrote:
> From: Mike Rapoport <rppt@linux.ibm.com>
> 
> The generic nommu implementation of page table manipulation takes care of
> folding of the upper levels and does not require fixups.
> 
> Simply replace of include/asm-generic/4level-fixup.h with
> include/asm-generic/pgtable-nopud.h.
> 
> Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> ---
>   arch/m68k/include/asm/pgtable_no.h | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/m68k/include/asm/pgtable_no.h b/arch/m68k/include/asm/pgtable_no.h
> index c18165b..ccc4568 100644
> --- a/arch/m68k/include/asm/pgtable_no.h
> +++ b/arch/m68k/include/asm/pgtable_no.h
> @@ -2,7 +2,7 @@
>   #ifndef _M68KNOMMU_PGTABLE_H
>   #define _M68KNOMMU_PGTABLE_H
>   
> -#include <asm-generic/4level-fixup.h>
> +#include <asm-generic/pgtable-nopud.h>
>   
>   /*
>    * (C) Copyright 2000-2002, Greg Ungerer <gerg@snapgear.com>

This fails to compile for me (targeting m5208evb_defconfig):

   CC      init/main.o
In file included from ./arch/m68k/include/asm/pgtable_no.h:56:0,
                  from ./arch/m68k/include/asm/pgtable.h:3,
                  from ./include/linux/mm.h:99,
                  from ./include/linux/ring_buffer.h:5,
                  from ./include/linux/trace_events.h:6,
                  from ./include/trace/syscall.h:7,
                  from ./include/linux/syscalls.h:85,
                  from init/main.c:21:
./include/asm-generic/pgtable.h:738:34: error: unknown type name ‘pmd_t’
  static inline int pmd_soft_dirty(pmd_t pmd)
                                   ^
./include/asm-generic/pgtable.h:748:15: error: unknown type name ‘pmd_t’
  static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
                ^
./include/asm-generic/pgtable.h:748:38: error: unknown type name ‘pmd_t’
  static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
                                       ^
./include/asm-generic/pgtable.h:758:15: error: unknown type name ‘pmd_t’
  static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
                ^
./include/asm-generic/pgtable.h:758:42: error: unknown type name ‘pmd_t’
  static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
                                           ^
./include/asm-generic/pgtable.h:778:15: error: unknown type name ‘pmd_t’
  static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd)
                ^
./include/asm-generic/pgtable.h:778:42: error: unknown type name ‘pmd_t’
  static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd)
                                           ^
./include/asm-generic/pgtable.h:783:38: error: unknown type name ‘pmd_t’
  static inline int pmd_swp_soft_dirty(pmd_t pmd)
                                       ^
./include/asm-generic/pgtable.h:788:15: error: unknown type name ‘pmd_t’
  static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
                ^
./include/asm-generic/pgtable.h:788:46: error: unknown type name ‘pmd_t’
  static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
                                               ^
./include/asm-generic/pgtable.h:1071:32: error: unknown type name ‘pmd_t’
  static inline int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot)
                                 ^
./include/asm-generic/pgtable.h:1083:34: error: unknown type name ‘pmd_t’
  static inline int pmd_clear_huge(pmd_t *pmd)
                                   ^
./include/asm-generic/pgtable.h:1095:37: error: unknown type name ‘pmd_t’
  static inline int pmd_free_pte_page(pmd_t *pmd, unsigned long addr)
                                      ^
In file included from ./include/linux/ring_buffer.h:5:0,
                  from ./include/linux/trace_events.h:6,
                  from ./include/trace/syscall.h:7,
                  from ./include/linux/syscalls.h:85,
                  from init/main.c:21:
./include/linux/mm.h:423:2: error: unknown type name ‘pmd_t’
   pmd_t *pmd;   /* Pointer to pmd entry matching
   ^
./include/linux/mm.h:568:30: error: unknown type name ‘pmd_t’
  static inline int pmd_devmap(pmd_t pmd)
                               ^
In file included from ./include/linux/mm.h:587:0,
                  from ./include/linux/ring_buffer.h:5,
                  from ./include/linux/trace_events.h:6,
                  from ./include/trace/syscall.h:7,
                  from ./include/linux/syscalls.h:85,
                  from init/main.c:21:
./include/linux/huge_mm.h:12:5: error: unknown type name ‘pmd_t’
      pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long addr,
      ^
./include/linux/huge_mm.h:12:21: error: unknown type name ‘pmd_t’
      pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long addr,
                      ^
./include/linux/huge_mm.h:14:57: error: unknown type name ‘pmd_t’
  extern void huge_pmd_set_accessed(struct vm_fault *vmf, pmd_t orig_pmd);
                                                          ^
./include/linux/huge_mm.h:27:61: error: unknown type name ‘pmd_t’
  extern vm_fault_t do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd);
                                                              ^
./include/linux/huge_mm.h:30:8: error: unknown type name ‘pmd_t’
         pmd_t *pmd,
         ^
./include/linux/huge_mm.h:34:4: error: unknown type name ‘pmd_t’
     pmd_t *pmd, unsigned long addr, unsigned long next);
     ^
./include/linux/huge_mm.h:37:4: error: unknown type name ‘pmd_t’
     pmd_t *pmd, unsigned long addr);
     ^
./include/linux/huge_mm.h:41:57: error: unknown type name ‘pmd_t’
  extern int mincore_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
                                                          ^
./include/linux/huge_mm.h:46:5: error: unknown type name ‘pmd_t’
      pmd_t *old_pmd, pmd_t *new_pmd);
      ^
./include/linux/huge_mm.h:46:21: error: unknown type name ‘pmd_t’
      pmd_t *old_pmd, pmd_t *new_pmd);
                      ^
./include/linux/huge_mm.h:47:56: error: unknown type name ‘pmd_t’
  extern int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
                                                         ^
./include/linux/huge_mm.h:336:65: error: unknown type name ‘pmd_t’
  static inline void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
                                                                  ^
./include/linux/huge_mm.h:356:31: error: unknown type name ‘pmd_t’
  static inline int is_swap_pmd(pmd_t pmd)
                                ^
./include/linux/huge_mm.h:360:47: error: unknown type name ‘pmd_t’
  static inline spinlock_t *pmd_trans_huge_lock(pmd_t *pmd,
                                                ^
./include/linux/huge_mm.h:372:3: error: unknown type name ‘pmd_t’
    pmd_t orig_pmd)
    ^
./include/linux/huge_mm.h:393:22: error: unknown type name ‘pmd_t’
   unsigned long addr, pmd_t *pmd, int flags, struct dev_pagemap **pgmap)
                       ^
In file included from ./include/linux/ring_buffer.h:5:0,
                  from ./include/linux/trace_events.h:6,
                  from ./include/trace/syscall.h:7,
                  from ./include/linux/syscalls.h:85,
                  from init/main.c:21:
./include/linux/mm.h:1447:5: error: unknown type name ‘pmd_t’
      pmd_t pmd);
      ^
./include/linux/mm.h:1464:21: error: unknown type name ‘pmd_t’
       pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp);
                      ^
./include/linux/mm.h:1850:39: error: unknown type name ‘pmd_t’
  int __pte_alloc(struct mm_struct *mm, pmd_t *pmd);
                                        ^
./include/linux/mm.h:1851:24: error: unknown type name ‘pmd_t’
  int __pte_alloc_kernel(pmd_t *pmd);
                         ^
./include/linux/mm.h:1937:61: error: unknown type name ‘pmd_t’
  static inline spinlock_t *pte_lockptr(struct mm_struct *mm, pmd_t *pmd)
                                                              ^
./include/linux/mm.h:2028:61: error: unknown type name ‘pmd_t’
  static inline spinlock_t *pmd_lockptr(struct mm_struct *mm, pmd_t *pmd)
                                                              ^
./include/linux/mm.h:2040:58: error: unknown type name ‘pmd_t’
  static inline spinlock_t *pmd_lock(struct mm_struct *mm, pmd_t *pmd)
                                                           ^
In file included from ./include/linux/ring_buffer.h:5:0,
                  from ./include/linux/trace_events.h:6,
                  from ./include/trace/syscall.h:7,
                  from ./include/linux/syscalls.h:85,
                  from init/main.c:21:
./include/linux/mm.h:2755:1: error: unknown type name ‘pmd_t’
  pmd_t *vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node);
  ^
./include/linux/mm.h:2756:29: error: unknown type name ‘pmd_t’
  pte_t *vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node);
                              ^
scripts/Makefile.build:265: recipe for target 'init/main.o' failed
make[1]: *** [init/main.o] Error 1
Makefile:1649: recipe for target 'init' failed
make: *** [init] Error 2

Regards
Greg


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 05/12] m68k: mm: use pgtable-nopXd instead of 4level-fixup
  2019-10-23  9:28 ` [PATCH 05/12] m68k: mm: use pgtable-nopXd " Mike Rapoport
@ 2019-10-24  4:12   ` Greg Ungerer
  2019-10-25  5:52   ` kbuild test robot
  1 sibling, 0 replies; 31+ messages in thread
From: Greg Ungerer @ 2019-10-24  4:12 UTC (permalink / raw)
  To: Mike Rapoport, linux-mm
  Cc: Andrew Morton, Anton Ivanov, Arnd Bergmann, David S. Miller,
	Geert Uytterhoeven, Greentime Hu, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, linux-alpha, linux-arch, linux-arm-kernel,
	linux-c6x-dev, linux-kernel, linux-m68k, linux-parisc, linux-um,
	sparclinux, Mike Rapoport

Hi Mike,

On 23/10/19 7:28 pm, Mike Rapoport wrote:
> From: Mike Rapoport <rppt@linux.ibm.com>
> 
> 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-nopmd.h for three-lelve configurations and
> adjust page table manipulation macros and functions accordingly.
> 
> Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>

Tested (on real hardware) for the ColdFire MMU m68k variants and working

Acked-by: Greg Ungerer <gerg@linux-m68k.org>

Regards
Greg


> ---
>   arch/m68k/include/asm/mcf_pgalloc.h      |  7 -------
>   arch/m68k/include/asm/mcf_pgtable.h      | 28 +++++++++----------------
>   arch/m68k/include/asm/mmu_context.h      | 12 ++++++++++-
>   arch/m68k/include/asm/motorola_pgalloc.h |  4 ++--
>   arch/m68k/include/asm/motorola_pgtable.h | 32 +++++++++++++++++-----------
>   arch/m68k/include/asm/page.h             |  9 +++++---
>   arch/m68k/include/asm/pgtable_mm.h       | 11 ++++++----
>   arch/m68k/include/asm/sun3_pgalloc.h     |  5 -----
>   arch/m68k/include/asm/sun3_pgtable.h     | 18 ----------------
>   arch/m68k/kernel/sys_m68k.c              | 10 ++++++++-
>   arch/m68k/mm/init.c                      |  6 ++++--
>   arch/m68k/mm/kmap.c                      | 36 ++++++++++++++++++++++++--------
>   arch/m68k/mm/mcfmmu.c                    | 16 +++++++++++++-
>   arch/m68k/mm/motorola.c                  | 17 +++++++++------
>   14 files changed, 122 insertions(+), 89 deletions(-)
> 
> diff --git a/arch/m68k/include/asm/mcf_pgalloc.h b/arch/m68k/include/asm/mcf_pgalloc.h
> index b34d44d..82ec54c 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 5d5502c..b9f45ae 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 f5b1852..cac9f28 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 acab315..ff9cc40 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 7f66a7b..62bedc6 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 700d819..c00b67a 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 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 646c174f..2bf5c35 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 8561211..11b95da 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 c987d50..bc41552 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 6363ec8..18a4de7 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 778cacb..27c453f 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 40a3b32..9f687da 100644
> --- a/arch/m68k/mm/kmap.c
> +++ b/arch/m68k/mm/kmap.c
> @@ -110,6 +110,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;
>   
> @@ -196,17 +198,21 @@ 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 (CPU_IS_020_OR_030) {
> +#if CONFIG_PGTABLE_LEVELS == 3
>   			pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr;
>   			physaddr += PTRTREESIZE;
>   			virtaddr += PTRTREESIZE;
>   			size -= PTRTREESIZE;
> +#endif
>   		} else {
>   			pte_dir = pte_alloc_kernel(pmd_dir, virtaddr);
>   			if (!pte_dir) {
> @@ -258,19 +264,24 @@ void __iounmap(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 pgd(%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 (CPU_IS_020_OR_030) {
> +#if CONFIG_PGTABLE_LEVELS == 3
>   			int pmd_off = (virtaddr/PTRTREESIZE) & 15;
>   			int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK;
>   
> @@ -281,6 +292,7 @@ void __iounmap(void *addr, unsigned long size)
>   				continue;
>   			} else if (pmd_type == 0)
>   				continue;
> +#endif
>   		}
>   
>   		if (pmd_bad(*pmd_dir)) {
> @@ -307,6 +319,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,14 +355,17 @@ 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 (CPU_IS_020_OR_030) {
> +#if CONFIG_PGTABLE_LEVELS == 3
>   			int pmd_off = (virtaddr/PTRTREESIZE) & 15;
>   
>   			if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) {
> @@ -358,6 +375,7 @@ void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
>   				size -= PTRTREESIZE;
>   				continue;
>   			}
> +#endif
>   		}
>   
>   		if (pmd_bad(*pmd_dir)) {
> diff --git a/arch/m68k/mm/mcfmmu.c b/arch/m68k/mm/mcfmmu.c
> index 6cb1e41..0ea3756 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 356601b..4857985 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);
>   	}
>   }
> -
> 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 04/12] m68k: nommu: use pgtable-nopud instead of 4level-fixup
  2019-10-24  4:09   ` Greg Ungerer
@ 2019-10-24  5:35     ` Mike Rapoport
  2019-10-24  6:23       ` Greg Ungerer
  0 siblings, 1 reply; 31+ messages in thread
From: Mike Rapoport @ 2019-10-24  5:35 UTC (permalink / raw)
  To: Greg Ungerer
  Cc: linux-mm, Andrew Morton, Anton Ivanov, Arnd Bergmann,
	David S. Miller, Geert Uytterhoeven, Greentime Hu, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, linux-alpha, linux-arch, linux-arm-kernel,
	linux-c6x-dev, linux-kernel, linux-m68k, linux-parisc, linux-um,
	sparclinux, Mike Rapoport

Hi Greg,

On Thu, Oct 24, 2019 at 02:09:01PM +1000, Greg Ungerer wrote:
> Hi Mike,
> 
> On 23/10/19 7:28 pm, Mike Rapoport wrote:
> >From: Mike Rapoport <rppt@linux.ibm.com>
> >
> >The generic nommu implementation of page table manipulation takes care of
> >folding of the upper levels and does not require fixups.
> >
> >Simply replace of include/asm-generic/4level-fixup.h with
> >include/asm-generic/pgtable-nopud.h.
> >
> >Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> >---
> >  arch/m68k/include/asm/pgtable_no.h | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> >diff --git a/arch/m68k/include/asm/pgtable_no.h b/arch/m68k/include/asm/pgtable_no.h
> >index c18165b..ccc4568 100644
> >--- a/arch/m68k/include/asm/pgtable_no.h
> >+++ b/arch/m68k/include/asm/pgtable_no.h
> >@@ -2,7 +2,7 @@
> >  #ifndef _M68KNOMMU_PGTABLE_H
> >  #define _M68KNOMMU_PGTABLE_H
> >-#include <asm-generic/4level-fixup.h>
> >+#include <asm-generic/pgtable-nopud.h>
> >  /*
> >   * (C) Copyright 2000-2002, Greg Ungerer <gerg@snapgear.com>
> 
> This fails to compile for me (targeting m5208evb_defconfig):
> 
>   CC      init/main.o
> In file included from ./arch/m68k/include/asm/pgtable_no.h:56:0,
>                  from ./arch/m68k/include/asm/pgtable.h:3,
>                  from ./include/linux/mm.h:99,
>                  from ./include/linux/ring_buffer.h:5,
>                  from ./include/linux/trace_events.h:6,
>                  from ./include/trace/syscall.h:7,
>                  from ./include/linux/syscalls.h:85,
>                  from init/main.c:21:
> ./include/asm-generic/pgtable.h:738:34: error: unknown type name ‘pmd_t’
>  static inline int pmd_soft_dirty(pmd_t pmd)
>                                   ^

...

> scripts/Makefile.build:265: recipe for target 'init/main.o' failed
> make[1]: *** [init/main.o] Error 1
> Makefile:1649: recipe for target 'init' failed
> make: *** [init] Error 2

The hunk below fixes the build.

diff --git a/arch/m68k/include/asm/page.h b/arch/m68k/include/asm/page.h
index c00b67a..05e1e1e 100644
--- a/arch/m68k/include/asm/page.h
+++ b/arch/m68k/include/asm/page.h
@@ -21,7 +21,7 @@
 /*
  * These are used to make use of C type-checking..
  */
-#if CONFIG_PGTABLE_LEVELS == 3
+#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) }, })
 
> Regards
> Greg
> 

-- 
Sincerely yours,
Mike.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 04/12] m68k: nommu: use pgtable-nopud instead of 4level-fixup
  2019-10-24  5:35     ` Mike Rapoport
@ 2019-10-24  6:23       ` Greg Ungerer
  0 siblings, 0 replies; 31+ messages in thread
From: Greg Ungerer @ 2019-10-24  6:23 UTC (permalink / raw)
  To: Mike Rapoport
  Cc: linux-mm, Andrew Morton, Anton Ivanov, Arnd Bergmann,
	David S. Miller, Geert Uytterhoeven, Greentime Hu, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Michal Simek,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, linux-alpha, linux-arch, linux-arm-kernel,
	linux-c6x-dev, linux-kernel, linux-m68k, linux-parisc, linux-um,
	sparclinux, Mike Rapoport

Hi Mike,

On 24/10/19 3:35 pm, Mike Rapoport wrote:
> Hi Greg,
> 
> On Thu, Oct 24, 2019 at 02:09:01PM +1000, Greg Ungerer wrote:
>> Hi Mike,
>>
>> On 23/10/19 7:28 pm, Mike Rapoport wrote:
>>> From: Mike Rapoport <rppt@linux.ibm.com>
>>>
>>> The generic nommu implementation of page table manipulation takes care of
>>> folding of the upper levels and does not require fixups.
>>>
>>> Simply replace of include/asm-generic/4level-fixup.h with
>>> include/asm-generic/pgtable-nopud.h.
>>>
>>> Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
>>> ---
>>>   arch/m68k/include/asm/pgtable_no.h | 2 +-
>>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/arch/m68k/include/asm/pgtable_no.h b/arch/m68k/include/asm/pgtable_no.h
>>> index c18165b..ccc4568 100644
>>> --- a/arch/m68k/include/asm/pgtable_no.h
>>> +++ b/arch/m68k/include/asm/pgtable_no.h
>>> @@ -2,7 +2,7 @@
>>>   #ifndef _M68KNOMMU_PGTABLE_H
>>>   #define _M68KNOMMU_PGTABLE_H
>>> -#include <asm-generic/4level-fixup.h>
>>> +#include <asm-generic/pgtable-nopud.h>
>>>   /*
>>>    * (C) Copyright 2000-2002, Greg Ungerer <gerg@snapgear.com>
>>
>> This fails to compile for me (targeting m5208evb_defconfig):
>>
>>    CC      init/main.o
>> In file included from ./arch/m68k/include/asm/pgtable_no.h:56:0,
>>                   from ./arch/m68k/include/asm/pgtable.h:3,
>>                   from ./include/linux/mm.h:99,
>>                   from ./include/linux/ring_buffer.h:5,
>>                   from ./include/linux/trace_events.h:6,
>>                   from ./include/trace/syscall.h:7,
>>                   from ./include/linux/syscalls.h:85,
>>                   from init/main.c:21:
>> ./include/asm-generic/pgtable.h:738:34: error: unknown type name ‘pmd_t’
>>   static inline int pmd_soft_dirty(pmd_t pmd)
>>                                    ^
> 
> ...
> 
>> scripts/Makefile.build:265: recipe for target 'init/main.o' failed
>> make[1]: *** [init/main.o] Error 1
>> Makefile:1649: recipe for target 'init' failed
>> make: *** [init] Error 2
> 
> The hunk below fixes the build.
> 
> diff --git a/arch/m68k/include/asm/page.h b/arch/m68k/include/asm/page.h
> index c00b67a..05e1e1e 100644
> --- a/arch/m68k/include/asm/page.h
> +++ b/arch/m68k/include/asm/page.h
> @@ -21,7 +21,7 @@
>   /*
>    * These are used to make use of C type-checking..
>    */
> -#if CONFIG_PGTABLE_LEVELS == 3
> +#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) }, })

That looks better. Thanks.
Tested and working on m68knommu. For the combined patches:

Acked-by: Greg Ungerer <gerg@linux-m68k.org>

Regards
Greg



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 08/12] parisc: use pgtable-nopXd instead of 4level-fixup
  2019-10-23 10:20   ` Rolf Eike Beer
@ 2019-10-24  8:51     ` Mike Rapoport
  0 siblings, 0 replies; 31+ messages in thread
From: Mike Rapoport @ 2019-10-24  8:51 UTC (permalink / raw)
  To: Rolf Eike Beer
  Cc: linux-mm, Andrew Morton, Anton Ivanov, Arnd Bergmann,
	David S. Miller, Geert Uytterhoeven, Greentime Hu, Greg Ungerer,
	Helge Deller, James E.J. Bottomley, Jeff Dike,
	Kirill A. Shutemov, Linus Torvalds, Mark Salter, Matt Turner,
	Michal Simek, Richard Weinberger, Russell King, Sam Creasey,
	Vincent Chen, Vineet Gupta, linux-alpha, linux-arch,
	linux-arm-kernel, linux-c6x-dev, linux-kernel, linux-m68k,
	linux-parisc, linux-um, sparclinux, Mike Rapoport,
	linux-parisc-owner

On Wed, Oct 23, 2019 at 12:20:29PM +0200, Rolf Eike Beer wrote:
> >diff --git a/arch/parisc/include/asm/page.h
> >b/arch/parisc/include/asm/page.h
> >index 93caf17..1d339ee 100644
> >--- a/arch/parisc/include/asm/page.h
> >+++ b/arch/parisc/include/asm/page.h
> >@@ -42,48 +42,54 @@ typedef struct { unsigned long pte; } pte_t; /*
> >either 32 or 64bit */
> >
> > /* NOTE: even on 64 bits, these entries are __u32 because we allocate
> >  * the pmd and pgd in ZONE_DMA (i.e. under 4GB) */
> >-typedef struct { __u32 pmd; } pmd_t;
> > typedef struct { __u32 pgd; } pgd_t;
> > typedef struct { unsigned long pgprot; } pgprot_t;
> >
> >-#define pte_val(x)	((x).pte)
> >-/* These do not work lvalues, so make sure we don't use them as such. */
> >+#if CONFIG_PGTABLE_LEVELS == 3
> >+typedef struct { __u32 pmd; } pmd_t;
> >+#define __pmd(x)	((pmd_t) { (x) } )
> >+/* pXd_val() do not work lvalues, so make sure we don't use them as such.
> >*/
> 
> For me it sounds like there is something missing, maybe an "as" before
> lvalues?

Right, "as lvalues" makes sense.

> And it was "These", so plural, and now it is singular, so do -> does?

There's also pgd_val() a few lines below, it's just not visible in the
patch.
 
> Eike

-- 
Sincerely yours,
Mike.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 08/12] parisc: use pgtable-nopXd instead of 4level-fixup
  2019-10-23  9:28 ` [PATCH 08/12] parisc: use pgtable-nopXd " Mike Rapoport
  2019-10-23 10:20   ` Rolf Eike Beer
@ 2019-10-24  9:35   ` Peter Rosin
  2019-10-24  9:50     ` Mike Rapoport
  2019-10-24 12:02   ` Helge Deller
  2 siblings, 1 reply; 31+ messages in thread
From: Peter Rosin @ 2019-10-24  9:35 UTC (permalink / raw)
  To: rppt
  Cc: James.Bottomley, Vineet.Gupta1, akpm, anton.ivanov, arnd, davem,
	deanbo422, deller, geert, gerg, green.hu, jdike, kirill,
	linux-alpha, linux-arch, linux-arm-kernel, linux-c6x-dev,
	linux-kernel, linux-m68k, linux-mm, linux-parisc, linux-um,
	linux, mattst88, monstr, msalter, richard, rppt, sammy,
	sparclinux, torvalds, Peter Rosin

On 2019-10-23 12:28, Mike Rapoport <rppt@kernel.org> wrote:
> parisc 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 parisc with
> include/asm-generic/pgtable-nopmd.h for two-level configurations and with
> include/asm-generic/pgtable-nopmd.h for three-lelve configurations and

I think you mean .../pgtable-nopud.h in the latter case.

Cheers,
Peter

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 08/12] parisc: use pgtable-nopXd instead of 4level-fixup
  2019-10-24  9:35   ` Peter Rosin
@ 2019-10-24  9:50     ` Mike Rapoport
  0 siblings, 0 replies; 31+ messages in thread
From: Mike Rapoport @ 2019-10-24  9:50 UTC (permalink / raw)
  To: Peter Rosin
  Cc: James.Bottomley, Vineet.Gupta1, akpm, anton.ivanov, arnd, davem,
	deanbo422, deller, geert, gerg, green.hu, jdike, kirill,
	linux-alpha, linux-arch, linux-arm-kernel, linux-c6x-dev,
	linux-kernel, linux-m68k, linux-mm, linux-parisc, linux-um,
	linux, mattst88, monstr, msalter, richard, rppt, sammy,
	sparclinux, torvalds

On Thu, Oct 24, 2019 at 09:35:12AM +0000, Peter Rosin wrote:
> On 2019-10-23 12:28, Mike Rapoport <rppt@kernel.org> wrote:
> > parisc 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 parisc with
> > include/asm-generic/pgtable-nopmd.h for two-level configurations and with
> > include/asm-generic/pgtable-nopmd.h for three-lelve configurations and
> 
> I think you mean .../pgtable-nopud.h in the latter case.

Right, thanks!
 
> Cheers,
> Peter

-- 
Sincerely yours,
Mike.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 08/12] parisc: use pgtable-nopXd instead of 4level-fixup
  2019-10-23  9:28 ` [PATCH 08/12] parisc: use pgtable-nopXd " Mike Rapoport
  2019-10-23 10:20   ` Rolf Eike Beer
  2019-10-24  9:35   ` Peter Rosin
@ 2019-10-24 12:02   ` Helge Deller
  2019-10-24 16:00     ` Mike Rapoport
  2 siblings, 1 reply; 31+ messages in thread
From: Helge Deller @ 2019-10-24 12:02 UTC (permalink / raw)
  To: Mike Rapoport, Linus Torvalds, linux-kernel, linux-parisc,
	James Bottomley, John David Anglin
  Cc: Andrew Morton, Arnd Bergmann, David S. Miller, Mike Rapoport

* Mike Rapoport <rppt@kernel.org>:
> From: Mike Rapoport <rppt@linux.ibm.com>
>
> parisc 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 parisc with
> include/asm-generic/pgtable-nopmd.h for two-level configurations and with
> include/asm-generic/pgtable-nopmd.h for three-lelve configurations and
> adjust page table manipulation macros and functions accordingly.
>
> Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> ---
>  arch/parisc/include/asm/page.h    | 30 +++++++++++++---------
>  arch/parisc/include/asm/pgalloc.h | 41 +++++++++++-------------------
>  arch/parisc/include/asm/pgtable.h | 52 +++++++++++++++++++--------------------
>  arch/parisc/include/asm/tlb.h     |  2 ++
>  arch/parisc/kernel/cache.c        | 13 ++++++----
>  arch/parisc/kernel/pci-dma.c      |  9 +++++--
>  arch/parisc/mm/fixmap.c           | 10 +++++---
>  7 files changed, 81 insertions(+), 76 deletions(-)

Mike, thanks for this clean-up!

Your patch is functional OK. I successfully tested it with a 32-bit
kernel in qemu, and with a 64-bit kernel on a physical box.
For 64-bit you missed to adapt the parisc hugetlb code, so maybe you
can add the patch below to your series?

Other than that (and the lexical corrections which other already mentioned):
Acked-by: Helge Deller <deller@gmx.de>

Thanks!
Helge

----------------
parisc/hugetlb: use pgtable-nopXd instead of 4level-fixup

Signed-off-by: Helge Deller <deller@gmx.de>

diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c
index d578809e55cf..0e1e212f1c96 100644
--- a/arch/parisc/mm/hugetlbpage.c
+++ b/arch/parisc/mm/hugetlbpage.c
@@ -49,6 +49,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
 			unsigned long addr, unsigned long sz)
 {
 	pgd_t *pgd;
+	p4d_t *p4d;
 	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte = NULL;
@@ -61,7 +62,8 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
 	addr &= HPAGE_MASK;

 	pgd = pgd_offset(mm, addr);
-	pud = pud_alloc(mm, pgd, addr);
+	p4d = p4d_offset(pgd, addr);
+	pud = pud_alloc(mm, p4d, addr);
 	if (pud) {
 		pmd = pmd_alloc(mm, pud, addr);
 		if (pmd)
@@ -74,6 +76,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
 		       unsigned long addr, unsigned long sz)
 {
 	pgd_t *pgd;
+	p4d_t *p4d;
 	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte = NULL;
@@ -82,11 +85,14 @@ pte_t *huge_pte_offset(struct mm_struct *mm,

 	pgd = pgd_offset(mm, addr);
 	if (!pgd_none(*pgd)) {
-		pud = pud_offset(pgd, addr);
-		if (!pud_none(*pud)) {
-			pmd = pmd_offset(pud, addr);
-			if (!pmd_none(*pmd))
-				pte = pte_offset_map(pmd, addr);
+		p4d = p4d_offset(pgd, addr);
+		if (!p4d_none(*p4d)) {
+			pud = pud_offset(p4d, addr);
+			if (!pud_none(*pud)) {
+				pmd = pmd_offset(pud, addr);
+				if (!pmd_none(*pmd))
+					pte = pte_offset_map(pmd, addr);
+			}
 		}
 	}
 	return pte;






^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 08/12] parisc: use pgtable-nopXd instead of 4level-fixup
  2019-10-24 12:02   ` Helge Deller
@ 2019-10-24 16:00     ` Mike Rapoport
  0 siblings, 0 replies; 31+ messages in thread
From: Mike Rapoport @ 2019-10-24 16:00 UTC (permalink / raw)
  To: Helge Deller
  Cc: Linus Torvalds, linux-kernel, linux-parisc, James Bottomley,
	John David Anglin, Andrew Morton, Arnd Bergmann, David S. Miller,
	Mike Rapoport

On Thu, Oct 24, 2019 at 02:02:08PM +0200, Helge Deller wrote:
> * Mike Rapoport <rppt@kernel.org>:
> > From: Mike Rapoport <rppt@linux.ibm.com>
> >
> > parisc 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 parisc with
> > include/asm-generic/pgtable-nopmd.h for two-level configurations and with
> > include/asm-generic/pgtable-nopmd.h for three-lelve configurations and
> > adjust page table manipulation macros and functions accordingly.
> >
> > Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> > ---
> >  arch/parisc/include/asm/page.h    | 30 +++++++++++++---------
> >  arch/parisc/include/asm/pgalloc.h | 41 +++++++++++-------------------
> >  arch/parisc/include/asm/pgtable.h | 52 +++++++++++++++++++--------------------
> >  arch/parisc/include/asm/tlb.h     |  2 ++
> >  arch/parisc/kernel/cache.c        | 13 ++++++----
> >  arch/parisc/kernel/pci-dma.c      |  9 +++++--
> >  arch/parisc/mm/fixmap.c           | 10 +++++---
> >  7 files changed, 81 insertions(+), 76 deletions(-)
> 
> Mike, thanks for this clean-up!
> 
> Your patch is functional OK. I successfully tested it with a 32-bit
> kernel in qemu, and with a 64-bit kernel on a physical box.
> For 64-bit you missed to adapt the parisc hugetlb code, so maybe you
> can add the patch below to your series?

Sure.
 
> Other than that (and the lexical corrections which other already mentioned):
> Acked-by: Helge Deller <deller@gmx.de>

Thanks!
 
> Thanks!
> Helge
> 
> ----------------
> parisc/hugetlb: use pgtable-nopXd instead of 4level-fixup
> 
> Signed-off-by: Helge Deller <deller@gmx.de>
> 
> diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c
> index d578809e55cf..0e1e212f1c96 100644
> --- a/arch/parisc/mm/hugetlbpage.c
> +++ b/arch/parisc/mm/hugetlbpage.c
> @@ -49,6 +49,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
>  			unsigned long addr, unsigned long sz)
>  {
>  	pgd_t *pgd;
> +	p4d_t *p4d;
>  	pud_t *pud;
>  	pmd_t *pmd;
>  	pte_t *pte = NULL;
> @@ -61,7 +62,8 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
>  	addr &= HPAGE_MASK;
> 
>  	pgd = pgd_offset(mm, addr);
> -	pud = pud_alloc(mm, pgd, addr);
> +	p4d = p4d_offset(pgd, addr);
> +	pud = pud_alloc(mm, p4d, addr);
>  	if (pud) {
>  		pmd = pmd_alloc(mm, pud, addr);
>  		if (pmd)
> @@ -74,6 +76,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
>  		       unsigned long addr, unsigned long sz)
>  {
>  	pgd_t *pgd;
> +	p4d_t *p4d;
>  	pud_t *pud;
>  	pmd_t *pmd;
>  	pte_t *pte = NULL;
> @@ -82,11 +85,14 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
> 
>  	pgd = pgd_offset(mm, addr);
>  	if (!pgd_none(*pgd)) {
> -		pud = pud_offset(pgd, addr);
> -		if (!pud_none(*pud)) {
> -			pmd = pmd_offset(pud, addr);
> -			if (!pmd_none(*pmd))
> -				pte = pte_offset_map(pmd, addr);
> +		p4d = p4d_offset(pgd, addr);
> +		if (!p4d_none(*p4d)) {
> +			pud = pud_offset(p4d, addr);
> +			if (!pud_none(*pud)) {
> +				pmd = pmd_offset(pud, addr);
> +				if (!pmd_none(*pmd))
> +					pte = pte_offset_map(pmd, addr);
> +			}
>  		}
>  	}
>  	return pte;
> 
> 
> 
> 
> 

-- 
Sincerely yours,
Mike.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 06/12] microblaze: use pgtable-nopmd instead of 4level-fixup
  2019-10-23  9:28 ` [PATCH 06/12] microblaze: use pgtable-nopmd " Mike Rapoport
@ 2019-10-25  2:17   ` kbuild test robot
  2019-10-25  8:24   ` Michal Simek
  1 sibling, 0 replies; 31+ messages in thread
From: kbuild test robot @ 2019-10-25  2:17 UTC (permalink / raw)
  To: Mike Rapoport
  Cc: kbuild-all, linux-mm, Andrew Morton, Anton Ivanov, Arnd Bergmann,
	David S. Miller, Geert Uytterhoeven, Greentime Hu, Greg Ungerer,
	Helge Deller, James E.J. Bottomley, Jeff Dike,
	Kirill A. Shutemov, Linus Torvalds, Mark Salter, Matt Turner,
	Michal Simek, Richard Weinberger, Russell King, Sam Creasey,
	Vincent Chen, Vineet Gupta, Mike Rapoport, linux-alpha,
	linux-arch, linux-arm-kernel, linux-c6x-dev, linux-kernel,
	linux-m68k, linux-parisc, linux-um, sparclinux, Mike Rapoport

[-- Attachment #1: Type: text/plain, Size: 6108 bytes --]

Hi Mike,

I love your patch! Yet something to improve:

[auto build test ERROR on mmotm/master]

url:    https://github.com/0day-ci/linux/commits/Mike-Rapoport/mm-remove-__ARCH_HAS_4LEVEL_HACK/20191025-063009
base:   git://git.cmpxchg.org/linux-mmotm.git master
config: microblaze-mmu_defconfig (attached as .config)
compiler: microblaze-linux-gcc (GCC) 7.4.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.4.0 make.cross ARCH=microblaze 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

   In file included from include/linux/shm.h:6:0,
                    from include/linux/sched.h:16,
                    from arch/microblaze/mm/consistent.c:15:
   arch/microblaze/mm/consistent.c: In function 'consistent_virt_to_pte':
>> arch/microblaze/include/asm/pgtable.h:458:34: error: passing argument 1 of 'pmd_offset' from incompatible pointer type [-Werror=incompatible-pointer-types]
    #define pgd_offset(mm, address)  ((mm)->pgd + pgd_index(address))
                                     ^
   arch/microblaze/include/asm/page.h:105:30: note: in definition of macro 'pgd_val'
    #   define pgd_val(x)      ((x).pgd)
                                 ^
>> include/asm-generic/pgtable-nopud.h:50:24: note: in expansion of macro 'p4d_val'
    #define pud_val(x)    (p4d_val((x).p4d))
                           ^~~~~~~
>> include/asm-generic/pgtable-nopmd.h:49:24: note: in expansion of macro 'pud_val'
    #define pmd_val(x)    (pud_val((x).pud))
                           ^~~~~~~
>> arch/microblaze/include/asm/pgtable.h:448:48: note: in expansion of macro 'pmd_val'
    #define pmd_page_kernel(pmd) ((unsigned long) (pmd_val(pmd) & PAGE_MASK))
                                                   ^~~~~~~
>> arch/microblaze/include/asm/pgtable.h:464:13: note: in expansion of macro 'pmd_page_kernel'
     ((pte_t *) pmd_page_kernel(*(dir)) + pte_index(addr))
                ^~~~~~~~~~~~~~~
>> arch/microblaze/mm/consistent.c:162:9: note: in expansion of macro 'pte_offset_kernel'
     return pte_offset_kernel(pmd_offset(pgd_offset_k(addr), addr), addr);
            ^~~~~~~~~~~~~~~~~
>> arch/microblaze/include/asm/pgtable.h:454:31: note: in expansion of macro 'pgd_offset'
    #define pgd_offset_k(address) pgd_offset(&init_mm, address)
                                  ^~~~~~~~~~
>> arch/microblaze/mm/consistent.c:162:38: note: in expansion of macro 'pgd_offset_k'
     return pte_offset_kernel(pmd_offset(pgd_offset_k(addr), addr), addr);
                                         ^~~~~~~~~~~~
   In file included from arch/microblaze/include/asm/pgtable.h:62:0,
                    from include/linux/mm.h:99,
                    from arch/microblaze/include/asm/uaccess.h:15,
                    from include/linux/uaccess.h:11,
                    from include/linux/sched/task.h:11,
                    from include/linux/sched/signal.h:9,
                    from include/linux/ptrace.h:7,
                    from arch/microblaze/mm/consistent.c:20:
   include/asm-generic/pgtable-nopmd.h:44:23: note: expected 'pud_t * {aka struct <anonymous> *}' but argument is of type 'pgd_t * {aka struct <anonymous> *}'
    static inline pmd_t * pmd_offset(pud_t * pud, unsigned long address)
                          ^~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/pmd_offset +458 arch/microblaze/include/asm/pgtable.h

15902bf63c8332 Michal Simek   2009-05-26  444  
15902bf63c8332 Michal Simek   2009-05-26  445  /* Convert pmd entry to page */
15902bf63c8332 Michal Simek   2009-05-26  446  /* our pmd entry is an effective address of pte table*/
15902bf63c8332 Michal Simek   2009-05-26  447  /* returns effective address of the pmd entry*/
15902bf63c8332 Michal Simek   2009-05-26 @448  #define pmd_page_kernel(pmd)	((unsigned long) (pmd_val(pmd) & PAGE_MASK))
15902bf63c8332 Michal Simek   2009-05-26  449  
15902bf63c8332 Michal Simek   2009-05-26  450  /* returns struct *page of the pmd entry*/
15902bf63c8332 Michal Simek   2009-05-26  451  #define pmd_page(pmd)	(pfn_to_page(__pa(pmd_val(pmd)) >> PAGE_SHIFT))
15902bf63c8332 Michal Simek   2009-05-26  452  
15902bf63c8332 Michal Simek   2009-05-26  453  /* to find an entry in a kernel page-table-directory */
15902bf63c8332 Michal Simek   2009-05-26 @454  #define pgd_offset_k(address) pgd_offset(&init_mm, address)
15902bf63c8332 Michal Simek   2009-05-26  455  
15902bf63c8332 Michal Simek   2009-05-26  456  /* to find an entry in a page-table-directory */
15902bf63c8332 Michal Simek   2009-05-26  457  #define pgd_index(address)	 ((address) >> PGDIR_SHIFT)
15902bf63c8332 Michal Simek   2009-05-26 @458  #define pgd_offset(mm, address)	 ((mm)->pgd + pgd_index(address))
15902bf63c8332 Michal Simek   2009-05-26  459  
15902bf63c8332 Michal Simek   2009-05-26  460  /* Find an entry in the third-level page table.. */
15902bf63c8332 Michal Simek   2009-05-26  461  #define pte_index(address)		\
15902bf63c8332 Michal Simek   2009-05-26  462  	(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
15902bf63c8332 Michal Simek   2009-05-26  463  #define pte_offset_kernel(dir, addr)	\
15902bf63c8332 Michal Simek   2009-05-26 @464  	((pte_t *) pmd_page_kernel(*(dir)) + pte_index(addr))
15902bf63c8332 Michal Simek   2009-05-26  465  #define pte_offset_map(dir, addr)		\
ece0e2b6406a99 Peter Zijlstra 2010-10-26  466  	((pte_t *) kmap_atomic(pmd_page(*(dir))) + pte_index(addr))
15902bf63c8332 Michal Simek   2009-05-26  467  

:::::: The code at line 458 was first introduced by commit
:::::: 15902bf63c8332946e5a1f48a72e3ae22874b11b microblaze_mmu_v2: Page table - ioremap - pgtable.c/h, section update

:::::: TO: Michal Simek <monstr@monstr.eu>
:::::: CC: Michal Simek <monstr@monstr.eu>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 14079 bytes --]

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 05/12] m68k: mm: use pgtable-nopXd instead of 4level-fixup
  2019-10-23  9:28 ` [PATCH 05/12] m68k: mm: use pgtable-nopXd " Mike Rapoport
  2019-10-24  4:12   ` Greg Ungerer
@ 2019-10-25  5:52   ` kbuild test robot
  1 sibling, 0 replies; 31+ messages in thread
From: kbuild test robot @ 2019-10-25  5:52 UTC (permalink / raw)
  To: Mike Rapoport
  Cc: kbuild-all, linux-mm, Andrew Morton, Anton Ivanov, Arnd Bergmann,
	David S. Miller, Geert Uytterhoeven, Greentime Hu, Greg Ungerer,
	Helge Deller, James E.J. Bottomley, Jeff Dike,
	Kirill A. Shutemov, Linus Torvalds, Mark Salter, Matt Turner,
	Michal Simek, Richard Weinberger, Russell King, Sam Creasey,
	Vincent Chen, Vineet Gupta, Mike Rapoport, linux-alpha,
	linux-arch, linux-arm-kernel, linux-c6x-dev, linux-kernel,
	linux-m68k, linux-parisc, linux-um, sparclinux, Mike Rapoport

[-- Attachment #1: Type: text/plain, Size: 6521 bytes --]

Hi Mike,

I love your patch! Yet something to improve:

[auto build test ERROR on mmotm/master]

url:    https://github.com/0day-ci/linux/commits/Mike-Rapoport/mm-remove-__ARCH_HAS_4LEVEL_HACK/20191025-063009
base:   git://git.cmpxchg.org/linux-mmotm.git master
config: m68k-multi_defconfig (attached as .config)
compiler: m68k-linux-gcc (GCC) 7.4.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.4.0 make.cross ARCH=m68k 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   arch/m68k/sun3x/dvma.c: In function 'dvma_map_cpu':
>> arch/m68k/sun3x/dvma.c:98:33: error: passing argument 2 of 'pmd_alloc' from incompatible pointer type [-Werror=incompatible-pointer-types]
      if((pmd = pmd_alloc(&init_mm, pgd, vaddr)) == NULL) {
                                    ^~~
   In file included from arch/m68k/sun3x/dvma.c:17:0:
   include/linux/mm.h:1917:22: note: expected 'pud_t * {aka struct <anonymous> *}' but argument is of type 'pgd_t * {aka struct <anonymous> *}'
    static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
                         ^~~~~~~~~
   cc1: some warnings being treated as errors

vim +/pmd_alloc +98 arch/m68k/sun3x/dvma.c

^1da177e4c3f41 Linus Torvalds     2005-04-16   75  
^1da177e4c3f41 Linus Torvalds     2005-04-16   76  
^1da177e4c3f41 Linus Torvalds     2005-04-16   77  /* create a virtual mapping for a page assigned within the IOMMU
^1da177e4c3f41 Linus Torvalds     2005-04-16   78     so that the cpu can reach it easily */
^1da177e4c3f41 Linus Torvalds     2005-04-16   79  inline int dvma_map_cpu(unsigned long kaddr,
^1da177e4c3f41 Linus Torvalds     2005-04-16   80  			       unsigned long vaddr, int len)
^1da177e4c3f41 Linus Torvalds     2005-04-16   81  {
^1da177e4c3f41 Linus Torvalds     2005-04-16   82  	pgd_t *pgd;
^1da177e4c3f41 Linus Torvalds     2005-04-16   83  	unsigned long end;
^1da177e4c3f41 Linus Torvalds     2005-04-16   84  	int ret = 0;
^1da177e4c3f41 Linus Torvalds     2005-04-16   85  
^1da177e4c3f41 Linus Torvalds     2005-04-16   86  	kaddr &= PAGE_MASK;
^1da177e4c3f41 Linus Torvalds     2005-04-16   87  	vaddr &= PAGE_MASK;
^1da177e4c3f41 Linus Torvalds     2005-04-16   88  
^1da177e4c3f41 Linus Torvalds     2005-04-16   89  	end = PAGE_ALIGN(vaddr + len);
^1da177e4c3f41 Linus Torvalds     2005-04-16   90  
4eee1e72ad06bd Geert Uytterhoeven 2016-12-06   91  	pr_debug("dvma: mapping kern %08lx to virt %08lx\n", kaddr, vaddr);
^1da177e4c3f41 Linus Torvalds     2005-04-16   92  	pgd = pgd_offset_k(vaddr);
^1da177e4c3f41 Linus Torvalds     2005-04-16   93  
^1da177e4c3f41 Linus Torvalds     2005-04-16   94  	do {
^1da177e4c3f41 Linus Torvalds     2005-04-16   95  		pmd_t *pmd;
^1da177e4c3f41 Linus Torvalds     2005-04-16   96  		unsigned long end2;
^1da177e4c3f41 Linus Torvalds     2005-04-16   97  
^1da177e4c3f41 Linus Torvalds     2005-04-16  @98  		if((pmd = pmd_alloc(&init_mm, pgd, vaddr)) == NULL) {
^1da177e4c3f41 Linus Torvalds     2005-04-16   99  			ret = -ENOMEM;
^1da177e4c3f41 Linus Torvalds     2005-04-16  100  			goto out;
^1da177e4c3f41 Linus Torvalds     2005-04-16  101  		}
^1da177e4c3f41 Linus Torvalds     2005-04-16  102  
^1da177e4c3f41 Linus Torvalds     2005-04-16  103  		if((end & PGDIR_MASK) > (vaddr & PGDIR_MASK))
^1da177e4c3f41 Linus Torvalds     2005-04-16  104  			end2 = (vaddr + (PGDIR_SIZE-1)) & PGDIR_MASK;
^1da177e4c3f41 Linus Torvalds     2005-04-16  105  		else
^1da177e4c3f41 Linus Torvalds     2005-04-16  106  			end2 = end;
^1da177e4c3f41 Linus Torvalds     2005-04-16  107  
^1da177e4c3f41 Linus Torvalds     2005-04-16  108  		do {
^1da177e4c3f41 Linus Torvalds     2005-04-16  109  			pte_t *pte;
^1da177e4c3f41 Linus Torvalds     2005-04-16  110  			unsigned long end3;
^1da177e4c3f41 Linus Torvalds     2005-04-16  111  
872fec16d9a0ed Hugh Dickins       2005-10-29  112  			if((pte = pte_alloc_kernel(pmd, vaddr)) == NULL) {
^1da177e4c3f41 Linus Torvalds     2005-04-16  113  				ret = -ENOMEM;
^1da177e4c3f41 Linus Torvalds     2005-04-16  114  				goto out;
^1da177e4c3f41 Linus Torvalds     2005-04-16  115  			}
^1da177e4c3f41 Linus Torvalds     2005-04-16  116  
^1da177e4c3f41 Linus Torvalds     2005-04-16  117  			if((end2 & PMD_MASK) > (vaddr & PMD_MASK))
^1da177e4c3f41 Linus Torvalds     2005-04-16  118  				end3 = (vaddr + (PMD_SIZE-1)) & PMD_MASK;
^1da177e4c3f41 Linus Torvalds     2005-04-16  119  			else
^1da177e4c3f41 Linus Torvalds     2005-04-16  120  				end3 = end2;
^1da177e4c3f41 Linus Torvalds     2005-04-16  121  
^1da177e4c3f41 Linus Torvalds     2005-04-16  122  			do {
4eee1e72ad06bd Geert Uytterhoeven 2016-12-06  123  				pr_debug("mapping %08lx phys to %08lx\n",
^1da177e4c3f41 Linus Torvalds     2005-04-16  124  					 __pa(kaddr), vaddr);
^1da177e4c3f41 Linus Torvalds     2005-04-16  125  				set_pte(pte, pfn_pte(virt_to_pfn(kaddr),
^1da177e4c3f41 Linus Torvalds     2005-04-16  126  						     PAGE_KERNEL));
^1da177e4c3f41 Linus Torvalds     2005-04-16  127  				pte++;
^1da177e4c3f41 Linus Torvalds     2005-04-16  128  				kaddr += PAGE_SIZE;
^1da177e4c3f41 Linus Torvalds     2005-04-16  129  				vaddr += PAGE_SIZE;
^1da177e4c3f41 Linus Torvalds     2005-04-16  130  			} while(vaddr < end3);
^1da177e4c3f41 Linus Torvalds     2005-04-16  131  
^1da177e4c3f41 Linus Torvalds     2005-04-16  132  		} while(vaddr < end2);
^1da177e4c3f41 Linus Torvalds     2005-04-16  133  
^1da177e4c3f41 Linus Torvalds     2005-04-16  134  	} while(vaddr < end);
^1da177e4c3f41 Linus Torvalds     2005-04-16  135  
^1da177e4c3f41 Linus Torvalds     2005-04-16  136  	flush_tlb_all();
^1da177e4c3f41 Linus Torvalds     2005-04-16  137  
^1da177e4c3f41 Linus Torvalds     2005-04-16  138   out:
^1da177e4c3f41 Linus Torvalds     2005-04-16  139  	return ret;
^1da177e4c3f41 Linus Torvalds     2005-04-16  140  }
^1da177e4c3f41 Linus Torvalds     2005-04-16  141  

:::::: The code at line 98 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2

:::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org>
:::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 14949 bytes --]

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 06/12] microblaze: use pgtable-nopmd instead of 4level-fixup
  2019-10-23  9:28 ` [PATCH 06/12] microblaze: use pgtable-nopmd " Mike Rapoport
  2019-10-25  2:17   ` kbuild test robot
@ 2019-10-25  8:24   ` Michal Simek
  2019-10-25 20:33     ` Mike Rapoport
  1 sibling, 1 reply; 31+ messages in thread
From: Michal Simek @ 2019-10-25  8:24 UTC (permalink / raw)
  To: Mike Rapoport, linux-mm
  Cc: Andrew Morton, Anton Ivanov, Arnd Bergmann, David S. Miller,
	Geert Uytterhoeven, Greentime Hu, Greg Ungerer, Helge Deller,
	James E.J. Bottomley, Jeff Dike, Kirill A. Shutemov,
	Linus Torvalds, Mark Salter, Matt Turner, Richard Weinberger,
	Russell King, Sam Creasey, Vincent Chen, Vineet Gupta,
	linux-alpha, linux-arch, linux-arm-kernel, linux-c6x-dev,
	linux-kernel, linux-m68k, linux-parisc, linux-um, sparclinux,
	Mike Rapoport

Hi Mike,

On 23. 10. 19 11:28, Mike Rapoport wrote:
> From: Mike Rapoport <rppt@linux.ibm.com>
> 
> microblaze has only two-level page tables and can use pgtable-nopmd and
> folding of the upper layers.
> 
> Replace usage of include/asm-generic/4level-fixup.h and explicit definition
> of __PAGETABLE_PMD_FOLDED in microblaze with
> include/asm-generic/pgtable-nopmd.h and adjust page table manipulation
> macros and functions accordingly.
> 
> Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> ---
>  arch/microblaze/include/asm/page.h    |  3 ---
>  arch/microblaze/include/asm/pgalloc.h | 16 ----------------
>  arch/microblaze/include/asm/pgtable.h | 32 ++------------------------------
>  arch/microblaze/kernel/signal.c       | 10 +++++++---
>  arch/microblaze/mm/init.c             |  7 +++++--
>  arch/microblaze/mm/pgtable.c          | 13 +++++++++++--
>  6 files changed, 25 insertions(+), 56 deletions(-)

I have take a look at this and when this is applied on the top of
5.4-rc2 there is not a problem.
But as was reported by 0-day there is compilation issue on the top of
mmotm/master tree and I am able to replicate it.
It means there are other changes in Andrew's tree which are causing it.

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 06/12] microblaze: use pgtable-nopmd instead of 4level-fixup
  2019-10-25  8:24   ` Michal Simek
@ 2019-10-25 20:33     ` Mike Rapoport
  0 siblings, 0 replies; 31+ messages in thread
From: Mike Rapoport @ 2019-10-25 20:33 UTC (permalink / raw)
  To: Michal Simek
  Cc: linux-mm, Andrew Morton, Anton Ivanov, Arnd Bergmann,
	David S. Miller, Geert Uytterhoeven, Greentime Hu, Greg Ungerer,
	Helge Deller, James E.J. Bottomley, Jeff Dike,
	Kirill A. Shutemov, Linus Torvalds, Mark Salter, Matt Turner,
	Richard Weinberger, Russell King, Sam Creasey, Vincent Chen,
	Vineet Gupta, linux-alpha, linux-arch, linux-arm-kernel,
	linux-c6x-dev, linux-kernel, linux-m68k, linux-parisc, linux-um,
	sparclinux, Mike Rapoport

On Fri, Oct 25, 2019 at 10:24:30AM +0200, Michal Simek wrote:
> Hi Mike,
> 
> On 23. 10. 19 11:28, Mike Rapoport wrote:
> > From: Mike Rapoport <rppt@linux.ibm.com>
> > 
> > microblaze has only two-level page tables and can use pgtable-nopmd and
> > folding of the upper layers.
> > 
> > Replace usage of include/asm-generic/4level-fixup.h and explicit definition
> > of __PAGETABLE_PMD_FOLDED in microblaze with
> > include/asm-generic/pgtable-nopmd.h and adjust page table manipulation
> > macros and functions accordingly.
> > 
> > Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> > ---
> >  arch/microblaze/include/asm/page.h    |  3 ---
> >  arch/microblaze/include/asm/pgalloc.h | 16 ----------------
> >  arch/microblaze/include/asm/pgtable.h | 32 ++------------------------------
> >  arch/microblaze/kernel/signal.c       | 10 +++++++---
> >  arch/microblaze/mm/init.c             |  7 +++++--
> >  arch/microblaze/mm/pgtable.c          | 13 +++++++++++--
> >  6 files changed, 25 insertions(+), 56 deletions(-)
> 
> I have take a look at this and when this is applied on the top of
> 5.4-rc2 there is not a problem.
> But as was reported by 0-day there is compilation issue on the top of
> mmotm/master tree and I am able to replicate it.
> It means there are other changes in Andrew's tree which are causing it.

0day is still using an old tree for mmotm:

> url:    https://github.com/0day-ci/linux/commits/Mike-Rapoport/mm-remove-__ARCH_HAS_4LEVEL_HACK/20191025-063009
> base:   git://git.cmpxchg.org/linux-mmotm.git master
> config: microblaze-mmu_defconfig (attached as .config)

A while ago Johannes moved the mmotm to github and the last commit in
git.cmpxchg.org/linux-mmotm.git was in the end of August.

[1] https://lore.kernel.org/linux-mm/20190916134327.GC29985@cmpxchg.org
 
> Thanks,
> Michal
> 
> -- 
> Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
> w: www.monstr.eu p: +42-0-721842854
> Maintainer of Linux kernel - Xilinx Microblaze
> Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
> U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs
> 

-- 
Sincerely yours,
Mike.

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, back to index

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-23  9:28 [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK Mike Rapoport
2019-10-23  9:28 ` [PATCH 01/12] alpha: use pgtable-nop4d instead of 4level-fixup Mike Rapoport
2019-10-23  9:28 ` [PATCH 02/12] arm: nommu: use pgtable-nopud " Mike Rapoport
2019-10-23  9:40   ` Russell King - ARM Linux admin
2019-10-23  9:28 ` [PATCH 03/12] c6x: " Mike Rapoport
2019-10-23  9:28 ` [PATCH 04/12] m68k: nommu: " Mike Rapoport
2019-10-24  4:09   ` Greg Ungerer
2019-10-24  5:35     ` Mike Rapoport
2019-10-24  6:23       ` Greg Ungerer
2019-10-23  9:28 ` [PATCH 05/12] m68k: mm: use pgtable-nopXd " Mike Rapoport
2019-10-24  4:12   ` Greg Ungerer
2019-10-25  5:52   ` kbuild test robot
2019-10-23  9:28 ` [PATCH 06/12] microblaze: use pgtable-nopmd " Mike Rapoport
2019-10-25  2:17   ` kbuild test robot
2019-10-25  8:24   ` Michal Simek
2019-10-25 20:33     ` Mike Rapoport
2019-10-23  9:28 ` [PATCH 07/12] nds32: " Mike Rapoport
2019-10-23  9:28 ` [PATCH 08/12] parisc: use pgtable-nopXd " Mike Rapoport
2019-10-23 10:20   ` Rolf Eike Beer
2019-10-24  8:51     ` Mike Rapoport
2019-10-24  9:35   ` Peter Rosin
2019-10-24  9:50     ` Mike Rapoport
2019-10-24 12:02   ` Helge Deller
2019-10-24 16:00     ` Mike Rapoport
2019-10-23  9:28 ` [PATCH 09/12] sparc32: use pgtable-nopud " Mike Rapoport
2019-10-23 19:59   ` [PATCH v2 " Mike Rapoport
2019-10-23 21:21     ` David Miller
2019-10-23  9:28 ` [PATCH 10/12] um: remove unused pxx_offset_proc() and addr_pte() functions Mike Rapoport
2019-10-23  9:29 ` [PATCH 11/12] um: add support for folded p4d page tables Mike Rapoport
2019-10-23  9:29 ` [PATCH 12/12] mm: remove __ARCH_HAS_4LEVEL_HACK and include/asm-generic/4level-fixup.h Mike Rapoport
2019-10-23 10:25 ` [PATCH 00/12] mm: remove __ARCH_HAS_4LEVEL_HACK Linus Torvalds

Linux-parisc archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-parisc/0 linux-parisc/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-parisc linux-parisc/ https://lore.kernel.org/linux-parisc \
		linux-parisc@vger.kernel.org
	public-inbox-index linux-parisc

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-parisc


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git