ARC: mm: use SCRATCH_DATA0 register for caching pgdir in ARCv2 only
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>
This commit is contained in:
parent
288ff7de62
commit
6128df5be4
|
@ -126,19 +126,11 @@
|
||||||
* to be saved again on kernel mode stack, as part of pt_regs.
|
* to be saved again on kernel mode stack, as part of pt_regs.
|
||||||
*-------------------------------------------------------------*/
|
*-------------------------------------------------------------*/
|
||||||
.macro PROLOG_FREEUP_REG reg, mem
|
.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
|
.endm
|
||||||
|
|
||||||
.macro PROLOG_RESTORE_REG reg, mem
|
.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
|
||||||
|
|
||||||
/*--------------------------------------------------------------
|
/*--------------------------------------------------------------
|
||||||
|
|
|
@ -31,10 +31,6 @@
|
||||||
#define ARC_REG_SCRATCH_DATA0 0x46c
|
#define ARC_REG_SCRATCH_DATA0 0x46c
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_ISA_ARCV2) || !defined(CONFIG_SMP)
|
|
||||||
#define ARC_USE_SCRATCH_REG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Bits in MMU PID register */
|
/* Bits in MMU PID register */
|
||||||
#define __TLB_ENABLE (1 << 31)
|
#define __TLB_ENABLE (1 << 31)
|
||||||
#define __PROG_ENABLE (1 << 30)
|
#define __PROG_ENABLE (1 << 30)
|
||||||
|
|
|
@ -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 */
|
/* PGD cached in MMU reg to avoid 3 mem lookups: task->mm->pgd */
|
||||||
write_aux_reg(ARC_REG_SCRATCH_DATA0, next->pgd);
|
write_aux_reg(ARC_REG_SCRATCH_DATA0, next->pgd);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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);
|
extern pgd_t swapper_pg_dir[] __aligned(PAGE_SIZE);
|
||||||
void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
|
void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
|
||||||
pte_t *ptep);
|
pte_t *ptep);
|
||||||
|
|
|
@ -33,7 +33,7 @@ noinline static int handle_kernel_vaddr_fault(unsigned long address)
|
||||||
pud_t *pud, *pud_k;
|
pud_t *pud, *pud_k;
|
||||||
pmd_t *pmd, *pmd_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);
|
pgd_k = pgd_offset_k(address);
|
||||||
|
|
||||||
if (!pgd_present(*pgd_k))
|
if (!pgd_present(*pgd_k))
|
||||||
|
|
|
@ -719,8 +719,8 @@ void arc_mmu_init(void)
|
||||||
/* Enable the MMU */
|
/* Enable the MMU */
|
||||||
write_aux_reg(ARC_REG_PID, MMU_ENABLE);
|
write_aux_reg(ARC_REG_PID, MMU_ENABLE);
|
||||||
|
|
||||||
/* In smp we use this reg for interrupt 1 scratch */
|
/* In arc700/smp needed for re-entrant interrupt handling */
|
||||||
#ifdef ARC_USE_SCRATCH_REG
|
#ifdef CONFIG_ISA_ARCV2
|
||||||
/* swapper_pg_dir is the pgd for the kernel, used by vmalloc */
|
/* swapper_pg_dir is the pgd for the kernel, used by vmalloc */
|
||||||
write_aux_reg(ARC_REG_SCRATCH_DATA0, swapper_pg_dir);
|
write_aux_reg(ARC_REG_SCRATCH_DATA0, swapper_pg_dir);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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
|
lr r1, [ARC_REG_SCRATCH_DATA0] ; current pgd
|
||||||
#else
|
#else
|
||||||
GET_CURR_TASK_ON_CPU r1
|
GET_CURR_TASK_ON_CPU r1
|
||||||
|
|
Loading…
Reference in New Issue