All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] powerpc/64s: ISAv3 initialize MMU registers before setting partition table
@ 2017-12-01  4:14 Nicholas Piggin
  0 siblings, 0 replies; only message in thread
From: Nicholas Piggin @ 2017-12-01  4:14 UTC (permalink / raw
  To: linuxppc-dev
  Cc: Nicholas Piggin, Aneesh Kumar K . V, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras

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

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2017-12-01  4:15 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-12-01  4:14 [PATCH] powerpc/64s: ISAv3 initialize MMU registers before setting partition table Nicholas Piggin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.