linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: guoren@kernel.org
To: guoren@kernel.org
Cc: linux-kernel@vger.kernel.org, linux-csky@vger.kernel.org,
	Guo Ren <guoren@linux.alibaba.com>
Subject: [PATCH 12/29] csky: Fix TLB maintenance synchronization problem
Date: Thu, 21 Jan 2021 14:53:32 +0800	[thread overview]
Message-ID: <20210121065349.3188251-12-guoren@kernel.org> (raw)
In-Reply-To: <20210121065349.3188251-1-guoren@kernel.org>

From: Guo Ren <guoren@linux.alibaba.com>

TLB invalidate didn't contain a barrier operation in csky cpu and
we need to prevent previous PTW response after TLB invalidation
instruction. Of cause, the ASID changing also needs to take care
of the issue.

CPU0                    CPU1
===============         ===============
set_pte
sync_is()        ->     See the previous set_pte for all harts
tlbi.vas         ->     Invalidate all harts TLB entry & flush pipeline

Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
---
 arch/csky/abiv1/inc/abi/ckmmu.h     |  3 ++-
 arch/csky/abiv2/inc/abi/ckmmu.h     | 35 ++++++++++++++++++++----
 arch/csky/include/asm/mmu_context.h |  3 +--
 arch/csky/mm/init.c                 |  2 +-
 arch/csky/mm/tlb.c                  | 42 ++++++++++++++++++++++++-----
 5 files changed, 69 insertions(+), 16 deletions(-)

diff --git a/arch/csky/abiv1/inc/abi/ckmmu.h b/arch/csky/abiv1/inc/abi/ckmmu.h
index cceb3afb4c91..b4650de43078 100644
--- a/arch/csky/abiv1/inc/abi/ckmmu.h
+++ b/arch/csky/abiv1/inc/abi/ckmmu.h
@@ -89,9 +89,10 @@ static inline void tlb_invalid_indexed(void)
 	cpwcr("cpcr8", 0x02000000);
 }
 
-static inline void setup_pgd(pgd_t *pgd)
+static inline void setup_pgd(pgd_t *pgd, int asid)
 {
 	cpwcr("cpcr29", __pa(pgd) | BIT(0));
+	write_mmu_entryhi(asid);
 }
 
 static inline pgd_t *get_pgd(void)
diff --git a/arch/csky/abiv2/inc/abi/ckmmu.h b/arch/csky/abiv2/inc/abi/ckmmu.h
index c39b13810550..530d2c7edc85 100644
--- a/arch/csky/abiv2/inc/abi/ckmmu.h
+++ b/arch/csky/abiv2/inc/abi/ckmmu.h
@@ -78,8 +78,13 @@ static inline void tlb_read(void)
 static inline void tlb_invalid_all(void)
 {
 #ifdef CONFIG_CPU_HAS_TLBI
-	asm volatile("tlbi.alls\n":::"memory");
 	sync_is();
+	asm volatile(
+		"tlbi.alls	\n"
+		"sync.i		\n"
+		:
+		:
+		: "memory");
 #else
 	mtcr("cr<8, 15>", 0x04000000);
 #endif
@@ -88,8 +93,13 @@ static inline void tlb_invalid_all(void)
 static inline void local_tlb_invalid_all(void)
 {
 #ifdef CONFIG_CPU_HAS_TLBI
-	asm volatile("tlbi.all\n":::"memory");
 	sync_is();
+	asm volatile(
+		"tlbi.all	\n"
+		"sync.i		\n"
+		:
+		:
+		: "memory");
 #else
 	tlb_invalid_all();
 #endif
@@ -100,12 +110,27 @@ static inline void tlb_invalid_indexed(void)
 	mtcr("cr<8, 15>", 0x02000000);
 }
 
-static inline void setup_pgd(pgd_t *pgd)
+#define NOP32 ".long 0x4820c400\n"
+
+static inline void setup_pgd(pgd_t *pgd, int asid)
 {
 #ifdef CONFIG_CPU_HAS_TLBI
-	mtcr("cr<28, 15>", __pa(pgd) | BIT(0));
+	sync_is();
+#else
+	mb();
+#endif
+	asm volatile(
+#ifdef CONFIG_CPU_HAS_TLBI
+		"mtcr %1, cr<28, 15>	\n"
 #endif
-	mtcr("cr<29, 15>", __pa(pgd) | BIT(0));
+		"mtcr %1, cr<29, 15>	\n"
+		"mtcr %0, cr< 4, 15>	\n"
+		".rept 64		\n"
+		NOP32
+		".endr			\n"
+		:
+		:"r"(asid), "r"(__pa(pgd) | BIT(0))
+		:"memory");
 }
 
 static inline pgd_t *get_pgd(void)
diff --git a/arch/csky/include/asm/mmu_context.h b/arch/csky/include/asm/mmu_context.h
index 3767dbffd02f..594167bbdc63 100644
--- a/arch/csky/include/asm/mmu_context.h
+++ b/arch/csky/include/asm/mmu_context.h
@@ -30,8 +30,7 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
 	if (prev != next)
 		check_and_switch_context(next, cpu);
 
-	setup_pgd(next->pgd);
-	write_mmu_entryhi(next->context.asid.counter);
+	setup_pgd(next->pgd, next->context.asid.counter);
 
 	flush_icache_deferred(next);
 }
diff --git a/arch/csky/mm/init.c b/arch/csky/mm/init.c
index 8170d7ce116b..bc05a3be9d57 100644
--- a/arch/csky/mm/init.c
+++ b/arch/csky/mm/init.c
@@ -164,7 +164,7 @@ void __init mmu_init(unsigned long min_pfn, unsigned long max_pfn)
 	/* Setup page mask to 4k */
 	write_mmu_pagemask(0);
 
-	setup_pgd(swapper_pg_dir);
+	setup_pgd(swapper_pg_dir, 0);
 }
 
 void __init fixrange_init(unsigned long start, unsigned long end,
diff --git a/arch/csky/mm/tlb.c b/arch/csky/mm/tlb.c
index ed1512381112..9234c5e5ceaf 100644
--- a/arch/csky/mm/tlb.c
+++ b/arch/csky/mm/tlb.c
@@ -24,7 +24,13 @@ void flush_tlb_all(void)
 void flush_tlb_mm(struct mm_struct *mm)
 {
 #ifdef CONFIG_CPU_HAS_TLBI
-	asm volatile("tlbi.asids %0"::"r"(cpu_asid(mm)));
+	sync_is();
+	asm volatile(
+		"tlbi.asids %0	\n"
+		"sync.i		\n"
+		:
+		: "r" (cpu_asid(mm))
+		: "memory");
 #else
 	tlb_invalid_all();
 #endif
@@ -53,11 +59,17 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 	end   &= TLB_ENTRY_SIZE_MASK;
 
 #ifdef CONFIG_CPU_HAS_TLBI
+	sync_is();
 	while (start < end) {
-		asm volatile("tlbi.vas %0"::"r"(start | newpid));
+		asm volatile(
+			"tlbi.vas %0	\n"
+			:
+			: "r" (start | newpid)
+			: "memory");
+
 		start += 2*PAGE_SIZE;
 	}
-	sync_is();
+	asm volatile("sync.i\n");
 #else
 	{
 	unsigned long flags, oldpid;
@@ -87,11 +99,17 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end)
 	end   &= TLB_ENTRY_SIZE_MASK;
 
 #ifdef CONFIG_CPU_HAS_TLBI
+	sync_is();
 	while (start < end) {
-		asm volatile("tlbi.vaas %0"::"r"(start));
+		asm volatile(
+			"tlbi.vaas %0	\n"
+			:
+			: "r" (start)
+			: "memory");
+
 		start += 2*PAGE_SIZE;
 	}
-	sync_is();
+	asm volatile("sync.i\n");
 #else
 	{
 	unsigned long flags, oldpid;
@@ -121,8 +139,13 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
 	addr &= TLB_ENTRY_SIZE_MASK;
 
 #ifdef CONFIG_CPU_HAS_TLBI
-	asm volatile("tlbi.vas %0"::"r"(addr | newpid));
 	sync_is();
+	asm volatile(
+		"tlbi.vas %0	\n"
+		"sync.i		\n"
+		:
+		: "r" (addr | newpid)
+		: "memory");
 #else
 	{
 	int oldpid, idx;
@@ -147,8 +170,13 @@ void flush_tlb_one(unsigned long addr)
 	addr &= TLB_ENTRY_SIZE_MASK;
 
 #ifdef CONFIG_CPU_HAS_TLBI
-	asm volatile("tlbi.vaas %0"::"r"(addr));
 	sync_is();
+	asm volatile(
+		"tlbi.vaas %0	\n"
+		"sync.i		\n"
+		:
+		: "r" (addr)
+		: "memory");
 #else
 	{
 	int oldpid, idx;
-- 
2.17.1


  parent reply	other threads:[~2021-01-21  7:49 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-21  6:53 [PATCH 01/29] csky: Add memory layout 2.5G(user):1.5G(kernel) guoren
2021-01-21  6:53 ` [PATCH 02/29] csky: Fixup perf probe failed guoren
2021-01-21  6:53 ` [PATCH 03/29] csky: Fixup show_regs doesn't contain regs->usp guoren
2021-01-21  6:53 ` [PATCH 04/29] csky: Remove custom asm/atomic.h implementation guoren
2021-01-21  6:53 ` [PATCH 05/29] csky: Fixup barrier design guoren
2021-01-21  6:53 ` [PATCH 06/29] csky: Fixup futex SMP implementation guoren
2021-01-21  6:53 ` [PATCH 07/29] csky: Fixup asm/cmpxchg.h with correct ordering barrier guoren
2021-01-21  6:53 ` [PATCH 08/29] csky: Cleanup asm/spinlock.h guoren
2021-01-21  6:53 ` [PATCH 09/29] csky: Fixup PTE global for 2.5:1.5 virtual memory guoren
2021-01-21  6:53 ` [PATCH 10/29] csky: Remove prologue of page fault handler in entry.S guoren
2021-01-21  6:53 ` [PATCH 11/29] csky: Add kmemleak support guoren
2021-01-21  6:53 ` guoren [this message]
2021-01-21  6:53 ` [PATCH 13/29] csky: Add show_tlb for CPU_CK860 debug guoren
2021-01-21  6:53 ` [PATCH 14/29] csky: Fixup FAULT_FLAG_XXX param for handle_mm_fault guoren
2021-01-21  6:53 ` [PATCH 15/29] csky: Fixup update_mmu_cache called with user io mapping guoren
2021-01-21  6:53 ` [PATCH 16/29] csky: Add faulthandler_disabled() check guoren
2021-01-21  6:53 ` [PATCH 17/29] csky: Fixup do_page_fault parent irq status guoren
2021-01-21  6:53 ` [PATCH 18/29] csky: Sync riscv mm/fault.c for easy maintenance guoren
2021-01-21  6:53 ` [PATCH 19/29] csky: mm: abort uaccess retries upon fatal signal guoren
2021-01-21 11:42   ` Mark Rutland
2021-01-21  6:53 ` [PATCH 20/29] csky: Reconstruct VDSO framework guoren
2021-01-21  6:53 ` [PATCH 21/29] csky: Fix a size determination in gpr_get() guoren
2021-01-21  6:53 ` [PATCH 22/29] csky: remove unused including <linux/version.h> guoren
2021-01-21  6:53 ` [PATCH 23/29] csky: Fixup _PAGE_ACCESSED for default pgprot guoren
2021-01-21  6:53 ` [PATCH 24/29] csky: Coding convention del unnecessary definition guoren
2021-01-21  6:53 ` [PATCH 25/29] csky: Fixup swapon guoren
2021-01-21  6:53 ` [PATCH 26/29] csky: kprobe: fix code in simulate without 'long' guoren
2021-01-21  6:53 ` [PATCH 27/29] csky: Add VDSO with GENERIC_GETTIMEOFDAY, GENERIC_TIME_VSYSCALL, HAVE_GENERIC_VDSO guoren
2021-01-21  6:53 ` [PATCH 28/29] csky: Using set_max_mapnr api guoren
2021-01-21  6:53 ` [PATCH 29/29] csky: Fixup pfn_valid error with wrong max_mapnr guoren

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210121065349.3188251-12-guoren@kernel.org \
    --to=guoren@kernel.org \
    --cc=guoren@linux.alibaba.com \
    --cc=linux-csky@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).