ARC: mm: use SCRATCH_DATA0 register for caching pgdir in ARCv2 only
authorVineet Gupta <vgupta@kernel.org>
Mon, 13 Jan 2020 17:16:06 +0000 (09:16 -0800)
committerVineet Gupta <vgupta@kernel.org>
Tue, 24 Aug 2021 21:25:48 +0000 (14:25 -0700)
MMU SCRATCH_DATA0 register is intended to cache task pgd. However in
ARC700 SMP port, it has to be repurposed for re-entrant interrupt
handling, while UP port doesn't. We currently handle these use-cases
using a fabricated #define which has usual issues of dependency nesting
and obvious 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().

Acked-by: Mike Rapoport <rppt@linux.ibm.com>
Signed-off-by: Vineet Gupta <vgupta@kernel.org>
arch/arc/include/asm/entry-compact.h
arch/arc/include/asm/mmu.h
arch/arc/include/asm/mmu_context.h
arch/arc/include/asm/pgtable.h
arch/arc/mm/fault.c
arch/arc/mm/tlb.c
arch/arc/mm/tlbex.S

index 6dbf5ce..5aab4f9 100644 (file)
  * to be saved again on kernel mode stack, as part of pt_regs.
  *-------------------------------------------------------------*/
 .macro PROLOG_FREEUP_REG       reg, mem
  * 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]
        st  \reg, [\mem]
-#endif
 .endm
 
 .macro PROLOG_RESTORE_REG      reg, mem
 .endm
 
 .macro PROLOG_RESTORE_REG      reg, mem
-#ifndef ARC_USE_SCRATCH_REG
-       lr  \reg, [ARC_REG_SCRATCH_DATA0]
-#else
        ld  \reg, [\mem]
        ld  \reg, [\mem]
-#endif
 .endm
 
 /*--------------------------------------------------------------
 .endm
 
 /*--------------------------------------------------------------
index a81d197..4065335 100644 (file)
 #define ARC_REG_SCRATCH_DATA0  0x46c
 #endif
 
 #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)
 /* Bits in MMU PID register */
 #define __TLB_ENABLE           (1 << 31)
 #define __PROG_ENABLE          (1 << 30)
index df16406..49318a1 100644 (file)
@@ -146,7 +146,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
         */
        cpumask_set_cpu(cpu, mm_cpumask(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
        /* PGD cached in MMU reg to avoid 3 mem lookups: task->mm->pgd */
        write_aux_reg(ARC_REG_SCRATCH_DATA0, next->pgd);
 #endif
index 0c3e220..80b57c1 100644 (file)
@@ -284,29 +284,6 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
        set_pte(ptep, pteval);
 }
 
        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);
 extern pgd_t swapper_pg_dir[] __aligned(PAGE_SIZE);
 void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
                      pte_t *ptep);
index f5657cb..41f1543 100644 (file)
@@ -33,7 +33,7 @@ noinline static int handle_kernel_vaddr_fault(unsigned long address)
        pud_t *pud, *pud_k;
        pmd_t *pmd, *pmd_k;
 
        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))
        pgd_k = pgd_offset_k(address);
 
        if (!pgd_present(*pgd_k))
index 8696829..349fb7a 100644 (file)
@@ -719,8 +719,8 @@ void arc_mmu_init(void)
        /* Enable the MMU */
        write_aux_reg(ARC_REG_PID, MMU_ENABLE);
 
        /* 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
        /* swapper_pg_dir is the pgd for the kernel, used by vmalloc */
        write_aux_reg(ARC_REG_SCRATCH_DATA0, swapper_pg_dir);
 #endif
index 96c3a5d..bcd2909 100644 (file)
@@ -202,7 +202,7 @@ ex_saved_reg1:
 
        lr  r2, [efa]
 
 
        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
        lr  r1, [ARC_REG_SCRATCH_DATA0] ; current pgd
 #else
        GET_CURR_TASK_ON_CPU  r1