linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Scott Wood <scottwood@freescale.com>
To: <linuxppc-dev@lists.ozlabs.org>
Cc: Tiejun Chen <tiejun.chen@intel.com>, <kexec@lists.infradead.org>,
	"Scott Wood" <scottwood@freescale.com>
Subject: [RFC PATCH 01/17] powerpc/85xx: Load all early TLB entries at once
Date: Sat, 18 Jul 2015 15:08:38 -0500	[thread overview]
Message-ID: <1437250134-307-2-git-send-email-scottwood@freescale.com> (raw)
In-Reply-To: <1437250134-307-1-git-send-email-scottwood@freescale.com>

Use an AS=1 trampoline TLB entry to allow all normal TLB1 entries to
be loaded at once.  This avoids the need to keep the translation that
code is executing from in the same TLB entry in the final TLB
configuration as during early boot, which in turn is helpful for
relocatable kernels (e.g. kdump) where the kernel is not running from
what would be the first TLB entry.

On e6500, we limit map_mem_in_cams() to the primary hwthread of a
core (the boot cpu is always considered primary, as a kdump kernel
can be entered on any cpu),  Each TLB only needs to be set up once,
and when we do, we don't want another thread to be running when we
create a temporary trampoline TLB1 entry.

Signed-off-by: Scott Wood <scottwood@freescale.com>
---
 arch/powerpc/kernel/setup_64.c   |  8 +++++
 arch/powerpc/mm/fsl_booke_mmu.c  | 15 ++++++++--
 arch/powerpc/mm/mmu_decl.h       |  1 +
 arch/powerpc/mm/tlb_nohash.c     | 19 +++++++++++-
 arch/powerpc/mm/tlb_nohash_low.S | 63 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 102 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index bdcbb71..505ec2c 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -108,6 +108,14 @@ static void setup_tlb_core_data(void)
 	for_each_possible_cpu(cpu) {
 		int first = cpu_first_thread_sibling(cpu);
 
+		/*
+		 * If we boot via kdump on a non-primary thread,
+		 * make sure we point at the thread that actually
+		 * set up this TLB.
+		 */
+		if (cpu_first_thread_sibling(boot_cpuid) == first)
+			first = boot_cpuid;
+
 		paca[cpu].tcd_ptr = &paca[first].tcd;
 
 		/*
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index 354ba3c..36d3c55 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -105,8 +105,9 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa)
  * an unsigned long (for example, 32-bit implementations cannot support a 4GB
  * size).
  */
-static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
-		unsigned long size, unsigned long flags, unsigned int pid)
+static void preptlbcam(int index, unsigned long virt, phys_addr_t phys,
+		       unsigned long size, unsigned long flags,
+		       unsigned int pid)
 {
 	unsigned int tsize;
 
@@ -141,7 +142,13 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
 	tlbcam_addrs[index].start = virt;
 	tlbcam_addrs[index].limit = virt + size - 1;
 	tlbcam_addrs[index].phys = phys;
+}
 
+void settlbcam(int index, unsigned long virt, phys_addr_t phys,
+	       unsigned long size, unsigned long flags,
+	       unsigned int pid)
+{
+	preptlbcam(index, virt, phys, size, flags, pid);
 	loadcam_entry(index);
 }
 
@@ -181,13 +188,15 @@ static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt,
 		unsigned long cam_sz;
 
 		cam_sz = calc_cam_sz(ram, virt, phys);
-		settlbcam(i, virt, phys, cam_sz, pgprot_val(PAGE_KERNEL_X), 0);
+		preptlbcam(i, virt, phys, cam_sz, pgprot_val(PAGE_KERNEL_X), 0);
 
 		ram -= cam_sz;
 		amount_mapped += cam_sz;
 		virt += cam_sz;
 		phys += cam_sz;
 	}
+
+	loadcam_multi(0, i, max_cam_idx);
 	tlbcam_index = i;
 
 #ifdef CONFIG_PPC64
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 085b66b..27c3a2d 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -152,6 +152,7 @@ extern int switch_to_as1(void);
 extern void restore_to_as0(int esel, int offset, void *dt_ptr, int bootcpu);
 #endif
 extern void loadcam_entry(unsigned int index);
+extern void loadcam_multi(int first_idx, int num, int tmp_idx);
 
 struct tlbcam {
 	u32	MAS0;
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index 723a099..a7381fb 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -42,6 +42,7 @@
 #include <asm/tlbflush.h>
 #include <asm/tlb.h>
 #include <asm/code-patching.h>
+#include <asm/cputhreads.h>
 #include <asm/hugetlb.h>
 #include <asm/paca.h>
 
@@ -628,10 +629,26 @@ static void early_init_this_mmu(void)
 #ifdef CONFIG_PPC_FSL_BOOK3E
 	if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
 		unsigned int num_cams;
+		int __maybe_unused cpu = smp_processor_id();
+		bool map = true;
 
 		/* use a quarter of the TLBCAM for bolted linear map */
 		num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
-		linear_map_top = map_mem_in_cams(linear_map_top, num_cams);
+
+		/*
+		 * Only do the mapping once per core, or else the
+		 * transient mapping would cause problems.
+		 */
+#ifdef CONFIG_SMP
+		if (cpu != boot_cpuid &&
+		    (cpu != cpu_first_thread_sibling(cpu) ||
+		     cpu == cpu_first_thread_sibling(boot_cpuid)))
+			map = false;
+#endif
+
+		if (map)
+			linear_map_top = map_mem_in_cams(linear_map_top,
+							 num_cams);
 	}
 #endif
 
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S
index 43ff3c7..68c4775 100644
--- a/arch/powerpc/mm/tlb_nohash_low.S
+++ b/arch/powerpc/mm/tlb_nohash_low.S
@@ -400,6 +400,7 @@ _GLOBAL(set_context)
  * extern void loadcam_entry(unsigned int index)
  *
  * Load TLBCAM[index] entry in to the L2 CAM MMU
+ * Must preserve r7, r8, r9, and r10
  */
 _GLOBAL(loadcam_entry)
 	mflr	r5
@@ -423,4 +424,66 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
 	tlbwe
 	isync
 	blr
+
+/*
+ * Load multiple TLB entries at once, using an alternate-space
+ * trampoline so that we don't have to care about whether the same
+ * TLB entry maps us before and after.
+ *
+ * r3 = first entry to write
+ * r4 = number of entries to write
+ * r5 = temporary tlb entry
+ */
+_GLOBAL(loadcam_multi)
+	mflr	r8
+
+	/*
+	 * Set up temporary TLB entry that is the same as what we're
+	 * running from, but in AS=1.
+	 */
+	bl	1f
+1:	mflr	r6
+	tlbsx	0,r8
+	mfspr	r6,SPRN_MAS1
+	ori	r6,r6,MAS1_TS
+	mtspr	SPRN_MAS1,r6
+	mfspr	r6,SPRN_MAS0
+	rlwimi	r6,r5,MAS0_ESEL_SHIFT,MAS0_ESEL_MASK
+	mr	r7,r5
+	mtspr	SPRN_MAS0,r6
+	isync
+	tlbwe
+	isync
+
+	/* Switch to AS=1 */
+	mfmsr	r6
+	ori	r6,r6,MSR_IS|MSR_DS
+	mtmsr	r6
+	isync
+
+	mr	r9,r3
+	add	r10,r3,r4
+2:	bl	loadcam_entry
+	addi	r9,r9,1
+	cmpw	r9,r10
+	mr	r3,r9
+	blt	2b
+
+	/* Return to AS=0 and clear the temporary entry */
+	mfmsr	r6
+	rlwinm.	r6,r6,0,~(MSR_IS|MSR_DS)
+	mtmsr	r6
+	isync
+
+	li	r6,0
+	mtspr	SPRN_MAS1,r6
+	rlwinm	r6,r7,MAS0_ESEL_SHIFT,MAS0_ESEL_MASK
+	oris	r6,r6,MAS0_TLBSEL(1)@h
+	mtspr	SPRN_MAS0,r6
+	isync
+	tlbwe
+	isync
+
+	mtlr	r8
+	blr
 #endif
-- 
2.1.4

  reply	other threads:[~2015-07-18 20:09 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-18 20:08 [RFC PATCH 00/17] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
2015-07-18 20:08 ` Scott Wood [this message]
2015-07-18 20:08 ` [RFC PATCH 02/17] powerpc/85xx: Don't use generic timebase sync on 64-bit Scott Wood
2015-07-18 20:08 ` [RFC PATCH 03/17] crypto: caam: Blacklist CAAM when kexec is enabled Scott Wood
2015-07-18 20:08 ` [RFC PATCH 04/17] powerpc/fsl-corenet: Disable coreint if " Scott Wood
2015-07-18 20:08 ` [RFC PATCH 05/17] powerpc/fsl-booke-64: Don't limit ppc64_rma_size to one TLB entry Scott Wood
2015-07-18 20:08 ` [RFC PATCH 06/17] powerpc/85xx: Implement 64-bit kexec support Scott Wood
2015-07-18 20:08 ` [RFC PATCH 07/17] powerpc/e6500: kexec: Handle hardware threads Scott Wood
2015-07-18 20:08 ` [RFC PATCH 08/17] powerpc/book3e-64: rename interrupt_end_book3e with __end_interrupts Scott Wood
2015-07-18 20:08 ` [RFC PATCH 09/17] powerpc/booke64: Fix args to copy_and_flush Scott Wood
2015-07-18 20:08 ` [RFC PATCH 10/17] powerpc/book3e: support CONFIG_RELOCATABLE Scott Wood
2015-07-18 20:08 ` [RFC PATCH 11/17] powerpc/book3e/kdump: Enable crash_kexec_wait_realmode Scott Wood
2015-07-18 20:08 ` [RFC PATCH 12/17] powerpc/book3e-64: Don't limit paca to 256 MiB Scott Wood
2015-07-18 20:08 ` [RFC PATCH 13/17] powerpc/book3e-64/kexec: create an identity TLB mapping Scott Wood
2015-07-18 20:08 ` [RFC PATCH 14/17] powerpc/book3e-64/kexec: Enable SMP release Scott Wood
2015-08-18  4:51   ` [RFC,14/17] " Michael Ellerman
2015-08-18  5:09     ` Scott Wood
2015-08-20  4:54   ` [RFC PATCH 14/17] " Michael Ellerman
2015-08-24 20:25     ` Scott Wood
2015-08-25  1:57       ` Michael Ellerman
2015-08-25 23:40         ` Scott Wood
2015-08-26  1:13           ` Michael Ellerman
2015-07-18 20:08 ` [RFC PATCH 15/17] powerpc/booke: Only use VIRT_PHYS_OFFSET on booke32 Scott Wood
2015-07-18 20:08 ` [RFC PATCH 16/17] powerpc/book3e-64/kexec: Set "r4 = 0" when entering spinloop Scott Wood
2015-07-18 20:08 ` [RFC PATCH 17/17] powerpc/book3e-64: Enable kexec Scott Wood

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=1437250134-307-2-git-send-email-scottwood@freescale.com \
    --to=scottwood@freescale.com \
    --cc=kexec@lists.infradead.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=tiejun.chen@intel.com \
    /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).