Skip to contentSkip to conversation

Bits and pieces for Power7 support in HV mode

PATCH New Benjamin Herrenschmidt 4 participants 23 messages Apr 5, 2011 – Apr 7, 2011

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Bits and pieces for Power7 support in HV mode

Here's a patch series which adds bits and pieces (and in some case not directly related cleanups that will be useful for the upcoming platform that uses that stuff) to allow running a recent CPU in hypervisor mode.

It applies on top of the few cleanups and the XICS rewrite I've already posted and is a pre-requisite for the upcoming KVM support and the "non-virtualized" platform (still brewing).

I've also put them in my "test" branch

Cheers,
Ben.

#1 lore raw

PATCH 1/15 powerpc: Add more Power7 specific definitions

This adds more SPR definitions used on newer processors when running in hypervisor mode. Along with some other P7 specific bits and pieces

---
 arch/powerpc/include/asm/ppc_asm.h |    1 +
 arch/powerpc/include/asm/reg.h     |   46 +++++++++++++++++++++++++++++++++++-
 2 files changed, 46 insertions(+), 1 deletions(-)
arch/powerpc/include/asm/ppc_asm.h +1 -0
index 9821006..1b42238 100644
@@ -170,6 +170,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
 #define HMT_MEDIUM	or	2,2,2
 #define HMT_MEDIUM_HIGH or	5,5,5		# medium high priority
 #define HMT_HIGH	or	3,3,3
+#define HMT_EXTRA_HIGH	or	7,7,7		# power7 only
 
 #ifdef __KERNEL__
 #ifdef CONFIG_PPC64
arch/powerpc/include/asm/reg.h +45 -1

75 lines not on this page · raw message

Signature · 1 line
1.7.1
#2 lore raw

PATCH 2/15 powerpc/rtas: Check RTAS presence when testing indicators

In reply to Benjamin Herrenschmidt
---
 arch/powerpc/kernel/rtas.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
arch/powerpc/kernel/rtas.c +2 -0
index 2097f2b..c2bfc4d 100644
@@ -591,6 +591,8 @@ bool rtas_indicator_present(int token, int *maxindex)
 		u32 maxindex;
 	} *indicators;
 
+	if (!rtas.dev)
+		return false;
 	indicators = of_get_property(rtas.dev, "rtas-indicators", &proplen);
 	if (!indicators)
 		return false;
Signature · 1 line
1.7.1
#3 lore raw

Re: [PATCH 02/15] powerpc/rtas: Check RTAS presence when testing indicators

Quoted 10 lines · Benjamin Herrenschmidt
---
 arch/powerpc/kernel/rtas.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
arch/powerpc/kernel/rtas.c +0 -0
index 2097f2b..c2bfc4d 100644

arch/powerpc/kernel/rtas.c bool rtas_indicator_present(int token, int *maxindex) · line 598

Quoted 8 lines
arch/powerpc/kernel/rtas.c +2 -0
@@ -591,6 +591,8 @@ bool rtas_indicator_present(int token, int *maxindex)
 		u32 maxindex;
 	} *indicators;
 
+	if (!rtas.dev)
+		return false;
 	indicators = of_get_property(rtas.dev, "rtas-indicators", &proplen);
 	if (!indicators)
 		return false;

Why? of_get_property() returns NULL if np is NULL, implemented in of_find_property(). It doesn't look like a fast path.

cheers

#4 lore raw

Re: [PATCH 02/15] powerpc/rtas: Check RTAS presence when testing indicators

Quoted 3 lines

Why? of_get_property() returns NULL if np is NULL, implemented in of_find_property(). It doesn't look like a fast path.

Fun... not sure, I though I had a problem but maybe I don't remember properly :-)

Cheers,
Ben.

#5 lore raw

PATCH 3/15 powerpc/xics: Make sure we have a sensible default distribution server

In reply to Benjamin Herrenschmidt

Even when nothing is specified in the device tree, and despite the fact that we don't setup links properly yet, we still need a reasonable value in there or some interrupts won't be setup properly to point to an existing processor.

---
 arch/powerpc/sysdev/xics/xics-common.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)
arch/powerpc/sysdev/xics/xics-common.c +9 -3
index ac26866..7c9cba3 100644
@@ -57,7 +57,9 @@ void xics_update_irq_servers(void)
 	BUG_ON(!np);
 
 	hcpuid = get_hard_smp_processor_id(boot_cpuid);
-	xics_default_server = hcpuid;
+	xics_default_server = xics_default_distrib_server = hcpuid;
+
+	pr_devel("xics: xics_default_server = 0x%x\n", xics_default_server);
 
 	ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
 	if (!ireg) {
@@ -75,9 +77,11 @@ void xics_update_irq_servers(void)
 	for (j = 0; j < i; j += 2) {
 		if (ireg[j] == hcpuid) {
 			xics_default_distrib_server = ireg[j+1];
+			break;
 		}
 	}
-
+	pr_devel("xics: xics_default_distrib_server = 0x%x\n",
+		 xics_default_distrib_server);
 	of_node_put(np);
 }
 
@@ -113,7 +117,7 @@ void xics_mask_unknown_vec(unsigned int vec)
 {
 	struct ics *ics;
 
-	pr_err("Interrupt %u (real) is invalid, disabling it.\n", vec);
+	pr_err("Interrupt 0x%x (real) is invalid, disabling it.\n", vec);
 
 	list_for_each_entry(ics, &ics_list, link)
 		ics->mask_unknown(ics, vec);
@@ -293,6 +297,8 @@ unlock:
  * If not we set it to the first cpu in the mask, even if multiple cpus
  * are set. This is so things like irqbalance (which set core and package
  * wide affinities) do the right thing.
+ *
+ * We need to fix this to implement support for the links
  */
 int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask,
 			unsigned int strict_check)
Signature · 1 line
1.7.1
#6 lore raw

PATCH 4/15 powerpc: Define CPU feature for Architected 2.06 HV mode

In reply to Benjamin Herrenschmidt

This bit indicates that we are operating in hypervisor mode on a CPU compliant to architecture 2.06 or later (currently server only).

We set it on POWER7 and have a boot-time CPU setup function that clears it if MSR:HV isn't set (booting under a hypervisor).

---
 arch/powerpc/include/asm/cputable.h    |    3 +-
 arch/powerpc/kernel/Makefile           |    1 +
 arch/powerpc/kernel/cpu_setup_power7.S |   65 ++++++++++++++++++++++++++++++++
 arch/powerpc/kernel/cputable.c         |    6 +++
 4 files changed, 74 insertions(+), 1 deletions(-)
 create mode 100644 arch/powerpc/kernel/cpu_setup_power7.S
arch/powerpc/include/asm/cputable.h +2 -1
index be3cdf9..7d2eb44 100644
@@ -181,6 +181,7 @@ extern const char *powerpc_base_platform;
 #define CPU_FTR_SLB			LONG_ASM_CONST(0x0000000100000000)
 #define CPU_FTR_16M_PAGE		LONG_ASM_CONST(0x0000000200000000)
 #define CPU_FTR_TLBIEL			LONG_ASM_CONST(0x0000000400000000)
+#define CPU_FTR_HVMODE_206		LONG_ASM_CONST(0x0000000800000000)
 #define CPU_FTR_IABR			LONG_ASM_CONST(0x0000002000000000)
 #define CPU_FTR_MMCRA			LONG_ASM_CONST(0x0000004000000000)
 #define CPU_FTR_CTRL			LONG_ASM_CONST(0x0000008000000000)
@@ -416,7 +417,7 @@ extern const char *powerpc_base_platform;
 	    CPU_FTR_DSCR | CPU_FTR_UNALIGNED_LD_STD | \
 	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB)
 #define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
-	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
+	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_HVMODE_206 |\
 	    CPU_FTR_MMCRA | CPU_FTR_SMT | \
 	    CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
 	    CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
arch/powerpc/kernel/Makefile +1 -0
index 3bb2a3e..7c6eb49 100644
@@ -38,6 +38,7 @@ obj-$(CONFIG_PPC64)		+= setup_64.o sys_ppc32.o \
 				   paca.o nvram_64.o firmware.o
 obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
 obj-$(CONFIG_PPC_BOOK3S_64)	+= cpu_setup_ppc970.o cpu_setup_pa6t.o
+obj-$(CONFIG_PPC_BOOK3S_64)	+= cpu_setup_power7.o
 obj64-$(CONFIG_RELOCATABLE)	+= reloc_64.o
 obj-$(CONFIG_PPC_BOOK3E_64)	+= exceptions-64e.o idle_book3e.o
 obj-$(CONFIG_PPC64)		+= vdso64/
arch/powerpc/kernel/cpu_setup_power7.S new file +65 -0

65 lines not on this page · raw message

arch/powerpc/kernel/cputable.c +6 -0
index c9b68d0..867ae30 100644
@@ -423,6 +423,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.dcache_bsize		= 128,
 		.oprofile_type		= PPC_OPROFILE_POWER4,
 		.oprofile_cpu_type	= "ppc64/ibm-compat-v1",
+		.cpu_setup		= __setup_cpu_power7,
+		.cpu_restore		= __restore_cpu_power7,
 		.platform		= "power7",
 	},
 	{	/* Power7 */
@@ -439,6 +441,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.pmc_type		= PPC_PMC_IBM,
 		.oprofile_cpu_type	= "ppc64/power7",
 		.oprofile_type		= PPC_OPROFILE_POWER4,
+		.cpu_setup		= __setup_cpu_power7,
+		.cpu_restore		= __restore_cpu_power7,
 		.platform		= "power7",
 	},
 	{	/* Power7+ */
@@ -455,6 +459,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.pmc_type		= PPC_PMC_IBM,
 		.oprofile_cpu_type	= "ppc64/power7",
 		.oprofile_type		= PPC_OPROFILE_POWER4,
+		.cpu_setup		= __setup_cpu_power7,
+		.cpu_restore		= __restore_cpu_power7,
 		.platform		= "power7+",
 	},
 	{	/* Cell Broadband Engine */
Signature · 1 line
1.7.1
#7 lore raw

Re: [PATCH 04/15] powerpc: Define CPU feature for Architected 2.06 HV mode

Quoted 5 lines · In message <[email protected]> you…

This bit indicates that we are operating in hypervisor mode on a CPU compliant to architecture 2.06 or later (currently server only).

We set it on POWER7 and have a boot-time CPU setup function that clears it if MSR:HV isn't set (booting under a hypervisor).

<snip>

Quoted 1 line

+#define CPU_FTR_HVMODE_206 LONG_ASM_CONST(0x0000000800000000)

FYI With this patch we could remove MMU_FTR_TLBIE_206.

Mikey

#8 lore raw

Re: [PATCH 04/15] powerpc: Define CPU feature for Architected 2.06 HV mode

Quoted 4 lines · Michael Neuling
Quoted 3 lines · In message <[email protected]> you…

This bit indicates that we are operating in hypervisor mode on a CPU compliant to architecture 2.06 or later (currently server only).

Quoted 8 lines
Quoted 2 lines

We set it on POWER7 and have a boot-time CPU setup function that clears it if MSR:HV isn't set (booting under a hypervisor).

<snip>

Quoted 1 line

+#define CPU_FTR_HVMODE_206 LONG_ASM_CONST(0x0000000800000000)

FYI With this patch we could remove MMU_FTR_TLBIE_206.

We could... care to send a patch ? :-)

Cheers,
Ben.

#9 lore raw

PATCH 1/1 powerpc: Use new CPU feature bit to select 2.06 tlbie

This removes MMU_FTR_TLBIE_206 as we can now use CPU_FTR_HVMODE_206. It also changes the logic to select which tlbie to use to be based on this new CPU feature bit.

This also duplicates the ASM_FTR_IF/SET/CLR defines for CPU features (copied from MMU features).

---
Subject: Re: [PATCH 04/15] powerpc: Define CPU feature for Architected 2.06 HV mode

Quoted 1 line
Quoted 1 line
Quoted 1 line

+#define CPU_FTR_HVMODE_206 LONG_ASM_CONST(0x00000008000000

00)

Quoted 4 lines
Quoted 2 lines

FYI With this patch we could remove MMU_FTR_TLBIE_206.

We could... care to send a patch ? :-)

Sure... How about this?

Mikey

 arch/powerpc/include/asm/feature-fixups.h |   13 +++++++++++++
 arch/powerpc/include/asm/mmu.h            |    5 -----
 arch/powerpc/kernel/cputable.c            |    9 +++------
 arch/powerpc/mm/hash_native_64.c          |    8 ++++----
 4 files changed, 20 insertions(+), 15 deletions(-)
arch/powerpc/include/asm/feature-fixups.h +13 -0
Index: clone1/arch/powerpc/include/asm/feature-fixups.h
===================================================================
@@ -146,6 +146,19 @@
 
 #ifndef __ASSEMBLY__
 
+#define ASM_FTR_IF(section_if, section_else, msk, val)	\
+	stringify_in_c(BEGIN_FTR_SECTION)			\
+	section_if "; "						\
+	stringify_in_c(FTR_SECTION_ELSE)			\
+	section_else "; "					\
+	stringify_in_c(ALT_FTR_SECTION_END((msk), (val)))
+
+#define ASM_FTR_IFSET(section_if, section_else, msk)	\
+	ASM_FTR_IF(section_if, section_else, (msk), (msk))
+
+#define ASM_FTR_IFCLR(section_if, section_else, msk)	\
+	ASM_FTR_IF(section_if, section_else, (msk), 0)
+
 #define ASM_MMU_FTR_IF(section_if, section_else, msk, val)	\
 	stringify_in_c(BEGIN_MMU_FTR_SECTION)			\
 	section_if "; "						\
arch/powerpc/include/asm/mmu.h +0 -5
Index: clone1/arch/powerpc/include/asm/mmu.h
===================================================================
@@ -56,11 +56,6 @@
  */
 #define MMU_FTR_NEED_DTLB_SW_LRU	ASM_CONST(0x00200000)
 
-/* This indicates that the processor uses the ISA 2.06 server tlbie
- * mnemonics
- */
-#define MMU_FTR_TLBIE_206		ASM_CONST(0x00400000)
-
 /* Enable use of TLB reservation.  Processor should support tlbsrx.
  * instruction and MAS0[WQ].
  */
arch/powerpc/kernel/cputable.c +3 -6
Index: clone1/arch/powerpc/kernel/cputable.c
===================================================================
@@ -417,8 +417,7 @@
 		.cpu_name		= "POWER7 (architected)",
 		.cpu_features		= CPU_FTRS_POWER7,
 		.cpu_user_features	= COMMON_USER_POWER7,
-		.mmu_features		= MMU_FTR_HPTE_TABLE |
-			MMU_FTR_TLBIE_206,
+		.mmu_features		= MMU_FTR_HPTE_TABLE,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.oprofile_type		= PPC_OPROFILE_POWER4,
@@ -433,8 +432,7 @@
 		.cpu_name		= "POWER7 (raw)",
 		.cpu_features		= CPU_FTRS_POWER7,
 		.cpu_user_features	= COMMON_USER_POWER7,
-		.mmu_features		= MMU_FTR_HPTE_TABLE |
-			MMU_FTR_TLBIE_206,
+		.mmu_features		= MMU_FTR_HPTE_TABLE,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 6,
@@ -451,8 +449,7 @@
 		.cpu_name		= "POWER7+ (raw)",
 		.cpu_features		= CPU_FTRS_POWER7,
 		.cpu_user_features	= COMMON_USER_POWER7,
-		.mmu_features		= MMU_FTR_HPTE_TABLE |
-			MMU_FTR_TLBIE_206,
+		.mmu_features		= MMU_FTR_HPTE_TABLE,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 6,
arch/powerpc/mm/hash_native_64.c +4 -4
Index: clone1/arch/powerpc/mm/hash_native_64.c
===================================================================
@@ -50,9 +50,9 @@
 	case MMU_PAGE_4K:
 		va &= ~0xffful;
 		va |= ssize << 8;
-		asm volatile(ASM_MMU_FTR_IFCLR("tlbie %0,0", PPC_TLBIE(%1,%0),
+		asm volatile(ASM_FTR_IFCLR("tlbie %0,0", PPC_TLBIE(%1,%0),
 					       %2)
-			     : : "r" (va), "r"(0), "i" (MMU_FTR_TLBIE_206)
+			     : : "r" (va), "r"(0), "i" (CPU_FTR_HVMODE_206)
 			     : "memory");
 		break;
 	default:
@@ -61,9 +61,9 @@
 		va |= penc << 12;
 		va |= ssize << 8;
 		va |= 1; /* L */
-		asm volatile(ASM_MMU_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0),
+		asm volatile(    ASM_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0),
 					       %2)
-			     : : "r" (va), "r"(0), "i" (MMU_FTR_TLBIE_206)
+			     : : "r" (va), "r"(0), "i" (CPU_FTR_HVMODE_206)
 			     : "memory");
 		break;
 	}
#10 lore raw

PATCH 5/15 powerpc: In HV mode, use HSPRG0 for PACA

In reply to Benjamin Herrenschmidt

When running in Hypervisor mode (arch 2.06 or later), we store the PACA in HSPRG0 instead of SPRG1. The architecture specifies that SPRGs may be lost during a "nap" power management operation (though they aren't currently on POWER7) and this enables use of SPRG1 by KVM guests.

---
 arch/powerpc/include/asm/exception-64s.h |    6 +++---
 arch/powerpc/include/asm/reg.h           |   27 ++++++++++++++++++++++++++-
 arch/powerpc/kernel/entry_64.S           |    4 ++--
 arch/powerpc/kernel/exceptions-64s.S     |    8 ++++----
 arch/powerpc/kernel/head_64.S            |    4 ++--
 arch/powerpc/kernel/paca.c               |   13 ++++++++++++-
 arch/powerpc/kvm/book3s_rmhandlers.S     |    4 +---
 7 files changed, 50 insertions(+), 16 deletions(-)
arch/powerpc/include/asm/exception-64s.h +3 -3
index 7778d6f..337b6fa 100644
@@ -56,8 +56,8 @@
 #define LOAD_HANDLER(reg, label)					\
 	addi	reg,reg,(label)-_stext;	/* virt addr of handler ... */
 
-#define EXCEPTION_PROLOG_1(area)				\
-	mfspr	r13,SPRN_SPRG_PACA;	/* get paca address into r13 */	\
+#define EXCEPTION_PROLOG_1(area)					\
+	GET_PACA(r13);							\
 	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
 	std	r10,area+EX_R10(r13);					\
 	std	r11,area+EX_R11(r13);					\
@@ -174,7 +174,7 @@ label##_pSeries:							\
 	HMT_MEDIUM;							\
 	DO_KVM	n;							\
 	mtspr	SPRN_SPRG_SCRATCH0,r13;	/* save r13 */			\
-	mfspr	r13,SPRN_SPRG_PACA;	/* get paca address into r13 */	\
+	GET_PACA(r13);							\
 	std	r9,PACA_EXGEN+EX_R9(r13);	/* save r9, r10 */	\
 	std	r10,PACA_EXGEN+EX_R10(r13);				\
 	lbz	r10,PACASOFTIRQEN(r13);					\
arch/powerpc/include/asm/reg.h +26 -1
index 6eb1d77..13429a0 100644
@@ -715,12 +715,15 @@
  * SPRG usage:
  *
  * All 64-bit:
- *	- SPRG1 stores PACA pointer
+ *	- SPRG1 stores PACA pointer except 64-bit server in
+ *        HV mode in which case it is HSPRG0
  *
  * 64-bit server:
  *	- SPRG0 unused (reserved for HV on Power4)
  *	- SPRG2 scratch for exception vectors
  *	- SPRG3 unused (user visible)
+ *      - HSPRG0 stores PACA in HV mode
+ *      - HSPRG1 scratch for "HV" exceptions
  *
  * 64-bit embedded
  *	- SPRG0 generic exception scratch
@@ -783,6 +786,22 @@
 
 #ifdef CONFIG_PPC_BOOK3S_64
 #define SPRN_SPRG_SCRATCH0	SPRN_SPRG2
+#define SPRN_SPRG_HPACA		SPRN_HSPRG0
+#define SPRN_SPRG_HSCRATCH0	SPRN_HSPRG1
+
+#define GET_PACA(rX)					\
+	BEGIN_FTR_SECTION_NESTED(66);			\
+	mfspr	rX,SPRN_SPRG_PACA;			\
+	FTR_SECTION_ELSE_NESTED(66);			\
+	mfspr	rX,SPRN_SPRG_HPACA;			\
+	ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
+
+#define SET_PACA(rX)					\
+	BEGIN_FTR_SECTION_NESTED(66);			\
+	mtspr	SPRN_SPRG_PACA,rX;			\
+	FTR_SECTION_ELSE_NESTED(66);			\
+	mtspr	SPRN_SPRG_HPACA,rX;			\
+	ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
 #endif
 
 #ifdef CONFIG_PPC_BOOK3E_64
@@ -792,6 +811,10 @@
 #define SPRN_SPRG_TLB_EXFRAME	SPRN_SPRG2
 #define SPRN_SPRG_TLB_SCRATCH	SPRN_SPRG6
 #define SPRN_SPRG_GEN_SCRATCH	SPRN_SPRG0
+
+#define SET_PACA(rX)	mtspr	SPRN_SPRG_PACA,rX
+#define GET_PACA(rX)	mfspr	rX,SPRN_SPRG_PACA
+
 #endif
 
 #ifdef CONFIG_PPC_BOOK3S_32
@@ -842,6 +865,8 @@
 #define SPRN_SPRG_SCRATCH1	SPRN_SPRG1
 #endif
 
+
+
 /*
  * An mtfsf instruction with the L bit set. On CPUs that support this a
  * full 64bits of FPSCR is restored and on other CPUs the L bit is ignored.
arch/powerpc/kernel/entry_64.S +2 -2
index d82878c..dbf5bfa 100644
@@ -838,7 +838,7 @@ _GLOBAL(enter_rtas)
 
 _STATIC(rtas_return_loc)
 	/* relocation is off at this point */
-	mfspr	r4,SPRN_SPRG_PACA	/* Get PACA */
+	GET_PACA(r4)
 	clrldi	r4,r4,2			/* convert to realmode address */
 
 	bcl	20,31,$+4
@@ -869,7 +869,7 @@ _STATIC(rtas_restore_regs)
 	REST_8GPRS(14, r1)		/* Restore the non-volatiles */
 	REST_10GPRS(22, r1)		/* ditto */
 
-	mfspr	r13,SPRN_SPRG_PACA
+	GET_PACA(r13)
 
 	ld	r4,_CCR(r1)
 	mtcr	r4
arch/powerpc/kernel/exceptions-64s.S +4 -4
index c532cb2..4ea3cc6 100644
@@ -53,7 +53,7 @@ data_access_pSeries:
 	DO_KVM	0x300
 	mtspr	SPRN_SPRG_SCRATCH0,r13
 BEGIN_FTR_SECTION
-	mfspr	r13,SPRN_SPRG_PACA
+	GET_PACA(r13)
 	std	r9,PACA_EXSLB+EX_R9(r13)
 	std	r10,PACA_EXSLB+EX_R10(r13)
 	mfspr	r10,SPRN_DAR
@@ -82,7 +82,7 @@ data_access_slb_pSeries:
 	HMT_MEDIUM
 	DO_KVM	0x380
 	mtspr	SPRN_SPRG_SCRATCH0,r13
-	mfspr	r13,SPRN_SPRG_PACA		/* get paca address into r13 */
+	GET_PACA(r13)
 	std	r3,PACA_EXSLB+EX_R3(r13)
 	mfspr	r3,SPRN_DAR
 	std	r9,PACA_EXSLB+EX_R9(r13)	/* save r9 - r12 */
@@ -121,7 +121,7 @@ instruction_access_slb_pSeries:
 	HMT_MEDIUM
 	DO_KVM	0x480
 	mtspr	SPRN_SPRG_SCRATCH0,r13
-	mfspr	r13,SPRN_SPRG_PACA		/* get paca address into r13 */
+	GET_PACA(r13)
 	std	r3,PACA_EXSLB+EX_R3(r13)
 	mfspr	r3,SPRN_SRR0		/* SRR0 is faulting address */
 	std	r9,PACA_EXSLB+EX_R9(r13)	/* save r9 - r12 */
@@ -165,7 +165,7 @@ BEGIN_FTR_SECTION
 	beq-	1f
 END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
 	mr	r9,r13
-	mfspr	r13,SPRN_SPRG_PACA
+	GET_PACA(r13)
 	mfspr	r11,SPRN_SRR0
 	ld	r12,PACAKBASE(r13)
 	ld	r10,PACAKMSR(r13)
arch/powerpc/kernel/head_64.S +2 -2
index 271140b..53d3bfd 100644
@@ -228,7 +228,7 @@ generic_secondary_common_init:
 	mr	r3,r24			/* not found, copy phys to r3	 */
 	b	.kexec_wait		/* next kernel might do better	 */
 
-2:	mtspr	SPRN_SPRG_PACA,r13	/* Save vaddr of paca in an SPRG */
+2:	SET_PACA(r13)
 #ifdef CONFIG_PPC_BOOK3E
 	addi	r12,r13,PACA_EXTLB	/* and TLB exc frame in another  */
 	mtspr	SPRN_SPRG_TLB_EXFRAME,r12
@@ -534,7 +534,7 @@ _GLOBAL(pmac_secondary_start)
 	ld	r4,0(r4)		/* Get base vaddr of paca array	*/
 	mulli	r13,r24,PACA_SIZE	/* Calculate vaddr of right paca */
 	add	r13,r13,r4		/* for this processor.		*/
-	mtspr	SPRN_SPRG_PACA,r13	/* Save vaddr of paca in an SPRG*/
+	SET_PACA(r13)			/* Save vaddr of paca in an SPRG*/
 
 	/* Mark interrupts soft and hard disabled (they might be enabled
 	 * in the PACA when doing hotplug)
arch/powerpc/kernel/paca.c +12 -1
index 10f0aad..102244e 100644
@@ -156,11 +156,22 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
 /* Put the paca pointer into r13 and SPRG_PACA */
 void setup_paca(struct paca_struct *new_paca)
 {
+	/* Setup r13 */
 	local_paca = new_paca;
-	mtspr(SPRN_SPRG_PACA, local_paca);
+
 #ifdef CONFIG_PPC_BOOK3E
+	/* On Book3E, initialize the TLB miss exception frames */
 	mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb);
+#else
+	/* In HV mode, we setup both HPACA and PACA to avoid problems
+	 * if we do a GET_PACA() before the feature fixups have been
+	 * applied
+	 */
+	if (cpu_has_feature(CPU_FTR_HVMODE_206))
+		mtspr(SPRN_SPRG_HPACA, local_paca);
 #endif
+	mtspr(SPRN_SPRG_PACA, local_paca);
+
 }
 
 static int __initdata paca_size;
arch/powerpc/kvm/book3s_rmhandlers.S +1 -3
index 2b9c908..b0ff5ff 100644
@@ -35,9 +35,7 @@
 
 #if defined(CONFIG_PPC_BOOK3S_64)
 
-#define LOAD_SHADOW_VCPU(reg)				\
-	mfspr	reg, SPRN_SPRG_PACA
-
+#define LOAD_SHADOW_VCPU(reg)	GET_PACA(reg)					
 #define SHADOW_VCPU_OFF		PACA_KVM_SVCPU
 #define MSR_NOIRQ		MSR_KERNEL & ~(MSR_IR | MSR_DR)
 #define FUNC(name) 		GLUE(.,name)
Signature · 1 line
1.7.1
#11 lore raw

PATCH 6/15 powerpc: Base support for exceptions using HSRR0/1

In reply to Benjamin Herrenschmidt

Pass the register type to the prolog, also provides alternate "HV" version of hardware interrupt (0x500) and adjust LPES accordingly

We tag those interrupts by setting bit 0x2 in the trap number

---
 arch/powerpc/include/asm/exception-64s.h   |   65 ++++++++++++++--------------
 arch/powerpc/include/asm/kvm_asm.h         |    1 +
 arch/powerpc/include/asm/kvm_book3s_asm.h  |    1 +
 arch/powerpc/kernel/cpu_setup_power7.S     |    3 +-
 arch/powerpc/kernel/exceptions-64s.S       |   48 ++++++++++++++++-----
 arch/powerpc/kvm/book3s_rmhandlers.S       |    1 +
 arch/powerpc/kvm/book3s_segment.S          |   10 +++-
 arch/powerpc/platforms/iseries/exception.S |    2 +-
 arch/powerpc/platforms/iseries/exception.h |    4 +-
 9 files changed, 86 insertions(+), 49 deletions(-)
arch/powerpc/include/asm/exception-64s.h +33 -32
index 337b6fa..1d98e05 100644
@@ -56,30 +56,37 @@
 #define LOAD_HANDLER(reg, label)					\
 	addi	reg,reg,(label)-_stext;	/* virt addr of handler ... */
 
-#define EXCEPTION_PROLOG_1(area)					\
+/* Exception register prefixes */
+#define EXC_HV	H
+#define EXC_STD
+
+#define __EXCEPTION_PROLOG_1(area, h)					\
 	GET_PACA(r13);							\
 	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
 	std	r10,area+EX_R10(r13);					\
 	std	r11,area+EX_R11(r13);					\
 	std	r12,area+EX_R12(r13);					\
-	mfspr	r9,SPRN_SPRG_SCRATCH0;					\
+	mfspr	r9,SPRN_SPRG_##h##SCRATCH0;				\
 	std	r9,area+EX_R13(r13);					\
 	mfcr	r9
+#define EXCEPTION_PROLOG_1(area, h) __EXCEPTION_PROLOG_1(area, h)
 
-#define EXCEPTION_PROLOG_PSERIES_1(label)				\
+#define __EXCEPTION_PROLOG_PSERIES_1(label, h)				\
 	ld	r12,PACAKBASE(r13);	/* get high part of &label */	\
 	ld	r10,PACAKMSR(r13);	/* get MSR value for kernel */	\
-	mfspr	r11,SPRN_SRR0;		/* save SRR0 */			\
+	mfspr	r11,SPRN_##h##SRR0;	/* save SRR0 */			\
 	LOAD_HANDLER(r12,label)						\
-	mtspr	SPRN_SRR0,r12;						\
-	mfspr	r12,SPRN_SRR1;		/* and SRR1 */			\
-	mtspr	SPRN_SRR1,r10;						\
-	rfid;								\
+	mtspr	SPRN_##h##SRR0,r12;					\
+	mfspr	r12,SPRN_##h##SRR1;	/* and SRR1 */			\
+	mtspr	SPRN_##h##SRR1,r10;					\
+	h##rfid;							\
 	b	.	/* prevent speculative execution */
+#define EXCEPTION_PROLOG_PSERIES_1(label, h) \
+	__EXCEPTION_PROLOG_PSERIES_1(label, h)
 
-#define EXCEPTION_PROLOG_PSERIES(area, label)				\
-	EXCEPTION_PROLOG_1(area);					\
-	EXCEPTION_PROLOG_PSERIES_1(label);
+#define EXCEPTION_PROLOG_PSERIES(area, label, h)			\
+	EXCEPTION_PROLOG_1(area, h);					\
+	EXCEPTION_PROLOG_PSERIES_1(label, h);
 
 /*
  * The common exception prolog is used for all except a few exceptions
@@ -150,50 +157,44 @@ label##_pSeries:					\
 	HMT_MEDIUM;					\
 	DO_KVM	n;					\
 	mtspr	SPRN_SPRG_SCRATCH0,r13;		/* save r13 */	\
-	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
+	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_STD)
 
 #define HSTD_EXCEPTION_PSERIES(n, label)		\
 	. = n;						\
 	.globl label##_pSeries;				\
 label##_pSeries:					\
 	HMT_MEDIUM;					\
-	mtspr	SPRN_SPRG_SCRATCH0,r20;	/* save r20 */	\
-	mfspr	r20,SPRN_HSRR0;		/* copy HSRR0 to SRR0 */ \
-	mtspr	SPRN_SRR0,r20;				\
-	mfspr	r20,SPRN_HSRR1;		/* copy HSRR0 to SRR0 */ \
-	mtspr	SPRN_SRR1,r20;				\
-	mfspr	r20,SPRN_SPRG_SCRATCH0;	/* restore r20 */ \
-	mtspr	SPRN_SPRG_SCRATCH0,r13;		/* save r13 */	\
-	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
+	DO_KVM	n;					\
+	mtspr	SPRN_SPRG_HSCRATCH0,r13;/* save r13 */	\
+	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_HV)
 
 
-#define MASKABLE_EXCEPTION_PSERIES(n, label)				\
-	. = n;								\
-	.globl label##_pSeries;						\
-label##_pSeries:							\
+#define __MASKABLE_EXCEPTION_PSERIES(n, label, h)			\
 	HMT_MEDIUM;							\
 	DO_KVM	n;							\
-	mtspr	SPRN_SPRG_SCRATCH0,r13;	/* save r13 */			\
+	mtspr	SPRN_SPRG_##h##SCRATCH0,r13;    /* save r13 */		\
 	GET_PACA(r13);							\
 	std	r9,PACA_EXGEN+EX_R9(r13);	/* save r9, r10 */	\
 	std	r10,PACA_EXGEN+EX_R10(r13);				\
 	lbz	r10,PACASOFTIRQEN(r13);					\
 	mfcr	r9;							\
 	cmpwi	r10,0;							\
-	beq	masked_interrupt;					\
-	mfspr	r10,SPRN_SPRG_SCRATCH0;					\
+	beq	masked_##h##interrupt;					\
+	mfspr	r10,SPRN_SPRG_##h##SCRATCH0;				\
 	std	r10,PACA_EXGEN+EX_R13(r13);				\
 	std	r11,PACA_EXGEN+EX_R11(r13);				\
 	std	r12,PACA_EXGEN+EX_R12(r13);				\
 	ld	r12,PACAKBASE(r13);	/* get high part of &label */	\
 	ld	r10,PACAKMSR(r13);	/* get MSR value for kernel */	\
-	mfspr	r11,SPRN_SRR0;		/* save SRR0 */			\
+	mfspr	r11,SPRN_##h##SRR0;	/* save SRR0 */			\
 	LOAD_HANDLER(r12,label##_common)				\
-	mtspr	SPRN_SRR0,r12;						\
-	mfspr	r12,SPRN_SRR1;		/* and SRR1 */			\
-	mtspr	SPRN_SRR1,r10;						\
-	rfid;								\
+	mtspr	SPRN_##h##SRR0,r12;					\
+	mfspr	r12,SPRN_##h##SRR1;	/* and SRR1 */			\
+	mtspr	SPRN_##h##SRR1,r10;					\
+	h##rfid;							\
 	b	.	/* prevent speculative execution */
+#define MASKABLE_EXCEPTION_PSERIES(n, label, h)				\
+	__MASKABLE_EXCEPTION_PSERIES(n, label, h)
 
 #ifdef CONFIG_PPC_ISERIES
 #define DISABLE_INTS				\
arch/powerpc/include/asm/kvm_asm.h +1 -0
index 5b75046..0951b17 100644
@@ -59,6 +59,7 @@
 #define BOOK3S_INTERRUPT_INST_SEGMENT	0x480
 #define BOOK3S_INTERRUPT_EXTERNAL	0x500
 #define BOOK3S_INTERRUPT_EXTERNAL_LEVEL	0x501
+#define BOOK3S_INTERRUPT_EXTERNAL_HV	0x502
 #define BOOK3S_INTERRUPT_ALIGNMENT	0x600
 #define BOOK3S_INTERRUPT_PROGRAM	0x700
 #define BOOK3S_INTERRUPT_FP_UNAVAIL	0x800
arch/powerpc/include/asm/kvm_book3s_asm.h +1 -0
index 36fdb3a..d5a8a38 100644
@@ -34,6 +34,7 @@
 	    (\intno == BOOK3S_INTERRUPT_DATA_SEGMENT) || \
 	    (\intno == BOOK3S_INTERRUPT_INST_SEGMENT) || \
 	    (\intno == BOOK3S_INTERRUPT_EXTERNAL) || \
+	    (\intno == BOOK3S_INTERRUPT_EXTERNAL_HV) || \
 	    (\intno == BOOK3S_INTERRUPT_ALIGNMENT) || \
 	    (\intno == BOOK3S_INTERRUPT_PROGRAM) || \
 	    (\intno == BOOK3S_INTERRUPT_FP_UNAVAIL) || \
arch/powerpc/kernel/cpu_setup_power7.S +2 -1
index f2b3178..e801ef1 100644
@@ -52,13 +52,14 @@ __init_hvmode_206:
 __init_LPCR:
 	/* Setup a sane LPCR:
 	 *
-	 *   LPES = 0b11 (SRR0/1 used for 0x500)
+	 *   LPES = 0b01 (HSRR0/1 used for 0x500)
 	 *   PECE = 0b111
 	 *
 	 * Other bits untouched for now
 	 */
 	mfspr	r3,SPRN_LPCR
 	ori	r3,r3,(LPCR_LPES0|LPCR_LPES1)
+	xori	r3,r3, LPCR_LPES0
 	ori	r3,r3,(LPCR_PECE0|LPCR_PECE1|LPCR_PECE2)
 	mtspr	SPRN_LPCR,r3
 	isync
arch/powerpc/kernel/exceptions-64s.S +37 -11

106 lines not on this page · raw message

arch/powerpc/kvm/book3s_rmhandlers.S +1 -0
index b0ff5ff..046e1f3 100644
@@ -112,6 +112,7 @@ INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_MACHINE_CHECK
 INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_DATA_STORAGE
 INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_INST_STORAGE
 INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_EXTERNAL
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_EXTERNAL_HV
 INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_ALIGNMENT
 INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_PROGRAM
 INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_FP_UNAVAIL
arch/powerpc/kvm/book3s_segment.S +8 -2
index 7c52ed0..d842795 100644
@@ -155,9 +155,15 @@ kvmppc_handler_trampoline_exit:
 	PPC_LL	r2, (SHADOW_VCPU_OFF + SVCPU_HOST_R2)(r13)
 
 	/* Save guest PC and MSR */
-	mfsrr0	r3
+	andi.	r0,r12,0x2
+	beq	1f
+	mfspr	r3,SPRN_HSRR0
+	mfspr	r4,SPRN_HSRR1
+	andi.	r12,r12,0x3ffd
+	b	2f
+1:	mfsrr0	r3
 	mfsrr1	r4
-
+2:
 	PPC_STL	r3, (SHADOW_VCPU_OFF + SVCPU_PC)(r13)
 	PPC_STL	r4, (SHADOW_VCPU_OFF + SVCPU_SHADOW_SRR1)(r13)
 
arch/powerpc/platforms/iseries/exception.S +1 -1
index 32a56c6..f7a4872 100644
@@ -155,7 +155,7 @@ BEGIN_FTR_SECTION
 	std	r12,PACA_EXGEN+EX_R13(r13)
 	EXCEPTION_PROLOG_ISERIES_1
 FTR_SECTION_ELSE
-	EXCEPTION_PROLOG_1(PACA_EXGEN)
+	EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_STD)
 	EXCEPTION_PROLOG_ISERIES_1
 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB)
 	b	data_access_common
arch/powerpc/platforms/iseries/exception.h +2 -2
index bae3fba..57127d8 100644
@@ -39,7 +39,7 @@
 label##_iSeries:							\
 	HMT_MEDIUM;							\
 	mtspr	SPRN_SPRG_SCRATCH0,r13;	/* save r13 */			\
-	EXCEPTION_PROLOG_1(area);					\
+	EXCEPTION_PROLOG_1(area, EXC_STD);				\
 	EXCEPTION_PROLOG_ISERIES_1;					\
 	b	label##_common
 
@@ -48,7 +48,7 @@ label##_iSeries:							\
 label##_iSeries:							\
 	HMT_MEDIUM;							\
 	mtspr	SPRN_SPRG_SCRATCH0,r13;	/* save r13 */			\
-	EXCEPTION_PROLOG_1(PACA_EXGEN);					\
+	EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_STD);			\
 	lbz	r10,PACASOFTIRQEN(r13);					\
 	cmpwi	0,r10,0;						\
 	beq-	label##_iSeries_masked;					\
Signature · 1 line
1.7.1
#12 lore raw

PATCH 7/15 powerpc: More work to support HV exceptions

In reply to Benjamin Herrenschmidt

Rework exception macros a bit to split offset from vector and add some basic support for HDEC, HDSI, HISI and a few more.

---
 arch/powerpc/include/asm/exception-64s.h  |   37 ++++++++----
 arch/powerpc/include/asm/feature-fixups.h |    2 +-
 arch/powerpc/kernel/exceptions-64s.S      |   92 ++++++++++++++++++++---------
 3 files changed, 89 insertions(+), 42 deletions(-)
arch/powerpc/include/asm/exception-64s.h +24 -13
index 1d98e05..fb5b0af 100644
@@ -150,28 +150,27 @@
 /*
  * Exception vectors.
  */
-#define STD_EXCEPTION_PSERIES(n, label)			\
-	. = n;						\
+#define STD_EXCEPTION_PSERIES(loc, vec, label)		\
+	. = loc;					\
 	.globl label##_pSeries;				\
 label##_pSeries:					\
 	HMT_MEDIUM;					\
-	DO_KVM	n;					\
+	DO_KVM	vec;					\
 	mtspr	SPRN_SPRG_SCRATCH0,r13;		/* save r13 */	\
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_STD)
 
-#define HSTD_EXCEPTION_PSERIES(n, label)		\
-	. = n;						\
-	.globl label##_pSeries;				\
-label##_pSeries:					\
+#define STD_EXCEPTION_HV(loc, vec, label)		\
+	. = loc;					\
+	.globl label##_hv;				\
+label##_hv:						\
 	HMT_MEDIUM;					\
-	DO_KVM	n;					\
+	DO_KVM	vec;					\
 	mtspr	SPRN_SPRG_HSCRATCH0,r13;/* save r13 */	\
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_HV)
 
-
-#define __MASKABLE_EXCEPTION_PSERIES(n, label, h)			\
+#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h)			\
 	HMT_MEDIUM;							\
-	DO_KVM	n;							\
+	DO_KVM	vec;							\
 	mtspr	SPRN_SPRG_##h##SCRATCH0,r13;    /* save r13 */		\
 	GET_PACA(r13);							\
 	std	r9,PACA_EXGEN+EX_R9(r13);	/* save r9, r10 */	\
@@ -193,8 +192,20 @@ label##_pSeries:					\
 	mtspr	SPRN_##h##SRR1,r10;					\
 	h##rfid;							\
 	b	.	/* prevent speculative execution */
-#define MASKABLE_EXCEPTION_PSERIES(n, label, h)				\
-	__MASKABLE_EXCEPTION_PSERIES(n, label, h)
+#define _MASKABLE_EXCEPTION_PSERIES(vec, label, h)			\
+	__MASKABLE_EXCEPTION_PSERIES(vec, label, h)
+
+#define MASKABLE_EXCEPTION_PSERIES(loc, vec, label)			\
+	. = loc;							\
+	.globl label##_pSeries;						\
+label##_pSeries:							\
+	_MASKABLE_EXCEPTION_PSERIES(vec, label, EXC_STD)
+
+#define MASKABLE_EXCEPTION_HV(loc, vec, label)				\
+	. = loc;							\
+	.globl label##_hv;						\
+label##_hv:								\
+	_MASKABLE_EXCEPTION_PSERIES(vec, label, EXC_HV)
 
 #ifdef CONFIG_PPC_ISERIES
 #define DISABLE_INTS				\
arch/powerpc/include/asm/feature-fixups.h +1 -1
index 921a847..bdc0d68 100644
@@ -49,7 +49,7 @@ label##5:							\
 	FTR_ENTRY_OFFSET label##2b-label##5b;			\
 	FTR_ENTRY_OFFSET label##3b-label##5b;			\
 	FTR_ENTRY_OFFSET label##4b-label##5b;			\
-	.ifgt (label##4b-label##3b)-(label##2b-label##1b);	\
+	.ifgt (label##4b- label##3b)-(label##2b- label##1b);	\
 	.error "Feature section else case larger than body";	\
 	.endif;							\
 	.popsection;
arch/powerpc/kernel/exceptions-64s.S +64 -28

169 lines not on this page · raw message

Signature · 1 line
1.7.1
#13 lore raw

PATCH 8/15 powerpc: Always use SPRN_SPRG_HSCRATCH0 when running in HV mode

In reply to Benjamin Herrenschmidt

From: Paul Mackerras <[email protected]>

This uses feature sections to arrange that we always use HSPRG1 as the scratch register in the interrupt entry code rather than SPRG2 when we're running in hypervisor mode on POWER7. This will ensure that we don't trash the guest's SPRG2 when we are running KVM guests. To simplify the code, we define GET_SCRATCH0() and SET_SCRATCH0() macros like the GET_PACA/SET_PACA macros.

---
 arch/powerpc/include/asm/exception-64s.h   |   15 +++++++--------
 arch/powerpc/include/asm/reg.h             |   14 ++++++++++++++
 arch/powerpc/kernel/exceptions-64s.S       |   26 +++++++++++++-------------
 arch/powerpc/kvm/book3s_rmhandlers.S       |    6 +++---
 arch/powerpc/kvm/book3s_segment.S          |    2 +-
 arch/powerpc/platforms/iseries/exception.S |    2 +-
 arch/powerpc/platforms/iseries/exception.h |    4 ++--
 7 files changed, 41 insertions(+), 28 deletions(-)
arch/powerpc/include/asm/exception-64s.h +7 -8
index fb5b0af..d6b4849 100644
@@ -60,16 +60,15 @@
 #define EXC_HV	H
 #define EXC_STD
 
-#define __EXCEPTION_PROLOG_1(area, h)					\
+#define EXCEPTION_PROLOG_1(area)					\
 	GET_PACA(r13);							\
 	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
 	std	r10,area+EX_R10(r13);					\
 	std	r11,area+EX_R11(r13);					\
 	std	r12,area+EX_R12(r13);					\
-	mfspr	r9,SPRN_SPRG_##h##SCRATCH0;				\
+	GET_SCRATCH0(r9);						\
 	std	r9,area+EX_R13(r13);					\
 	mfcr	r9
-#define EXCEPTION_PROLOG_1(area, h) __EXCEPTION_PROLOG_1(area, h)
 
 #define __EXCEPTION_PROLOG_PSERIES_1(label, h)				\
 	ld	r12,PACAKBASE(r13);	/* get high part of &label */	\
@@ -85,7 +84,7 @@
 	__EXCEPTION_PROLOG_PSERIES_1(label, h)
 
 #define EXCEPTION_PROLOG_PSERIES(area, label, h)			\
-	EXCEPTION_PROLOG_1(area, h);					\
+	EXCEPTION_PROLOG_1(area);					\
 	EXCEPTION_PROLOG_PSERIES_1(label, h);
 
 /*
@@ -156,7 +155,7 @@
 label##_pSeries:					\
 	HMT_MEDIUM;					\
 	DO_KVM	vec;					\
-	mtspr	SPRN_SPRG_SCRATCH0,r13;		/* save r13 */	\
+	SET_SCRATCH0(r13);		/* save r13 */		\
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_STD)
 
 #define STD_EXCEPTION_HV(loc, vec, label)		\
@@ -165,13 +164,13 @@ label##_pSeries:					\
 label##_hv:						\
 	HMT_MEDIUM;					\
 	DO_KVM	vec;					\
-	mtspr	SPRN_SPRG_HSCRATCH0,r13;/* save r13 */	\
+	SET_SCRATCH0(r13);	/* save r13 */		\
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_HV)
 
 #define __MASKABLE_EXCEPTION_PSERIES(vec, label, h)			\
 	HMT_MEDIUM;							\
 	DO_KVM	vec;							\
-	mtspr	SPRN_SPRG_##h##SCRATCH0,r13;    /* save r13 */		\
+	SET_SCRATCH0(r13);    /* save r13 */				\
 	GET_PACA(r13);							\
 	std	r9,PACA_EXGEN+EX_R9(r13);	/* save r9, r10 */	\
 	std	r10,PACA_EXGEN+EX_R10(r13);				\
@@ -179,7 +178,7 @@ label##_hv:						\
 	mfcr	r9;							\
 	cmpwi	r10,0;							\
 	beq	masked_##h##interrupt;					\
-	mfspr	r10,SPRN_SPRG_##h##SCRATCH0;				\
+	GET_SCRATCH0(r10);						\
 	std	r10,PACA_EXGEN+EX_R13(r13);				\
 	std	r11,PACA_EXGEN+EX_R11(r13);				\
 	std	r12,PACA_EXGEN+EX_R12(r13);				\
arch/powerpc/include/asm/reg.h +14 -0
index 13429a0..76d7d5f 100644
@@ -802,6 +802,20 @@
 	FTR_SECTION_ELSE_NESTED(66);			\
 	mtspr	SPRN_SPRG_HPACA,rX;			\
 	ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
+
+#define GET_SCRATCH0(rX)				\
+	BEGIN_FTR_SECTION_NESTED(66);			\
+	mfspr	rX,SPRN_SPRG_SCRATCH0;			\
+	FTR_SECTION_ELSE_NESTED(66);			\
+	mfspr	rX,SPRN_SPRG_HSCRATCH0;			\
+	ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
+
+#define SET_SCRATCH0(rX)				\
+	BEGIN_FTR_SECTION_NESTED(66);			\
+	mtspr	SPRN_SPRG_SCRATCH0,rX;			\
+	FTR_SECTION_ELSE_NESTED(66);			\
+	mtspr	SPRN_SPRG_HSCRATCH0,rX;			\
+	ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
 #endif
 
 #ifdef CONFIG_PPC_BOOK3E_64
arch/powerpc/kernel/exceptions-64s.S +13 -13
index 54429ee..0c50a52 100644
@@ -43,7 +43,7 @@ __start_interrupts:
 _machine_check_pSeries:
 	HMT_MEDIUM
 	DO_KVM	0x200
-	mtspr	SPRN_SPRG_SCRATCH0,r13		/* save r13 */
+	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, EXC_STD)
 
 	. = 0x300
@@ -51,7 +51,7 @@ _machine_check_pSeries:
 data_access_pSeries:
 	HMT_MEDIUM
 	DO_KVM	0x300
-	mtspr	SPRN_SPRG_SCRATCH0,r13
+	SET_SCRATCH0(r13)
 BEGIN_FTR_SECTION
 	GET_PACA(r13)
 	std	r9,PACA_EXSLB+EX_R9(r13)
@@ -67,7 +67,7 @@ BEGIN_FTR_SECTION
 	std	r11,PACA_EXGEN+EX_R11(r13)
 	ld	r11,PACA_EXSLB+EX_R9(r13)
 	std	r12,PACA_EXGEN+EX_R12(r13)
-	mfspr	r12,SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r12)
 	std	r10,PACA_EXGEN+EX_R10(r13)
 	std	r11,PACA_EXGEN+EX_R9(r13)
 	std	r12,PACA_EXGEN+EX_R13(r13)
@@ -81,7 +81,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB)
 data_access_slb_pSeries:
 	HMT_MEDIUM
 	DO_KVM	0x380
-	mtspr	SPRN_SPRG_SCRATCH0,r13
+	SET_SCRATCH0(r13)
 	GET_PACA(r13)
 	std	r3,PACA_EXSLB+EX_R3(r13)
 	mfspr	r3,SPRN_DAR
@@ -95,7 +95,7 @@ data_access_slb_pSeries:
 	std	r10,PACA_EXSLB+EX_R10(r13)
 	std	r11,PACA_EXSLB+EX_R11(r13)
 	std	r12,PACA_EXSLB+EX_R12(r13)
-	mfspr	r10,SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r10)
 	std	r10,PACA_EXSLB+EX_R13(r13)
 	mfspr	r12,SPRN_SRR1		/* and SRR1 */
 #ifndef CONFIG_RELOCATABLE
@@ -120,7 +120,7 @@ data_access_slb_pSeries:
 instruction_access_slb_pSeries:
 	HMT_MEDIUM
 	DO_KVM	0x480
-	mtspr	SPRN_SPRG_SCRATCH0,r13
+	SET_SCRATCH0(r13)
 	GET_PACA(r13)
 	std	r3,PACA_EXSLB+EX_R3(r13)
 	mfspr	r3,SPRN_SRR0		/* SRR0 is faulting address */
@@ -134,7 +134,7 @@ instruction_access_slb_pSeries:
 	std	r10,PACA_EXSLB+EX_R10(r13)
 	std	r11,PACA_EXSLB+EX_R11(r13)
 	std	r12,PACA_EXSLB+EX_R12(r13)
-	mfspr	r10,SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r10)
 	std	r10,PACA_EXSLB+EX_R13(r13)
 	mfspr	r12,SPRN_SRR1		/* and SRR1 */
 #ifndef CONFIG_RELOCATABLE
@@ -272,7 +272,7 @@ masked_interrupt:
 	rotldi	r10,r10,16
 	mtspr	SPRN_SRR1,r10
 	ld	r10,PACA_EXGEN+EX_R10(r13)
-	mfspr	r13,SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r13)
 	rfid
 	b	.
 
@@ -285,7 +285,7 @@ masked_Hinterrupt:
 	rotldi	r10,r10,16
 	mtspr	SPRN_HSRR1,r10
 	ld	r10,PACA_EXGEN+EX_R10(r13)
-	mfspr	r13,SPRN_SPRG_HSCRATCH0
+	GET_SCRATCH0(r13)
 	hrfid
 	b	.
 
@@ -293,7 +293,7 @@ masked_Hinterrupt:
 do_stab_bolted_pSeries:
 	std	r11,PACA_EXSLB+EX_R11(r13)
 	std	r12,PACA_EXSLB+EX_R12(r13)
-	mfspr	r10,SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r10)
 	std	r10,PACA_EXSLB+EX_R13(r13)
 	EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted, EXC_STD)
 
@@ -305,14 +305,14 @@ do_stab_bolted_pSeries:
       .align 7
 system_reset_fwnmi:
 	HMT_MEDIUM
-	mtspr	SPRN_SPRG_SCRATCH0,r13		/* save r13 */
+	SET_SCRATCH0(r13)		/* save r13 */
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD)
 
 	.globl machine_check_fwnmi
       .align 7
 machine_check_fwnmi:
 	HMT_MEDIUM
-	mtspr	SPRN_SPRG_SCRATCH0,r13		/* save r13 */
+	SET_SCRATCH0(r13)		/* save r13 */
 	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, EXC_STD)
 
 #endif /* CONFIG_PPC_PSERIES */
@@ -327,7 +327,7 @@ slb_miss_user_pseries:
 	std	r10,PACA_EXGEN+EX_R10(r13)
 	std	r11,PACA_EXGEN+EX_R11(r13)
 	std	r12,PACA_EXGEN+EX_R12(r13)
-	mfspr	r10,SPRG_SCRATCH0
+	GET_SCRATCH0(r10)
 	ld	r11,PACA_EXSLB+EX_R9(r13)
 	ld	r12,PACA_EXSLB+EX_R3(r13)
 	std	r10,PACA_EXGEN+EX_R13(r13)
arch/powerpc/kvm/book3s_rmhandlers.S +3 -3
index 046e1f3..ae99af6 100644
@@ -70,7 +70,7 @@
 .global kvmppc_trampoline_\intno
 kvmppc_trampoline_\intno:
 
-	mtspr	SPRN_SPRG_SCRATCH0, r13		/* Save r13 */
+	SET_SCRATCH0(r13)		/* Save r13 */
 
 	/*
 	 * First thing to do is to find out if we're coming
@@ -89,7 +89,7 @@ kvmppc_trampoline_\intno:
 	lwz	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13)
 	mtcr	r12
 	PPC_LL	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13)
-	mfspr	r13, SPRN_SPRG_SCRATCH0		/* r13 = original r13 */
+	GET_SCRATCH0(r13)			/* r13 = original r13 */
 	b	kvmppc_resume_\intno		/* Get back original handler */
 
 	/* Now we know we're handling a KVM guest */
@@ -157,7 +157,7 @@ kvmppc_handler_skip_ins:
 	lwz	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13)
 	mtcr	r12
 	PPC_LL	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13)
-	mfspr	r13, SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r13)
 
 	/* And get back into the code */
 	RFI
arch/powerpc/kvm/book3s_segment.S +1 -1
index d842795..4512642 100644
@@ -168,7 +168,7 @@ kvmppc_handler_trampoline_exit:
 	PPC_STL	r4, (SHADOW_VCPU_OFF + SVCPU_SHADOW_SRR1)(r13)
 
 	/* Get scratch'ed off registers */
-	mfspr	r9, SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r9)
 	PPC_LL	r8, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13)
 	lwz	r7, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13)
 
arch/powerpc/platforms/iseries/exception.S +1 -1
index f7a4872..32a56c6 100644
@@ -155,7 +155,7 @@ BEGIN_FTR_SECTION
 	std	r12,PACA_EXGEN+EX_R13(r13)
 	EXCEPTION_PROLOG_ISERIES_1
 FTR_SECTION_ELSE
-	EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_STD)
+	EXCEPTION_PROLOG_1(PACA_EXGEN)
 	EXCEPTION_PROLOG_ISERIES_1
 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB)
 	b	data_access_common
arch/powerpc/platforms/iseries/exception.h +2 -2
index 57127d8..bae3fba 100644
@@ -39,7 +39,7 @@
 label##_iSeries:							\
 	HMT_MEDIUM;							\
 	mtspr	SPRN_SPRG_SCRATCH0,r13;	/* save r13 */			\
-	EXCEPTION_PROLOG_1(area, EXC_STD);				\
+	EXCEPTION_PROLOG_1(area);					\
 	EXCEPTION_PROLOG_ISERIES_1;					\
 	b	label##_common
 
@@ -48,7 +48,7 @@ label##_iSeries:							\
 label##_iSeries:							\
 	HMT_MEDIUM;							\
 	mtspr	SPRN_SPRG_SCRATCH0,r13;	/* save r13 */			\
-	EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_STD);			\
+	EXCEPTION_PROLOG_1(PACA_EXGEN);					\
 	lbz	r10,PACASOFTIRQEN(r13);					\
 	cmpwi	0,r10,0;						\
 	beq-	label##_iSeries_masked;					\
Signature · 1 line
1.7.1
#14 lore raw

PATCH 9/15 powerpc: Initialize LPCR:DPFD on power7 to a sane default

In reply to Benjamin Herrenschmidt

This sets the default data stream prefetch size for operating systems that don't set their own value in DSCR. We use 4 which is "medium".

---
 arch/powerpc/kernel/cpu_setup_power7.S |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
arch/powerpc/kernel/cpu_setup_power7.S +7 -0
index e801ef1..2390f6f 100644
@@ -54,6 +54,7 @@ __init_LPCR:
 	 *
 	 *   LPES = 0b01 (HSRR0/1 used for 0x500)
 	 *   PECE = 0b111
+	 *   DPFD = 4
 	 *
 	 * Other bits untouched for now
 	 */
@@ -61,6 +62,12 @@ __init_LPCR:
 	ori	r3,r3,(LPCR_LPES0|LPCR_LPES1)
 	xori	r3,r3, LPCR_LPES0
 	ori	r3,r3,(LPCR_PECE0|LPCR_PECE1|LPCR_PECE2)
+	li	r5,7
+	sldi	r5,r5,LPCR_DPFD_SH
+	andc	r3,r3,r5
+	li	r5,4
+	sldi	r5,r5,LPCR_DPFD_SH
+	or	r3,r3,r5
 	mtspr	SPRN_LPCR,r3
 	isync
 	blr
Signature · 1 line
1.7.1
#15 lore raw

PATCH 10/15 powerpc: Initialize TLB and LPID register on HV mode Power7

In reply to Benjamin Herrenschmidt

In case entry from the bootloader isn't "clean"

---
 arch/powerpc/kernel/cpu_setup_power7.S |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)
arch/powerpc/kernel/cpu_setup_power7.S +18 -0
index 2390f6f..4f9a93f 100644
@@ -25,7 +25,10 @@ _GLOBAL(__setup_cpu_power7)
 	bl	__init_hvmode_206
 	mtlr	r11
 	beqlr
+	li	r0,0
+	mtspr	SPRN_LPID,r0
 	bl	__init_LPCR
+	bl	__init_TLB
 	mtlr	r11
 	blr
 
@@ -34,7 +37,10 @@ _GLOBAL(__restore_cpu_power7)
 	mfmsr	r3
 	rldicl.	r0,r3,4,63
 	beqlr
+	li	r0,0
+	mtspr	SPRN_LPID,r0
 	bl	__init_LPCR
+	bl	__init_TLB
 	mtlr	r11
 	blr
 
@@ -71,3 +77,15 @@ __init_LPCR:
 	mtspr	SPRN_LPCR,r3
 	isync
 	blr
+
+__init_TLB:
+	/* Clear the TLB */
+	li	r6,128
+	mtctr	r6
+	li	r7,0xc00	/* IS field = 0b11 */
+	ptesync
+2:	tlbiel	r7
+	addi	r7,r7,0x1000
+	bdnz	2b
+	ptesync
+1:	blr
Signature · 1 line
1.7.1
#16 lore raw

PATCH 11/15 powerpc: Call CPU ->restore callback earlier on secondary CPUs

In reply to Benjamin Herrenschmidt

We do it before we loop on the PACA start flag. This way, we get a chance to set critical SPRs on all CPUs before Linux tries to start them up, which avoids problems when changing some bits such as LPCR bits that need to be identical on all threads of a core or similar things like that. Ideally, some of that should also be done before the MMU is enabled, but that's a separate issue which would require moving some of the SMP startup code earlier, let's not get there for now, it works with that change alone.

---
 arch/powerpc/kernel/head_64.S |   22 +++++++++++-----------
 1 files changed, 11 insertions(+), 11 deletions(-)
arch/powerpc/kernel/head_64.S +11 -11
index 53d3bfd..43a3cff 100644
@@ -236,17 +236,6 @@ generic_secondary_common_init:
 
 	/* From now on, r24 is expected to be logical cpuid */
 	mr	r24,r5
-3:	HMT_LOW
-	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor should */
-					/* start.			 */
-
-#ifndef CONFIG_SMP
-	b	3b			/* Never go on non-SMP		 */
-#else
-	cmpwi	0,r23,0
-	beq	3b			/* Loop until told to go	 */
-
-	sync				/* order paca.run and cur_cpu_spec */
 
 	/* See if we need to call a cpu state restore handler */
 	LOAD_REG_ADDR(r23, cur_cpu_spec)
@@ -258,6 +247,17 @@ generic_secondary_common_init:
 	mtctr	r23
 	bctrl
 
+3:	HMT_LOW
+	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor should */
+					/* start.			 */
+#ifndef CONFIG_SMP
+	b	3b			/* Never go on non-SMP		 */
+#else
+	cmpwi	0,r23,0
+	beq	3b			/* Loop until told to go	 */
+
+	sync				/* order paca.run and cur_cpu_spec */
+
 4:	/* Create a temp kernel stack for use before relocation is on.	*/
 	ld	r1,PACAEMERGSP(r13)
 	subi	r1,r1,STACK_FRAME_OVERHEAD
Signature · 1 line
1.7.1
#17 lore raw

PATCH 12/15 powerpc: Properly handshake CPUs going out of boot spin loop

In reply to Benjamin Herrenschmidt

We need to wait a bit for them to have done their CPU setup or we might end up with translation and EE on with different LPCR values between threads

---
 arch/powerpc/include/asm/smp.h |    1 +
 arch/powerpc/kernel/head_64.S  |   18 +++++++++++++-----
 arch/powerpc/kernel/prom.c     |   27 ++++++++++-----------------
 arch/powerpc/kernel/setup_32.c |    1 +
 arch/powerpc/kernel/setup_64.c |   13 ++++++++++++-
 5 files changed, 37 insertions(+), 23 deletions(-)
arch/powerpc/include/asm/smp.h +1 -0
index a902a0d..bb4c033 100644
@@ -29,6 +29,7 @@
 #include <asm/percpu.h>
 
 extern int boot_cpuid;
+extern int boot_cpu_count;
 
 extern void cpu_die(void);
 
arch/powerpc/kernel/head_64.S +13 -5
index 43a3cff..370afd4 100644
@@ -242,23 +242,31 @@ generic_secondary_common_init:
 	ld	r23,0(r23)
 	ld	r23,CPU_SPEC_RESTORE(r23)
 	cmpdi	0,r23,0
-	beq	4f
+	beq	3f
 	ld	r23,0(r23)
 	mtctr	r23
 	bctrl
 
-3:	HMT_LOW
+3:	LOAD_REG_ADDR(r3, boot_cpu_count) /* Decrement boot_cpu_count */
+	lwarx	r4,0,r3
+	subi	r4,r4,1
+	stwcx.	r4,0,r3
+	bne	3b
+	isync
+
+4:	HMT_LOW
 	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor should */
 					/* start.			 */
 #ifndef CONFIG_SMP
-	b	3b			/* Never go on non-SMP		 */
+	b	4b			/* Never go on non-SMP		 */
 #else
 	cmpwi	0,r23,0
-	beq	3b			/* Loop until told to go	 */
+	beq	4b			/* Loop until told to go	 */
 
 	sync				/* order paca.run and cur_cpu_spec */
+	isync				/* In case code patching happened */
 
-4:	/* Create a temp kernel stack for use before relocation is on.	*/
+	/* Create a temp kernel stack for use before relocation is on.	*/
 	ld	r1,PACAEMERGSP(r13)
 	subi	r1,r1,STACK_FRAME_OVERHEAD
 
arch/powerpc/kernel/prom.c +10 -17
index 05b7139..236246f 100644
@@ -268,13 +268,12 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
 					  const char *uname, int depth,
 					  void *data)
 {
-	static int logical_cpuid = 0;
 	char *type = of_get_flat_dt_prop(node, "device_type", NULL);
 	const u32 *prop;
 	const u32 *intserv;
 	int i, nthreads;
 	unsigned long len;
-	int found = 0;
+	int found = -1;
 
 	/* We are scanning "cpu" nodes only */
 	if (type == NULL || strcmp(type, "cpu") != 0)
@@ -299,11 +298,8 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
 		 * booted proc.
 		 */
 		if (initial_boot_params && initial_boot_params->version >= 2) {
-			if (intserv[i] ==
-					initial_boot_params->boot_cpuid_phys) {
-				found = 1;
-				break;
-			}
+			if (intserv[i] == initial_boot_params->boot_cpuid_phys)
+				found = boot_cpu_count;
 		} else {
 			/*
 			 * Check if it's the boot-cpu, set it's hw index now,
@@ -311,23 +307,20 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
 			 * off secondary threads.
 			 */
 			if (of_get_flat_dt_prop(node,
-					"linux,boot-cpu", NULL) != NULL) {
-				found = 1;
-				break;
-			}
+					"linux,boot-cpu", NULL) != NULL)
+				found = boot_cpu_count;
 		}
-
 #ifdef CONFIG_SMP
 		/* logical cpu id is always 0 on UP kernels */
-		logical_cpuid++;
+		boot_cpu_count++;
 #endif
 	}
 
-	if (found) {
-		DBG("boot cpu: logical %d physical %d\n", logical_cpuid,
+	if (found >= 0) {
+		DBG("boot cpu: logical %d physical %d\n", found,
 			intserv[i]);
-		boot_cpuid = logical_cpuid;
-		set_hard_smp_processor_id(boot_cpuid, intserv[i]);
+		boot_cpuid = found;
+		set_hard_smp_processor_id(found, intserv[i]);
 
 		/*
 		 * PAPR defines "logical" PVR values for cpus that
arch/powerpc/kernel/setup_32.c +1 -0
index 1d2fbc9..620d792 100644
@@ -48,6 +48,7 @@ extern void bootx_init(unsigned long r4, unsigned long phys);
 
 int boot_cpuid = -1;
 EXPORT_SYMBOL_GPL(boot_cpuid);
+int __initdata boot_cpu_count;
 int boot_cpuid_phys;
 
 int smp_hw_index[NR_CPUS];
arch/powerpc/kernel/setup_64.c +12 -1
index 5a0401f..91a5cc5 100644
@@ -72,6 +72,7 @@
 #endif
 
 int boot_cpuid = 0;
+int __initdata boot_cpu_count;
 u64 ppc64_pft_size;
 
 /* Pick defaults since we might want to patch instructions
@@ -233,6 +234,7 @@ void early_setup_secondary(void)
 void smp_release_cpus(void)
 {
 	unsigned long *ptr;
+	int i;
 
 	DBG(" -> smp_release_cpus()\n");
 
@@ -245,7 +247,16 @@ void smp_release_cpus(void)
 	ptr  = (unsigned long *)((unsigned long)&__secondary_hold_spinloop
 			- PHYSICAL_START);
 	*ptr = __pa(generic_secondary_smp_init);
-	mb();
+
+	/* And wait a bit for them to catch up */
+	for (i = 0; i < 100000; i++) {
+		mb();
+		HMT_low();
+		if (boot_cpu_count == 0)
+			break;
+		udelay(1);
+	}
+	DBG("boot_cpu_count = %d\n", boot_cpu_count);
 
 	DBG(" <- smp_release_cpus()\n");
 }
Signature · 1 line
1.7.1
#18 lore raw

PATCH 13/15 powerpc: Add NAP mode support on Power7 in HV mode

In reply to Benjamin Herrenschmidt

Wakeup comes from the system reset handler with a potential loss of the non-hypervisor CPU state. We save the non-volatile state on the stack and a pointer to it in the PACA, which the system reset handler uses to restore things

---
 arch/powerpc/include/asm/machdep.h    |    1 +
 arch/powerpc/include/asm/paca.h       |    2 +-
 arch/powerpc/include/asm/ppc-opcode.h |    6 ++
 arch/powerpc/kernel/Makefile          |    1 +
 arch/powerpc/kernel/exceptions-64s.S  |   30 ++++++++++-
 arch/powerpc/kernel/idle_power7.S     |   97 +++++++++++++++++++++++++++++++++
 arch/powerpc/platforms/Kconfig        |    4 ++
 7 files changed, 139 insertions(+), 2 deletions(-)
 create mode 100644 arch/powerpc/kernel/idle_power7.S
arch/powerpc/include/asm/machdep.h +1 -0
index e4f0191..493dbb3 100644
@@ -267,6 +267,7 @@ struct machdep_calls {
 
 extern void e500_idle(void);
 extern void power4_idle(void);
+extern void power7_idle(void);
 extern void ppc6xx_idle(void);
 extern void book3e_idle(void);
 
arch/powerpc/include/asm/paca.h +1 -1
index ec57540..f6da4f5 100644
@@ -125,7 +125,7 @@ struct paca_struct {
 	struct task_struct *__current;	/* Pointer to current */
 	u64 kstack;			/* Saved Kernel stack addr */
 	u64 stab_rr;			/* stab/slb round-robin counter */
-	u64 saved_r1;			/* r1 save for RTAS calls */
+	u64 saved_r1;			/* r1 save for RTAS calls or PM */
 	u64 saved_msr;			/* MSR saved here by enter_rtas */
 	u16 trap_save;			/* Used when bad stack is encountered */
 	u8 soft_enabled;		/* irq soft-enable flag */
arch/powerpc/include/asm/ppc-opcode.h +6 -0
index 1255569..384a96d 100644
@@ -56,6 +56,9 @@
 #define PPC_INST_TLBSRX_DOT		0x7c0006a5
 #define PPC_INST_XXLOR			0xf0000510
 
+#define PPC_INST_NAP			0x4c000364
+#define PPC_INST_SLEEP			0x4c0003a4
+
 /* macros to insert fields into opcodes */
 #define __PPC_RA(a)	(((a) & 0x1f) << 16)
 #define __PPC_RB(b)	(((b) & 0x1f) << 11)
@@ -126,4 +129,7 @@
 #define XXLOR(t, a, b)		stringify_in_c(.long PPC_INST_XXLOR | \
 					       VSX_XX3((t), (a), (b)))
 
+#define PPC_NAP			stringify_in_c(.long PPC_INST_NAP)
+#define PPC_SLEEP		stringify_in_c(.long PPC_INST_SLEEP)
+
 #endif /* _ASM_POWERPC_PPC_OPCODE_H */
arch/powerpc/kernel/Makefile +1 -0
index 7c6eb49..0fd6273 100644
@@ -44,6 +44,7 @@ obj-$(CONFIG_PPC_BOOK3E_64)	+= exceptions-64e.o idle_book3e.o
 obj-$(CONFIG_PPC64)		+= vdso64/
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o
 obj-$(CONFIG_PPC_970_NAP)	+= idle_power4.o
+obj-$(CONFIG_PPC_P7_NAP)	+= idle_power7.o
 obj-$(CONFIG_PPC_OF)		+= of_platform.o prom_parse.o
 obj-$(CONFIG_PPC_CLOCK)		+= clock.o
 procfs-y			:= proc_powerpc.o
arch/powerpc/kernel/exceptions-64s.S +29 -1
index 0c50a52..a6ead27 100644
@@ -37,7 +37,35 @@
 	.globl __start_interrupts
 __start_interrupts:
 
-	STD_EXCEPTION_PSERIES(0x100, 0x100, system_reset)
+	.globl system_reset_pSeries;
+system_reset_pSeries:
+	HMT_MEDIUM;
+	DO_KVM	0x100;
+	SET_SCRATCH0(r13)
+#ifdef CONFIG_PPC_P7_NAP
+BEGIN_FTR_SECTION
+	/* Running native on arch 2.06 or later, check if we are
+	 * waking up from nap. We only handle no state loss and
+	 * supervisor state loss. We do -not- handle hypervisor
+	 * state loss at this time.
+	 */
+	mfspr	r13,SPRN_SRR1
+	rlwinm	r13,r13,47-31,30,31
+	cmpwi	cr0,r13,1
+	bne	1f
+	b	.power7_wakeup_noloss
+1:	cmpwi	cr0,r13,2
+	bne	1f
+	b	.power7_wakeup_loss
+	/* Total loss of HV state is fatal, we could try to use the
+	 * PIR to locate a PACA, then use an emergency stack etc...
+	 * but for now, let's just stay stuck here
+	 */
+1:	cmpwi	cr0,r13,3
+	beq	.
+END_FTR_SECTION_IFSET(CPU_FTR_HVMODE_206)
+#endif /* CONFIG_PPC_P7_NAP */
+	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD)
 
 	. = 0x200
 _machine_check_pSeries:
arch/powerpc/kernel/idle_power7.S new file +97 -0

97 lines not on this page · raw message

arch/powerpc/platforms/Kconfig +4 -0
index 2057682..59eeb77 100644
@@ -147,6 +147,10 @@ config PPC_970_NAP
 	bool
 	default n
 
+config PPC_P7_NAP
+	bool
+	default n
+
 config PPC_INDIRECT_IO
 	bool
 	select GENERIC_IOMAP
Signature · 1 line
1.7.1
#19 lore raw

PATCH 14/15 powerpc: Perform an isync to synchronize CPUs coming out of secondary_hold

In reply to Benjamin Herrenschmidt

We need to do that to guarantee they see any code change done by dynamic patching during boot.

---
 arch/powerpc/kernel/head_64.S |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
arch/powerpc/kernel/head_64.S +2 -0
index 370afd4..2505f78 100644
@@ -147,6 +147,8 @@ __secondary_hold:
 	mtctr	r4
 	mr	r3,r24
 	li	r4,0
+	/* Make sure that patched code is visible */
+	isync
 	bctr
 #else
 	BUG_OPCODE
Signature · 1 line
1.7.1
#20 lore raw

PATCH 15/15 powerpc: Improve prom_printf()

In reply to Benjamin Herrenschmidt

Adds the ability to print decimal numbers and adds some more format string variants

---
 arch/powerpc/kernel/prom_init.c |   26 +++++++++++++++++++++++++-
 1 files changed, 25 insertions(+), 1 deletions(-)
arch/powerpc/kernel/prom_init.c +25 -1
index 941ff4d..29c67e9 100644
@@ -335,6 +335,7 @@ static void __init prom_printf(const char *format, ...)
 	const char *p, *q, *s;
 	va_list args;
 	unsigned long v;
+	long vs;
 	struct prom_t *_prom = &RELOC(prom);
 
 	va_start(args, format);
@@ -368,12 +369,35 @@ static void __init prom_printf(const char *format, ...)
 			v = va_arg(args, unsigned long);
 			prom_print_hex(v);
 			break;
+		case 'd':
+			++q;
+			vs = va_arg(args, long);
+			if (vs < 0) {
+				prom_print("-");
+				vs = -vs;
+			}
+			prom_print_dec(vs);
+			break;
 		case 'l':
 			++q;
-			if (*q == 'u') { /* '%lu' */
+			if (*q == 0)
+				break;
+			else if (*q == 'x') {
+				++q;
+				v = va_arg(args, unsigned long);
+				prom_print_hex(v);
+			} else if (*q == 'u') { /* '%lu' */
 				++q;
 				v = va_arg(args, unsigned long);
 				prom_print_dec(v);
+			} else if (*q == 'd') { /* %ld */
+				++q;
+				vs = va_arg(args, long);
+				if (vs < 0) {
+					prom_print(RELOC("-"));
+					vs = -vs;
+				}
+				prom_print_dec(vs);
 			}
 			break;
 		}
Signature · 1 line
1.7.1
#21 lore raw

Re: [PATCH 15/15] powerpc: Improve prom_printf()

Hi Ben,

arch/powerpc/kernel/prom_init.c static void __init prom_printf(const char *format, ...) · line 374

Quoted 3 lines
arch/powerpc/kernel/prom_init.c +3 -0
+		case 'd':
+			++q;
+			vs = va_arg(args, long);

'd' takes an int, not a long.

arch/powerpc/kernel/prom_init.c static void __init prom_printf(const char *format, ...) · line 376

Quoted 2 lines
arch/powerpc/kernel/prom_init.c +2 -0
+			if (vs < 0) {
+				prom_print("-");

RELOC()?

Segher

#22 lore raw

Re: [PATCH 15/15] powerpc: Improve prom_printf()

Quoted 7 lines · Segher Boessenkool

Hi Ben,

arch/powerpc/kernel/prom_init.c static void __init prom_printf(const char *format, ...) · line 374

Quoted 3 lines
arch/powerpc/kernel/prom_init.c +3 -0
+		case 'd':
+			++q;
+			vs = va_arg(args, long);

'd' takes an int, not a long.

Oops :-) Indeed ... copy/lpaste bogon I think

Quoted 4 lines

arch/powerpc/kernel/prom_init.c static void __init prom_printf(const char *format, ...) · line 376

Quoted 2 lines
arch/powerpc/kernel/prom_init.c +2 -0
+			if (vs < 0) {
+				prom_print("-");

RELOC()?

Interesting, I had that bug and fixed it in the "ld" case and not the "d" case :-)

Thanks !

Cheers,
Ben.