linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc
@ 2021-08-12 23:37 Vineet Gupta
  2021-08-12 23:37 ` [PATCH v2 01/19] ARC: mm: use SCRATCH_DATA0 register for caching pgdir in ARCv2 only Vineet Gupta
                   ` (19 more replies)
  0 siblings, 20 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

Hi,

Big pile of ARC mm changes to prepare for 3 or 4 levels of paging (from
current 2) needed for new hardware page walked MMUv6 (in aRCv3 ISA based
cores).

Most of these changes are incremental cleanups to make way for 14/18 and
15/18 which actually imeplement the new levels (in existing ARCv2 port)
and worth a critical eye.

CC'ing some of you guys dealing with page tables for a while :-)
to spot any obvious gotchas.

Thx,
-Vineet

Changes since v1 [1]
 - Switched ARC to asm-generic/pgalloc.h  (so struct page based pgtable_t)      [Mike Rapoport]
 - Dropped {pud,pmd}_alloc_one/{pud,pmd}_free provided by asm-generic/pgalloc.h [Mike Rapoport]
 - Negative diffstat now due to above
 - Added BUILD_BUG_ON() to arch/arc/mm/init.c for sanity of table sizes
 - Consolidated 2 patches related to ARC_USE_SCRATCH_REG			   [Mike Rapoport]
 - Reworked how mmu is re-enabled in entry code                                 [Jose Abreu]

[1] http://lists.infradead.org/pipermail/linux-snps-arc/2021-August/005326.html

Vineet Gupta (19):
  ARC: mm: use SCRATCH_DATA0 register for caching pgdir in ARCv2 only
  ARC: mm: remove tlb paranoid code
  ARC: mm: move mmu/cache externs out to setup.h
  ARC: mm: Fixes to allow STRICT_MM_TYPECHECKS
  ARC: mm: Enable STRICT_MM_TYPECHECKS
  ARC: ioremap: use more commonly used PAGE_KERNEL based uncached flag
  ARC: mm: pmd_populate* to use the canonical set_pmd (and drop pmd_set)
  ARC: mm: switch pgtable_t back to struct page *
  ARC: mm: switch to asm-generic/pgalloc.h
  ARC: mm: non-functional code cleanup ahead of 3 levels
  ARC: mm: move MMU specific bits out of ASID allocator
  ARC: mm: move MMU specific bits out of entry code ...
  ARC: mm: disintegrate mmu.h (arcv2 bits out)
  ARC: mm: disintegrate pgtable.h into levels and flags
  ARC: mm: hack to allow 2 level build with 4 level code
  ARC: mm: support 3 levels of page tables
  ARC: mm: support 4 levels of page tables
  ARC: mm: vmalloc sync from kernel to user table to update PMD ...
  ARC: mm: introduce _PAGE_TABLE to explicitly link pgd,pud,pmd entries

 arch/arc/Kconfig                          |   7 +-
 arch/arc/include/asm/cache.h              |   4 -
 arch/arc/include/asm/entry-compact.h      |   8 -
 arch/arc/include/asm/mmu-arcv2.h          | 103 +++++++
 arch/arc/include/asm/mmu.h                |  73 +----
 arch/arc/include/asm/mmu_context.h        |  28 +-
 arch/arc/include/asm/page.h               |  74 +++--
 arch/arc/include/asm/pgalloc.h            |  81 ++----
 arch/arc/include/asm/pgtable-bits-arcv2.h | 151 +++++++++++
 arch/arc/include/asm/pgtable-levels.h     | 179 ++++++++++++
 arch/arc/include/asm/pgtable.h            | 315 +---------------------
 arch/arc/include/asm/processor.h          |   2 +-
 arch/arc/include/asm/setup.h              |  12 +-
 arch/arc/kernel/entry-arcv2.S             |   1 +
 arch/arc/kernel/entry.S                   |   7 +-
 arch/arc/mm/fault.c                       |  20 +-
 arch/arc/mm/init.c                        |   5 +
 arch/arc/mm/ioremap.c                     |   3 +-
 arch/arc/mm/tlb.c                         |  68 +----
 arch/arc/mm/tlbex.S                       |  78 ++----
 20 files changed, 591 insertions(+), 628 deletions(-)
 create mode 100644 arch/arc/include/asm/mmu-arcv2.h
 create mode 100644 arch/arc/include/asm/pgtable-bits-arcv2.h
 create mode 100644 arch/arc/include/asm/pgtable-levels.h

-- 
2.25.1


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

* [PATCH v2 01/19] ARC: mm: use SCRATCH_DATA0 register for caching pgdir in ARCv2 only
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-15  9:27   ` Mike Rapoport
  2021-08-12 23:37 ` [PATCH v2 02/19] ARC: mm: remove tlb paranoid code Vineet Gupta
                   ` (18 subsequent siblings)
  19 siblings, 1 reply; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

MMU SCRATCH_DATA0 register is intended to cache task pgd. However in
ARC700 SMP port, it has to be repurposed for reentrant interrupt
handling, while UP port doesn't. We  currently ahandle boe usecases
using a fabricated which has usual issues of dependency nesting and
ugliness.

So clean this up: for ARC700 don't use to cache pgd (even in UP) and do
the opposite for ARCv2.

And while here, switch to canonical pgd_offset().

Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/include/asm/entry-compact.h |  8 --------
 arch/arc/include/asm/mmu.h           |  4 ----
 arch/arc/include/asm/mmu_context.h   |  2 +-
 arch/arc/include/asm/pgtable.h       | 23 -----------------------
 arch/arc/mm/fault.c                  |  2 +-
 arch/arc/mm/tlb.c                    |  4 ++--
 arch/arc/mm/tlbex.S                  |  2 +-
 7 files changed, 5 insertions(+), 40 deletions(-)

diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h
index 6dbf5cecc8cc..5aab4f93ab8a 100644
--- a/arch/arc/include/asm/entry-compact.h
+++ b/arch/arc/include/asm/entry-compact.h
@@ -126,19 +126,11 @@
  * to be saved again on kernel mode stack, as part of pt_regs.
  *-------------------------------------------------------------*/
 .macro PROLOG_FREEUP_REG	reg, mem
-#ifndef ARC_USE_SCRATCH_REG
-	sr  \reg, [ARC_REG_SCRATCH_DATA0]
-#else
 	st  \reg, [\mem]
-#endif
 .endm
 
 .macro PROLOG_RESTORE_REG	reg, mem
-#ifndef ARC_USE_SCRATCH_REG
-	lr  \reg, [ARC_REG_SCRATCH_DATA0]
-#else
 	ld  \reg, [\mem]
-#endif
 .endm
 
 /*--------------------------------------------------------------
diff --git a/arch/arc/include/asm/mmu.h b/arch/arc/include/asm/mmu.h
index a81d1975866a..4065335a7922 100644
--- a/arch/arc/include/asm/mmu.h
+++ b/arch/arc/include/asm/mmu.h
@@ -31,10 +31,6 @@
 #define ARC_REG_SCRATCH_DATA0	0x46c
 #endif
 
-#if defined(CONFIG_ISA_ARCV2) || !defined(CONFIG_SMP)
-#define	ARC_USE_SCRATCH_REG
-#endif
-
 /* Bits in MMU PID register */
 #define __TLB_ENABLE		(1 << 31)
 #define __PROG_ENABLE		(1 << 30)
diff --git a/arch/arc/include/asm/mmu_context.h b/arch/arc/include/asm/mmu_context.h
index df164066e172..49318a126879 100644
--- a/arch/arc/include/asm/mmu_context.h
+++ b/arch/arc/include/asm/mmu_context.h
@@ -146,7 +146,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
 	 */
 	cpumask_set_cpu(cpu, mm_cpumask(next));
 
-#ifdef ARC_USE_SCRATCH_REG
+#ifdef CONFIG_ISA_ARCV2
 	/* PGD cached in MMU reg to avoid 3 mem lookups: task->mm->pgd */
 	write_aux_reg(ARC_REG_SCRATCH_DATA0, next->pgd);
 #endif
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index 0c3e220bd2b4..80b57c14b430 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -284,29 +284,6 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
 	set_pte(ptep, pteval);
 }
 
-/*
- * Macro to quickly access the PGD entry, utlising the fact that some
- * arch may cache the pointer to Page Directory of "current" task
- * in a MMU register
- *
- * Thus task->mm->pgd (3 pointer dereferences, cache misses etc simply
- * becomes read a register
- *
- * ********CAUTION*******:
- * Kernel code might be dealing with some mm_struct of NON "current"
- * Thus use this macro only when you are certain that "current" is current
- * e.g. when dealing with signal frame setup code etc
- */
-#ifdef ARC_USE_SCRATCH_REG
-#define pgd_offset_fast(mm, addr)	\
-({					\
-	pgd_t *pgd_base = (pgd_t *) read_aux_reg(ARC_REG_SCRATCH_DATA0);  \
-	pgd_base + pgd_index(addr);	\
-})
-#else
-#define pgd_offset_fast(mm, addr)	pgd_offset(mm, addr)
-#endif
-
 extern pgd_t swapper_pg_dir[] __aligned(PAGE_SIZE);
 void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
 		      pte_t *ptep);
diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c
index f5657cb68e4f..41f154320964 100644
--- a/arch/arc/mm/fault.c
+++ b/arch/arc/mm/fault.c
@@ -33,7 +33,7 @@ noinline static int handle_kernel_vaddr_fault(unsigned long address)
 	pud_t *pud, *pud_k;
 	pmd_t *pmd, *pmd_k;
 
-	pgd = pgd_offset_fast(current->active_mm, address);
+	pgd = pgd_offset(current->active_mm, address);
 	pgd_k = pgd_offset_k(address);
 
 	if (!pgd_present(*pgd_k))
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 8696829d37c0..349fb7a75d1d 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -719,8 +719,8 @@ void arc_mmu_init(void)
 	/* Enable the MMU */
 	write_aux_reg(ARC_REG_PID, MMU_ENABLE);
 
-	/* In smp we use this reg for interrupt 1 scratch */
-#ifdef ARC_USE_SCRATCH_REG
+	/* In arc700/smp needed for re-entrant interrupt handling */
+#ifdef CONFIG_ISA_ARCV2
 	/* swapper_pg_dir is the pgd for the kernel, used by vmalloc */
 	write_aux_reg(ARC_REG_SCRATCH_DATA0, swapper_pg_dir);
 #endif
diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S
index 96c3a5de9dd4..bcd2909c691f 100644
--- a/arch/arc/mm/tlbex.S
+++ b/arch/arc/mm/tlbex.S
@@ -202,7 +202,7 @@ ex_saved_reg1:
 
 	lr  r2, [efa]
 
-#ifdef ARC_USE_SCRATCH_REG
+#ifdef CONFIG_ISA_ARCV2
 	lr  r1, [ARC_REG_SCRATCH_DATA0] ; current pgd
 #else
 	GET_CURR_TASK_ON_CPU  r1
-- 
2.25.1


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

* [PATCH v2 02/19] ARC: mm: remove tlb paranoid code
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
  2021-08-12 23:37 ` [PATCH v2 01/19] ARC: mm: use SCRATCH_DATA0 register for caching pgdir in ARCv2 only Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-12 23:37 ` [PATCH v2 03/19] ARC: mm: move mmu/cache externs out to setup.h Vineet Gupta
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

This was used back in arc700 days when ASID allocator was fragile.
Not needed in last 5 years

Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/Kconfig           |  3 ---
 arch/arc/include/asm/mmu.h |  6 -----
 arch/arc/mm/tlb.c          | 40 ------------------------------
 arch/arc/mm/tlbex.S        | 50 --------------------------------------
 4 files changed, 99 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 0680b1de0fc3..59d5b2a179f6 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -537,9 +537,6 @@ config ARC_DW2_UNWIND
 	  If you don't debug the kernel, you can say N, but we may not be able
 	  to solve problems without frame unwind information
 
-config ARC_DBG_TLB_PARANOIA
-	bool "Paranoia Checks in Low Level TLB Handlers"
-
 config ARC_DBG_JUMP_LABEL
 	bool "Paranoid checks in Static Keys (jump labels) code"
 	depends on JUMP_LABEL
diff --git a/arch/arc/include/asm/mmu.h b/arch/arc/include/asm/mmu.h
index 4065335a7922..38a036508699 100644
--- a/arch/arc/include/asm/mmu.h
+++ b/arch/arc/include/asm/mmu.h
@@ -64,12 +64,6 @@ typedef struct {
 	unsigned long asid[NR_CPUS];	/* 8 bit MMU PID + Generation cycle */
 } mm_context_t;
 
-#ifdef CONFIG_ARC_DBG_TLB_PARANOIA
-void tlb_paranoid_check(unsigned int mm_asid, unsigned long address);
-#else
-#define tlb_paranoid_check(a, b)
-#endif
-
 void arc_mmu_init(void);
 extern char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len);
 void read_decode_mmu_bcr(void);
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 349fb7a75d1d..6079dfd129b9 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -400,7 +400,6 @@ void create_tlb(struct vm_area_struct *vma, unsigned long vaddr, pte_t *ptep)
 	 *
 	 * Removing the assumption involves
 	 * -Using vma->mm->context{ASID,SASID}, as opposed to MMU reg.
-	 * -Fix the TLB paranoid debug code to not trigger false negatives.
 	 * -More importantly it makes this handler inconsistent with fast-path
 	 *  TLB Refill handler which always deals with "current"
 	 *
@@ -423,8 +422,6 @@ void create_tlb(struct vm_area_struct *vma, unsigned long vaddr, pte_t *ptep)
 
 	local_irq_save(flags);
 
-	tlb_paranoid_check(asid_mm(vma->vm_mm, smp_processor_id()), vaddr);
-
 	vaddr &= PAGE_MASK;
 
 	/* update this PTE credentials */
@@ -818,40 +815,3 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address,
 
 	local_irq_restore(flags);
 }
-
-/***********************************************************************
- * Diagnostic Routines
- *  -Called from Low Level TLB Handlers if things don;t look good
- **********************************************************************/
-
-#ifdef CONFIG_ARC_DBG_TLB_PARANOIA
-
-/*
- * Low Level ASM TLB handler calls this if it finds that HW and SW ASIDS
- * don't match
- */
-void print_asid_mismatch(int mm_asid, int mmu_asid, int is_fast_path)
-{
-	pr_emerg("ASID Mismatch in %s Path Handler: sw-pid=0x%x hw-pid=0x%x\n",
-	       is_fast_path ? "Fast" : "Slow", mm_asid, mmu_asid);
-
-	__asm__ __volatile__("flag 1");
-}
-
-void tlb_paranoid_check(unsigned int mm_asid, unsigned long addr)
-{
-	unsigned int mmu_asid;
-
-	mmu_asid = read_aux_reg(ARC_REG_PID) & 0xff;
-
-	/*
-	 * At the time of a TLB miss/installation
-	 *   - HW version needs to match SW version
-	 *   - SW needs to have a valid ASID
-	 */
-	if (addr < 0x70000000 &&
-	    ((mm_asid == MM_CTXT_NO_ASID) ||
-	      (mmu_asid != (mm_asid & MM_CTXT_ASID_MASK))))
-		print_asid_mismatch(mm_asid, mmu_asid, 0);
-}
-#endif
diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S
index bcd2909c691f..0b4bb62fa0ab 100644
--- a/arch/arc/mm/tlbex.S
+++ b/arch/arc/mm/tlbex.S
@@ -93,11 +93,6 @@ ex_saved_reg1:
 	st_s  r1, [r0, 4]
 	st_s  r2, [r0, 8]
 	st_s  r3, [r0, 12]
-
-	; VERIFY if the ASID in MMU-PID Reg is same as
-	; one in Linux data structures
-
-	tlb_paranoid_check_asm
 .endm
 
 .macro TLBMISS_RESTORE_REGS
@@ -146,51 +141,6 @@ ex_saved_reg1:
 
 #endif
 
-;============================================================================
-;  Troubleshooting Stuff
-;============================================================================
-
-; Linux keeps ASID (Address Space ID) in task->active_mm->context.asid
-; When Creating TLB Entries, instead of doing 3 dependent loads from memory,
-; we use the MMU PID Reg to get current ASID.
-; In bizzare scenrios SW and HW ASID can get out-of-sync which is trouble.
-; So we try to detect this in TLB Mis shandler
-
-.macro tlb_paranoid_check_asm
-
-#ifdef CONFIG_ARC_DBG_TLB_PARANOIA
-
-	GET_CURR_TASK_ON_CPU  r3
-	ld r0, [r3, TASK_ACT_MM]
-	ld r0, [r0, MM_CTXT+MM_CTXT_ASID]
-	breq r0, 0, 55f	; Error if no ASID allocated
-
-	lr r1, [ARC_REG_PID]
-	and r1, r1, 0xFF
-
-	and r2, r0, 0xFF	; MMU PID bits only for comparison
-	breq r1, r2, 5f
-
-55:
-	; Error if H/w and S/w ASID don't match, but NOT if in kernel mode
-	lr  r2, [erstatus]
-	bbit0 r2, STATUS_U_BIT, 5f
-
-	; We sure are in troubled waters, Flag the error, but to do so
-	; need to switch to kernel mode stack to call error routine
-	GET_TSK_STACK_BASE   r3, sp
-
-	; Call printk to shoutout aloud
-	mov r2, 1
-	j print_asid_mismatch
-
-5:	; ASIDs match so proceed normally
-	nop
-
-#endif
-
-.endm
-
 ;============================================================================
 ;TLB Miss handling Code
 ;============================================================================
-- 
2.25.1


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

* [PATCH v2 03/19] ARC: mm: move mmu/cache externs out to setup.h
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
  2021-08-12 23:37 ` [PATCH v2 01/19] ARC: mm: use SCRATCH_DATA0 register for caching pgdir in ARCv2 only Vineet Gupta
  2021-08-12 23:37 ` [PATCH v2 02/19] ARC: mm: remove tlb paranoid code Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-15  9:27   ` Mike Rapoport
  2021-08-12 23:37 ` [PATCH v2 04/19] ARC: mm: Fixes to allow STRICT_MM_TYPECHECKS Vineet Gupta
                   ` (16 subsequent siblings)
  19 siblings, 1 reply; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/include/asm/cache.h |  4 ----
 arch/arc/include/asm/mmu.h   |  4 ----
 arch/arc/include/asm/setup.h | 12 ++++++++++--
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h
index d8ece4292388..f0f1fc5d62b6 100644
--- a/arch/arc/include/asm/cache.h
+++ b/arch/arc/include/asm/cache.h
@@ -62,10 +62,6 @@
 #define ARCH_SLAB_MINALIGN	8
 #endif
 
-extern void arc_cache_init(void);
-extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len);
-extern void read_decode_cache_bcr(void);
-
 extern int ioc_enable;
 extern unsigned long perip_base, perip_end;
 
diff --git a/arch/arc/include/asm/mmu.h b/arch/arc/include/asm/mmu.h
index 38a036508699..762cfe66e16b 100644
--- a/arch/arc/include/asm/mmu.h
+++ b/arch/arc/include/asm/mmu.h
@@ -64,10 +64,6 @@ typedef struct {
 	unsigned long asid[NR_CPUS];	/* 8 bit MMU PID + Generation cycle */
 } mm_context_t;
 
-void arc_mmu_init(void);
-extern char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len);
-void read_decode_mmu_bcr(void);
-
 static inline int is_pae40_enabled(void)
 {
 	return IS_ENABLED(CONFIG_ARC_HAS_PAE40);
diff --git a/arch/arc/include/asm/setup.h b/arch/arc/include/asm/setup.h
index 01f85478170d..028a8cf76206 100644
--- a/arch/arc/include/asm/setup.h
+++ b/arch/arc/include/asm/setup.h
@@ -2,8 +2,8 @@
 /*
  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
  */
-#ifndef __ASMARC_SETUP_H
-#define __ASMARC_SETUP_H
+#ifndef __ASM_ARC_SETUP_H
+#define __ASM_ARC_SETUP_H
 
 
 #include <linux/types.h>
@@ -34,4 +34,12 @@ long __init arc_get_mem_sz(void);
 #define IS_AVAIL2(v, s, cfg)	IS_AVAIL1(v, s), IS_AVAIL1(v, IS_USED_CFG(cfg))
 #define IS_AVAIL3(v, v2, s)	IS_AVAIL1(v, s), IS_AVAIL1(v, IS_DISABLED_RUN(v2))
 
+extern void arc_mmu_init(void);
+extern char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len);
+extern void read_decode_mmu_bcr(void);
+
+extern void arc_cache_init(void);
+extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len);
+extern void read_decode_cache_bcr(void);
+
 #endif /* __ASMARC_SETUP_H */
-- 
2.25.1


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

* [PATCH v2 04/19] ARC: mm: Fixes to allow STRICT_MM_TYPECHECKS
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
                   ` (2 preceding siblings ...)
  2021-08-12 23:37 ` [PATCH v2 03/19] ARC: mm: move mmu/cache externs out to setup.h Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-12 23:37 ` [PATCH v2 05/19] ARC: mm: Enable STRICT_MM_TYPECHECKS Vineet Gupta
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/mm/tlb.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 6079dfd129b9..15cbc285b0de 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -71,7 +71,7 @@ static void tlb_entry_erase(unsigned int vaddr_n_asid)
 	}
 }
 
-static void tlb_entry_insert(unsigned int pd0, pte_t pd1)
+static void tlb_entry_insert(unsigned int pd0, phys_addr_t pd1)
 {
 	unsigned int idx;
 
@@ -109,13 +109,16 @@ static void tlb_entry_erase(unsigned int vaddr_n_asid)
 	write_aux_reg(ARC_REG_TLBCOMMAND, TLBDeleteEntry);
 }
 
-static void tlb_entry_insert(unsigned int pd0, pte_t pd1)
+static void tlb_entry_insert(unsigned int pd0, phys_addr_t pd1)
 {
 	write_aux_reg(ARC_REG_TLBPD0, pd0);
-	write_aux_reg(ARC_REG_TLBPD1, pd1);
 
-	if (is_pae40_enabled())
+	if (!is_pae40_enabled()) {
+		write_aux_reg(ARC_REG_TLBPD1, pd1);
+	} else {
+		write_aux_reg(ARC_REG_TLBPD1, pd1 & 0xFFFFFFFF);
 		write_aux_reg(ARC_REG_TLBPD1HI, (u64)pd1 >> 32);
+	}
 
 	write_aux_reg(ARC_REG_TLBCOMMAND, TLBInsertEntry);
 }
@@ -391,7 +394,7 @@ void create_tlb(struct vm_area_struct *vma, unsigned long vaddr, pte_t *ptep)
 	unsigned long flags;
 	unsigned int asid_or_sasid, rwx;
 	unsigned long pd0;
-	pte_t pd1;
+	phys_addr_t pd1;
 
 	/*
 	 * create_tlb() assumes that current->mm == vma->mm, since
-- 
2.25.1


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

* [PATCH v2 05/19] ARC: mm: Enable STRICT_MM_TYPECHECKS
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
                   ` (3 preceding siblings ...)
  2021-08-12 23:37 ` [PATCH v2 04/19] ARC: mm: Fixes to allow STRICT_MM_TYPECHECKS Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-12 23:37 ` [PATCH v2 06/19] ARC: ioremap: use more commonly used PAGE_KERNEL based uncached flag Vineet Gupta
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

In the past I've refrained from doing this (at least 2 times) due to the
slight code bloat due to ABI implications of pte_t etc becoming struct

Per ARC ABI, functions return struct via memory and not through register
r0, even if the struct would fit in register(s)

 - caller allocates space on stack and passes the address as first arg
   (r0), shifting rest of args by one

 - callee creates return struct in memory (referenced via r0)

This time around the code actually shrunk slightly (due to subtle
inlining heuristic effects), but still slightly inefficient due to
return values passed through memory. That however seems like a small
cost compared to maintenance burden given the impending new mmu support
for page walk etc

Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/include/asm/page.h | 26 --------------------------
 arch/arc/mm/ioremap.c       |  2 +-
 2 files changed, 1 insertion(+), 27 deletions(-)

diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h
index 4a9d33372fe2..c4ac827379cd 100644
--- a/arch/arc/include/asm/page.h
+++ b/arch/arc/include/asm/page.h
@@ -34,12 +34,6 @@ void copy_user_highpage(struct page *to, struct page *from,
 			unsigned long u_vaddr, struct vm_area_struct *vma);
 void clear_user_page(void *to, unsigned long u_vaddr, struct page *page);
 
-#undef STRICT_MM_TYPECHECKS
-
-#ifdef STRICT_MM_TYPECHECKS
-/*
- * These are used to make use of C type-checking..
- */
 typedef struct {
 #ifdef CONFIG_ARC_HAS_PAE40
 	unsigned long long pte;
@@ -64,26 +58,6 @@ typedef struct {
 
 #define pte_pgprot(x) __pgprot(pte_val(x))
 
-#else /* !STRICT_MM_TYPECHECKS */
-
-#ifdef CONFIG_ARC_HAS_PAE40
-typedef unsigned long long pte_t;
-#else
-typedef unsigned long pte_t;
-#endif
-typedef unsigned long pgd_t;
-typedef unsigned long pgprot_t;
-
-#define pte_val(x)	(x)
-#define pgd_val(x)	(x)
-#define pgprot_val(x)	(x)
-#define __pte(x)	(x)
-#define __pgd(x)	(x)
-#define __pgprot(x)	(x)
-#define pte_pgprot(x)	(x)
-
-#endif
-
 typedef pte_t * pgtable_t;
 
 /*
diff --git a/arch/arc/mm/ioremap.c b/arch/arc/mm/ioremap.c
index 95c649fbc95a..052bbd8b1e5f 100644
--- a/arch/arc/mm/ioremap.c
+++ b/arch/arc/mm/ioremap.c
@@ -39,7 +39,7 @@ void __iomem *ioremap(phys_addr_t paddr, unsigned long size)
 	if (arc_uncached_addr_space(paddr))
 		return (void __iomem *)(u32)paddr;
 
-	return ioremap_prot(paddr, size, PAGE_KERNEL_NO_CACHE);
+	return ioremap_prot(paddr, size, pgprot_val(PAGE_KERNEL_NO_CACHE));
 }
 EXPORT_SYMBOL(ioremap);
 
-- 
2.25.1


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

* [PATCH v2 06/19] ARC: ioremap: use more commonly used PAGE_KERNEL based uncached flag
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
                   ` (4 preceding siblings ...)
  2021-08-12 23:37 ` [PATCH v2 05/19] ARC: mm: Enable STRICT_MM_TYPECHECKS Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-12 23:37 ` [PATCH v2 07/19] ARC: mm: pmd_populate* to use the canonical set_pmd (and drop pmd_set) Vineet Gupta
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

and remove the one off uncached definition for ARC

Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/include/asm/pgtable.h | 3 ---
 arch/arc/mm/ioremap.c          | 3 ++-
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index 80b57c14b430..b054c14f8bf6 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -103,9 +103,6 @@
  */
 #define PAGE_KERNEL          __pgprot(_K_PAGE_PERMS | _PAGE_CACHEABLE)
 
-/* ioremap */
-#define PAGE_KERNEL_NO_CACHE __pgprot(_K_PAGE_PERMS)
-
 /* Masks for actual TLB "PD"s */
 #define PTE_BITS_IN_PD0		(_PAGE_GLOBAL | _PAGE_PRESENT | _PAGE_HW_SZ)
 #define PTE_BITS_RWX		(_PAGE_EXECUTE | _PAGE_WRITE | _PAGE_READ)
diff --git a/arch/arc/mm/ioremap.c b/arch/arc/mm/ioremap.c
index 052bbd8b1e5f..0ee75aca6e10 100644
--- a/arch/arc/mm/ioremap.c
+++ b/arch/arc/mm/ioremap.c
@@ -39,7 +39,8 @@ void __iomem *ioremap(phys_addr_t paddr, unsigned long size)
 	if (arc_uncached_addr_space(paddr))
 		return (void __iomem *)(u32)paddr;
 
-	return ioremap_prot(paddr, size, pgprot_val(PAGE_KERNEL_NO_CACHE));
+	return ioremap_prot(paddr, size,
+			    pgprot_val(pgprot_noncached(PAGE_KERNEL)));
 }
 EXPORT_SYMBOL(ioremap);
 
-- 
2.25.1


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

* [PATCH v2 07/19] ARC: mm: pmd_populate* to use the canonical set_pmd (and drop pmd_set)
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
                   ` (5 preceding siblings ...)
  2021-08-12 23:37 ` [PATCH v2 06/19] ARC: ioremap: use more commonly used PAGE_KERNEL based uncached flag Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-12 23:37 ` [PATCH v2 08/19] ARC: mm: switch pgtable_t back to struct page * Vineet Gupta
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/include/asm/pgalloc.h | 14 ++++++++++----
 arch/arc/include/asm/pgtable.h |  6 ------
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/arc/include/asm/pgalloc.h b/arch/arc/include/asm/pgalloc.h
index a32ca3104ced..408bc4b0842d 100644
--- a/arch/arc/include/asm/pgalloc.h
+++ b/arch/arc/include/asm/pgalloc.h
@@ -35,13 +35,19 @@
 static inline void
 pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
 {
-	pmd_set(pmd, pte);
+	/*
+	 * The cast to long below is OK in 32-bit PAE40 regime with long long pte
+	 * Despite "wider" pte, the pte table needs to be in non-PAE low memory
+	 * as all higher levels can only hold long pointers.
+	 *
+	 * The cast itself is needed given simplistic definition of set_pmd()
+	 */
+	set_pmd(pmd, __pmd((unsigned long)pte));
 }
 
-static inline void
-pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t ptep)
+static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t pte)
 {
-	pmd_set(pmd, (pte_t *) ptep);
+	set_pmd(pmd, __pmd((unsigned long)pte));
 }
 
 static inline int __get_order_pgd(void)
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index b054c14f8bf6..f762bacb2358 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -222,12 +222,6 @@ extern char empty_zero_page[PAGE_SIZE];
 /* find the logical addr (phy for ARC) of the Page Tbl ref by PMD entry */
 #define pmd_page_vaddr(pmd)	(pmd_val(pmd) & PAGE_MASK)
 
-/* In a 2 level sys, setup the PGD entry with PTE value */
-static inline void pmd_set(pmd_t *pmdp, pte_t *ptep)
-{
-	pmd_val(*pmdp) = (unsigned long)ptep;
-}
-
 #define pte_none(x)			(!pte_val(x))
 #define pte_present(x)			(pte_val(x) & _PAGE_PRESENT)
 #define pte_clear(mm, addr, ptep)	set_pte_at(mm, addr, ptep, __pte(0))
-- 
2.25.1


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

* [PATCH v2 08/19] ARC: mm: switch pgtable_t back to struct page *
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
                   ` (6 preceding siblings ...)
  2021-08-12 23:37 ` [PATCH v2 07/19] ARC: mm: pmd_populate* to use the canonical set_pmd (and drop pmd_set) Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-13 10:45   ` kernel test robot
  2021-08-12 23:37 ` [PATCH v2 09/19] ARC: mm: switch to asm-generic/pgalloc.h Vineet Gupta
                   ` (11 subsequent siblings)
  19 siblings, 1 reply; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

So far ARC pgtable_t has not been struct page based to avoid extra
page_address() calls involved. However the differences are down to
noise and get in the way of using generic code, hence this patch.

Suggested-by: Mike Rapoport <rppt@kernel.org>
Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/include/asm/page.h    |  2 +-
 arch/arc/include/asm/pgalloc.h | 57 ++++++++++------------------------
 arch/arc/mm/init.c             |  3 ++
 3 files changed, 21 insertions(+), 41 deletions(-)

diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h
index c4ac827379cd..514b8b70df50 100644
--- a/arch/arc/include/asm/page.h
+++ b/arch/arc/include/asm/page.h
@@ -58,7 +58,7 @@ typedef struct {
 
 #define pte_pgprot(x) __pgprot(pte_val(x))
 
-typedef pte_t * pgtable_t;
+typedef struct page *pgtable_t;
 
 /*
  * Use virt_to_pfn with caution:
diff --git a/arch/arc/include/asm/pgalloc.h b/arch/arc/include/asm/pgalloc.h
index 408bc4b0842d..8ab1af3da6e7 100644
--- a/arch/arc/include/asm/pgalloc.h
+++ b/arch/arc/include/asm/pgalloc.h
@@ -45,22 +45,17 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
 	set_pmd(pmd, __pmd((unsigned long)pte));
 }
 
-static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t pte)
+static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t pte_page)
 {
-	set_pmd(pmd, __pmd((unsigned long)pte));
-}
-
-static inline int __get_order_pgd(void)
-{
-	return get_order(PTRS_PER_PGD * sizeof(pgd_t));
+	set_pmd(pmd, __pmd((unsigned long)page_address(pte_page)));
 }
 
 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-	int num, num2;
-	pgd_t *ret = (pgd_t *) __get_free_pages(GFP_KERNEL, __get_order_pgd());
+	pgd_t *ret = (pgd_t *) __get_free_page(GFP_KERNEL);
 
 	if (ret) {
+		int num, num2;
 		num = USER_PTRS_PER_PGD + USER_KERNEL_GUTTER / PGDIR_SIZE;
 		memzero(ret, num * sizeof(pgd_t));
 
@@ -76,61 +71,43 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 
 static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 {
-	free_pages((unsigned long)pgd, __get_order_pgd());
-}
-
-
-/*
- * With software-only page-tables, addr-split for traversal is tweakable and
- * that directly governs how big tables would be at each level.
- * Further, the MMU page size is configurable.
- * Thus we need to programatically assert the size constraint
- * All of this is const math, allowing gcc to do constant folding/propagation.
- */
-
-static inline int __get_order_pte(void)
-{
-	return get_order(PTRS_PER_PTE * sizeof(pte_t));
+	free_page((unsigned long)pgd);
 }
 
 static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
 	pte_t *pte;
 
-	pte = (pte_t *) __get_free_pages(GFP_KERNEL | __GFP_ZERO,
-					 __get_order_pte());
+	pte = (pte_t *) __get_free_page(GFP_KERNEL | __GFP_ZERO);
 
 	return pte;
 }
 
-static inline pgtable_t
-pte_alloc_one(struct mm_struct *mm)
+static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
 {
-	pgtable_t pte_pg;
 	struct page *page;
 
-	pte_pg = (pgtable_t)__get_free_pages(GFP_KERNEL, __get_order_pte());
-	if (!pte_pg)
-		return 0;
-	memzero((void *)pte_pg, PTRS_PER_PTE * sizeof(pte_t));
-	page = virt_to_page(pte_pg);
+	page = (pgtable_t)alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_ACCOUNT);
+	if (!page)
+		return NULL;
+
 	if (!pgtable_pte_page_ctor(page)) {
 		__free_page(page);
-		return 0;
+		return NULL;
 	}
 
-	return pte_pg;
+	return page;
 }
 
 static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
 {
-	free_pages((unsigned long)pte, __get_order_pte()); /* takes phy addr */
+	free_page((unsigned long)pte);
 }
 
-static inline void pte_free(struct mm_struct *mm, pgtable_t ptep)
+static inline void pte_free(struct mm_struct *mm, pgtable_t pte_page)
 {
-	pgtable_pte_page_dtor(virt_to_page(ptep));
-	free_pages((unsigned long)ptep, __get_order_pte());
+	pgtable_pte_page_dtor(pte_page);
+	__free_page(pte_page);
 }
 
 #define __pte_free_tlb(tlb, pte, addr)  pte_free((tlb)->mm, pte)
diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c
index c083bf660cec..46ad9aee7a73 100644
--- a/arch/arc/mm/init.c
+++ b/arch/arc/mm/init.c
@@ -189,6 +189,9 @@ void __init mem_init(void)
 {
 	memblock_free_all();
 	highmem_init();
+
+	BUILD_BUG_ON((PTRS_PER_PGD * sizeof(pgd_t)) > PAGE_SIZE);
+	BUILD_BUG_ON((PTRS_PER_PTE * sizeof(pte_t)) > PAGE_SIZE);
 }
 
 #ifdef CONFIG_HIGHMEM
-- 
2.25.1


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

* [PATCH v2 09/19] ARC: mm: switch to asm-generic/pgalloc.h
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
                   ` (7 preceding siblings ...)
  2021-08-12 23:37 ` [PATCH v2 08/19] ARC: mm: switch pgtable_t back to struct page * Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-12 23:37 ` [PATCH v2 10/19] ARC: mm: non-functional code cleanup ahead of 3 levels Vineet Gupta
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

With previous patch ARC pgalloc functions are same as generic, hence
switch to that.

Suggested-by: Mike Rapoport <rppt@kernel.org>
Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/include/asm/pgalloc.h | 42 +---------------------------------
 1 file changed, 1 insertion(+), 41 deletions(-)

diff --git a/arch/arc/include/asm/pgalloc.h b/arch/arc/include/asm/pgalloc.h
index 8ab1af3da6e7..0cde9e5eefd7 100644
--- a/arch/arc/include/asm/pgalloc.h
+++ b/arch/arc/include/asm/pgalloc.h
@@ -31,6 +31,7 @@
 
 #include <linux/mm.h>
 #include <linux/log2.h>
+#include <asm-generic/pgalloc.h>
 
 static inline void
 pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
@@ -69,47 +70,6 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 	return ret;
 }
 
-static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
-{
-	free_page((unsigned long)pgd);
-}
-
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
-{
-	pte_t *pte;
-
-	pte = (pte_t *) __get_free_page(GFP_KERNEL | __GFP_ZERO);
-
-	return pte;
-}
-
-static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
-{
-	struct page *page;
-
-	page = (pgtable_t)alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_ACCOUNT);
-	if (!page)
-		return NULL;
-
-	if (!pgtable_pte_page_ctor(page)) {
-		__free_page(page);
-		return NULL;
-	}
-
-	return page;
-}
-
-static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
-{
-	free_page((unsigned long)pte);
-}
-
-static inline void pte_free(struct mm_struct *mm, pgtable_t pte_page)
-{
-	pgtable_pte_page_dtor(pte_page);
-	__free_page(pte_page);
-}
-
 #define __pte_free_tlb(tlb, pte, addr)  pte_free((tlb)->mm, pte)
 
 #endif /* _ASM_ARC_PGALLOC_H */
-- 
2.25.1


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

* [PATCH v2 10/19] ARC: mm: non-functional code cleanup ahead of 3 levels
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
                   ` (8 preceding siblings ...)
  2021-08-12 23:37 ` [PATCH v2 09/19] ARC: mm: switch to asm-generic/pgalloc.h Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-12 23:37 ` [PATCH v2 11/19] ARC: mm: move MMU specific bits out of ASID allocator Vineet Gupta
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/include/asm/page.h | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h
index 514b8b70df50..28ed82b1800f 100644
--- a/arch/arc/include/asm/page.h
+++ b/arch/arc/include/asm/page.h
@@ -34,6 +34,13 @@ void copy_user_highpage(struct page *to, struct page *from,
 			unsigned long u_vaddr, struct vm_area_struct *vma);
 void clear_user_page(void *to, unsigned long u_vaddr, struct page *page);
 
+typedef struct {
+	unsigned long pgd;
+} pgd_t;
+
+#define pgd_val(x)	((x).pgd)
+#define __pgd(x)	((pgd_t) { (x) })
+
 typedef struct {
 #ifdef CONFIG_ARC_HAS_PAE40
 	unsigned long long pte;
@@ -41,22 +48,17 @@ typedef struct {
 	unsigned long pte;
 #endif
 } pte_t;
-typedef struct {
-	unsigned long pgd;
-} pgd_t;
+
+#define pte_val(x)	((x).pte)
+#define __pte(x)	((pte_t) { (x) })
+
 typedef struct {
 	unsigned long pgprot;
 } pgprot_t;
 
-#define pte_val(x)      ((x).pte)
-#define pgd_val(x)      ((x).pgd)
-#define pgprot_val(x)   ((x).pgprot)
-
-#define __pte(x)        ((pte_t) { (x) })
-#define __pgd(x)        ((pgd_t) { (x) })
-#define __pgprot(x)     ((pgprot_t) { (x) })
-
-#define pte_pgprot(x) __pgprot(pte_val(x))
+#define pgprot_val(x)	((x).pgprot)
+#define __pgprot(x)	((pgprot_t) { (x) })
+#define pte_pgprot(x)	__pgprot(pte_val(x))
 
 typedef struct page *pgtable_t;
 
@@ -96,8 +98,8 @@ extern int pfn_valid(unsigned long pfn);
  * virt here means link-address/program-address as embedded in object code.
  * And for ARC, link-addr = physical address
  */
-#define __pa(vaddr)  ((unsigned long)(vaddr))
-#define __va(paddr)  ((void *)((unsigned long)(paddr)))
+#define __pa(vaddr)  		((unsigned long)(vaddr))
+#define __va(paddr)  		((void *)((unsigned long)(paddr)))
 
 #define virt_to_page(kaddr)	pfn_to_page(virt_to_pfn(kaddr))
 #define virt_addr_valid(kaddr)  pfn_valid(virt_to_pfn(kaddr))
-- 
2.25.1


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

* [PATCH v2 11/19] ARC: mm: move MMU specific bits out of ASID allocator
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
                   ` (9 preceding siblings ...)
  2021-08-12 23:37 ` [PATCH v2 10/19] ARC: mm: non-functional code cleanup ahead of 3 levels Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-12 23:37 ` [PATCH v2 12/19] ARC: mm: move MMU specific bits out of entry code Vineet Gupta
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

And while at it, rewrite commentary on ASID allocator

Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/include/asm/mmu.h         | 13 +++++++++++++
 arch/arc/include/asm/mmu_context.h | 28 +++++++++++++---------------
 arch/arc/mm/tlb.c                  | 11 ++++-------
 3 files changed, 30 insertions(+), 22 deletions(-)

diff --git a/arch/arc/include/asm/mmu.h b/arch/arc/include/asm/mmu.h
index 762cfe66e16b..0b117ea07048 100644
--- a/arch/arc/include/asm/mmu.h
+++ b/arch/arc/include/asm/mmu.h
@@ -64,6 +64,19 @@ typedef struct {
 	unsigned long asid[NR_CPUS];	/* 8 bit MMU PID + Generation cycle */
 } mm_context_t;
 
+static void inline mmu_setup_asid(struct mm_struct *mm, unsigned int asid)
+{
+	write_aux_reg(ARC_REG_PID, asid | MMU_ENABLE);
+}
+
+static void inline mmu_setup_pgd(struct mm_struct *mm, void *pgd)
+{
+	/* PGD cached in MMU reg to avoid 3 mem lookups: task->mm->pgd */
+#ifdef CONFIG_ISA_ARCV2
+	write_aux_reg(ARC_REG_SCRATCH_DATA0, (unsigned int)pgd);
+#endif
+}
+
 static inline int is_pae40_enabled(void)
 {
 	return IS_ENABLED(CONFIG_ARC_HAS_PAE40);
diff --git a/arch/arc/include/asm/mmu_context.h b/arch/arc/include/asm/mmu_context.h
index 49318a126879..dda471f5f05b 100644
--- a/arch/arc/include/asm/mmu_context.h
+++ b/arch/arc/include/asm/mmu_context.h
@@ -15,22 +15,23 @@
 #ifndef _ASM_ARC_MMU_CONTEXT_H
 #define _ASM_ARC_MMU_CONTEXT_H
 
-#include <asm/arcregs.h>
-#include <asm/tlb.h>
 #include <linux/sched/mm.h>
 
+#include <asm/tlb.h>
 #include <asm-generic/mm_hooks.h>
 
-/*		ARC700 ASID Management
+/*		ARC ASID Management
+ *
+ * MMU tags TLBs with an 8-bit ASID, avoiding need to flush the TLB on
+ * context-switch.
  *
- * ARC MMU provides 8-bit ASID (0..255) to TAG TLB entries, allowing entries
- * with same vaddr (different tasks) to co-exit. This provides for
- * "Fast Context Switch" i.e. no TLB flush on ctxt-switch
+ * ASID is managed per cpu, so task threads across CPUs can have different
+ * ASID. Global ASID management is needed if hardware supports TLB shootdown
+ * and/or shared TLB across cores, which ARC doesn't.
  *
- * Linux assigns each task a unique ASID. A simple round-robin allocation
- * of H/w ASID is done using software tracker @asid_cpu.
- * When it reaches max 255, the allocation cycle starts afresh by flushing
- * the entire TLB and wrapping ASID back to zero.
+ * Each task is assigned unique ASID, with a simple round-robin allocator
+ * tracked in @asid_cpu. When 8-bit value rolls over,a new cycle is started
+ * over from 0, and TLB is flushed
  *
  * A new allocation cycle, post rollover, could potentially reassign an ASID
  * to a different task. Thus the rule is to refresh the ASID in a new cycle.
@@ -93,7 +94,7 @@ static inline void get_new_mmu_context(struct mm_struct *mm)
 	asid_mm(mm, cpu) = asid_cpu(cpu);
 
 set_hw:
-	write_aux_reg(ARC_REG_PID, hw_pid(mm, cpu) | MMU_ENABLE);
+	mmu_setup_asid(mm, hw_pid(mm, cpu));
 
 	local_irq_restore(flags);
 }
@@ -146,10 +147,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
 	 */
 	cpumask_set_cpu(cpu, mm_cpumask(next));
 
-#ifdef CONFIG_ISA_ARCV2
-	/* PGD cached in MMU reg to avoid 3 mem lookups: task->mm->pgd */
-	write_aux_reg(ARC_REG_SCRATCH_DATA0, next->pgd);
-#endif
+	mmu_setup_pgd(next, next->pgd);
 
 	get_new_mmu_context(next);
 }
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 15cbc285b0de..b68d5798327b 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -716,14 +716,11 @@ void arc_mmu_init(void)
 	if (IS_ENABLED(CONFIG_ARC_HAS_PAE40) && !mmu->pae)
 		panic("Hardware doesn't support PAE40\n");
 
-	/* Enable the MMU */
-	write_aux_reg(ARC_REG_PID, MMU_ENABLE);
+	/* Enable the MMU with ASID 0 */
+	mmu_setup_asid(NULL, 0);
 
-	/* In arc700/smp needed for re-entrant interrupt handling */
-#ifdef CONFIG_ISA_ARCV2
-	/* swapper_pg_dir is the pgd for the kernel, used by vmalloc */
-	write_aux_reg(ARC_REG_SCRATCH_DATA0, swapper_pg_dir);
-#endif
+	/* cache the pgd pointer in MMU SCRATCH reg (ARCv2 only) */
+	mmu_setup_pgd(NULL, swapper_pg_dir);
 
 	if (pae40_exist_but_not_enab())
 		write_aux_reg(ARC_REG_TLBPD1HI, 0);
-- 
2.25.1


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

* [PATCH v2 12/19] ARC: mm: move MMU specific bits out of entry code ...
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
                   ` (10 preceding siblings ...)
  2021-08-12 23:37 ` [PATCH v2 11/19] ARC: mm: move MMU specific bits out of ASID allocator Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-12 23:37 ` [PATCH v2 13/19] ARC: mm: disintegrate mmu.h (arcv2 bits out) Vineet Gupta
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport,
	Vineet Gupta, Jose Abreu

... to avoid polluting shared entry code (across three ISA variants)
with ISA/MMU specific code.

Cc: Jose Abreu <joabreu@synopsys.com>
Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/include/asm/mmu.h    | 8 ++++++++
 arch/arc/kernel/entry-arcv2.S | 1 +
 arch/arc/kernel/entry.S       | 7 ++-----
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/arch/arc/include/asm/mmu.h b/arch/arc/include/asm/mmu.h
index 0b117ea07048..414a27e806b6 100644
--- a/arch/arc/include/asm/mmu.h
+++ b/arch/arc/include/asm/mmu.h
@@ -84,6 +84,14 @@ static inline int is_pae40_enabled(void)
 
 extern int pae40_exist_but_not_enab(void);
 
+#else
+
+.macro ARC_MMU_REENABLE reg
+	lr \reg, [ARC_REG_PID]
+	or \reg, \reg, MMU_ENABLE
+	sr \reg, [ARC_REG_PID]
+.endm
+
 #endif	/* !__ASSEMBLY__ */
 
 #endif
diff --git a/arch/arc/kernel/entry-arcv2.S b/arch/arc/kernel/entry-arcv2.S
index 12d5f12d10d2..a7e6a2174187 100644
--- a/arch/arc/kernel/entry-arcv2.S
+++ b/arch/arc/kernel/entry-arcv2.S
@@ -10,6 +10,7 @@
 #include <asm/errno.h>
 #include <asm/arcregs.h>
 #include <asm/irqflags.h>
+#include <asm/mmu.h>
 
 ; A maximum number of supported interrupts in the core interrupt controller.
 ; This number is not equal to the maximum interrupt number (256) because
diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S
index 2cb8dfe866b6..dd77a0c8f740 100644
--- a/arch/arc/kernel/entry.S
+++ b/arch/arc/kernel/entry.S
@@ -101,11 +101,8 @@ ENTRY(EV_MachineCheck)
 	lr  r0, [efa]
 	mov r1, sp
 
-	; hardware auto-disables MMU, re-enable it to allow kernel vaddr
-	; access for say stack unwinding of modules for crash dumps
-	lr	r3, [ARC_REG_PID]
-	or	r3, r3, MMU_ENABLE
-	sr	r3, [ARC_REG_PID]
+	; MC excpetions disable MMU
+	ARC_MMU_REENABLE r3
 
 	lsr  	r3, r2, 8
 	bmsk 	r3, r3, 7
-- 
2.25.1


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

* [PATCH v2 13/19] ARC: mm: disintegrate mmu.h (arcv2 bits out)
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
                   ` (11 preceding siblings ...)
  2021-08-12 23:37 ` [PATCH v2 12/19] ARC: mm: move MMU specific bits out of entry code Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-13  4:01   ` kernel test robot
  2021-08-12 23:37 ` [PATCH v2 14/19] ARC: mm: disintegrate pgtable.h into levels and flags Vineet Gupta
                   ` (6 subsequent siblings)
  19 siblings, 1 reply; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

non functional change

Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/include/asm/mmu-arcv2.h | 103 +++++++++++++++++++++++++++++++
 arch/arc/include/asm/mmu.h       |  80 +-----------------------
 arch/arc/include/asm/pgtable.h   |   6 --
 3 files changed, 105 insertions(+), 84 deletions(-)
 create mode 100644 arch/arc/include/asm/mmu-arcv2.h

diff --git a/arch/arc/include/asm/mmu-arcv2.h b/arch/arc/include/asm/mmu-arcv2.h
new file mode 100644
index 000000000000..4c47dd3864d1
--- /dev/null
+++ b/arch/arc/include/asm/mmu-arcv2.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2004, 2007-2010, 2011-2012, 2019-20 Synopsys, Inc. (www.synopsys.com)
+ *
+ * MMUv3 (arc700) / MMUv4 (archs) are software page walked and software managed.
+ * This file contains the TLB access registers and commands
+ */
+
+#ifndef _ASM_ARC_MMU_ARCV2_H
+#define _ASM_ARC_MMU_ARCV2_H
+
+/*
+ * TLB Management regs
+ */
+#define ARC_REG_MMU_BCR		0x06f
+
+#ifdef CONFIG_ARC_MMU_V3
+#define ARC_REG_TLBPD0		0x405
+#define ARC_REG_TLBPD1		0x406
+#define ARC_REG_TLBPD1HI	0	/* Dummy: allows common code */
+#define ARC_REG_TLBINDEX	0x407
+#define ARC_REG_TLBCOMMAND	0x408
+#define ARC_REG_PID		0x409
+#define ARC_REG_SCRATCH_DATA0	0x418
+#else
+#define ARC_REG_TLBPD0		0x460
+#define ARC_REG_TLBPD1		0x461
+#define ARC_REG_TLBPD1HI	0x463
+#define ARC_REG_TLBINDEX	0x464
+#define ARC_REG_TLBCOMMAND	0x465
+#define ARC_REG_PID		0x468
+#define ARC_REG_SCRATCH_DATA0	0x46c
+#endif
+
+/* Bits in MMU PID reg */
+#define __TLB_ENABLE		(1 << 31)
+#define __PROG_ENABLE		(1 << 30)
+#define MMU_ENABLE		(__TLB_ENABLE | __PROG_ENABLE)
+
+/* Bits in TLB Index reg */
+#define TLB_LKUP_ERR		0x80000000
+
+#ifdef CONFIG_ARC_MMU_V3
+#define TLB_DUP_ERR		(TLB_LKUP_ERR | 0x00000001)
+#else
+#define TLB_DUP_ERR		(TLB_LKUP_ERR | 0x40000000)
+#endif
+
+/*
+ * TLB Commands
+ */
+#define TLBWrite    		0x1
+#define TLBRead     		0x2
+#define TLBGetIndex 		0x3
+#define TLBProbe    		0x4
+#define TLBWriteNI		0x5  /* write JTLB without inv uTLBs */
+#define TLBIVUTLB		0x6  /* explicitly inv uTLBs */
+
+#ifdef CONFIG_ARC_MMU_V4
+#define TLBInsertEntry		0x7
+#define TLBDeleteEntry		0x8
+#endif
+
+/* Masks for actual TLB "PD"s */
+#define PTE_BITS_IN_PD0		(_PAGE_GLOBAL | _PAGE_PRESENT | _PAGE_HW_SZ)
+#define PTE_BITS_RWX		(_PAGE_EXECUTE | _PAGE_WRITE | _PAGE_READ)
+
+#define PTE_BITS_NON_RWX_IN_PD1	(PAGE_MASK_PHYS | _PAGE_CACHEABLE)
+
+#ifndef __ASSEMBLY__
+
+struct mm_struct;
+extern int pae40_exist_but_not_enab(void);
+
+static inline int is_pae40_enabled(void)
+{
+	return IS_ENABLED(CONFIG_ARC_HAS_PAE40);
+}
+
+static void inline mmu_setup_asid(struct mm_struct *mm, unsigned long asid)
+{
+	write_aux_reg(ARC_REG_PID, asid | MMU_ENABLE);
+}
+
+static void inline mmu_setup_pgd(struct mm_struct *mm, void *pgd)
+{
+	/* PGD cached in MMU reg to avoid 3 mem lookups: task->mm->pgd */
+#ifdef CONFIG_ISA_ARCV2
+	write_aux_reg(ARC_REG_SCRATCH_DATA0, (unsigned int)pgd);
+#endif
+}
+
+#else
+
+.macro ARC_MMU_REENABLE reg
+	lr \reg, [ARC_REG_PID]
+	or \reg, \reg, MMU_ENABLE
+	sr \reg, [ARC_REG_PID]
+.endm
+
+#endif /* !__ASSEMBLY__ */
+
+#endif
diff --git a/arch/arc/include/asm/mmu.h b/arch/arc/include/asm/mmu.h
index 414a27e806b6..ca427c30f70e 100644
--- a/arch/arc/include/asm/mmu.h
+++ b/arch/arc/include/asm/mmu.h
@@ -7,91 +7,15 @@
 #define _ASM_ARC_MMU_H
 
 #ifndef __ASSEMBLY__
-#include <linux/threads.h>	/* NR_CPUS */
-#endif
-
-/* MMU Management regs */
-#define ARC_REG_MMU_BCR		0x06f
-
-#ifdef CONFIG_ARC_MMU_V3
-#define ARC_REG_TLBPD0		0x405
-#define ARC_REG_TLBPD1		0x406
-#define ARC_REG_TLBPD1HI	0	/* Dummy: allows code sharing with ARC700 */
-#define ARC_REG_TLBINDEX	0x407
-#define ARC_REG_TLBCOMMAND	0x408
-#define ARC_REG_PID		0x409
-#define ARC_REG_SCRATCH_DATA0	0x418
-#else
-#define ARC_REG_TLBPD0		0x460
-#define ARC_REG_TLBPD1		0x461
-#define ARC_REG_TLBPD1HI	0x463
-#define ARC_REG_TLBINDEX	0x464
-#define ARC_REG_TLBCOMMAND	0x465
-#define ARC_REG_PID		0x468
-#define ARC_REG_SCRATCH_DATA0	0x46c
-#endif
-
-/* Bits in MMU PID register */
-#define __TLB_ENABLE		(1 << 31)
-#define __PROG_ENABLE		(1 << 30)
-#define MMU_ENABLE		(__TLB_ENABLE | __PROG_ENABLE)
-
-/* Error code if probe fails */
-#define TLB_LKUP_ERR		0x80000000
-
-#ifdef CONFIG_ARC_MMU_V3
-#define TLB_DUP_ERR	(TLB_LKUP_ERR | 0x00000001)
-#else
-#define TLB_DUP_ERR	(TLB_LKUP_ERR | 0x40000000)
-#endif
-
-/* TLB Commands */
-#define TLBWrite    0x1
-#define TLBRead     0x2
-#define TLBGetIndex 0x3
-#define TLBProbe    0x4
-#define TLBWriteNI  0x5		/* write JTLB without inv uTLBs */
-#define TLBIVUTLB   0x6		/* explicitly inv uTLBs */
 
-#ifdef CONFIG_ARC_MMU_V4
-#define TLBInsertEntry	0x7
-#define TLBDeleteEntry	0x8
-#endif
-
-#ifndef __ASSEMBLY__
+#include <linux/threads.h>	/* NR_CPUS */
 
 typedef struct {
 	unsigned long asid[NR_CPUS];	/* 8 bit MMU PID + Generation cycle */
 } mm_context_t;
 
-static void inline mmu_setup_asid(struct mm_struct *mm, unsigned int asid)
-{
-	write_aux_reg(ARC_REG_PID, asid | MMU_ENABLE);
-}
-
-static void inline mmu_setup_pgd(struct mm_struct *mm, void *pgd)
-{
-	/* PGD cached in MMU reg to avoid 3 mem lookups: task->mm->pgd */
-#ifdef CONFIG_ISA_ARCV2
-	write_aux_reg(ARC_REG_SCRATCH_DATA0, (unsigned int)pgd);
 #endif
-}
-
-static inline int is_pae40_enabled(void)
-{
-	return IS_ENABLED(CONFIG_ARC_HAS_PAE40);
-}
-
-extern int pae40_exist_but_not_enab(void);
-
-#else
-
-.macro ARC_MMU_REENABLE reg
-	lr \reg, [ARC_REG_PID]
-	or \reg, \reg, MMU_ENABLE
-	sr \reg, [ARC_REG_PID]
-.endm
 
-#endif	/* !__ASSEMBLY__ */
+#include <asm/mmu-arcv2.h>
 
 #endif
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index f762bacb2358..de4576e8d17a 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -103,12 +103,6 @@
  */
 #define PAGE_KERNEL          __pgprot(_K_PAGE_PERMS | _PAGE_CACHEABLE)
 
-/* Masks for actual TLB "PD"s */
-#define PTE_BITS_IN_PD0		(_PAGE_GLOBAL | _PAGE_PRESENT | _PAGE_HW_SZ)
-#define PTE_BITS_RWX		(_PAGE_EXECUTE | _PAGE_WRITE | _PAGE_READ)
-
-#define PTE_BITS_NON_RWX_IN_PD1	(PAGE_MASK_PHYS | _PAGE_CACHEABLE)
-
 /**************************************************************************
  * Mapping of vm_flags (Generic VM) to PTE flags (arch specific)
  *
-- 
2.25.1


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

* [PATCH v2 14/19] ARC: mm: disintegrate pgtable.h into levels and flags
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
                   ` (12 preceding siblings ...)
  2021-08-12 23:37 ` [PATCH v2 13/19] ARC: mm: disintegrate mmu.h (arcv2 bits out) Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-12 23:37 ` [PATCH v2 15/19] ARC: mm: hack to allow 2 level build with 4 level code Vineet Gupta
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

 - pgtable-bits-arcv2.h (MMU specific page table flags)
 - pgtable-levels.h (paging levels)

No functional changes, but paves way for easy addition of new MMU code
with different bits and levels etc

Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/include/asm/pgtable-bits-arcv2.h | 149 ++++++++++++
 arch/arc/include/asm/pgtable-levels.h     |  91 +++++++
 arch/arc/include/asm/pgtable.h            | 277 +---------------------
 3 files changed, 244 insertions(+), 273 deletions(-)
 create mode 100644 arch/arc/include/asm/pgtable-bits-arcv2.h
 create mode 100644 arch/arc/include/asm/pgtable-levels.h

diff --git a/arch/arc/include/asm/pgtable-bits-arcv2.h b/arch/arc/include/asm/pgtable-bits-arcv2.h
new file mode 100644
index 000000000000..183d23bc1e00
--- /dev/null
+++ b/arch/arc/include/asm/pgtable-bits-arcv2.h
@@ -0,0 +1,149 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
+ */
+
+/*
+ * page table flags for software walked/managed MMUv3 (ARC700) and MMUv4 (HS)
+ * There correspond to the corresponding bits in the TLB
+ */
+
+#ifndef _ASM_ARC_PGTABLE_BITS_ARCV2_H
+#define _ASM_ARC_PGTABLE_BITS_ARCV2_H
+
+#ifdef CONFIG_ARC_CACHE_PAGES
+#define _PAGE_CACHEABLE		(1 << 0)  /* Cached (H) */
+#else
+#define _PAGE_CACHEABLE		0
+#endif
+
+#define _PAGE_EXECUTE		(1 << 1)  /* User Execute  (H) */
+#define _PAGE_WRITE		(1 << 2)  /* User Write    (H) */
+#define _PAGE_READ		(1 << 3)  /* User Read     (H) */
+#define _PAGE_ACCESSED		(1 << 4)  /* Accessed      (s) */
+#define _PAGE_DIRTY		(1 << 5)  /* Modified      (s) */
+#define _PAGE_SPECIAL		(1 << 6)
+#define _PAGE_GLOBAL		(1 << 8)  /* ASID agnostic (H) */
+#define _PAGE_PRESENT		(1 << 9)  /* PTE/TLB Valid (H) */
+
+#ifdef CONFIG_ARC_MMU_V4
+#define _PAGE_HW_SZ		(1 << 10)  /* Normal/super (H) */
+#else
+#define _PAGE_HW_SZ		0
+#endif
+
+/* Defaults for every user page */
+#define ___DEF		(_PAGE_PRESENT | _PAGE_CACHEABLE)
+
+/* Set of bits not changed in pte_modify */
+#define _PAGE_CHG_MASK	(PAGE_MASK_PHYS | _PAGE_ACCESSED | _PAGE_DIRTY | \
+							   _PAGE_SPECIAL)
+
+/* More Abbrevaited helpers */
+#define PAGE_U_NONE     __pgprot(___DEF)
+#define PAGE_U_R        __pgprot(___DEF | _PAGE_READ)
+#define PAGE_U_W_R      __pgprot(___DEF | _PAGE_READ | _PAGE_WRITE)
+#define PAGE_U_X_R      __pgprot(___DEF | _PAGE_READ | _PAGE_EXECUTE)
+#define PAGE_U_X_W_R    __pgprot(___DEF \
+				| _PAGE_READ | _PAGE_WRITE | _PAGE_EXECUTE)
+#define PAGE_KERNEL     __pgprot(___DEF | _PAGE_GLOBAL \
+				| _PAGE_READ | _PAGE_WRITE | _PAGE_EXECUTE)
+
+#define PAGE_SHARED	PAGE_U_W_R
+
+#define pgprot_noncached(prot)	(__pgprot(pgprot_val(prot) & ~_PAGE_CACHEABLE))
+
+/*
+ * Mapping of vm_flags (Generic VM) to PTE flags (arch specific)
+ *
+ * Certain cases have 1:1 mapping
+ *  e.g. __P101 means VM_READ, VM_EXEC and !VM_SHARED
+ *       which directly corresponds to  PAGE_U_X_R
+ *
+ * Other rules which cause the divergence from 1:1 mapping
+ *
+ *  1. Although ARC700 can do exclusive execute/write protection (meaning R
+ *     can be tracked independet of X/W unlike some other CPUs), still to
+ *     keep things consistent with other archs:
+ *      -Write implies Read:   W => R
+ *      -Execute implies Read: X => R
+ *
+ *  2. Pvt Writable doesn't have Write Enabled initially: Pvt-W => !W
+ *     This is to enable COW mechanism
+ */
+	/* xwr */
+#define __P000  PAGE_U_NONE
+#define __P001  PAGE_U_R
+#define __P010  PAGE_U_R	/* Pvt-W => !W */
+#define __P011  PAGE_U_R	/* Pvt-W => !W */
+#define __P100  PAGE_U_X_R	/* X => R */
+#define __P101  PAGE_U_X_R
+#define __P110  PAGE_U_X_R	/* Pvt-W => !W and X => R */
+#define __P111  PAGE_U_X_R	/* Pvt-W => !W */
+
+#define __S000  PAGE_U_NONE
+#define __S001  PAGE_U_R
+#define __S010  PAGE_U_W_R	/* W => R */
+#define __S011  PAGE_U_W_R
+#define __S100  PAGE_U_X_R	/* X => R */
+#define __S101  PAGE_U_X_R
+#define __S110  PAGE_U_X_W_R	/* X => R */
+#define __S111  PAGE_U_X_W_R
+
+#ifndef __ASSEMBLY__
+
+#define pte_write(pte)		(pte_val(pte) & _PAGE_WRITE)
+#define pte_dirty(pte)		(pte_val(pte) & _PAGE_DIRTY)
+#define pte_young(pte)		(pte_val(pte) & _PAGE_ACCESSED)
+#define pte_special(pte)	(pte_val(pte) & _PAGE_SPECIAL)
+
+#define PTE_BIT_FUNC(fn, op) \
+	static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
+
+PTE_BIT_FUNC(mknotpresent,     &= ~(_PAGE_PRESENT));
+PTE_BIT_FUNC(wrprotect,	&= ~(_PAGE_WRITE));
+PTE_BIT_FUNC(mkwrite,	|= (_PAGE_WRITE));
+PTE_BIT_FUNC(mkclean,	&= ~(_PAGE_DIRTY));
+PTE_BIT_FUNC(mkdirty,	|= (_PAGE_DIRTY));
+PTE_BIT_FUNC(mkold,	&= ~(_PAGE_ACCESSED));
+PTE_BIT_FUNC(mkyoung,	|= (_PAGE_ACCESSED));
+PTE_BIT_FUNC(mkspecial,	|= (_PAGE_SPECIAL));
+PTE_BIT_FUNC(mkhuge,	|= (_PAGE_HW_SZ));
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+	return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
+}
+
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+			      pte_t *ptep, pte_t pteval)
+{
+	set_pte(ptep, pteval);
+}
+
+void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
+		      pte_t *ptep);
+
+/* Encode swap {type,off} tuple into PTE
+ * We reserve 13 bits for 5-bit @type, keeping bits 12-5 zero, ensuring that
+ * PAGE_PRESENT is zero in a PTE holding swap "identifier"
+ */
+#define __swp_entry(type, off)		((swp_entry_t) \
+					{ ((type) & 0x1f) | ((off) << 13) })
+
+/* Decode a PTE containing swap "identifier "into constituents */
+#define __swp_type(pte_lookalike)	(((pte_lookalike).val) & 0x1f)
+#define __swp_offset(pte_lookalike)	((pte_lookalike).val >> 13)
+
+#define __pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x)		((pte_t) { (x).val })
+
+#define kern_addr_valid(addr)	(1)
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#include <asm/hugepage.h>
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff --git a/arch/arc/include/asm/pgtable-levels.h b/arch/arc/include/asm/pgtable-levels.h
new file mode 100644
index 000000000000..8ece75335bb5
--- /dev/null
+++ b/arch/arc/include/asm/pgtable-levels.h
@@ -0,0 +1,91 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 Synopsys, Inc. (www.synopsys.com)
+ */
+
+/*
+ * Helpers for implemenintg paging levels
+ */
+
+#ifndef _ASM_ARC_PGTABLE_LEVELS_H
+#define _ASM_ARC_PGTABLE_LEVELS_H
+
+/*
+ * 2 level paging setup for software walked MMUv3 (ARC700) and MMUv4 (HS)
+ *
+ * [31]            32 bit virtual address              [0]
+ * -------------------------------------------------------
+ * |               | <---------- PGDIR_SHIFT ----------> |
+ * |               |                | <-- PAGE_SHIFT --> |
+ * -------------------------------------------------------
+ *       |                  |                |
+ *       |                  |                --> off in page frame
+ *       |                  ---> index into Page Table
+ *       ----> index into Page Directory
+ *
+ * Given software walk, the vaddr split is arbitrary set to 11:8:13
+ * However enabling of super page in a 2 level regime pegs PGDIR_SHIFT to
+ * super page size.
+ */
+
+#if defined(CONFIG_ARC_HUGEPAGE_16M)
+#define PGDIR_SHIFT		24
+#elif defined(CONFIG_ARC_HUGEPAGE_2M)
+#define PGDIR_SHIFT		21
+#else
+/* No Super page case: in theory this can be any number */
+#define PGDIR_SHIFT		21
+#endif
+
+#define PGDIR_SIZE		BIT(PGDIR_SHIFT)	/* vaddr span, not PDG sz */
+#define PGDIR_MASK		(~(PGDIR_SIZE - 1))
+
+#define PTRS_PER_PGD		BIT(32 - PGDIR_SHIFT)
+
+#define PTRS_PER_PTE		BIT(PGDIR_SHIFT - PAGE_SHIFT)
+
+#ifndef __ASSEMBLY__
+
+#include <asm-generic/pgtable-nopmd.h>
+
+/*
+ * 1st level paging: pgd
+ */
+#define pgd_index(addr)		((addr) >> PGDIR_SHIFT)
+#define pgd_offset(mm, addr)	(((mm)->pgd) + pgd_index(addr))
+#define pgd_offset_k(addr)	pgd_offset(&init_mm, addr)
+#define pgd_ERROR(e) \
+	pr_crit("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+/*
+ * Due to the strange way generic pgtable level folding works, in a 2 level
+ * setup, pmd_val() returns pgd, so these pmd_* macros actually work on pgd
+ */
+#define pmd_none(x)		(!pmd_val(x))
+#define pmd_bad(x)		((pmd_val(x) & ~PAGE_MASK))
+#define pmd_present(x)		(pmd_val(x))
+#define pmd_clear(xp)		do { pmd_val(*(xp)) = 0; } while (0)
+#define pmd_page_vaddr(pmd)	(pmd_val(pmd) & PAGE_MASK)
+#define pmd_page(pmd)		virt_to_page(pmd_page_vaddr(pmd))
+#define set_pmd(pmdp, pmd)	(*(pmdp) = pmd)
+#define pmd_pgtable(pmd)	((pgtable_t) pmd_page_vaddr(pmd))
+
+#define pte_ERROR(e) \
+	pr_crit("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+
+#define pte_none(x)		(!pte_val(x))
+#define pte_present(x)		(pte_val(x) & _PAGE_PRESENT)
+#define pte_clear(mm,addr,ptep)	set_pte_at(mm, addr, ptep, __pte(0))
+#define pte_page(pte)		pfn_to_page(pte_pfn(pte))
+#define set_pte(ptep, pte)	((*(ptep)) = (pte))
+#define pte_pfn(pte)		(pte_val(pte) >> PAGE_SHIFT)
+#define pfn_pte(pfn, prot)	__pte(__pfn_to_phys(pfn) | pgprot_val(prot))
+#define mk_pte(page, prot)	pfn_pte(page_to_pfn(page), prot)
+
+#ifdef CONFIG_ISA_ARCV2
+#define pmd_leaf(x)		(pmd_val(x) & _PAGE_HW_SZ)
+#endif
+
+#endif	/* !__ASSEMBLY__ */
+
+#endif
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index de4576e8d17a..9320b04c04bf 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -1,304 +1,35 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
- *
- * vineetg: May 2011
- *  -Folded PAGE_PRESENT (used by VM) and PAGE_VALID (used by MMU) into 1.
- *     They are semantically the same although in different contexts
- *     VALID marks a TLB entry exists and it will only happen if PRESENT
- *  - Utilise some unused free bits to confine PTE flags to 12 bits
- *     This is a must for 4k pg-sz
- *
- * vineetg: Mar 2011 - changes to accommodate MMU TLB Page Descriptor mods
- *  -TLB Locking never really existed, except for initial specs
- *  -SILENT_xxx not needed for our port
- *  -Per my request, MMU V3 changes the layout of some of the bits
- *     to avoid a few shifts in TLB Miss handlers.
- *
- * vineetg: April 2010
- *  -PGD entry no longer contains any flags. If empty it is 0, otherwise has
- *   Pg-Tbl ptr. Thus pmd_present(), pmd_valid(), pmd_set( ) become simpler
- *
- * vineetg: April 2010
- *  -Switched form 8:11:13 split for page table lookup to 11:8:13
- *  -this speeds up page table allocation itself as we now have to memset 1K
- *    instead of 8k per page table.
- * -TODO: Right now page table alloc is 8K and rest 7K is unused
- *    need to optimise it
- *
- * Amit Bhor, Sameer Dhavale: Codito Technologies 2004
  */
 
 #ifndef _ASM_ARC_PGTABLE_H
 #define _ASM_ARC_PGTABLE_H
 
 #include <linux/bits.h>
-#include <asm-generic/pgtable-nopmd.h>
+
+#include <asm/pgtable-levels.h>
+#include <asm/pgtable-bits-arcv2.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
 
-/**************************************************************************
- * Page Table Flags
- *
- * ARC700 MMU only deals with softare managed TLB entries.
- * Page Tables are purely for Linux VM's consumption and the bits below are
- * suited to that (uniqueness). Hence some are not implemented in the TLB and
- * some have different value in TLB.
- * e.g. MMU v2: K_READ bit is 8 and so is GLOBAL (possible because they live in
- *      seperate PD0 and PD1, which combined forms a translation entry)
- *      while for PTE perspective, they are 8 and 9 respectively
- * with MMU v3: Most bits (except SHARED) represent the exact hardware pos
- *      (saves some bit shift ops in TLB Miss hdlrs)
- */
-
-#define _PAGE_CACHEABLE     (1<<0)	/* Page is cached (H) */
-#define _PAGE_EXECUTE       (1<<1)	/* Page has user execute perm (H) */
-#define _PAGE_WRITE         (1<<2)	/* Page has user write perm (H) */
-#define _PAGE_READ          (1<<3)	/* Page has user read perm (H) */
-#define _PAGE_ACCESSED      (1<<4)	/* Page is accessed (S) */
-#define _PAGE_DIRTY         (1<<5)	/* Page modified (dirty) (S) */
-#define _PAGE_SPECIAL       (1<<6)
-
-#define _PAGE_GLOBAL        (1<<8)	/* Page is global (H) */
-#define _PAGE_PRESENT       (1<<9)	/* TLB entry is valid (H) */
-
-#ifdef CONFIG_ARC_MMU_V4
-#define _PAGE_HW_SZ         (1<<10)	/* Page Size indicator (H): 0 normal, 1 super */
-#endif
-
-#define _PAGE_SHARED_CODE   (1<<11)	/* Shared Code page with cmn vaddr
-					   usable for shared TLB entries (H) */
-/* vmalloc permissions */
-#define _K_PAGE_PERMS  (_PAGE_EXECUTE | _PAGE_WRITE | _PAGE_READ | \
-			_PAGE_GLOBAL | _PAGE_PRESENT)
-
-#ifndef CONFIG_ARC_CACHE_PAGES
-#undef _PAGE_CACHEABLE
-#define _PAGE_CACHEABLE 0
-#endif
-
-#ifndef _PAGE_HW_SZ
-#define _PAGE_HW_SZ	0
-#endif
-
-/* Defaults for every user page */
-#define ___DEF (_PAGE_PRESENT | _PAGE_CACHEABLE)
-
-/* Set of bits not changed in pte_modify */
-#define _PAGE_CHG_MASK	(PAGE_MASK_PHYS | _PAGE_ACCESSED | _PAGE_DIRTY | \
-							   _PAGE_SPECIAL)
-/* More Abbrevaited helpers */
-#define PAGE_U_NONE     __pgprot(___DEF)
-#define PAGE_U_R        __pgprot(___DEF | _PAGE_READ)
-#define PAGE_U_W_R      __pgprot(___DEF | _PAGE_READ | _PAGE_WRITE)
-#define PAGE_U_X_R      __pgprot(___DEF | _PAGE_READ | _PAGE_EXECUTE)
-#define PAGE_U_X_W_R    __pgprot(___DEF | _PAGE_READ | _PAGE_WRITE | \
-						       _PAGE_EXECUTE)
-
-#define PAGE_SHARED	PAGE_U_W_R
-
-/* While kernel runs out of unstranslated space, vmalloc/modules use a chunk of
- * user vaddr space - visible in all addr spaces, but kernel mode only
- * Thus Global, all-kernel-access, no-user-access, cached
- */
-#define PAGE_KERNEL          __pgprot(_K_PAGE_PERMS | _PAGE_CACHEABLE)
-
-/**************************************************************************
- * Mapping of vm_flags (Generic VM) to PTE flags (arch specific)
- *
- * Certain cases have 1:1 mapping
- *  e.g. __P101 means VM_READ, VM_EXEC and !VM_SHARED
- *       which directly corresponds to  PAGE_U_X_R
- *
- * Other rules which cause the divergence from 1:1 mapping
- *
- *  1. Although ARC700 can do exclusive execute/write protection (meaning R
- *     can be tracked independet of X/W unlike some other CPUs), still to
- *     keep things consistent with other archs:
- *      -Write implies Read:   W => R
- *      -Execute implies Read: X => R
- *
- *  2. Pvt Writable doesn't have Write Enabled initially: Pvt-W => !W
- *     This is to enable COW mechanism
- */
-	/* xwr */
-#define __P000  PAGE_U_NONE
-#define __P001  PAGE_U_R
-#define __P010  PAGE_U_R	/* Pvt-W => !W */
-#define __P011  PAGE_U_R	/* Pvt-W => !W */
-#define __P100  PAGE_U_X_R	/* X => R */
-#define __P101  PAGE_U_X_R
-#define __P110  PAGE_U_X_R	/* Pvt-W => !W and X => R */
-#define __P111  PAGE_U_X_R	/* Pvt-W => !W */
-
-#define __S000  PAGE_U_NONE
-#define __S001  PAGE_U_R
-#define __S010  PAGE_U_W_R	/* W => R */
-#define __S011  PAGE_U_W_R
-#define __S100  PAGE_U_X_R	/* X => R */
-#define __S101  PAGE_U_X_R
-#define __S110  PAGE_U_X_W_R	/* X => R */
-#define __S111  PAGE_U_X_W_R
-
-/****************************************************************
- * 2 tier (PGD:PTE) software page walker
- *
- * [31]		    32 bit virtual address              [0]
- * -------------------------------------------------------
- * |               | <------------ PGDIR_SHIFT ----------> |
- * |		   |					 |
- * | BITS_FOR_PGD  |  BITS_FOR_PTE  | <-- PAGE_SHIFT --> |
- * -------------------------------------------------------
- *       |                  |                |
- *       |                  |                --> off in page frame
- *       |                  ---> index into Page Table
- *       ----> index into Page Directory
- *
- * In a single page size configuration, only PAGE_SHIFT is fixed
- * So both PGD and PTE sizing can be tweaked
- *  e.g. 8K page (PAGE_SHIFT 13) can have
- *  - PGDIR_SHIFT 21  -> 11:8:13 address split
- *  - PGDIR_SHIFT 24  -> 8:11:13 address split
- *
- * If Super Page is configured, PGDIR_SHIFT becomes fixed too,
- * so the sizing flexibility is gone.
- */
-
-#if defined(CONFIG_ARC_HUGEPAGE_16M)
-#define PGDIR_SHIFT	24
-#elif defined(CONFIG_ARC_HUGEPAGE_2M)
-#define PGDIR_SHIFT	21
-#else
-/*
- * Only Normal page support so "hackable" (see comment above)
- * Default value provides 11:8:13 (8K), 11:9:12 (4K)
- */
-#define PGDIR_SHIFT	21
-#endif
-
-#define BITS_FOR_PTE	(PGDIR_SHIFT - PAGE_SHIFT)
-#define BITS_FOR_PGD	(32 - PGDIR_SHIFT)
-
-#define PGDIR_SIZE	BIT(PGDIR_SHIFT)	/* vaddr span, not PDG sz */
-#define PGDIR_MASK	(~(PGDIR_SIZE-1))
-
-#define	PTRS_PER_PTE	BIT(BITS_FOR_PTE)
-#define	PTRS_PER_PGD	BIT(BITS_FOR_PGD)
-
 /*
  * Number of entries a user land program use.
  * TASK_SIZE is the maximum vaddr that can be used by a userland program.
  */
 #define	USER_PTRS_PER_PGD	(TASK_SIZE / PGDIR_SIZE)
 
-
-/****************************************************************
- * Bucket load of VM Helpers
- */
-
 #ifndef __ASSEMBLY__
 
-#define pte_ERROR(e) \
-	pr_crit("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
-#define pgd_ERROR(e) \
-	pr_crit("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
-
-/* the zero page used for uninitialized and anonymous pages */
 extern char empty_zero_page[PAGE_SIZE];
 #define ZERO_PAGE(vaddr)	(virt_to_page(empty_zero_page))
 
-#define set_pte(pteptr, pteval)	((*(pteptr)) = (pteval))
-#define set_pmd(pmdptr, pmdval)	(*(pmdptr) = pmdval)
-
-/* find the page descriptor of the Page Tbl ref by PMD entry */
-#define pmd_page(pmd)		virt_to_page(pmd_val(pmd) & PAGE_MASK)
-
-/* find the logical addr (phy for ARC) of the Page Tbl ref by PMD entry */
-#define pmd_page_vaddr(pmd)	(pmd_val(pmd) & PAGE_MASK)
-
-#define pte_none(x)			(!pte_val(x))
-#define pte_present(x)			(pte_val(x) & _PAGE_PRESENT)
-#define pte_clear(mm, addr, ptep)	set_pte_at(mm, addr, ptep, __pte(0))
-
-#define pmd_none(x)			(!pmd_val(x))
-#define	pmd_bad(x)			((pmd_val(x) & ~PAGE_MASK))
-#define pmd_present(x)			(pmd_val(x))
-#define pmd_leaf(x)			(pmd_val(x) & _PAGE_HW_SZ)
-#define pmd_clear(xp)			do { pmd_val(*(xp)) = 0; } while (0)
-
-#define pte_page(pte)		pfn_to_page(pte_pfn(pte))
-#define mk_pte(page, prot)	pfn_pte(page_to_pfn(page), prot)
-#define pfn_pte(pfn, prot)	__pte(__pfn_to_phys(pfn) | pgprot_val(prot))
-
-/* Don't use virt_to_pfn for macros below: could cause truncations for PAE40*/
-#define pte_pfn(pte)		(pte_val(pte) >> PAGE_SHIFT)
-
-/* Zoo of pte_xxx function */
-#define pte_read(pte)		(pte_val(pte) & _PAGE_READ)
-#define pte_write(pte)		(pte_val(pte) & _PAGE_WRITE)
-#define pte_dirty(pte)		(pte_val(pte) & _PAGE_DIRTY)
-#define pte_young(pte)		(pte_val(pte) & _PAGE_ACCESSED)
-#define pte_special(pte)	(pte_val(pte) & _PAGE_SPECIAL)
-
-#define PTE_BIT_FUNC(fn, op) \
-	static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
-
-PTE_BIT_FUNC(mknotpresent,	&= ~(_PAGE_PRESENT));
-PTE_BIT_FUNC(wrprotect,	&= ~(_PAGE_WRITE));
-PTE_BIT_FUNC(mkwrite,	|= (_PAGE_WRITE));
-PTE_BIT_FUNC(mkclean,	&= ~(_PAGE_DIRTY));
-PTE_BIT_FUNC(mkdirty,	|= (_PAGE_DIRTY));
-PTE_BIT_FUNC(mkold,	&= ~(_PAGE_ACCESSED));
-PTE_BIT_FUNC(mkyoung,	|= (_PAGE_ACCESSED));
-PTE_BIT_FUNC(exprotect,	&= ~(_PAGE_EXECUTE));
-PTE_BIT_FUNC(mkexec,	|= (_PAGE_EXECUTE));
-PTE_BIT_FUNC(mkspecial,	|= (_PAGE_SPECIAL));
-PTE_BIT_FUNC(mkhuge,	|= (_PAGE_HW_SZ));
-
-static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
-{
-	return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
-}
+extern pgd_t swapper_pg_dir[] __aligned(PAGE_SIZE);
 
 /* Macro to mark a page protection as uncacheable */
 #define pgprot_noncached(prot)	(__pgprot(pgprot_val(prot) & ~_PAGE_CACHEABLE))
 
-static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
-			      pte_t *ptep, pte_t pteval)
-{
-	set_pte(ptep, pteval);
-}
-
 extern pgd_t swapper_pg_dir[] __aligned(PAGE_SIZE);
-void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
-		      pte_t *ptep);
-
-/* Encode swap {type,off} tuple into PTE
- * We reserve 13 bits for 5-bit @type, keeping bits 12-5 zero, ensuring that
- * PAGE_PRESENT is zero in a PTE holding swap "identifier"
- */
-#define __swp_entry(type, off)	((swp_entry_t) { \
-					((type) & 0x1f) | ((off) << 13) })
-
-/* Decode a PTE containing swap "identifier "into constituents */
-#define __swp_type(pte_lookalike)	(((pte_lookalike).val) & 0x1f)
-#define __swp_offset(pte_lookalike)	((pte_lookalike).val >> 13)
-
-/* NOPs, to keep generic kernel happy */
-#define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
-#define __swp_entry_to_pte(x)	((pte_t) { (x).val })
-
-#define kern_addr_valid(addr)	(1)
-
-#define pmd_pgtable(pmd)       ((pgtable_t) pmd_page_vaddr(pmd))
-
-/*
- * remap a physical page `pfn' of size `size' with page protection `prot'
- * into virtual address `from'
- */
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-#include <asm/hugepage.h>
-#endif
 
 /* to cope with aliasing VIPT cache */
 #define HAVE_ARCH_UNMAPPED_AREA
-- 
2.25.1


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

* [PATCH v2 15/19] ARC: mm: hack to allow 2 level build with 4 level code
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
                   ` (13 preceding siblings ...)
  2021-08-12 23:37 ` [PATCH v2 14/19] ARC: mm: disintegrate pgtable.h into levels and flags Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-12 23:37 ` [PATCH v2 16/19] ARC: mm: support 3 levels of page tables Vineet Gupta
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

PMD_SHIFT is mapped to PUD_SHIFT or PGD_SHIFT by asm-generic/pgtable-*
but only for !__ASSEMBLY__

tlbex.S asm code has PTRS_PER_PTE which uses PMD_SHIFT hence barfs
for CONFIG_PGTABLE_LEVEL={2,3} and works for 4.

So add a workaround local to tlbex.S - the proper fix is to change
asm-generic/pgtable-* headers to expose the defines for __ASSEMBLY__ too

Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/mm/tlbex.S | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S
index 0b4bb62fa0ab..c4a5f16444ce 100644
--- a/arch/arc/mm/tlbex.S
+++ b/arch/arc/mm/tlbex.S
@@ -145,6 +145,14 @@ ex_saved_reg1:
 ;TLB Miss handling Code
 ;============================================================================
 
+#ifndef PMD_SHIFT
+#define PMD_SHIFT PUD_SHIFT
+#endif
+
+#ifndef PUD_SHIFT
+#define PUD_SHIFT PGDIR_SHIFT
+#endif
+
 ;-----------------------------------------------------------------------------
 ; This macro does the page-table lookup for the faulting address.
 ; OUT: r0 = PTE faulted on, r1 = ptr to PTE, r2 = Faulting V-address
-- 
2.25.1


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

* [PATCH v2 16/19] ARC: mm: support 3 levels of page tables
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
                   ` (14 preceding siblings ...)
  2021-08-12 23:37 ` [PATCH v2 15/19] ARC: mm: hack to allow 2 level build with 4 level code Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-15  9:27   ` Mike Rapoport
  2021-08-12 23:37 ` [PATCH v2 17/19] ARC: mm: support 4 " Vineet Gupta
                   ` (3 subsequent siblings)
  19 siblings, 1 reply; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

ARCv2 MMU is software walked and Linux implements 2 levels of paging: pgd/pte.
Forthcoming hw will have multiple levels, so this change preps mm code
for same. It is also fun to try multi levels even on soft-walked code to
ensure generic mm code is robust to handle.

overview
________

2 levels {pgd, pte} : pmd is folded but pmd_* macros are valid and operate on pgd
3 levels {pgd, pmd, pte}:
  - pud is folded and pud_* macros point to pgd
  - pmd_* macros operate on actual pmd

code changes
____________

1. #include <asm-generic/pgtable-nopud.h>

2. Define CONFIG_PGTABLE_LEVELS 3

3a. Define PMD_SHIFT, PMD_SIZE, PMD_MASK, pmd_t
3b. Define pmd_val() which actually deals with pmd
    (pmd_offset(), pmd_index() are provided by generic code)
3c. pmd_alloc_one()/pmd_free() also provided by generic code
    (pmd_populate/pmd_free already exist)

4. Define pud_none(), pud_bad() macros based on generic pud_val() which
   internally pertains to pgd now.
4b. define pud_populate() to just setup pgd

Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/Kconfig                      |  4 ++
 arch/arc/include/asm/page.h           | 11 +++++
 arch/arc/include/asm/pgalloc.h        | 11 +++++
 arch/arc/include/asm/pgtable-levels.h | 63 ++++++++++++++++++++++++---
 arch/arc/include/asm/processor.h      |  2 +-
 arch/arc/mm/fault.c                   |  4 ++
 arch/arc/mm/init.c                    |  1 +
 arch/arc/mm/tlb.c                     |  4 +-
 arch/arc/mm/tlbex.S                   |  9 ++++
 9 files changed, 101 insertions(+), 8 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 59d5b2a179f6..43cb8aaf57a2 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -314,6 +314,10 @@ config ARC_HUGEPAGE_16M
 
 endchoice
 
+config PGTABLE_LEVELS
+	int "Number of Page table levels"
+	default 2
+
 config ARC_COMPACT_IRQ_LEVELS
 	depends on ISA_ARCOMPACT
 	bool "Setup Timer IRQ as high Priority"
diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h
index 28ed82b1800f..5d7899d87c08 100644
--- a/arch/arc/include/asm/page.h
+++ b/arch/arc/include/asm/page.h
@@ -41,6 +41,17 @@ typedef struct {
 #define pgd_val(x)	((x).pgd)
 #define __pgd(x)	((pgd_t) { (x) })
 
+#if CONFIG_PGTABLE_LEVELS > 2
+
+typedef struct {
+	unsigned long pmd;
+} pmd_t;
+
+#define pmd_val(x)	((x).pmd)
+#define __pmd(x)	((pmd_t) { (x) })
+
+#endif
+
 typedef struct {
 #ifdef CONFIG_ARC_HAS_PAE40
 	unsigned long long pte;
diff --git a/arch/arc/include/asm/pgalloc.h b/arch/arc/include/asm/pgalloc.h
index 0cde9e5eefd7..781620d2e86f 100644
--- a/arch/arc/include/asm/pgalloc.h
+++ b/arch/arc/include/asm/pgalloc.h
@@ -70,6 +70,17 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 	return ret;
 }
 
+#if CONFIG_PGTABLE_LEVELS > 2
+
+static inline void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmdp)
+{
+	set_pud(pudp, __pud((unsigned long)pmdp));
+}
+
+#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 /* _ASM_ARC_PGALLOC_H */
diff --git a/arch/arc/include/asm/pgtable-levels.h b/arch/arc/include/asm/pgtable-levels.h
index 8ece75335bb5..1c2f022d4ad0 100644
--- a/arch/arc/include/asm/pgtable-levels.h
+++ b/arch/arc/include/asm/pgtable-levels.h
@@ -10,6 +10,8 @@
 #ifndef _ASM_ARC_PGTABLE_LEVELS_H
 #define _ASM_ARC_PGTABLE_LEVELS_H
 
+#if CONFIG_PGTABLE_LEVELS == 2
+
 /*
  * 2 level paging setup for software walked MMUv3 (ARC700) and MMUv4 (HS)
  *
@@ -37,16 +39,38 @@
 #define PGDIR_SHIFT		21
 #endif
 
-#define PGDIR_SIZE		BIT(PGDIR_SHIFT)	/* vaddr span, not PDG sz */
-#define PGDIR_MASK		(~(PGDIR_SIZE - 1))
+#else
+
+/*
+ * A default 3 level paging testing setup in software walked MMU
+ *   MMUv4 (8K page): <4> : <7> : <8> : <13>
+ */
+#define PGDIR_SHIFT		28
+#if CONFIG_PGTABLE_LEVELS > 2
+#define PMD_SHIFT		21
+#endif
+
+#endif
 
+#define PGDIR_SIZE		BIT(PGDIR_SHIFT)
+#define PGDIR_MASK		(~(PGDIR_SIZE - 1))
 #define PTRS_PER_PGD		BIT(32 - PGDIR_SHIFT)
 
-#define PTRS_PER_PTE		BIT(PGDIR_SHIFT - PAGE_SHIFT)
+#if CONFIG_PGTABLE_LEVELS > 2
+#define PMD_SIZE		BIT(PMD_SHIFT)
+#define PMD_MASK		(~(PMD_SIZE - 1))
+#define PTRS_PER_PMD		BIT(PGDIR_SHIFT - PMD_SHIFT)
+#endif
+
+#define PTRS_PER_PTE		BIT(PMD_SHIFT - PAGE_SHIFT)
 
 #ifndef __ASSEMBLY__
 
+#if CONFIG_PGTABLE_LEVELS > 2
+#include <asm-generic/pgtable-nopud.h>
+#else
 #include <asm-generic/pgtable-nopmd.h>
+#endif
 
 /*
  * 1st level paging: pgd
@@ -57,9 +81,35 @@
 #define pgd_ERROR(e) \
 	pr_crit("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
 
+#if CONFIG_PGTABLE_LEVELS > 2
+
+/* In 3 level paging, pud_* macros work on pgd */
+#define pud_none(x)		(!pud_val(x))
+#define pud_bad(x)		((pud_val(x) & ~PAGE_MASK))
+#define pud_present(x)		(pud_val(x))
+#define pud_clear(xp)		do { pud_val(*(xp)) = 0; } while (0)
+#define pud_pgtable(pud)	((pmd_t *)(pud_val(pud) & PAGE_MASK))
+#define pud_page(pud)		virt_to_page(pud_pgtable(pud))
+#define set_pud(pudp, pud)	(*(pudp) = pud)
+
+/*
+ * 2nd level paging: pmd
+ */
+#define pmd_ERROR(e) \
+	pr_crit("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+
+#define pmd_pfn(pmd)		((pmd_val(pmd) & PMD_MASK) >> PAGE_SHIFT)
+#define pfn_pmd(pfn,prot)	__pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+#define mk_pmd(page,prot)	pfn_pmd(page_to_pfn(page),prot)
+
+#endif
+
 /*
- * Due to the strange way generic pgtable level folding works, in a 2 level
- * setup, pmd_val() returns pgd, so these pmd_* macros actually work on pgd
+ * Due to the strange way generic pgtable level folding works, the pmd_* macros
+ *  - are valid even for 2 levels (which supposedly only has pgd - pte)
+ *  - behave differently for 2 vs. 3
+ * In 2  level paging        (pgd -> pte), pmd_* macros work on pgd
+ * In 3+ level paging (pgd -> pmd -> pte), pmd_* macros work on pmd
  */
 #define pmd_none(x)		(!pmd_val(x))
 #define pmd_bad(x)		((pmd_val(x) & ~PAGE_MASK))
@@ -70,6 +120,9 @@
 #define set_pmd(pmdp, pmd)	(*(pmdp) = pmd)
 #define pmd_pgtable(pmd)	((pgtable_t) pmd_page_vaddr(pmd))
 
+/*
+ * 3rd level paging: pte
+ */
 #define pte_ERROR(e) \
 	pr_crit("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
 
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index e4031ecd3c8c..f28afcf5c6d1 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -93,7 +93,7 @@ extern unsigned int get_wchan(struct task_struct *p);
 #define VMALLOC_START	(PAGE_OFFSET - (CONFIG_ARC_KVADDR_SIZE << 20))
 
 /* 1 PGDIR_SIZE each for fixmap/pkmap, 2 PGDIR_SIZE gutter (see asm/highmem.h) */
-#define VMALLOC_SIZE	((CONFIG_ARC_KVADDR_SIZE << 20) - PGDIR_SIZE * 4)
+#define VMALLOC_SIZE	((CONFIG_ARC_KVADDR_SIZE << 20) - PMD_SIZE * 4)
 
 #define VMALLOC_END	(VMALLOC_START + VMALLOC_SIZE)
 
diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c
index 41f154320964..8da2f0ad8c69 100644
--- a/arch/arc/mm/fault.c
+++ b/arch/arc/mm/fault.c
@@ -39,6 +39,8 @@ noinline static int handle_kernel_vaddr_fault(unsigned long address)
 	if (!pgd_present(*pgd_k))
 		goto bad_area;
 
+	set_pgd(pgd, *pgd_k);
+
 	p4d = p4d_offset(pgd, address);
 	p4d_k = p4d_offset(pgd_k, address);
 	if (!p4d_present(*p4d_k))
@@ -49,6 +51,8 @@ noinline static int handle_kernel_vaddr_fault(unsigned long address)
 	if (!pud_present(*pud_k))
 		goto bad_area;
 
+	set_pud(pud, *pud_k);
+
 	pmd = pmd_offset(pud, address);
 	pmd_k = pmd_offset(pud_k, address);
 	if (!pmd_present(*pmd_k))
diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c
index 46ad9aee7a73..f7ba2a5d5ec8 100644
--- a/arch/arc/mm/init.c
+++ b/arch/arc/mm/init.c
@@ -191,6 +191,7 @@ void __init mem_init(void)
 	highmem_init();
 
 	BUILD_BUG_ON((PTRS_PER_PGD * sizeof(pgd_t)) > PAGE_SIZE);
+	BUILD_BUG_ON((PTRS_PER_PMD * sizeof(pmd_t)) > PAGE_SIZE);
 	BUILD_BUG_ON((PTRS_PER_PTE * sizeof(pte_t)) > PAGE_SIZE);
 }
 
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index b68d5798327b..352abb35a2ad 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -658,8 +658,8 @@ char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len)
 			  IS_USED_CFG(CONFIG_TRANSPARENT_HUGEPAGE));
 
 	n += scnprintf(buf + n, len - n,
-		      "MMU [v%x]\t: %dk PAGE, %sJTLB %d (%dx%d), uDTLB %d, uITLB %d%s%s\n",
-		       p_mmu->ver, p_mmu->pg_sz_k, super_pg,
+		      "MMU [v%x]\t: %dk PAGE, %s, swalk %d lvl, JTLB %d (%dx%d), uDTLB %d, uITLB %d%s%s\n",
+		       p_mmu->ver, p_mmu->pg_sz_k, super_pg,  CONFIG_PGTABLE_LEVELS,
 		       p_mmu->sets * p_mmu->ways, p_mmu->sets, p_mmu->ways,
 		       p_mmu->u_dtlb, p_mmu->u_itlb,
 		       IS_AVAIL2(p_mmu->pae, ", PAE40 ", CONFIG_ARC_HAS_PAE40));
diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S
index c4a5f16444ce..5f57eba1089d 100644
--- a/arch/arc/mm/tlbex.S
+++ b/arch/arc/mm/tlbex.S
@@ -173,6 +173,15 @@ ex_saved_reg1:
 	tst	r3, r3
 	bz	do_slow_path_pf         ; if no Page Table, do page fault
 
+#if CONFIG_PGTABLE_LEVELS > 2
+	lsr     r0, r2, PMD_SHIFT	; Bits for indexing into PMD
+	and	r0, r0, (PTRS_PER_PMD - 1)
+	ld.as	r1, [r3, r0]		; PMD entry
+	tst	r1, r1
+	bz	do_slow_path_pf
+	mov	r3, r1
+#endif
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 	and.f	0, r3, _PAGE_HW_SZ	; Is this Huge PMD (thp)
 	add2.nz	r1, r1, r0
-- 
2.25.1


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

* [PATCH v2 17/19] ARC: mm: support 4 levels of page tables
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
                   ` (15 preceding siblings ...)
  2021-08-12 23:37 ` [PATCH v2 16/19] ARC: mm: support 3 levels of page tables Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-12 23:37 ` [PATCH v2 18/19] ARC: mm: vmalloc sync from kernel to user table to update PMD Vineet Gupta
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/include/asm/page.h           | 11 +++++++
 arch/arc/include/asm/pgalloc.h        | 11 +++++++
 arch/arc/include/asm/pgtable-levels.h | 45 ++++++++++++++++++++++++---
 arch/arc/mm/fault.c                   |  2 ++
 arch/arc/mm/init.c                    |  1 +
 arch/arc/mm/tlbex.S                   |  9 ++++++
 6 files changed, 74 insertions(+), 5 deletions(-)

diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h
index 5d7899d87c08..9a62e1d87967 100644
--- a/arch/arc/include/asm/page.h
+++ b/arch/arc/include/asm/page.h
@@ -41,6 +41,17 @@ typedef struct {
 #define pgd_val(x)	((x).pgd)
 #define __pgd(x)	((pgd_t) { (x) })
 
+#if CONFIG_PGTABLE_LEVELS > 3
+
+typedef struct {
+	unsigned long pud;
+} pud_t;
+
+#define pud_val(x)      	((x).pud)
+#define __pud(x)        	((pud_t) { (x) })
+
+#endif
+
 #if CONFIG_PGTABLE_LEVELS > 2
 
 typedef struct {
diff --git a/arch/arc/include/asm/pgalloc.h b/arch/arc/include/asm/pgalloc.h
index 781620d2e86f..096b8ef58edb 100644
--- a/arch/arc/include/asm/pgalloc.h
+++ b/arch/arc/include/asm/pgalloc.h
@@ -70,6 +70,17 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 	return ret;
 }
 
+#if CONFIG_PGTABLE_LEVELS > 3
+
+static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4dp, pud_t *pudp)
+{
+	set_p4d(p4dp, __p4d((unsigned long)pudp));
+}
+
+#define __pud_free_tlb(tlb, pmd, addr)  pud_free((tlb)->mm, pmd)
+
+#endif
+
 #if CONFIG_PGTABLE_LEVELS > 2
 
 static inline void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmdp)
diff --git a/arch/arc/include/asm/pgtable-levels.h b/arch/arc/include/asm/pgtable-levels.h
index 1c2f022d4ad0..2da3c4e52a91 100644
--- a/arch/arc/include/asm/pgtable-levels.h
+++ b/arch/arc/include/asm/pgtable-levels.h
@@ -44,8 +44,13 @@
 /*
  * A default 3 level paging testing setup in software walked MMU
  *   MMUv4 (8K page): <4> : <7> : <8> : <13>
+ * A default 4 level paging testing setup in software walked MMU
+ *   MMUv4 (8K page): <4> : <3> : <4> : <8> : <13>
  */
 #define PGDIR_SHIFT		28
+#if CONFIG_PGTABLE_LEVELS > 3
+#define PUD_SHIFT		25
+#endif
 #if CONFIG_PGTABLE_LEVELS > 2
 #define PMD_SHIFT		21
 #endif
@@ -56,17 +61,25 @@
 #define PGDIR_MASK		(~(PGDIR_SIZE - 1))
 #define PTRS_PER_PGD		BIT(32 - PGDIR_SHIFT)
 
+#if CONFIG_PGTABLE_LEVELS > 3
+#define PUD_SIZE		BIT(PUD_SHIFT)
+#define PUD_MASK		(~(PUD_SIZE - 1))
+#define PTRS_PER_PUD		BIT(PGDIR_SHIFT - PUD_SHIFT)
+#endif
+
 #if CONFIG_PGTABLE_LEVELS > 2
 #define PMD_SIZE		BIT(PMD_SHIFT)
 #define PMD_MASK		(~(PMD_SIZE - 1))
-#define PTRS_PER_PMD		BIT(PGDIR_SHIFT - PMD_SHIFT)
+#define PTRS_PER_PMD		BIT(PUD_SHIFT - PMD_SHIFT)
 #endif
 
 #define PTRS_PER_PTE		BIT(PMD_SHIFT - PAGE_SHIFT)
 
 #ifndef __ASSEMBLY__
 
-#if CONFIG_PGTABLE_LEVELS > 2
+#if CONFIG_PGTABLE_LEVELS > 3
+#include <asm-generic/pgtable-nop4d.h>
+#elif CONFIG_PGTABLE_LEVELS > 2
 #include <asm-generic/pgtable-nopud.h>
 #else
 #include <asm-generic/pgtable-nopmd.h>
@@ -81,9 +94,31 @@
 #define pgd_ERROR(e) \
 	pr_crit("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
 
+#if CONFIG_PGTABLE_LEVELS > 3
+
+/* In 4 level paging, p4d_* macros work on pgd */
+#define p4d_none(x)		(!p4d_val(x))
+#define p4d_bad(x)		((p4d_val(x) & ~PAGE_MASK))
+#define p4d_present(x)		(p4d_val(x))
+#define p4d_clear(xp)		do { p4d_val(*(xp)) = 0; } while (0)
+#define p4d_pgtable(p4d)	((pud_t *)(p4d_val(p4d) & PAGE_MASK))
+#define p4d_page(p4d)		virt_to_page(p4d_pgtable(p4d))
+#define set_p4d(p4dp, p4d)	(*(p4dp) = p4d)
+
+/*
+ * 2nd level paging: pud
+ */
+#define pud_ERROR(e) \
+	pr_crit("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e))
+
+#endif
+
 #if CONFIG_PGTABLE_LEVELS > 2
 
-/* In 3 level paging, pud_* macros work on pgd */
+/*
+ * In 3 level paging, pud_* macros work on pgd
+ * In 4 level paging, pud_* macros work on pud
+ */
 #define pud_none(x)		(!pud_val(x))
 #define pud_bad(x)		((pud_val(x) & ~PAGE_MASK))
 #define pud_present(x)		(pud_val(x))
@@ -93,7 +128,7 @@
 #define set_pud(pudp, pud)	(*(pudp) = pud)
 
 /*
- * 2nd level paging: pmd
+ * 3rd level paging: pmd
  */
 #define pmd_ERROR(e) \
 	pr_crit("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
@@ -121,7 +156,7 @@
 #define pmd_pgtable(pmd)	((pgtable_t) pmd_page_vaddr(pmd))
 
 /*
- * 3rd level paging: pte
+ * 4th level paging: pte
  */
 #define pte_ERROR(e) \
 	pr_crit("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c
index 8da2f0ad8c69..f8994164fa36 100644
--- a/arch/arc/mm/fault.c
+++ b/arch/arc/mm/fault.c
@@ -46,6 +46,8 @@ noinline static int handle_kernel_vaddr_fault(unsigned long address)
 	if (!p4d_present(*p4d_k))
 		goto bad_area;
 
+	set_p4d(p4d, *p4d_k);
+
 	pud = pud_offset(p4d, address);
 	pud_k = pud_offset(p4d_k, address);
 	if (!pud_present(*pud_k))
diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c
index f7ba2a5d5ec8..699ecf119641 100644
--- a/arch/arc/mm/init.c
+++ b/arch/arc/mm/init.c
@@ -191,6 +191,7 @@ void __init mem_init(void)
 	highmem_init();
 
 	BUILD_BUG_ON((PTRS_PER_PGD * sizeof(pgd_t)) > PAGE_SIZE);
+	BUILD_BUG_ON((PTRS_PER_PUD * sizeof(pud_t)) > PAGE_SIZE);
 	BUILD_BUG_ON((PTRS_PER_PMD * sizeof(pmd_t)) > PAGE_SIZE);
 	BUILD_BUG_ON((PTRS_PER_PTE * sizeof(pte_t)) > PAGE_SIZE);
 }
diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S
index 5f57eba1089d..e054780a8fe0 100644
--- a/arch/arc/mm/tlbex.S
+++ b/arch/arc/mm/tlbex.S
@@ -173,6 +173,15 @@ ex_saved_reg1:
 	tst	r3, r3
 	bz	do_slow_path_pf         ; if no Page Table, do page fault
 
+#if CONFIG_PGTABLE_LEVELS > 3
+	lsr     r0, r2, PUD_SHIFT	; Bits for indexing into PUD
+	and	r0, r0, (PTRS_PER_PUD - 1)
+	ld.as	r1, [r3, r0]		; PMD entry
+	tst	r1, r1
+	bz	do_slow_path_pf
+	mov	r3, r1
+#endif
+
 #if CONFIG_PGTABLE_LEVELS > 2
 	lsr     r0, r2, PMD_SHIFT	; Bits for indexing into PMD
 	and	r0, r0, (PTRS_PER_PMD - 1)
-- 
2.25.1


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

* [PATCH v2 18/19] ARC: mm: vmalloc sync from kernel to user table to update PMD ...
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
                   ` (16 preceding siblings ...)
  2021-08-12 23:37 ` [PATCH v2 17/19] ARC: mm: support 4 " Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-12 23:37 ` [PATCH v2 19/19] ARC: mm: introduce _PAGE_TABLE to explicitly link pgd,pud,pmd entries Vineet Gupta
  2021-08-15  9:26 ` [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Mike Rapoport
  19 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

... not PGD

vmalloc() sets up the kernel page table (starting from @swapper_pg_dir).
But when vmalloc area is accessed in context of a user task, say opening
terminal in n_tty_open(), the user page tables need to be synced from
kernel page tables so that TLB entry is created in "user context".

The old code was doing this incorrectly, as it was updating the user pgd
entry (first level itself) to point to kernel pud table (2nd level),
effectively yanking away the entire user space translation with kernel one.

The correct way to do this is to ONLY update a user space pgd/pud/pmd entry
if it is not popluated already. This ensures that only the missing leaf
pmd entry gets updated to point to relevant kernel pte table.

From code change pov, we are chaging the pattern:

	p4d = p4d_offset(pgd, address);
	p4d_k = p4d_offset(pgd_k, address);
	if (!p4d_present(*p4d_k))
		goto bad_area;
	set_p4d(p4d, *p4d_k);

with
	p4d = p4d_offset(pgd, address);
	p4d_k = p4d_offset(pgd_k, address);
	if (p4d_none(*p4d_k))
		goto bad_area;
	if (!p4d_present(*p4d))
		set_p4d(p4d, *p4d_k);

Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/mm/fault.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c
index f8994164fa36..5787c261c9a4 100644
--- a/arch/arc/mm/fault.c
+++ b/arch/arc/mm/fault.c
@@ -36,31 +36,31 @@ noinline static int handle_kernel_vaddr_fault(unsigned long address)
 	pgd = pgd_offset(current->active_mm, address);
 	pgd_k = pgd_offset_k(address);
 
-	if (!pgd_present(*pgd_k))
+	if (pgd_none (*pgd_k))
 		goto bad_area;
-
-	set_pgd(pgd, *pgd_k);
+	if (!pgd_present(*pgd))
+		set_pgd(pgd, *pgd_k);
 
 	p4d = p4d_offset(pgd, address);
 	p4d_k = p4d_offset(pgd_k, address);
-	if (!p4d_present(*p4d_k))
+	if (p4d_none(*p4d_k))
 		goto bad_area;
-
-	set_p4d(p4d, *p4d_k);
+	if (!p4d_present(*p4d))
+		set_p4d(p4d, *p4d_k);
 
 	pud = pud_offset(p4d, address);
 	pud_k = pud_offset(p4d_k, address);
-	if (!pud_present(*pud_k))
+	if (pud_none(*pud_k))
 		goto bad_area;
-
-	set_pud(pud, *pud_k);
+	if (!pud_present(*pud))
+		set_pud(pud, *pud_k);
 
 	pmd = pmd_offset(pud, address);
 	pmd_k = pmd_offset(pud_k, address);
-	if (!pmd_present(*pmd_k))
+	if (pmd_none(*pmd_k))
 		goto bad_area;
-
-	set_pmd(pmd, *pmd_k);
+	if (!pmd_present(*pmd))
+		set_pmd(pmd, *pmd_k);
 
 	/* XXX: create the TLB entry here */
 	return 0;
-- 
2.25.1


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

* [PATCH v2 19/19] ARC: mm: introduce _PAGE_TABLE to explicitly link pgd,pud,pmd entries
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
                   ` (17 preceding siblings ...)
  2021-08-12 23:37 ` [PATCH v2 18/19] ARC: mm: vmalloc sync from kernel to user table to update PMD Vineet Gupta
@ 2021-08-12 23:37 ` Vineet Gupta
  2021-08-15  9:26 ` [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Mike Rapoport
  19 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-12 23:37 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport, Vineet Gupta

ARCv3 hardware walker expects Table Descriptors to have b'11 in LSB bits
to continue moving to next level.

This commits adds that (to ARCv2 code) and ensures that it works in
software walked regime.

The pte entries stil need tagging, but that is not possible in ARCv2
since the LSB 2 bits are currently used.

Signed-off-by: Vineet Gupta <vgupta@kernel.org>
---
 arch/arc/include/asm/pgalloc.h            | 8 ++++----
 arch/arc/include/asm/pgtable-bits-arcv2.h | 2 ++
 arch/arc/include/asm/pgtable-levels.h     | 6 +++---
 arch/arc/mm/tlbex.S                       | 4 +++-
 4 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/arch/arc/include/asm/pgalloc.h b/arch/arc/include/asm/pgalloc.h
index 096b8ef58edb..a8c01eceba1b 100644
--- a/arch/arc/include/asm/pgalloc.h
+++ b/arch/arc/include/asm/pgalloc.h
@@ -43,12 +43,12 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
 	 *
 	 * The cast itself is needed given simplistic definition of set_pmd()
 	 */
-	set_pmd(pmd, __pmd((unsigned long)pte));
+	set_pmd(pmd, __pmd((unsigned long)pte | _PAGE_TABLE));
 }
 
 static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t pte_page)
 {
-	set_pmd(pmd, __pmd((unsigned long)page_address(pte_page)));
+	set_pmd(pmd, __pmd((unsigned long)page_address(pte_page) | _PAGE_TABLE));
 }
 
 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
@@ -74,7 +74,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 
 static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4dp, pud_t *pudp)
 {
-	set_p4d(p4dp, __p4d((unsigned long)pudp));
+	set_p4d(p4dp, __p4d((unsigned long)pudp | _PAGE_TABLE));
 }
 
 #define __pud_free_tlb(tlb, pmd, addr)  pud_free((tlb)->mm, pmd)
@@ -85,7 +85,7 @@ static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4dp, pud_t *pudp)
 
 static inline void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmdp)
 {
-	set_pud(pudp, __pud((unsigned long)pmdp));
+	set_pud(pudp, __pud((unsigned long)pmdp | _PAGE_TABLE));
 }
 
 #define __pmd_free_tlb(tlb, pmd, addr)  pmd_free((tlb)->mm, pmd)
diff --git a/arch/arc/include/asm/pgtable-bits-arcv2.h b/arch/arc/include/asm/pgtable-bits-arcv2.h
index 183d23bc1e00..54aba0d3ae34 100644
--- a/arch/arc/include/asm/pgtable-bits-arcv2.h
+++ b/arch/arc/include/asm/pgtable-bits-arcv2.h
@@ -32,6 +32,8 @@
 #define _PAGE_HW_SZ		0
 #endif
 
+#define _PAGE_TABLE		0x3
+
 /* Defaults for every user page */
 #define ___DEF		(_PAGE_PRESENT | _PAGE_CACHEABLE)
 
diff --git a/arch/arc/include/asm/pgtable-levels.h b/arch/arc/include/asm/pgtable-levels.h
index 2da3c4e52a91..6c7a8360d986 100644
--- a/arch/arc/include/asm/pgtable-levels.h
+++ b/arch/arc/include/asm/pgtable-levels.h
@@ -98,7 +98,7 @@
 
 /* In 4 level paging, p4d_* macros work on pgd */
 #define p4d_none(x)		(!p4d_val(x))
-#define p4d_bad(x)		((p4d_val(x) & ~PAGE_MASK))
+#define p4d_bad(x)		(!(p4d_val(x) & _PAGE_TABLE))
 #define p4d_present(x)		(p4d_val(x))
 #define p4d_clear(xp)		do { p4d_val(*(xp)) = 0; } while (0)
 #define p4d_pgtable(p4d)	((pud_t *)(p4d_val(p4d) & PAGE_MASK))
@@ -120,7 +120,7 @@
  * In 4 level paging, pud_* macros work on pud
  */
 #define pud_none(x)		(!pud_val(x))
-#define pud_bad(x)		((pud_val(x) & ~PAGE_MASK))
+#define pud_bad(x)		(!(pud_val(x) & _PAGE_TABLE))
 #define pud_present(x)		(pud_val(x))
 #define pud_clear(xp)		do { pud_val(*(xp)) = 0; } while (0)
 #define pud_pgtable(pud)	((pmd_t *)(pud_val(pud) & PAGE_MASK))
@@ -147,7 +147,7 @@
  * In 3+ level paging (pgd -> pmd -> pte), pmd_* macros work on pmd
  */
 #define pmd_none(x)		(!pmd_val(x))
-#define pmd_bad(x)		((pmd_val(x) & ~PAGE_MASK))
+#define pmd_bad(pmd)		(!(pmd_val(pmd) & _PAGE_TABLE))
 #define pmd_present(x)		(pmd_val(x))
 #define pmd_clear(xp)		do { pmd_val(*(xp)) = 0; } while (0)
 #define pmd_page_vaddr(pmd)	(pmd_val(pmd) & PAGE_MASK)
diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S
index e054780a8fe0..3874a8086591 100644
--- a/arch/arc/mm/tlbex.S
+++ b/arch/arc/mm/tlbex.S
@@ -171,11 +171,12 @@ ex_saved_reg1:
 	lsr     r0, r2, PGDIR_SHIFT     ; Bits for indexing into PGD
 	ld.as   r3, [r1, r0]            ; PGD entry corresp to faulting addr
 	tst	r3, r3
-	bz	do_slow_path_pf         ; if no Page Table, do page fault
+	bz	do_slow_path_pf         ; next level table missing, handover to linux vm code
 
 #if CONFIG_PGTABLE_LEVELS > 3
 	lsr     r0, r2, PUD_SHIFT	; Bits for indexing into PUD
 	and	r0, r0, (PTRS_PER_PUD - 1)
+	bmskn	r3, r3, 1		; clear _PAGE_TABLE bits
 	ld.as	r1, [r3, r0]		; PMD entry
 	tst	r1, r1
 	bz	do_slow_path_pf
@@ -185,6 +186,7 @@ ex_saved_reg1:
 #if CONFIG_PGTABLE_LEVELS > 2
 	lsr     r0, r2, PMD_SHIFT	; Bits for indexing into PMD
 	and	r0, r0, (PTRS_PER_PMD - 1)
+	bmskn	r3, r3, 1		; clear _PAGE_TABLE bits
 	ld.as	r1, [r3, r0]		; PMD entry
 	tst	r1, r1
 	bz	do_slow_path_pf
-- 
2.25.1


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

* Re: [PATCH v2 13/19] ARC: mm: disintegrate mmu.h (arcv2 bits out)
  2021-08-12 23:37 ` [PATCH v2 13/19] ARC: mm: disintegrate mmu.h (arcv2 bits out) Vineet Gupta
@ 2021-08-13  4:01   ` kernel test robot
  2021-08-13 14:48     ` Vineet Gupta
  0 siblings, 1 reply; 34+ messages in thread
From: kernel test robot @ 2021-08-13  4:01 UTC (permalink / raw)
  To: Vineet Gupta, linux-snps-arc
  Cc: kbuild-all, linux-kernel, linux-mm, Anshuman Khandual,
	Mike Rapoport, Vineet Gupta

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

Hi Vineet,

I love your patch! Yet something to improve:

[auto build test ERROR on arc/for-next]
[also build test ERROR on next-20210812]
[cannot apply to linux/master linus/master v5.14-rc5]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Vineet-Gupta/ARC-mm-updates-support-3-4-levels-and-asm-generic-pgalloc/20210813-074023
base:   https://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git for-next
config: arc-allyesconfig (attached as .config)
compiler: arceb-elf-gcc (GCC) 10.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/0411d3a95cb73722d026f7b3d9c9d8abab8c0d79
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Vineet-Gupta/ARC-mm-updates-support-3-4-levels-and-asm-generic-pgalloc/20210813-074023
        git checkout 0411d3a95cb73722d026f7b3d9c9d8abab8c0d79
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross ARCH=arc 

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

All errors (new ones prefixed by >>):

   In file included from arch/arc/include/asm/mmu.h:19,
                    from include/linux/mm_types.h:19,
                    from include/linux/buildid.h:5,
                    from include/linux/module.h:14,
                    from lib/test_bitops.c:9:
>> arch/arc/include/asm/mmu-arcv2.h:80:1: error: 'inline' is not at beginning of declaration [-Werror=old-style-declaration]
      80 | static void inline mmu_setup_asid(struct mm_struct *mm, unsigned long asid)
         | ^~~~~~
   arch/arc/include/asm/mmu-arcv2.h:85:1: error: 'inline' is not at beginning of declaration [-Werror=old-style-declaration]
      85 | static void inline mmu_setup_pgd(struct mm_struct *mm, void *pgd)
         | ^~~~~~
   cc1: all warnings being treated as errors


vim +/inline +80 arch/arc/include/asm/mmu-arcv2.h

    79	
  > 80	static void inline mmu_setup_asid(struct mm_struct *mm, unsigned long asid)
    81	{
    82		write_aux_reg(ARC_REG_PID, asid | MMU_ENABLE);
    83	}
    84	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

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

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

* Re: [PATCH v2 08/19] ARC: mm: switch pgtable_t back to struct page *
  2021-08-12 23:37 ` [PATCH v2 08/19] ARC: mm: switch pgtable_t back to struct page * Vineet Gupta
@ 2021-08-13 10:45   ` kernel test robot
  2021-08-13 14:25     ` Vineet Gupta
  0 siblings, 1 reply; 34+ messages in thread
From: kernel test robot @ 2021-08-13 10:45 UTC (permalink / raw)
  To: Vineet Gupta, linux-snps-arc
  Cc: kbuild-all, linux-kernel, linux-mm, Anshuman Khandual,
	Mike Rapoport, Vineet Gupta

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

Hi Vineet,

I love your patch! Yet something to improve:

[auto build test ERROR on arc/for-next]
[also build test ERROR on linux/master linus/master v5.14-rc5 next-20210812]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Vineet-Gupta/ARC-mm-updates-support-3-4-levels-and-asm-generic-pgalloc/20210813-074023
base:   https://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git for-next
config: arc-randconfig-s032-20210812 (attached as .config)
compiler: arceb-elf-gcc (GCC) 10.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.3-348-gf0e6938b-dirty
        # https://github.com/0day-ci/linux/commit/36e618e081c5a49b2aff51823c5f012045e902ef
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Vineet-Gupta/ARC-mm-updates-support-3-4-levels-and-asm-generic-pgalloc/20210813-074023
        git checkout 36e618e081c5a49b2aff51823c5f012045e902ef
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=arc 

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

All errors (new ones prefixed by >>):

   arch/arc/mm/init.c:35:13: warning: no previous prototype for 'arc_get_mem_sz' [-Wmissing-prototypes]
      35 | long __init arc_get_mem_sz(void)
         |             ^~~~~~~~~~~~~~
   arch/arc/mm/init.c:88:13: warning: no previous prototype for 'setup_arch_memory' [-Wmissing-prototypes]
      88 | void __init setup_arch_memory(void)
         |             ^~~~~~~~~~~~~~~~~
   In file included from <command-line>:
   arch/arc/mm/init.c: In function 'mem_init':
>> include/linux/compiler_types.h:328:38: error: call to '__compiletime_assert_328' declared with attribute error: BUILD_BUG_ON failed: (PTRS_PER_PGD * sizeof(pgd_t)) > PAGE_SIZE
     328 |  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
         |                                      ^
   include/linux/compiler_types.h:309:4: note: in definition of macro '__compiletime_assert'
     309 |    prefix ## suffix();    \
         |    ^~~~~~
   include/linux/compiler_types.h:328:2: note: in expansion of macro '_compiletime_assert'
     328 |  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
         |  ^~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
      39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
         |                                     ^~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:50:2: note: in expansion of macro 'BUILD_BUG_ON_MSG'
      50 |  BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
         |  ^~~~~~~~~~~~~~~~
   arch/arc/mm/init.c:193:2: note: in expansion of macro 'BUILD_BUG_ON'
     193 |  BUILD_BUG_ON((PTRS_PER_PGD * sizeof(pgd_t)) > PAGE_SIZE);
         |  ^~~~~~~~~~~~


vim +/__compiletime_assert_328 +328 include/linux/compiler_types.h

eb5c2d4b45e3d2 Will Deacon 2020-07-21  314  
eb5c2d4b45e3d2 Will Deacon 2020-07-21  315  #define _compiletime_assert(condition, msg, prefix, suffix) \
eb5c2d4b45e3d2 Will Deacon 2020-07-21  316  	__compiletime_assert(condition, msg, prefix, suffix)
eb5c2d4b45e3d2 Will Deacon 2020-07-21  317  
eb5c2d4b45e3d2 Will Deacon 2020-07-21  318  /**
eb5c2d4b45e3d2 Will Deacon 2020-07-21  319   * compiletime_assert - break build and emit msg if condition is false
eb5c2d4b45e3d2 Will Deacon 2020-07-21  320   * @condition: a compile-time constant condition to check
eb5c2d4b45e3d2 Will Deacon 2020-07-21  321   * @msg:       a message to emit if condition is false
eb5c2d4b45e3d2 Will Deacon 2020-07-21  322   *
eb5c2d4b45e3d2 Will Deacon 2020-07-21  323   * In tradition of POSIX assert, this macro will break the build if the
eb5c2d4b45e3d2 Will Deacon 2020-07-21  324   * supplied condition is *false*, emitting the supplied error message if the
eb5c2d4b45e3d2 Will Deacon 2020-07-21  325   * compiler has support to do so.
eb5c2d4b45e3d2 Will Deacon 2020-07-21  326   */
eb5c2d4b45e3d2 Will Deacon 2020-07-21  327  #define compiletime_assert(condition, msg) \
eb5c2d4b45e3d2 Will Deacon 2020-07-21 @328  	_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
eb5c2d4b45e3d2 Will Deacon 2020-07-21  329  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

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

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

* Re: [PATCH v2 08/19] ARC: mm: switch pgtable_t back to struct page *
  2021-08-13 10:45   ` kernel test robot
@ 2021-08-13 14:25     ` Vineet Gupta
  0 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-13 14:25 UTC (permalink / raw)
  To: kernel test robot, linux-snps-arc
  Cc: kbuild-all, linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport

On 8/13/21 3:45 AM, kernel test robot wrote:
> Hi Vineet,
>
> I love your patch! Yet something to improve:
>
> [auto build test ERROR on arc/for-next]
> [also build test ERROR on linux/master linus/master v5.14-rc5 next-20210812]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
>
> url:    https://github.com/0day-ci/linux/commits/Vineet-Gupta/ARC-mm-updates-support-3-4-levels-and-asm-generic-pgalloc/20210813-074023
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git for-next
> config: arc-randconfig-s032-20210812 (attached as .config)
> compiler: arceb-elf-gcc (GCC) 10.3.0
> reproduce:
>          wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>          chmod +x ~/bin/make.cross
>          # apt-get install sparse
>          # sparse version: v0.6.3-348-gf0e6938b-dirty
>          # https://github.com/0day-ci/linux/commit/36e618e081c5a49b2aff51823c5f012045e902ef
>          git remote add linux-review https://github.com/0day-ci/linux
>          git fetch --no-tags linux-review Vineet-Gupta/ARC-mm-updates-support-3-4-levels-and-asm-generic-pgalloc/20210813-074023
>          git checkout 36e618e081c5a49b2aff51823c5f012045e902ef
>          # save the attached .config to linux build tree
>          COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=arc
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
>
> All errors (new ones prefixed by >>):
>
>     arch/arc/mm/init.c:35:13: warning: no previous prototype for 'arc_get_mem_sz' [-Wmissing-prototypes]
>        35 | long __init arc_get_mem_sz(void)
>           |             ^~~~~~~~~~~~~~
>     arch/arc/mm/init.c:88:13: warning: no previous prototype for 'setup_arch_memory' [-Wmissing-prototypes]
>        88 | void __init setup_arch_memory(void)
>           |             ^~~~~~~~~~~~~~~~~
>     In file included from <command-line>:
>     arch/arc/mm/init.c: In function 'mem_init':
>>> include/linux/compiler_types.h:328:38: error: call to '__compiletime_assert_328' declared with attribute error: BUILD_BUG_ON failed: (PTRS_PER_PGD * sizeof(pgd_t)) > PAGE_SIZE
>       328 |  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>           |                                      ^
>     include/linux/compiler_types.h:309:4: note: in definition of macro '__compiletime_assert'
>       309 |    prefix ## suffix();    \
>           |    ^~~~~~
>     include/linux/compiler_types.h:328:2: note: in expansion of macro '_compiletime_assert'
>       328 |  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>           |  ^~~~~~~~~~~~~~~~~~~
>     include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
>        39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
>           |                                     ^~~~~~~~~~~~~~~~~~
>     include/linux/build_bug.h:50:2: note: in expansion of macro 'BUILD_BUG_ON_MSG'
>        50 |  BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
>           |  ^~~~~~~~~~~~~~~~
>     arch/arc/mm/init.c:193:2: note: in expansion of macro 'BUILD_BUG_ON'
>       193 |  BUILD_BUG_ON((PTRS_PER_PGD * sizeof(pgd_t)) > PAGE_SIZE);
>           |  ^~~~~~~~~~~~
>

Thx for the report. This is 4K page config, where PGDIR_SHIFT 21 causes 
32-21 = 11 bits or 2k entries which won't fit in 4k page.
I've added the fix and added Tested-by.

-Vineet

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

* Re: [PATCH v2 13/19] ARC: mm: disintegrate mmu.h (arcv2 bits out)
  2021-08-13  4:01   ` kernel test robot
@ 2021-08-13 14:48     ` Vineet Gupta
  0 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-13 14:48 UTC (permalink / raw)
  To: kernel test robot, Vineet Gupta, linux-snps-arc
  Cc: kbuild-all, linux-kernel, linux-mm, Anshuman Khandual, Mike Rapoport

On 8/12/21 9:01 PM, kernel test robot wrote:
> Hi Vineet,
>
> I love your patch! Yet something to improve:
>
> [auto build test ERROR on arc/for-next]
> [also build test ERROR on next-20210812]
> [cannot apply to linux/master linus/master v5.14-rc5]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
>
> url:https://github.com/0day-ci/linux/commits/Vineet-Gupta/ARC-mm-updates-support-3-4-levels-and-asm-generic-pgalloc/20210813-074023
> base:https://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git  for-next
> config: arc-allyesconfig (attached as .config)
> compiler: arceb-elf-gcc (GCC) 10.3.0
> reproduce (this is a W=1 build):
>          wgethttps://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross  -O ~/bin/make.cross
>          chmod +x ~/bin/make.cross
>          #https://github.com/0day-ci/linux/commit/0411d3a95cb73722d026f7b3d9c9d8abab8c0d79
>          git remote add linux-reviewhttps://github.com/0day-ci/linux
>          git fetch --no-tags linux-review Vineet-Gupta/ARC-mm-updates-support-3-4-levels-and-asm-generic-pgalloc/20210813-074023
>          git checkout 0411d3a95cb73722d026f7b3d9c9d8abab8c0d79
>          # save the attached .config to linux build tree
>          COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross ARCH=arc
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot<lkp@intel.com>
>
> All errors (new ones prefixed by >>):
>
>     In file included from arch/arc/include/asm/mmu.h:19,
>                      from include/linux/mm_types.h:19,
>                      from include/linux/buildid.h:5,
>                      from include/linux/module.h:14,
>                      from lib/test_bitops.c:9:
>>> arch/arc/include/asm/mmu-arcv2.h:80:1: error: 'inline' is not at beginning of declaration [-Werror=old-style-declaration]
>        80 | static void inline mmu_setup_asid(struct mm_struct *mm, unsigned long asid)
>           | ^~~~~~
>     arch/arc/include/asm/mmu-arcv2.h:85:1: error: 'inline' is not at beginning of declaration [-Werror=old-style-declaration]
>        85 | static void inline mmu_setup_pgd(struct mm_struct *mm, void *pgd)
>           | ^~~~~~
>     cc1: all warnings being treated as errors

Strange my gcc11 is not tripping on this snafu. Fixed now.
Thx for the report as always.

-Vineet

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

* Re: [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc
  2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
                   ` (18 preceding siblings ...)
  2021-08-12 23:37 ` [PATCH v2 19/19] ARC: mm: introduce _PAGE_TABLE to explicitly link pgd,pud,pmd entries Vineet Gupta
@ 2021-08-15  9:26 ` Mike Rapoport
  2021-08-16 19:58   ` Vineet Gupta
  19 siblings, 1 reply; 34+ messages in thread
From: Mike Rapoport @ 2021-08-15  9:26 UTC (permalink / raw)
  To: Vineet Gupta; +Cc: linux-snps-arc, linux-kernel, linux-mm, Anshuman Khandual

On Thu, Aug 12, 2021 at 04:37:34PM -0700, Vineet Gupta wrote:
> Hi,
> 
> Big pile of ARC mm changes to prepare for 3 or 4 levels of paging (from
> current 2) needed for new hardware page walked MMUv6 (in aRCv3 ISA based
> cores).
> 
> Most of these changes are incremental cleanups to make way for 14/18 and
> 15/18 which actually imeplement the new levels (in existing ARCv2 port)
> and worth a critical eye.
> 
> CC'ing some of you guys dealing with page tables for a while :-)
> to spot any obvious gotchas.

There are a couple of small nits here and there, but overall

Acked-by: Mike Rapoport <rppt@linux.ibm.com>

> Thx,
> -Vineet
> 
> Changes since v1 [1]
>  - Switched ARC to asm-generic/pgalloc.h  (so struct page based pgtable_t)      [Mike Rapoport]
>  - Dropped {pud,pmd}_alloc_one/{pud,pmd}_free provided by asm-generic/pgalloc.h [Mike Rapoport]
>  - Negative diffstat now due to above
>  - Added BUILD_BUG_ON() to arch/arc/mm/init.c for sanity of table sizes
>  - Consolidated 2 patches related to ARC_USE_SCRATCH_REG			   [Mike Rapoport]
>  - Reworked how mmu is re-enabled in entry code                                 [Jose Abreu]
> 
> [1] http://lists.infradead.org/pipermail/linux-snps-arc/2021-August/005326.html
> 
> Vineet Gupta (19):
>   ARC: mm: use SCRATCH_DATA0 register for caching pgdir in ARCv2 only
>   ARC: mm: remove tlb paranoid code
>   ARC: mm: move mmu/cache externs out to setup.h
>   ARC: mm: Fixes to allow STRICT_MM_TYPECHECKS
>   ARC: mm: Enable STRICT_MM_TYPECHECKS
>   ARC: ioremap: use more commonly used PAGE_KERNEL based uncached flag
>   ARC: mm: pmd_populate* to use the canonical set_pmd (and drop pmd_set)
>   ARC: mm: switch pgtable_t back to struct page *
>   ARC: mm: switch to asm-generic/pgalloc.h
>   ARC: mm: non-functional code cleanup ahead of 3 levels
>   ARC: mm: move MMU specific bits out of ASID allocator
>   ARC: mm: move MMU specific bits out of entry code ...
>   ARC: mm: disintegrate mmu.h (arcv2 bits out)
>   ARC: mm: disintegrate pgtable.h into levels and flags
>   ARC: mm: hack to allow 2 level build with 4 level code
>   ARC: mm: support 3 levels of page tables
>   ARC: mm: support 4 levels of page tables
>   ARC: mm: vmalloc sync from kernel to user table to update PMD ...
>   ARC: mm: introduce _PAGE_TABLE to explicitly link pgd,pud,pmd entries
> 
>  arch/arc/Kconfig                          |   7 +-
>  arch/arc/include/asm/cache.h              |   4 -
>  arch/arc/include/asm/entry-compact.h      |   8 -
>  arch/arc/include/asm/mmu-arcv2.h          | 103 +++++++
>  arch/arc/include/asm/mmu.h                |  73 +----
>  arch/arc/include/asm/mmu_context.h        |  28 +-
>  arch/arc/include/asm/page.h               |  74 +++--
>  arch/arc/include/asm/pgalloc.h            |  81 ++----
>  arch/arc/include/asm/pgtable-bits-arcv2.h | 151 +++++++++++
>  arch/arc/include/asm/pgtable-levels.h     | 179 ++++++++++++
>  arch/arc/include/asm/pgtable.h            | 315 +---------------------
>  arch/arc/include/asm/processor.h          |   2 +-
>  arch/arc/include/asm/setup.h              |  12 +-
>  arch/arc/kernel/entry-arcv2.S             |   1 +
>  arch/arc/kernel/entry.S                   |   7 +-
>  arch/arc/mm/fault.c                       |  20 +-
>  arch/arc/mm/init.c                        |   5 +
>  arch/arc/mm/ioremap.c                     |   3 +-
>  arch/arc/mm/tlb.c                         |  68 +----
>  arch/arc/mm/tlbex.S                       |  78 ++----
>  20 files changed, 591 insertions(+), 628 deletions(-)
>  create mode 100644 arch/arc/include/asm/mmu-arcv2.h
>  create mode 100644 arch/arc/include/asm/pgtable-bits-arcv2.h
>  create mode 100644 arch/arc/include/asm/pgtable-levels.h
> 
> -- 
> 2.25.1
> 

-- 
Sincerely yours,
Mike.

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

* Re: [PATCH v2 01/19] ARC: mm: use SCRATCH_DATA0 register for caching pgdir in ARCv2 only
  2021-08-12 23:37 ` [PATCH v2 01/19] ARC: mm: use SCRATCH_DATA0 register for caching pgdir in ARCv2 only Vineet Gupta
@ 2021-08-15  9:27   ` Mike Rapoport
  2021-08-16 19:45     ` Vineet Gupta
  0 siblings, 1 reply; 34+ messages in thread
From: Mike Rapoport @ 2021-08-15  9:27 UTC (permalink / raw)
  To: Vineet Gupta; +Cc: linux-snps-arc, linux-kernel, linux-mm, Anshuman Khandual

On Thu, Aug 12, 2021 at 04:37:35PM -0700, Vineet Gupta wrote:
> MMU SCRATCH_DATA0 register is intended to cache task pgd. However in
> ARC700 SMP port, it has to be repurposed for reentrant interrupt
> handling, while UP port doesn't. We  currently ahandle boe usecases

					       ^ handle both

maybe ':set spell' for changelog editing? ;-)

> using a fabricated which has usual issues of dependency nesting and
> ugliness.
> 
> So clean this up: for ARC700 don't use to cache pgd (even in UP) and do
> the opposite for ARCv2.
> 
> And while here, switch to canonical pgd_offset().
> 
> Signed-off-by: Vineet Gupta <vgupta@kernel.org>
> ---
>  arch/arc/include/asm/entry-compact.h |  8 --------
>  arch/arc/include/asm/mmu.h           |  4 ----
>  arch/arc/include/asm/mmu_context.h   |  2 +-
>  arch/arc/include/asm/pgtable.h       | 23 -----------------------
>  arch/arc/mm/fault.c                  |  2 +-
>  arch/arc/mm/tlb.c                    |  4 ++--
>  arch/arc/mm/tlbex.S                  |  2 +-
>  7 files changed, 5 insertions(+), 40 deletions(-)
> 
> diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h
> index 6dbf5cecc8cc..5aab4f93ab8a 100644
> --- a/arch/arc/include/asm/entry-compact.h
> +++ b/arch/arc/include/asm/entry-compact.h
> @@ -126,19 +126,11 @@
>   * to be saved again on kernel mode stack, as part of pt_regs.
>   *-------------------------------------------------------------*/
>  .macro PROLOG_FREEUP_REG	reg, mem
> -#ifndef ARC_USE_SCRATCH_REG
> -	sr  \reg, [ARC_REG_SCRATCH_DATA0]
> -#else
>  	st  \reg, [\mem]
> -#endif
>  .endm
>  
>  .macro PROLOG_RESTORE_REG	reg, mem
> -#ifndef ARC_USE_SCRATCH_REG
> -	lr  \reg, [ARC_REG_SCRATCH_DATA0]
> -#else
>  	ld  \reg, [\mem]
> -#endif
>  .endm
>  
>  /*--------------------------------------------------------------
> diff --git a/arch/arc/include/asm/mmu.h b/arch/arc/include/asm/mmu.h
> index a81d1975866a..4065335a7922 100644
> --- a/arch/arc/include/asm/mmu.h
> +++ b/arch/arc/include/asm/mmu.h
> @@ -31,10 +31,6 @@
>  #define ARC_REG_SCRATCH_DATA0	0x46c
>  #endif
>  
> -#if defined(CONFIG_ISA_ARCV2) || !defined(CONFIG_SMP)
> -#define	ARC_USE_SCRATCH_REG
> -#endif
> -
>  /* Bits in MMU PID register */
>  #define __TLB_ENABLE		(1 << 31)
>  #define __PROG_ENABLE		(1 << 30)
> diff --git a/arch/arc/include/asm/mmu_context.h b/arch/arc/include/asm/mmu_context.h
> index df164066e172..49318a126879 100644
> --- a/arch/arc/include/asm/mmu_context.h
> +++ b/arch/arc/include/asm/mmu_context.h
> @@ -146,7 +146,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
>  	 */
>  	cpumask_set_cpu(cpu, mm_cpumask(next));
>  
> -#ifdef ARC_USE_SCRATCH_REG
> +#ifdef CONFIG_ISA_ARCV2
>  	/* PGD cached in MMU reg to avoid 3 mem lookups: task->mm->pgd */
>  	write_aux_reg(ARC_REG_SCRATCH_DATA0, next->pgd);
>  #endif
> diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
> index 0c3e220bd2b4..80b57c14b430 100644
> --- a/arch/arc/include/asm/pgtable.h
> +++ b/arch/arc/include/asm/pgtable.h
> @@ -284,29 +284,6 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
>  	set_pte(ptep, pteval);
>  }
>  
> -/*
> - * Macro to quickly access the PGD entry, utlising the fact that some
> - * arch may cache the pointer to Page Directory of "current" task
> - * in a MMU register
> - *
> - * Thus task->mm->pgd (3 pointer dereferences, cache misses etc simply
> - * becomes read a register
> - *
> - * ********CAUTION*******:
> - * Kernel code might be dealing with some mm_struct of NON "current"
> - * Thus use this macro only when you are certain that "current" is current
> - * e.g. when dealing with signal frame setup code etc
> - */
> -#ifdef ARC_USE_SCRATCH_REG
> -#define pgd_offset_fast(mm, addr)	\
> -({					\
> -	pgd_t *pgd_base = (pgd_t *) read_aux_reg(ARC_REG_SCRATCH_DATA0);  \
> -	pgd_base + pgd_index(addr);	\
> -})
> -#else
> -#define pgd_offset_fast(mm, addr)	pgd_offset(mm, addr)
> -#endif
> -
>  extern pgd_t swapper_pg_dir[] __aligned(PAGE_SIZE);
>  void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
>  		      pte_t *ptep);
> diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c
> index f5657cb68e4f..41f154320964 100644
> --- a/arch/arc/mm/fault.c
> +++ b/arch/arc/mm/fault.c
> @@ -33,7 +33,7 @@ noinline static int handle_kernel_vaddr_fault(unsigned long address)
>  	pud_t *pud, *pud_k;
>  	pmd_t *pmd, *pmd_k;
>  
> -	pgd = pgd_offset_fast(current->active_mm, address);
> +	pgd = pgd_offset(current->active_mm, address);
>  	pgd_k = pgd_offset_k(address);
>  
>  	if (!pgd_present(*pgd_k))
> diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
> index 8696829d37c0..349fb7a75d1d 100644
> --- a/arch/arc/mm/tlb.c
> +++ b/arch/arc/mm/tlb.c
> @@ -719,8 +719,8 @@ void arc_mmu_init(void)
>  	/* Enable the MMU */
>  	write_aux_reg(ARC_REG_PID, MMU_ENABLE);
>  
> -	/* In smp we use this reg for interrupt 1 scratch */
> -#ifdef ARC_USE_SCRATCH_REG
> +	/* In arc700/smp needed for re-entrant interrupt handling */
> +#ifdef CONFIG_ISA_ARCV2
>  	/* swapper_pg_dir is the pgd for the kernel, used by vmalloc */
>  	write_aux_reg(ARC_REG_SCRATCH_DATA0, swapper_pg_dir);
>  #endif
> diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S
> index 96c3a5de9dd4..bcd2909c691f 100644
> --- a/arch/arc/mm/tlbex.S
> +++ b/arch/arc/mm/tlbex.S
> @@ -202,7 +202,7 @@ ex_saved_reg1:
>  
>  	lr  r2, [efa]
>  
> -#ifdef ARC_USE_SCRATCH_REG
> +#ifdef CONFIG_ISA_ARCV2
>  	lr  r1, [ARC_REG_SCRATCH_DATA0] ; current pgd
>  #else
>  	GET_CURR_TASK_ON_CPU  r1
> -- 
> 2.25.1
> 

-- 
Sincerely yours,
Mike.

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

* Re: [PATCH v2 03/19] ARC: mm: move mmu/cache externs out to setup.h
  2021-08-12 23:37 ` [PATCH v2 03/19] ARC: mm: move mmu/cache externs out to setup.h Vineet Gupta
@ 2021-08-15  9:27   ` Mike Rapoport
  2021-08-16 19:47     ` Vineet Gupta
  0 siblings, 1 reply; 34+ messages in thread
From: Mike Rapoport @ 2021-08-15  9:27 UTC (permalink / raw)
  To: Vineet Gupta; +Cc: linux-snps-arc, linux-kernel, linux-mm, Anshuman Khandual

Heh, 

"Don't pollute mmu.h and cache.h with some of ARC internal bootlog/setup
related functions.
move them aside to setup.h"

is still not there :)

On Thu, Aug 12, 2021 at 04:37:37PM -0700, Vineet Gupta wrote:
> Signed-off-by: Vineet Gupta <vgupta@kernel.org>
> ---
>  arch/arc/include/asm/cache.h |  4 ----
>  arch/arc/include/asm/mmu.h   |  4 ----
>  arch/arc/include/asm/setup.h | 12 ++++++++++--
>  3 files changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h
> index d8ece4292388..f0f1fc5d62b6 100644
> --- a/arch/arc/include/asm/cache.h
> +++ b/arch/arc/include/asm/cache.h
> @@ -62,10 +62,6 @@
>  #define ARCH_SLAB_MINALIGN	8
>  #endif
>  
> -extern void arc_cache_init(void);
> -extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len);
> -extern void read_decode_cache_bcr(void);
> -
>  extern int ioc_enable;
>  extern unsigned long perip_base, perip_end;
>  
> diff --git a/arch/arc/include/asm/mmu.h b/arch/arc/include/asm/mmu.h
> index 38a036508699..762cfe66e16b 100644
> --- a/arch/arc/include/asm/mmu.h
> +++ b/arch/arc/include/asm/mmu.h
> @@ -64,10 +64,6 @@ typedef struct {
>  	unsigned long asid[NR_CPUS];	/* 8 bit MMU PID + Generation cycle */
>  } mm_context_t;
>  
> -void arc_mmu_init(void);
> -extern char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len);
> -void read_decode_mmu_bcr(void);
> -
>  static inline int is_pae40_enabled(void)
>  {
>  	return IS_ENABLED(CONFIG_ARC_HAS_PAE40);
> diff --git a/arch/arc/include/asm/setup.h b/arch/arc/include/asm/setup.h
> index 01f85478170d..028a8cf76206 100644
> --- a/arch/arc/include/asm/setup.h
> +++ b/arch/arc/include/asm/setup.h
> @@ -2,8 +2,8 @@
>  /*
>   * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
>   */
> -#ifndef __ASMARC_SETUP_H
> -#define __ASMARC_SETUP_H
> +#ifndef __ASM_ARC_SETUP_H
> +#define __ASM_ARC_SETUP_H
>  
>  
>  #include <linux/types.h>
> @@ -34,4 +34,12 @@ long __init arc_get_mem_sz(void);
>  #define IS_AVAIL2(v, s, cfg)	IS_AVAIL1(v, s), IS_AVAIL1(v, IS_USED_CFG(cfg))
>  #define IS_AVAIL3(v, v2, s)	IS_AVAIL1(v, s), IS_AVAIL1(v, IS_DISABLED_RUN(v2))
>  
> +extern void arc_mmu_init(void);
> +extern char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len);
> +extern void read_decode_mmu_bcr(void);
> +
> +extern void arc_cache_init(void);
> +extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len);
> +extern void read_decode_cache_bcr(void);
> +
>  #endif /* __ASMARC_SETUP_H */
> -- 
> 2.25.1
> 

-- 
Sincerely yours,
Mike.

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

* Re: [PATCH v2 16/19] ARC: mm: support 3 levels of page tables
  2021-08-12 23:37 ` [PATCH v2 16/19] ARC: mm: support 3 levels of page tables Vineet Gupta
@ 2021-08-15  9:27   ` Mike Rapoport
  2021-08-16 19:53     ` Vineet Gupta
  0 siblings, 1 reply; 34+ messages in thread
From: Mike Rapoport @ 2021-08-15  9:27 UTC (permalink / raw)
  To: Vineet Gupta; +Cc: linux-snps-arc, linux-kernel, linux-mm, Anshuman Khandual

On Thu, Aug 12, 2021 at 04:37:50PM -0700, Vineet Gupta wrote:
> ARCv2 MMU is software walked and Linux implements 2 levels of paging: pgd/pte.
> Forthcoming hw will have multiple levels, so this change preps mm code
> for same. It is also fun to try multi levels even on soft-walked code to
> ensure generic mm code is robust to handle.
> 
> overview
> ________
> 
> 2 levels {pgd, pte} : pmd is folded but pmd_* macros are valid and operate on pgd
> 3 levels {pgd, pmd, pte}:
>   - pud is folded and pud_* macros point to pgd
>   - pmd_* macros operate on actual pmd
> 
> code changes
> ____________
> 
> 1. #include <asm-generic/pgtable-nopud.h>
> 
> 2. Define CONFIG_PGTABLE_LEVELS 3
> 
> 3a. Define PMD_SHIFT, PMD_SIZE, PMD_MASK, pmd_t
> 3b. Define pmd_val() which actually deals with pmd
>     (pmd_offset(), pmd_index() are provided by generic code)
> 3c. pmd_alloc_one()/pmd_free() also provided by generic code
>     (pmd_populate/pmd_free already exist)
> 
> 4. Define pud_none(), pud_bad() macros based on generic pud_val() which
>    internally pertains to pgd now.
> 4b. define pud_populate() to just setup pgd
> 
> Signed-off-by: Vineet Gupta <vgupta@kernel.org>
> ---

...

> diff --git a/arch/arc/include/asm/pgtable-levels.h b/arch/arc/include/asm/pgtable-levels.h
> index 8ece75335bb5..1c2f022d4ad0 100644
> --- a/arch/arc/include/asm/pgtable-levels.h
> +++ b/arch/arc/include/asm/pgtable-levels.h
> @@ -10,6 +10,8 @@
>  #ifndef _ASM_ARC_PGTABLE_LEVELS_H
>  #define _ASM_ARC_PGTABLE_LEVELS_H
>  
> +#if CONFIG_PGTABLE_LEVELS == 2
> +
>  /*
>   * 2 level paging setup for software walked MMUv3 (ARC700) and MMUv4 (HS)
>   *
> @@ -37,16 +39,38 @@
>  #define PGDIR_SHIFT		21
>  #endif
>  
> -#define PGDIR_SIZE		BIT(PGDIR_SHIFT)	/* vaddr span, not PDG sz */
> -#define PGDIR_MASK		(~(PGDIR_SIZE - 1))
> +#else

Adding /* CONFIG_PGTABLE_LEVELS == 2 */ would make the whole thing a bit
more readable, I think.

> +
> +/*
> + * A default 3 level paging testing setup in software walked MMU
> + *   MMUv4 (8K page): <4> : <7> : <8> : <13>
> + */
> +#define PGDIR_SHIFT		28
> +#if CONFIG_PGTABLE_LEVELS > 2
> +#define PMD_SHIFT		21
> +#endif
> +
> +#endif

and here as well.
  
> +#define PGDIR_SIZE		BIT(PGDIR_SHIFT)
> +#define PGDIR_MASK		(~(PGDIR_SIZE - 1))
>  #define PTRS_PER_PGD		BIT(32 - PGDIR_SHIFT)
>  
> -#define PTRS_PER_PTE		BIT(PGDIR_SHIFT - PAGE_SHIFT)
> +#if CONFIG_PGTABLE_LEVELS > 2
> +#define PMD_SIZE		BIT(PMD_SHIFT)
> +#define PMD_MASK		(~(PMD_SIZE - 1))
> +#define PTRS_PER_PMD		BIT(PGDIR_SHIFT - PMD_SHIFT)
> +#endif
> +
> +#define PTRS_PER_PTE		BIT(PMD_SHIFT - PAGE_SHIFT)
>  

-- 
Sincerely yours,
Mike.

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

* Re: [PATCH v2 01/19] ARC: mm: use SCRATCH_DATA0 register for caching pgdir in ARCv2 only
  2021-08-15  9:27   ` Mike Rapoport
@ 2021-08-16 19:45     ` Vineet Gupta
  0 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-16 19:45 UTC (permalink / raw)
  To: Mike Rapoport, Vineet Gupta
  Cc: linux-snps-arc, linux-kernel, linux-mm, Anshuman Khandual

On 8/15/21 2:27 AM, Mike Rapoport wrote:
> On Thu, Aug 12, 2021 at 04:37:35PM -0700, Vineet Gupta wrote:
>> MMU SCRATCH_DATA0 register is intended to cache task pgd. However in
>> ARC700 SMP port, it has to be repurposed for reentrant interrupt
>> handling, while UP port doesn't. We  currently ahandle boe usecases
> 					       ^ handle both
>
> maybe ':set spell' for changelog editing? ;-)

Seriously, about time I stopped fat-fingering

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

* Re: [PATCH v2 03/19] ARC: mm: move mmu/cache externs out to setup.h
  2021-08-15  9:27   ` Mike Rapoport
@ 2021-08-16 19:47     ` Vineet Gupta
  0 siblings, 0 replies; 34+ messages in thread
From: Vineet Gupta @ 2021-08-16 19:47 UTC (permalink / raw)
  To: Mike Rapoport; +Cc: linux-snps-arc, linux-kernel, linux-mm, Anshuman Khandual

On 8/15/21 2:27 AM, Mike Rapoport wrote:
> Heh,
>
> "Don't pollute mmu.h and cache.h with some of ARC internal bootlog/setup
> related functions.
> move them aside to setup.h"
>
> is still not there :)

Oops my bad, indeed missed out on that one. Fixed now.

Thx,
-Vineet


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

* Re: [PATCH v2 16/19] ARC: mm: support 3 levels of page tables
  2021-08-15  9:27   ` Mike Rapoport
@ 2021-08-16 19:53     ` Vineet Gupta
  2021-08-17  5:03       ` Mike Rapoport
  0 siblings, 1 reply; 34+ messages in thread
From: Vineet Gupta @ 2021-08-16 19:53 UTC (permalink / raw)
  To: Mike Rapoport, Vineet Gupta
  Cc: linux-snps-arc, linux-kernel, linux-mm, Anshuman Khandual

On 8/15/21 2:27 AM, Mike Rapoport wrote:
> On Thu, Aug 12, 2021 at 04:37:50PM -0700, Vineet Gupta wrote:
>> ARCv2 MMU is software walked and Linux implements 2 levels of paging: pgd/pte.
>> Forthcoming hw will have multiple levels, so this change preps mm code
>> for same. It is also fun to try multi levels even on soft-walked code to
>> ensure generic mm code is robust to handle.
>>
>> overview
>> ________
>>
>> 2 levels {pgd, pte} : pmd is folded but pmd_* macros are valid and operate on pgd
>> 3 levels {pgd, pmd, pte}:
>>    - pud is folded and pud_* macros point to pgd
>>    - pmd_* macros operate on actual pmd
>>
>> code changes
>> ____________
>>
>> 1. #include <asm-generic/pgtable-nopud.h>
>>
>> 2. Define CONFIG_PGTABLE_LEVELS 3
>>
>> 3a. Define PMD_SHIFT, PMD_SIZE, PMD_MASK, pmd_t
>> 3b. Define pmd_val() which actually deals with pmd
>>      (pmd_offset(), pmd_index() are provided by generic code)
>> 3c. pmd_alloc_one()/pmd_free() also provided by generic code
>>      (pmd_populate/pmd_free already exist)
>>
>> 4. Define pud_none(), pud_bad() macros based on generic pud_val() which
>>     internally pertains to pgd now.
>> 4b. define pud_populate() to just setup pgd
>>
>> Signed-off-by: Vineet Gupta <vgupta@kernel.org>
>> ---
> ...
>
>> diff --git a/arch/arc/include/asm/pgtable-levels.h b/arch/arc/include/asm/pgtable-levels.h
>> index 8ece75335bb5..1c2f022d4ad0 100644
>> --- a/arch/arc/include/asm/pgtable-levels.h
>> +++ b/arch/arc/include/asm/pgtable-levels.h
>> @@ -10,6 +10,8 @@
>>   #ifndef _ASM_ARC_PGTABLE_LEVELS_H
>>   #define _ASM_ARC_PGTABLE_LEVELS_H
>>   
>> +#if CONFIG_PGTABLE_LEVELS == 2
>> +
>>   /*
>>    * 2 level paging setup for software walked MMUv3 (ARC700) and MMUv4 (HS)
>>    *
>> @@ -37,16 +39,38 @@
>>   #define PGDIR_SHIFT		21
>>   #endif
>>   
>> -#define PGDIR_SIZE		BIT(PGDIR_SHIFT)	/* vaddr span, not PDG sz */
>> -#define PGDIR_MASK		(~(PGDIR_SIZE - 1))
>> +#else
> Adding /* CONFIG_PGTABLE_LEVELS == 2 */ would make the whole thing a bit
> more readable, I think.

You meant

+#else /* CONFIG_PGTABLE_LEVELS != 2

>
>> +
>> +/*
>> + * A default 3 level paging testing setup in software walked MMU
>> + *   MMUv4 (8K page): <4> : <7> : <8> : <13>
>> + */
>> +#define PGDIR_SHIFT		28
>> +#if CONFIG_PGTABLE_LEVELS > 2
>> +#define PMD_SHIFT		21
>> +#endif
>> +
>> +#endif
> and here as well.

I added following to indicate conditional coding for levels related code

+#endif /* CONFIG_PGTABLE_LEVELS */


>    
>> +#define PGDIR_SIZE		BIT(PGDIR_SHIFT)
>> +#define PGDIR_MASK		(~(PGDIR_SIZE - 1))
>>   #define PTRS_PER_PGD		BIT(32 - PGDIR_SHIFT)
>>   
>> -#define PTRS_PER_PTE		BIT(PGDIR_SHIFT - PAGE_SHIFT)
>> +#if CONFIG_PGTABLE_LEVELS > 2
>> +#define PMD_SIZE		BIT(PMD_SHIFT)
>> +#define PMD_MASK		(~(PMD_SIZE - 1))
>> +#define PTRS_PER_PMD		BIT(PGDIR_SHIFT - PMD_SHIFT)
>> +#endif
>> +
>> +#define PTRS_PER_PTE		BIT(PMD_SHIFT - PAGE_SHIFT)
>>   


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

* Re: [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc
  2021-08-15  9:26 ` [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Mike Rapoport
@ 2021-08-16 19:58   ` Vineet Gupta
  2021-08-17  5:04     ` Mike Rapoport
  0 siblings, 1 reply; 34+ messages in thread
From: Vineet Gupta @ 2021-08-16 19:58 UTC (permalink / raw)
  To: Mike Rapoport, Vineet Gupta
  Cc: linux-snps-arc, linux-kernel, linux-mm, Anshuman Khandual

On 8/15/21 2:26 AM, Mike Rapoport wrote:
> On Thu, Aug 12, 2021 at 04:37:34PM -0700, Vineet Gupta wrote:
>> Hi,
>>
>> Big pile of ARC mm changes to prepare for 3 or 4 levels of paging (from
>> current 2) needed for new hardware page walked MMUv6 (in aRCv3 ISA based
>> cores).
>>
>> Most of these changes are incremental cleanups to make way for 14/18 and
>> 15/18 which actually imeplement the new levels (in existing ARCv2 port)
>> and worth a critical eye.
>>
>> CC'ing some of you guys dealing with page tables for a while :-)
>> to spot any obvious gotchas.
> There are a couple of small nits here and there, but overall

I've fixed the last remaining things locally and won't repost, unless 
you want me to.

>
> Acked-by: Mike Rapoport <rppt@linux.ibm.com>

Thx for spending time to review this Mike. Much appreciated.


-Vineet

>
>> Thx,
>> -Vineet
>>
>> Changes since v1 [1]
>>   - Switched ARC to asm-generic/pgalloc.h  (so struct page based pgtable_t)      [Mike Rapoport]
>>   - Dropped {pud,pmd}_alloc_one/{pud,pmd}_free provided by asm-generic/pgalloc.h [Mike Rapoport]
>>   - Negative diffstat now due to above
>>   - Added BUILD_BUG_ON() to arch/arc/mm/init.c for sanity of table sizes
>>   - Consolidated 2 patches related to ARC_USE_SCRATCH_REG			   [Mike Rapoport]
>>   - Reworked how mmu is re-enabled in entry code                                 [Jose Abreu]
>>
>> [1] http://lists.infradead.org/pipermail/linux-snps-arc/2021-August/005326.html
>>
>> Vineet Gupta (19):
>>    ARC: mm: use SCRATCH_DATA0 register for caching pgdir in ARCv2 only
>>    ARC: mm: remove tlb paranoid code
>>    ARC: mm: move mmu/cache externs out to setup.h
>>    ARC: mm: Fixes to allow STRICT_MM_TYPECHECKS
>>    ARC: mm: Enable STRICT_MM_TYPECHECKS
>>    ARC: ioremap: use more commonly used PAGE_KERNEL based uncached flag
>>    ARC: mm: pmd_populate* to use the canonical set_pmd (and drop pmd_set)
>>    ARC: mm: switch pgtable_t back to struct page *
>>    ARC: mm: switch to asm-generic/pgalloc.h
>>    ARC: mm: non-functional code cleanup ahead of 3 levels
>>    ARC: mm: move MMU specific bits out of ASID allocator
>>    ARC: mm: move MMU specific bits out of entry code ...
>>    ARC: mm: disintegrate mmu.h (arcv2 bits out)
>>    ARC: mm: disintegrate pgtable.h into levels and flags
>>    ARC: mm: hack to allow 2 level build with 4 level code
>>    ARC: mm: support 3 levels of page tables
>>    ARC: mm: support 4 levels of page tables
>>    ARC: mm: vmalloc sync from kernel to user table to update PMD ...
>>    ARC: mm: introduce _PAGE_TABLE to explicitly link pgd,pud,pmd entries
>>
>>   arch/arc/Kconfig                          |   7 +-
>>   arch/arc/include/asm/cache.h              |   4 -
>>   arch/arc/include/asm/entry-compact.h      |   8 -
>>   arch/arc/include/asm/mmu-arcv2.h          | 103 +++++++
>>   arch/arc/include/asm/mmu.h                |  73 +----
>>   arch/arc/include/asm/mmu_context.h        |  28 +-
>>   arch/arc/include/asm/page.h               |  74 +++--
>>   arch/arc/include/asm/pgalloc.h            |  81 ++----
>>   arch/arc/include/asm/pgtable-bits-arcv2.h | 151 +++++++++++
>>   arch/arc/include/asm/pgtable-levels.h     | 179 ++++++++++++
>>   arch/arc/include/asm/pgtable.h            | 315 +---------------------
>>   arch/arc/include/asm/processor.h          |   2 +-
>>   arch/arc/include/asm/setup.h              |  12 +-
>>   arch/arc/kernel/entry-arcv2.S             |   1 +
>>   arch/arc/kernel/entry.S                   |   7 +-
>>   arch/arc/mm/fault.c                       |  20 +-
>>   arch/arc/mm/init.c                        |   5 +
>>   arch/arc/mm/ioremap.c                     |   3 +-
>>   arch/arc/mm/tlb.c                         |  68 +----
>>   arch/arc/mm/tlbex.S                       |  78 ++----
>>   20 files changed, 591 insertions(+), 628 deletions(-)
>>   create mode 100644 arch/arc/include/asm/mmu-arcv2.h
>>   create mode 100644 arch/arc/include/asm/pgtable-bits-arcv2.h
>>   create mode 100644 arch/arc/include/asm/pgtable-levels.h
>>
>> -- 
>> 2.25.1
>>


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

* Re: [PATCH v2 16/19] ARC: mm: support 3 levels of page tables
  2021-08-16 19:53     ` Vineet Gupta
@ 2021-08-17  5:03       ` Mike Rapoport
  0 siblings, 0 replies; 34+ messages in thread
From: Mike Rapoport @ 2021-08-17  5:03 UTC (permalink / raw)
  To: Vineet Gupta; +Cc: linux-snps-arc, linux-kernel, linux-mm, Anshuman Khandual

On Mon, Aug 16, 2021 at 12:53:46PM -0700, Vineet Gupta wrote:
> On 8/15/21 2:27 AM, Mike Rapoport wrote:
> > On Thu, Aug 12, 2021 at 04:37:50PM -0700, Vineet Gupta wrote:
> > > ARCv2 MMU is software walked and Linux implements 2 levels of paging: pgd/pte.
> > > Forthcoming hw will have multiple levels, so this change preps mm code
> > > for same. It is also fun to try multi levels even on soft-walked code to
> > > ensure generic mm code is robust to handle.
> > > 
> > > overview
> > > ________
> > > 
> > > 2 levels {pgd, pte} : pmd is folded but pmd_* macros are valid and operate on pgd
> > > 3 levels {pgd, pmd, pte}:
> > >    - pud is folded and pud_* macros point to pgd
> > >    - pmd_* macros operate on actual pmd
> > > 
> > > code changes
> > > ____________
> > > 
> > > 1. #include <asm-generic/pgtable-nopud.h>
> > > 
> > > 2. Define CONFIG_PGTABLE_LEVELS 3
> > > 
> > > 3a. Define PMD_SHIFT, PMD_SIZE, PMD_MASK, pmd_t
> > > 3b. Define pmd_val() which actually deals with pmd
> > >      (pmd_offset(), pmd_index() are provided by generic code)
> > > 3c. pmd_alloc_one()/pmd_free() also provided by generic code
> > >      (pmd_populate/pmd_free already exist)
> > > 
> > > 4. Define pud_none(), pud_bad() macros based on generic pud_val() which
> > >     internally pertains to pgd now.
> > > 4b. define pud_populate() to just setup pgd
> > > 
> > > Signed-off-by: Vineet Gupta <vgupta@kernel.org>
> > > ---
> > ...
> > 
> > > diff --git a/arch/arc/include/asm/pgtable-levels.h b/arch/arc/include/asm/pgtable-levels.h
> > > index 8ece75335bb5..1c2f022d4ad0 100644
> > > --- a/arch/arc/include/asm/pgtable-levels.h
> > > +++ b/arch/arc/include/asm/pgtable-levels.h
> > > @@ -10,6 +10,8 @@
> > >   #ifndef _ASM_ARC_PGTABLE_LEVELS_H
> > >   #define _ASM_ARC_PGTABLE_LEVELS_H
> > > +#if CONFIG_PGTABLE_LEVELS == 2
> > > +
> > >   /*
> > >    * 2 level paging setup for software walked MMUv3 (ARC700) and MMUv4 (HS)
> > >    *
> > > @@ -37,16 +39,38 @@
> > >   #define PGDIR_SHIFT		21
> > >   #endif
> > > -#define PGDIR_SIZE		BIT(PGDIR_SHIFT)	/* vaddr span, not PDG sz */
> > > -#define PGDIR_MASK		(~(PGDIR_SIZE - 1))
> > > +#else
> > Adding /* CONFIG_PGTABLE_LEVELS == 2 */ would make the whole thing a bit
> > more readable, I think.
> 
> You meant
> 
> +#else /* CONFIG_PGTABLE_LEVELS != 2

I don't think we are consistent about it in the kernel, there are places
that just copy the condition in #if and some change it to match the #else.
I don't have a preference, up to you.
 
> > 
> > > +
> > > +/*
> > > + * A default 3 level paging testing setup in software walked MMU
> > > + *   MMUv4 (8K page): <4> : <7> : <8> : <13>
> > > + */
> > > +#define PGDIR_SHIFT		28
> > > +#if CONFIG_PGTABLE_LEVELS > 2
> > > +#define PMD_SHIFT		21
> > > +#endif
> > > +
> > > +#endif
> > and here as well.
> 
> I added following to indicate conditional coding for levels related code
> 
> +#endif /* CONFIG_PGTABLE_LEVELS */
> 
> 
> > > +#define PGDIR_SIZE		BIT(PGDIR_SHIFT)
> > > +#define PGDIR_MASK		(~(PGDIR_SIZE - 1))
> > >   #define PTRS_PER_PGD		BIT(32 - PGDIR_SHIFT)
> > > -#define PTRS_PER_PTE		BIT(PGDIR_SHIFT - PAGE_SHIFT)
> > > +#if CONFIG_PGTABLE_LEVELS > 2
> > > +#define PMD_SIZE		BIT(PMD_SHIFT)
> > > +#define PMD_MASK		(~(PMD_SIZE - 1))
> > > +#define PTRS_PER_PMD		BIT(PGDIR_SHIFT - PMD_SHIFT)
> > > +#endif
> > > +
> > > +#define PTRS_PER_PTE		BIT(PMD_SHIFT - PAGE_SHIFT)
> 

-- 
Sincerely yours,
Mike.

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

* Re: [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc
  2021-08-16 19:58   ` Vineet Gupta
@ 2021-08-17  5:04     ` Mike Rapoport
  0 siblings, 0 replies; 34+ messages in thread
From: Mike Rapoport @ 2021-08-17  5:04 UTC (permalink / raw)
  To: Vineet Gupta; +Cc: linux-snps-arc, linux-kernel, linux-mm, Anshuman Khandual

On Mon, Aug 16, 2021 at 12:58:18PM -0700, Vineet Gupta wrote:
> On 8/15/21 2:26 AM, Mike Rapoport wrote:
> > On Thu, Aug 12, 2021 at 04:37:34PM -0700, Vineet Gupta wrote:
> > > Hi,
> > > 
> > > Big pile of ARC mm changes to prepare for 3 or 4 levels of paging (from
> > > current 2) needed for new hardware page walked MMUv6 (in aRCv3 ISA based
> > > cores).
> > > 
> > > Most of these changes are incremental cleanups to make way for 14/18 and
> > > 15/18 which actually imeplement the new levels (in existing ARCv2 port)
> > > and worth a critical eye.
> > > 
> > > CC'ing some of you guys dealing with page tables for a while :-)
> > > to spot any obvious gotchas.
> > There are a couple of small nits here and there, but overall
> 
> I've fixed the last remaining things locally and won't repost, unless you
> want me to.

No need.
 
> > 
> > Acked-by: Mike Rapoport <rppt@linux.ibm.com>
> 
> Thx for spending time to review this Mike. Much appreciated.

You are welcome :)

> 
> -Vineet
> 
> > 
> > > Thx,
> > > -Vineet
> > > 
> > > Changes since v1 [1]
> > >   - Switched ARC to asm-generic/pgalloc.h  (so struct page based pgtable_t)      [Mike Rapoport]
> > >   - Dropped {pud,pmd}_alloc_one/{pud,pmd}_free provided by asm-generic/pgalloc.h [Mike Rapoport]
> > >   - Negative diffstat now due to above
> > >   - Added BUILD_BUG_ON() to arch/arc/mm/init.c for sanity of table sizes
> > >   - Consolidated 2 patches related to ARC_USE_SCRATCH_REG			   [Mike Rapoport]
> > >   - Reworked how mmu is re-enabled in entry code                                 [Jose Abreu]
> > > 
> > > [1] http://lists.infradead.org/pipermail/linux-snps-arc/2021-August/005326.html
> > > 
> > > Vineet Gupta (19):
> > >    ARC: mm: use SCRATCH_DATA0 register for caching pgdir in ARCv2 only
> > >    ARC: mm: remove tlb paranoid code
> > >    ARC: mm: move mmu/cache externs out to setup.h
> > >    ARC: mm: Fixes to allow STRICT_MM_TYPECHECKS
> > >    ARC: mm: Enable STRICT_MM_TYPECHECKS
> > >    ARC: ioremap: use more commonly used PAGE_KERNEL based uncached flag
> > >    ARC: mm: pmd_populate* to use the canonical set_pmd (and drop pmd_set)
> > >    ARC: mm: switch pgtable_t back to struct page *
> > >    ARC: mm: switch to asm-generic/pgalloc.h
> > >    ARC: mm: non-functional code cleanup ahead of 3 levels
> > >    ARC: mm: move MMU specific bits out of ASID allocator
> > >    ARC: mm: move MMU specific bits out of entry code ...
> > >    ARC: mm: disintegrate mmu.h (arcv2 bits out)
> > >    ARC: mm: disintegrate pgtable.h into levels and flags
> > >    ARC: mm: hack to allow 2 level build with 4 level code
> > >    ARC: mm: support 3 levels of page tables
> > >    ARC: mm: support 4 levels of page tables
> > >    ARC: mm: vmalloc sync from kernel to user table to update PMD ...
> > >    ARC: mm: introduce _PAGE_TABLE to explicitly link pgd,pud,pmd entries
> > > 
> > >   arch/arc/Kconfig                          |   7 +-
> > >   arch/arc/include/asm/cache.h              |   4 -
> > >   arch/arc/include/asm/entry-compact.h      |   8 -
> > >   arch/arc/include/asm/mmu-arcv2.h          | 103 +++++++
> > >   arch/arc/include/asm/mmu.h                |  73 +----
> > >   arch/arc/include/asm/mmu_context.h        |  28 +-
> > >   arch/arc/include/asm/page.h               |  74 +++--
> > >   arch/arc/include/asm/pgalloc.h            |  81 ++----
> > >   arch/arc/include/asm/pgtable-bits-arcv2.h | 151 +++++++++++
> > >   arch/arc/include/asm/pgtable-levels.h     | 179 ++++++++++++
> > >   arch/arc/include/asm/pgtable.h            | 315 +---------------------
> > >   arch/arc/include/asm/processor.h          |   2 +-
> > >   arch/arc/include/asm/setup.h              |  12 +-
> > >   arch/arc/kernel/entry-arcv2.S             |   1 +
> > >   arch/arc/kernel/entry.S                   |   7 +-
> > >   arch/arc/mm/fault.c                       |  20 +-
> > >   arch/arc/mm/init.c                        |   5 +
> > >   arch/arc/mm/ioremap.c                     |   3 +-
> > >   arch/arc/mm/tlb.c                         |  68 +----
> > >   arch/arc/mm/tlbex.S                       |  78 ++----
> > >   20 files changed, 591 insertions(+), 628 deletions(-)
> > >   create mode 100644 arch/arc/include/asm/mmu-arcv2.h
> > >   create mode 100644 arch/arc/include/asm/pgtable-bits-arcv2.h
> > >   create mode 100644 arch/arc/include/asm/pgtable-levels.h
> > > 
> > > -- 
> > > 2.25.1
> > > 
> 

-- 
Sincerely yours,
Mike.

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

end of thread, other threads:[~2021-08-17  5:04 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-12 23:37 [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 01/19] ARC: mm: use SCRATCH_DATA0 register for caching pgdir in ARCv2 only Vineet Gupta
2021-08-15  9:27   ` Mike Rapoport
2021-08-16 19:45     ` Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 02/19] ARC: mm: remove tlb paranoid code Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 03/19] ARC: mm: move mmu/cache externs out to setup.h Vineet Gupta
2021-08-15  9:27   ` Mike Rapoport
2021-08-16 19:47     ` Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 04/19] ARC: mm: Fixes to allow STRICT_MM_TYPECHECKS Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 05/19] ARC: mm: Enable STRICT_MM_TYPECHECKS Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 06/19] ARC: ioremap: use more commonly used PAGE_KERNEL based uncached flag Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 07/19] ARC: mm: pmd_populate* to use the canonical set_pmd (and drop pmd_set) Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 08/19] ARC: mm: switch pgtable_t back to struct page * Vineet Gupta
2021-08-13 10:45   ` kernel test robot
2021-08-13 14:25     ` Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 09/19] ARC: mm: switch to asm-generic/pgalloc.h Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 10/19] ARC: mm: non-functional code cleanup ahead of 3 levels Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 11/19] ARC: mm: move MMU specific bits out of ASID allocator Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 12/19] ARC: mm: move MMU specific bits out of entry code Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 13/19] ARC: mm: disintegrate mmu.h (arcv2 bits out) Vineet Gupta
2021-08-13  4:01   ` kernel test robot
2021-08-13 14:48     ` Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 14/19] ARC: mm: disintegrate pgtable.h into levels and flags Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 15/19] ARC: mm: hack to allow 2 level build with 4 level code Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 16/19] ARC: mm: support 3 levels of page tables Vineet Gupta
2021-08-15  9:27   ` Mike Rapoport
2021-08-16 19:53     ` Vineet Gupta
2021-08-17  5:03       ` Mike Rapoport
2021-08-12 23:37 ` [PATCH v2 17/19] ARC: mm: support 4 " Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 18/19] ARC: mm: vmalloc sync from kernel to user table to update PMD Vineet Gupta
2021-08-12 23:37 ` [PATCH v2 19/19] ARC: mm: introduce _PAGE_TABLE to explicitly link pgd,pud,pmd entries Vineet Gupta
2021-08-15  9:26 ` [PATCH v2 00/19] ARC mm updates: support 3/4 levels and asm-generic/pgalloc Mike Rapoport
2021-08-16 19:58   ` Vineet Gupta
2021-08-17  5:04     ` Mike Rapoport

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).