aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@kernel.org>2021-08-19 18:33:30 -0700
committerVineet Gupta <vineetg@rivosinc.com>2021-10-25 22:46:35 -0700
commit703ac4a3b0cb0ccfa928dd06edadcc8e2183806f (patch)
tree7ce491ec77bfc0290d6de6b3edcfaf3667a15491
parent6a9553a885fe021944af52732b3bca20a58d6e54 (diff)
downloadarc-topic-zol-remove.tar.gz
ARCv3: mm: Better way to setup kernel mappings in per-task page tabletopic-zol-remove
In the current RTP0 only mapping regime, kernel translations are also setup via RTP0 (which canonically is used for user mappings) - early boot code sets RTP0 directly with kernel swapper_pg_dir / swapper_pud - when userspace starts, RTP0 has user PGD -> PUD, but kernel identity mapppings are copied into user PUD at right location via arc_map_kernel_in_mm(). So far this was done on demand: - activate_mm() -> execve - arch_dup_mmap() -> fork However a better way to do this is to copy the kernel entries into user pud right when user pud is allocated (like some other arches). This avoids the need for the additional arch 2 hooks to do on-demand copy. This patch thus removes them. Signed-off-by: Vineet Gupta <vgupta@kernel.org>
-rw-r--r--arch/arc/include/asm/mmu_context.h8
-rw-r--r--arch/arc/include/asm/pgalloc.h23
-rw-r--r--arch/arc/mm/tlb-arcv3.c18
3 files changed, 24 insertions, 25 deletions
diff --git a/arch/arc/include/asm/mmu_context.h b/arch/arc/include/asm/mmu_context.h
index 4f9eaa303e0b38..2ae7d39271168c 100644
--- a/arch/arc/include/asm/mmu_context.h
+++ b/arch/arc/include/asm/mmu_context.h
@@ -151,7 +151,6 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
mmu_setup_pgd(next, next->pgd);
}
-#ifdef CONFIG_ARC_MMU_V6
/*
* activate_mm defaults (in asm-generic) to switch_mm and is called at the
* time of execve() to get a new ASID Note the subtlety here:
@@ -160,9 +159,6 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
* value, while in latter, it moves to a new ASID, only if it was
* unallocated
*/
-extern void activate_mm(struct mm_struct *prev, struct mm_struct *next);
-#define activate_mm activate_mm
-#endif
/* it seemed that deactivate_mm( ) is a reasonable place to do book-keeping
* for retiring-mm. However destroy_context( ) still needs to do that because
@@ -176,19 +172,17 @@ extern void activate_mm(struct mm_struct *prev, struct mm_struct *next);
/* override mm_hooks.h */
-#ifndef CONFIG_ARC_MMU_V6
static inline int arch_dup_mmap(struct mm_struct *oldmm,
struct mm_struct *mm)
{
return 0;
}
+#ifndef CONFIG_ARC_MMU_V6
static inline void arch_exit_mmap(struct mm_struct *mm)
{
}
-
#else
-extern int arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm);
extern void arch_exit_mmap(struct mm_struct *mm);
#endif
diff --git a/arch/arc/include/asm/pgalloc.h b/arch/arc/include/asm/pgalloc.h
index a8c01eceba1bc9..cc3aa61888fc16 100644
--- a/arch/arc/include/asm/pgalloc.h
+++ b/arch/arc/include/asm/pgalloc.h
@@ -31,6 +31,8 @@
#include <linux/mm.h>
#include <linux/log2.h>
+
+#define __HAVE_ARCH_PUD_ALLOC_ONE
#include <asm-generic/pgalloc.h>
static inline void
@@ -77,6 +79,27 @@ static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4dp, pud_t *pudp)
set_p4d(p4dp, __p4d((unsigned long)pudp | _PAGE_TABLE));
}
+
+static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+ pud_t *pud;
+
+ BUILD_BUG_ON((PTRS_PER_PUD * sizeof(pud_t)) > PAGE_SIZE);
+
+ /*
+ * For kernel in high address, there will be a dedicated swapper_pud
+ * and its base pointet needs to be set in user pgd
+ */
+ BUILD_BUG_ON(PAGE_OFFSET != 0x80000000);
+
+ pud = (pud_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
+
+ pud[2] = swapper_pud[2];
+ pud[3] = swapper_pud[3];
+
+ return pud;
+}
+
#define __pud_free_tlb(tlb, pmd, addr) pud_free((tlb)->mm, pmd)
#endif
diff --git a/arch/arc/mm/tlb-arcv3.c b/arch/arc/mm/tlb-arcv3.c
index 875cf47584d680..4b6c8536af16cf 100644
--- a/arch/arc/mm/tlb-arcv3.c
+++ b/arch/arc/mm/tlb-arcv3.c
@@ -163,24 +163,6 @@ noinline void mmu_setup_asid(struct mm_struct *mm, unsigned long asid)
#endif
}
-void activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
-{
- int map = 0;
-
- map = arc_map_kernel_in_mm(next_mm);
- BUG_ON(map);
-
- switch_mm(prev_mm, next_mm, NULL);
-}
-
-int arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
-{
- int map = arc_map_kernel_in_mm(mm);
- BUG_ON(map);
-
- return 0;
-}
-
void arch_exit_mmap(struct mm_struct *mm)
{
/*