summaryrefslogtreecommitdiffstats
path: root/arch/csky/mm
diff options
context:
space:
mode:
authorGuo Ren <ren_guo@c-sky.com>2019-06-18 14:33:32 +0200
committerGuo Ren <ren_guo@c-sky.com>2019-07-19 08:21:36 +0200
commit22d55f02b8922a097cd4be1e2f131dfa7ef65901 (patch)
treee8e0c0f8c5071343902090aa225fb92bd5747536 /arch/csky/mm
parentcsky: Add new asid lib code from arm (diff)
downloadlinux-22d55f02b8922a097cd4be1e2f131dfa7ef65901.tar.xz
linux-22d55f02b8922a097cd4be1e2f131dfa7ef65901.zip
csky: Use generic asid algorithm to implement switch_mm
Use linux generic asid/vmid algorithm to implement csky switch_mm function. The algorithm is from arm and it could work with SMP system. It'll help reduce tlb flush for switch_mm in task/vm switch. Signed-off-by: Guo Ren <ren_guo@c-sky.com> Cc: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/csky/mm')
-rw-r--r--arch/csky/mm/Makefile1
-rw-r--r--arch/csky/mm/context.c46
2 files changed, 47 insertions, 0 deletions
diff --git a/arch/csky/mm/Makefile b/arch/csky/mm/Makefile
index d3d564e5da61..c94ef6481098 100644
--- a/arch/csky/mm/Makefile
+++ b/arch/csky/mm/Makefile
@@ -13,3 +13,4 @@ obj-y += ioremap.o
obj-y += syscache.o
obj-y += tlb.o
obj-y += asid.o
+obj-y += context.o
diff --git a/arch/csky/mm/context.c b/arch/csky/mm/context.c
new file mode 100644
index 000000000000..0d95bdd93846
--- /dev/null
+++ b/arch/csky/mm/context.c
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+
+#include <linux/bitops.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+
+#include <asm/asid.h>
+#include <asm/mmu_context.h>
+#include <asm/smp.h>
+#include <asm/tlbflush.h>
+
+static DEFINE_PER_CPU(atomic64_t, active_asids);
+static DEFINE_PER_CPU(u64, reserved_asids);
+
+struct asid_info asid_info;
+
+void check_and_switch_context(struct mm_struct *mm, unsigned int cpu)
+{
+ asid_check_context(&asid_info, &mm->context.asid, cpu, mm);
+}
+
+static void asid_flush_cpu_ctxt(void)
+{
+ local_tlb_invalid_all();
+}
+
+static int asids_init(void)
+{
+ BUG_ON(((1 << CONFIG_CPU_ASID_BITS) - 1) <= num_possible_cpus());
+
+ if (asid_allocator_init(&asid_info, CONFIG_CPU_ASID_BITS, 1,
+ asid_flush_cpu_ctxt))
+ panic("Unable to initialize ASID allocator for %lu ASIDs\n",
+ NUM_ASIDS(&asid_info));
+
+ asid_info.active = &active_asids;
+ asid_info.reserved = &reserved_asids;
+
+ pr_info("ASID allocator initialised with %lu entries\n",
+ NUM_CTXT_ASIDS(&asid_info));
+
+ return 0;
+}
+early_initcall(asids_init);