Re: [PATCH 07/18] ARC: ioremap: use more commonly used PAGE_KERNEL based uncached flag

2021-08-10 Thread Mike Rapoport
On Tue, Aug 10, 2021 at 05:42:47PM -0700, Vineet Gupta wrote:
> and remove the one off uncached definition for ARC
> 
> Signed-off-by: Vineet Gupta 
> ---
>  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)));

But this becomes _PAGE_CACHEABLE now. What did I miss?

>  }
>  EXPORT_SYMBOL(ioremap);
>  
> -- 
> 2.25.1
> 

-- 
Sincerely yours,
Mike.

___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


Re: [PATCH 04/18] ARC: mm: remove pgd_offset_fast

2021-08-10 Thread Mike Rapoport
On Tue, Aug 10, 2021 at 05:42:44PM -0700, Vineet Gupta wrote:
> Signed-off-by: Vineet Gupta 
> ---
>  arch/arc/include/asm/pgtable.h | 23 ---
>  arch/arc/mm/fault.c|  2 +-
>  2 files changed, 1 insertion(+), 24 deletions(-)

Shouldn't this be a part of the patch that removed usage of the scratch reg
for pgd?
 
> 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))
> -- 
> 2.25.1
> 

-- 
Sincerely yours,
Mike.

___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


Re: [PATCH 03/18] ARC: mm: move mmu/cache externs out to setup.h

2021-08-10 Thread Mike Rapoport
Hi Vineet,

On Tue, Aug 10, 2021 at 05:42:43PM -0700, Vineet Gupta wrote:
> Signed-off-by: Vineet Gupta 

Hmm, this one seems odd. Try https://www.kernel.com/ ;-)

> Signed-off-by: Vineet Gupta 
> ---
>  arch/arc/include/asm/cache.h |  4 
>  arch/arc/include/asm/mmu.h   |  4 
>  arch/arc/include/asm/setup.h | 12 ++--

A sentence about why these move would have been nice.

>  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 
> @@ -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.

___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


Re: [GIT PULL] ARC updates for 5.14-rc6

2021-08-10 Thread pr-tracker-bot
The pull request you sent on Tue, 10 Aug 2021 16:21:30 -0700:

> git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git/ 
> tags/arc-5.14-rc6

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/761c6d7ec820f123b931e7b8ef7ec7c8564e450f

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html

___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 18/18] ARC: mm: introduce _PAGE_TABLE to explicitly link pgd, pud, pmd entries

2021-08-10 Thread 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 
---
 arch/arc/include/asm/pgalloc.h| 6 +++---
 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, 11 insertions(+), 7 deletions(-)

diff --git a/arch/arc/include/asm/pgalloc.h b/arch/arc/include/asm/pgalloc.h
index e99c724d9235..230d43a998af 100644
--- a/arch/arc/include/asm/pgalloc.h
+++ b/arch/arc/include/asm/pgalloc.h
@@ -47,7 +47,7 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t 
*ptep)
 *
 * The cast itself is needed given simplistic definition of set_pmd()
 */
-   set_pmd(pmdp, __pmd((unsigned long)ptep));
+   set_pmd(pmdp, __pmd((unsigned long)ptep | _PAGE_TABLE));
 }
 
 /*
@@ -90,7 +90,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 
 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));
 }
 
 static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
@@ -112,7 +112,7 @@ static inline void pud_free(struct mm_struct *mm, 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));
 }
 
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
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_SZ0
 #endif
 
+#define _PAGE_TABLE0x3
+
 /* 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 e1831b6fafa9..24a9670186b3 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



[PATCH 15/18] ARC: mm: support 3 levels of page tables

2021-08-10 Thread 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 

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. Define pmd_alloc_one() and pmd_free() to allocate pmd
(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 
---
 arch/arc/Kconfig  |  4 ++
 arch/arc/include/asm/page.h   | 11 +
 arch/arc/include/asm/pgalloc.h| 22 ++
 arch/arc/include/asm/pgtable-levels.h | 63 ---
 arch/arc/include/asm/processor.h  |  2 +-
 arch/arc/mm/fault.c   |  4 ++
 arch/arc/mm/tlb.c |  4 +-
 arch/arc/mm/tlbex.S   |  9 
 8 files changed, 111 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 313e6f543d2d..df3cc154ae4a 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 0cf73431eb89..01c2d84418ed 100644
--- a/arch/arc/include/asm/pgalloc.h
+++ b/arch/arc/include/asm/pgalloc.h
@@ -86,6 +86,28 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 }
 
 
+#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));
+}
+
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+   return (pmd_t *)__get_free_page(
+   GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_ZERO);
+}
+
+static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
+{
+   free_page((unsigned long)pmd);
+}
+
+#define __pmd_free_tlb(tlb, pmd, addr)  pmd_free((tlb)->mm, pmd)
+
+#endif
+
 /*
  * With software-only page-tables, addr-split for traversal is tweakable and
  * that directly governs how big tables would be at each level.
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_SHIFT21
 #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_SHIFT28
+#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 
+#else
 #include 
+#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))
 

[PATCH 17/18] ARC: mm: vmalloc sync from kernel to user table to update PMD ...

2021-08-10 Thread 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 
---
 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


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 14/18] ARC: mm: hack to allow 2 level build with 4 level code

2021-08-10 Thread 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 
---
 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 6b5872197005..d08bd09a0afc 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


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 11/18] ARC: mm: move MMU specific bits out of entry code

2021-08-10 Thread Vineet Gupta
Signed-off-by: Vineet Gupta 
---
 arch/arc/kernel/entry.S | 6 --
 arch/arc/mm/tlb.c   | 3 +++
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S
index 2cb8dfe866b6..684efd094520 100644
--- a/arch/arc/kernel/entry.S
+++ b/arch/arc/kernel/entry.S
@@ -101,12 +101,6 @@ 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]
-
lsr r3, r2, 8
bmskr3, r3, 7
brner3, ECR_C_MCHK_DUP_TLB, 1f
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index b68d5798327b..34f16e0b41e6 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -813,5 +813,8 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned 
long address,
}
}
 
+   /* Re-enable MMU as hardware may have auto-disabled it upon exception */
+   write_aux_reg(ARC_REG_PID, read_aux_reg(ARC_REG_PID) | MMU_ENABLE);
+
local_irq_restore(flags);
 }
-- 
2.25.1


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 16/18] ARC: mm: support 4 levels of page tables

2021-08-10 Thread Vineet Gupta
Signed-off-by: Vineet Gupta 
---
 arch/arc/include/asm/page.h   | 11 +++
 arch/arc/include/asm/pgalloc.h| 22 +
 arch/arc/include/asm/pgtable-levels.h | 45 ---
 arch/arc/mm/fault.c   |  2 ++
 arch/arc/mm/tlbex.S   |  9 ++
 5 files changed, 84 insertions(+), 5 deletions(-)

diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h
index df3cc154ae4a..883856f12afe 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 01c2d84418ed..e99c724d9235 100644
--- a/arch/arc/include/asm/pgalloc.h
+++ b/arch/arc/include/asm/pgalloc.h
@@ -86,6 +86,28 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 }
 
 
+#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));
+}
+
+static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+   return (pud_t *)__get_free_page(
+   GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_ZERO);
+}
+
+static inline void pud_free(struct mm_struct *mm, pud_t *pudp)
+{
+   free_page((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_SHIFT28
+#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 
+#elif CONFIG_PGTABLE_LEVELS > 2
 #include 
 #else
 #include 
@@ -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
--- 

[PATCH 03/18] ARC: mm: move mmu/cache externs out to setup.h

2021-08-10 Thread Vineet Gupta
Signed-off-by: Vineet Gupta 
Signed-off-by: Vineet Gupta 
---
 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 
@@ -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


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 13/18] ARC: mm: disintegrate pgtable.h into levels and flags

2021-08-10 Thread 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 
---
 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 ..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_CACHEABLE0
+#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_SZ0
+#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_SHAREDPAGE_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));

[PATCH 06/18] ARC: mm: Enable STRICT_MM_TYPECHECKS

2021-08-10 Thread Vineet Gupta
In the past I've refrained from doing this (atleast 2 times) due to the
slight code bloat due to ABI implications of pte_t etc becoming sttuct

Per ARC ABI, functions return struct via memory and not through register
r0, even if the struct would fits 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 
---
 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


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 10/18] ARC: mm: move MMU specific bits out of ASID allocator

2021-08-10 Thread Vineet Gupta
And while at it, rewrite commentary on ASID allocator

Signed-off-by: Vineet Gupta 
---
 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..2cabdfaf2afb 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, pgd_t *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 
-#include 
 #include 
 
+#include 
 #include 
 
-/* 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


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 07/18] ARC: ioremap: use more commonly used PAGE_KERNEL based uncached flag

2021-08-10 Thread Vineet Gupta
and remove the one off uncached definition for ARC

Signed-off-by: Vineet Gupta 
---
 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


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 12/18] ARC: mm: disintegrate mmu.h (arcv2 bits out)

2021-08-10 Thread Vineet Gupta
non functional change

Signed-off-by: Vineet Gupta 
---
 arch/arc/include/asm/mmu-arcv2.h   | 94 ++
 arch/arc/include/asm/mmu.h | 72 +--
 arch/arc/include/asm/mmu_context.h |  1 +
 arch/arc/include/asm/pgtable.h |  6 --
 arch/arc/mm/tlbex.S|  2 +-
 5 files changed, 97 insertions(+), 78 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 ..837a54e39539
--- /dev/null
+++ b/arch/arc/include/asm/mmu-arcv2.h
@@ -0,0 +1,94 @@
+/* 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_BCR0x06f
+
+#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_PID0x409
+#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_PID0x468
+#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   0x8000
+
+#ifdef CONFIG_ARC_MMU_V3
+#define TLB_DUP_ERR(TLB_LKUP_ERR | 0x0001)
+#else
+#define TLB_DUP_ERR(TLB_LKUP_ERR | 0x4000)
+#endif
+
+/*
+ * TLB Commands
+ */
+#define TLBWrite   0x1
+#define TLBRead0x2
+#define TLBGetIndex0x3
+#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__
+
+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, pgd_t *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
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif
diff --git a/arch/arc/include/asm/mmu.h b/arch/arc/include/asm/mmu.h
index 2cabdfaf2afb..6a27a4caa44c 100644
--- a/arch/arc/include/asm/mmu.h
+++ b/arch/arc/include/asm/mmu.h
@@ -7,83 +7,13 @@
 #define _ASM_ARC_MMU_H
 
 #ifndef __ASSEMBLY__
-#include  /* NR_CPUS */
-#endif
-
-/* MMU Management regs */
-#define ARC_REG_MMU_BCR0x06f
-
-#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_PID0x409
-#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_PID0x468
-#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   0x8000
-
-#ifdef CONFIG_ARC_MMU_V3
-#define TLB_DUP_ERR(TLB_LKUP_ERR | 0x0001)
-#else
-#define TLB_DUP_ERR(TLB_LKUP_ERR | 0x4000)
-#endif
 
-/* TLB Commands */
-#define TLBWrite0x1
-#define TLBRead 0x2
-#define TLBGetIndex 0x3
-#define TLBProbe0x4
-#define TLBWriteNI  0x5/* write JTLB without inv uTLBs */
-#define TLBIVUTLB   0x6

[PATCH 05/18] ARC: mm: Fixes to allow STRICT_MM_TYPECHECKS

2021-08-10 Thread Vineet Gupta
Signed-off-by: Vineet Gupta 
---
 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 & 0x);
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


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 04/18] ARC: mm: remove pgd_offset_fast

2021-08-10 Thread Vineet Gupta
Signed-off-by: Vineet Gupta 
---
 arch/arc/include/asm/pgtable.h | 23 ---
 arch/arc/mm/fault.c|  2 +-
 2 files changed, 1 insertion(+), 24 deletions(-)

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))
-- 
2.25.1


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 09/18] ARC: mm: non-functional code cleanup ahead of 3 levels

2021-08-10 Thread Vineet Gupta
Signed-off-by: Vineet Gupta 
---
 arch/arc/include/asm/page.h| 30 --
 arch/arc/include/asm/pgalloc.h |  7 ++-
 2 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h
index c4ac827379cd..313e6f543d2d 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 pte_t * 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))
diff --git a/arch/arc/include/asm/pgalloc.h b/arch/arc/include/asm/pgalloc.h
index 356237b9c537..0cf73431eb89 100644
--- a/arch/arc/include/asm/pgalloc.h
+++ b/arch/arc/include/asm/pgalloc.h
@@ -29,6 +29,11 @@
 #ifndef _ASM_ARC_PGALLOC_H
 #define _ASM_ARC_PGALLOC_H
 
+/*
+ * For ARC, pgtable_t is not struct page *, but pte_t * (to avoid
+ * extraneous page_address() calculations) hence can't use
+ * use asm-generic/pgalloc.h which assumes it being struct page *
+ */
 #include 
 #include 
 
@@ -36,7 +41,7 @@ static inline void
 pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
 {
/*
-* The cast to long below is OK even when pte is long long (PAE40)
+* 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.
 *
-- 
2.25.1


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 00/18] ARC mm updates to support 3 or 4 levels of paging

2021-08-10 Thread 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

Vineet Gupta (18):
  ARC: mm: simplify mmu scratch register assingment to mmu needs
  ARC: mm: remove tlb paranoid code
  ARC: mm: move mmu/cache externs out to setup.h
  ARC: mm: remove pgd_offset_fast
  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: 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  |  94 +++
 arch/arc/include/asm/mmu.h|  73 +
 arch/arc/include/asm/mmu_context.h|  29 +-
 arch/arc/include/asm/page.h   |  72 +++--
 arch/arc/include/asm/pgalloc.h|  70 -
 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.S   |   6 -
 arch/arc/mm/fault.c   |  20 +-
 arch/arc/mm/ioremap.c |   3 +-
 arch/arc/mm/tlb.c |  71 ++---
 arch/arc/mm/tlbex.S   |  80 ++
 18 files changed, 617 insertions(+), 579 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


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 02/18] ARC: mm: remove tlb paranoid code

2021-08-10 Thread Vineet Gupta
This was used way back when in arc700 debugging when ASID allocator was
still bit flaky. Not needed in last 5 years

Signed-off-by: Vineet Gupta 
Signed-off-by: Vineet Gupta 
---
 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 < 0x7000 &&
-   ((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]
-   

[PATCH 08/18] ARC: mm: pmd_populate* to use the canonical set_pmd (and drop pmd_set)

2021-08-10 Thread Vineet Gupta
Signed-off-by: Vineet Gupta 
---
 arch/arc/include/asm/pgalloc.h | 21 ++---
 arch/arc/include/asm/pgtable.h |  6 --
 2 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/arch/arc/include/asm/pgalloc.h b/arch/arc/include/asm/pgalloc.h
index a32ca3104ced..356237b9c537 100644
--- a/arch/arc/include/asm/pgalloc.h
+++ b/arch/arc/include/asm/pgalloc.h
@@ -33,16 +33,23 @@
 #include 
 
 static inline void
-pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
+pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
 {
-   pmd_set(pmd, pte);
+   /*
+* The cast to long below is OK even when pte is long long (PAE40)
+* 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(pmdp, __pmd((unsigned long)ptep));
 }
 
-static inline void
-pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t ptep)
-{
-   pmd_set(pmd, (pte_t *) ptep);
-}
+/*
+ * pmd_populate can be implemented in terms of pmd_populate_kernel since
+ * pgtable_t is pte * on ARC
+ */
+#define pmd_populate(mm, pmdp, ptep)   pmd_populate_kernel(mm, pmdp, ptep)
 
 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


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 01/18] ARC: mm: simplify mmu scratch register assingment to mmu needs

2021-08-10 Thread Vineet Gupta
ARC700 SMP uses MMU scratch reg for re-entrant interrupt handling (as
opposed to the canonical usage for task pgd pointer caching for ARCv2
and ARC700 UP builds). However this requires fabricating a #define in a
header which has usual issues of dependency nesting and ugliness.

So clean this up and just use it as intended for ARCv2 only.
For ARC700 just don't use it for mmu needs (even for UP which it
potentially can (degrades it slightly) but that config it not a
big deal in this day and age.

Signed-off-by: Vineet Gupta 
---
 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/mm/tlb.c| 4 ++--
 arch/arc/mm/tlbex.S  | 2 +-
 5 files changed, 4 insertions(+), 16 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)
-#defineARC_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/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


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[GIT PULL] ARC updates for 5.14-rc6

2021-08-10 Thread Vineet Gupta

Hi Linus,

ARC fixes for 5.14-rc6. Please pull.

Thx,
-Vineet

>
The following changes since commit c500bee1c5b2f1d59b1081ac879d73268ab0ff17:

  Linux 5.14-rc4 (2021-08-01 17:04:17 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git/ 
tags/arc-5.14-rc6


for you to fetch changes up to 669d94219d91a2ba950bb12ece69cf0ada53ad4f:

  MAINTAINERS: update Vineet's email address (2021-08-09 15:17:14 -0700)


ARC updates for 5.14-rc6

 - Fix FPU_STATUS update

 - Update my email address

 - Other spellos and fixes


Colin Ian King (1):
  arc: Fix spelling mistake and grammar in Kconfig

Guenter Roeck (1):
  ARC: Fix CONFIG_STACKDEPOT

Jinchao Wang (1):
  arc: Prefer unsigned int to bare use of unsigned

Vineet Gupta (2):
  ARC: fp: set FPU_STATUS.FWE to enable FPU_STATUS update on 
context switch

  MAINTAINERS: update Vineet's email address

 MAINTAINERS   |  2 +-
 arch/arc/Kconfig  |  2 +-
 arch/arc/include/asm/checksum.h   |  2 +-
 arch/arc/include/asm/perf_event.h |  2 +-
 arch/arc/kernel/fpu.c |  9 ++---
 arch/arc/kernel/unwind.c  | 10 +-
 arch/arc/kernel/vmlinux.lds.S |  2 ++
 7 files changed, 17 insertions(+), 12 deletions(-)

___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc