linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Nicholas Piggin <npiggin@gmail.com>
To: linuxppc-dev@lists.ozlabs.org
Cc: Nicholas Piggin <npiggin@gmail.com>,
	"Aneesh Kumar K . V" <aneesh.kumar@linux.vnet.ibm.com>,
	Michael Ellerman <mpe@ellerman.id.au>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Paul Mackerras <paulus@ozlabs.org>
Subject: [PATCH] powerpc/64s: ISAv3 initialize MMU registers before setting partition table
Date: Fri,  1 Dec 2017 14:14:48 +1000	[thread overview]
Message-ID: <20171201041448.28053-1-npiggin@gmail.com> (raw)

kexec can leave MMU registers set, PIDR in particular, when booting the
new kernel. The boot sequence does not zero PIDR ever, and it only gets
changed as CPUs first switch to userspace processes. This can leave a
window where speculative accesses from a CPU to quadrant 0 can pick up
translations in the partition table that may be set up for processes
running on other CPUs. These cached translations will not be involved in
the invalidation protocol, so we can end with stable TLB and PWC.

This can cause the kernel to hang in infinite page fault loops (usually
in schedule_tail, which is usually the first quardant 0 access to a new
PID.

Fix this by zeroing out PIDR before setting PTCR.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/mm/hash_utils_64.c |  6 ++++++
 arch/powerpc/mm/pgtable-radix.c | 15 +++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 655a5a9a183d..9176e1dda8e0 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -1029,6 +1029,9 @@ void __init hash__early_init_mmu(void)
 	pci_io_base = ISA_IO_BASE;
 #endif
 
+	if (cpu_has_feature(CPU_FTR_ARCH_300))
+		mtspr(SPRN_PID, 0);
+
 	/* Select appropriate backend */
 	if (firmware_has_feature(FW_FEATURE_PS3_LV1))
 		ps3_early_mm_init();
@@ -1055,6 +1058,9 @@ void __init hash__early_init_mmu(void)
 void hash__early_init_mmu_secondary(void)
 {
 	/* Initialize hash table for that CPU */
+	if (cpu_has_feature(CPU_FTR_ARCH_300))
+		mtspr(SPRN_PID, 0);
+
 	if (!firmware_has_feature(FW_FEATURE_LPAR)) {
 
 		if (cpu_has_feature(CPU_FTR_POWER9_DD1))
diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c
index cfbbee941a76..88430acf4b85 100644
--- a/arch/powerpc/mm/pgtable-radix.c
+++ b/arch/powerpc/mm/pgtable-radix.c
@@ -563,12 +563,25 @@ void __init radix__early_init_mmu(void)
 	__pte_frag_nr = H_PTE_FRAG_NR;
 	__pte_frag_size_shift = H_PTE_FRAG_SIZE_SHIFT;
 
+	/*
+	 * kexec kernels can boot into the new kernel with PIDR non-zero.
+	 *
+	 * PIDR should be zeroed before we set the partition table,
+	 * to ensure no speculative TLB fill goes off to non-zero PIDs.
+	 * This shouldn't be a problem in real-mode, but I have not
+	 * found definitively in the ISA.
+	 *
+	 * We do need to ensure all CPUs have PID=0 when the MMU
+	 * is turned on.
+	 */
+	mtspr(SPRN_PID, 0);
 	if (!firmware_has_feature(FW_FEATURE_LPAR)) {
 		radix_init_native();
 		if (cpu_has_feature(CPU_FTR_POWER9_DD1))
 			update_hid_for_radix();
 		lpcr = mfspr(SPRN_LPCR);
 		mtspr(SPRN_LPCR, lpcr | LPCR_UPRT | LPCR_HR);
+		mtspr(SPRN_LPID, 0);
 		radix_init_partition_table();
 		radix_init_amor();
 	} else {
@@ -587,6 +600,7 @@ void radix__early_init_mmu_secondary(void)
 	/*
 	 * update partition table control register and UPRT
 	 */
+	mtspr(SPRN_PID, 0);
 	if (!firmware_has_feature(FW_FEATURE_LPAR)) {
 
 		if (cpu_has_feature(CPU_FTR_POWER9_DD1))
@@ -595,6 +609,7 @@ void radix__early_init_mmu_secondary(void)
 		lpcr = mfspr(SPRN_LPCR);
 		mtspr(SPRN_LPCR, lpcr | LPCR_UPRT | LPCR_HR);
 
+		mtspr(SPRN_LPID, 0);
 		mtspr(SPRN_PTCR,
 		      __pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
 		radix_init_amor();
-- 
2.15.0

                 reply	other threads:[~2017-12-01  4:15 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20171201041448.28053-1-npiggin@gmail.com \
    --to=npiggin@gmail.com \
    --cc=aneesh.kumar@linux.vnet.ibm.com \
    --cc=benh@kernel.crashing.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mpe@ellerman.id.au \
    --cc=paulus@ozlabs.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).