Skip to contentSkip to conversation

powerpc: Add Initiate Coprocessor Store Word (icswx) support

PATCH In review Anton Blanchard 2 participants 3 messages Mar 25, 2011 – Mar 28, 2011 PowerPC

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 powerpc: Add Initiate Coprocessor Store Word (icswx) support

From: Tseng-Hui (Frank) Lin <[email protected]>

Icswx is a PowerPC instruction to send data to a co-processor. On Book-S processors the LPAR_ID and process ID (PID) of the owning process are registered in the window context of the co-processor at initialization time. When the icswx instruction is executed the L2 generates a cop-reg transaction on PowerBus. The transaction has no address and the processor does not perform an MMU access to authenticate the transaction. The co-processor compares the LPAR_ID and the PID included in the transaction and the LPAR_ID and PID held in the window context to determine if the process is authorized to generate the transaction.

The OS needs to assign a 16-bit PID for the process. This cop-PID needs to be updated during context switch. The cop-PID needs to be destroyed when the context is destroyed.

---

This is the v4 patch with a few changes:

- Remove the lazy option. If we see overhead in the context switch path we can add it back in once we have the basic patch working and merged.

- Remove comment and ifdef around spinlock forward declaration. We don't wrap forward declarations in ifdefs and they are common enough that we don't need to explain them individually.

- Check for CPU_FTR_ICSWX in drop_cop. Even though we shouldn't enter with mm == active_mm, we export the function and we should avoid doing writes to model specific SPRs in any circumstance.

- Convert WARN_ON -> WARN_ON_ONCE in drop_cop.

- Fix comments to be docbook compliant

- Update the Kconfig help text to read a bit better

arch/powerpc/include/asm/cputable.h +3 -1
Index: powerpc.git/arch/powerpc/include/asm/cputable.h
===================================================================
@@ -202,6 +202,7 @@ extern const char *powerpc_base_platform
 #define CPU_FTR_STCX_CHECKS_ADDRESS	LONG_ASM_CONST(0x0200000000000000)
 #define CPU_FTR_POPCNTB			LONG_ASM_CONST(0x0400000000000000)
 #define CPU_FTR_POPCNTD			LONG_ASM_CONST(0x0800000000000000)
+#define CPU_FTR_ICSWX			LONG_ASM_CONST(0x1000000000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -421,7 +422,8 @@ extern const char *powerpc_base_platform
 	    CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
 	    CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
 	    CPU_FTR_DSCR | CPU_FTR_SAO  | CPU_FTR_ASYM_SMT | \
-	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD)
+	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
+	    CPU_FTR_ICSWX)
 #define CPU_FTRS_CELL	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
arch/powerpc/include/asm/mmu-hash64.h +6 -0
Index: powerpc.git/arch/powerpc/include/asm/mmu-hash64.h
===================================================================
@@ -408,6 +408,7 @@ static inline void subpage_prot_init_new
 #endif /* CONFIG_PPC_SUBPAGE_PROT */
 
 typedef unsigned long mm_context_id_t;
+struct spinlock;
 
 typedef struct {
 	mm_context_id_t id;
@@ -423,6 +424,11 @@ typedef struct {
 #ifdef CONFIG_PPC_SUBPAGE_PROT
 	struct subpage_prot_table spt;
 #endif /* CONFIG_PPC_SUBPAGE_PROT */
+#ifdef CONFIG_ICSWX
+	struct spinlock *cop_lockp; /* guard acop and cop_pid */
+	unsigned long acop;	/* mask of enabled coprocessor types */
+	unsigned int cop_pid;	/* pid value used with coprocessors */
+#endif /* CONFIG_ICSWX */
 } mm_context_t;
 
 
arch/powerpc/include/asm/mmu_context.h +10 -0
Index: powerpc.git/arch/powerpc/include/asm/mmu_context.h
===================================================================
@@ -32,6 +32,10 @@ extern void __destroy_context(unsigned l
 extern void mmu_context_init(void);
 #endif
 
+extern void switch_cop(struct mm_struct *next);
+extern int use_cop(unsigned long acop, struct mm_struct *mm);
+extern void drop_cop(unsigned long acop, struct mm_struct *mm);
+
 /*
  * switch_mm is the entry point called from the architecture independent
  * code in kernel/sched.c
@@ -55,6 +59,12 @@ static inline void switch_mm(struct mm_s
 	if (prev == next)
 		return;
 
+#ifdef CONFIG_ICSWX
+	/* Switch coprocessor context only if prev or next uses a coprocessor */
+	if (prev->context.acop || next->context.acop)
+		switch_cop(next);
+#endif /* CONFIG_ICSWX */
+
 	/* We must stop all altivec streams before changing the HW
 	 * context
 	 */
arch/powerpc/include/asm/reg.h +1 -0
Index: powerpc.git/arch/powerpc/include/asm/reg.h
===================================================================
@@ -182,6 +182,7 @@
 
 #define SPRN_CTR	0x009	/* Count Register */
 #define SPRN_DSCR	0x11
+#define SPRN_ACOP	0x1F	/* Available Coprocessor Register */
 #define SPRN_CTRLF	0x088
 #define SPRN_CTRLT	0x098
 #define   CTRL_CT	0xc0000000	/* current thread */
arch/powerpc/mm/mmu_context_hash64.c +172 -0

193 lines not on this page · raw message

arch/powerpc/platforms/Kconfig.cputype +18 -0
Index: powerpc.git/arch/powerpc/platforms/Kconfig.cputype
===================================================================
@@ -226,6 +226,24 @@ config VSX
 
 	  If in doubt, say Y here.
 
+config ICSWX
+	bool "Support for PowerPC icswx coprocessor instruction"
+	depends on POWER4
+	default n
+	---help---
+
+	  This option enables kernel support for the PowerPC Initiate
+	  Coprocessor Store Word (icswx) coprocessor instruction on POWER7
+	  or newer processors.
+
+	  This option is only useful if you have a processor that supports
+	  the icswx coprocessor instruction. It does not have any effect
+	  on processors without the icswx coprocessor instruction.
+
+	  This option slightly increases kernel memory usage.
+
+	  If in doubt, say N here.
+
 config SPE
 	bool "SPE Support"
 	depends on E200 || (E500 && !PPC_E500MC)
#1 lore raw
Quoted 3 lines · Anton Blanchard

From: Tseng-Hui (Frank) Lin <[email protected]> =20
Icswx is a PowerPC instruction to send data to a co-processor. On =

Book-S

Quoted 3 lines

processors the LPAR_ID and process ID (PID) of the owning process are registered in the window context of the co-processor at initialization time. When the icswx instruction is executed the L2 generates a =

cop-reg

Quoted 2 lines

transaction on PowerBus. The transaction has no address and the processor does not perform an MMU access to authenticate the =

transaction.

Quoted 5 lines

The co-processor compares the LPAR_ID and the PID included in the transaction and the LPAR_ID and PID held in the window context to determine if the process is authorized to generate the transaction. =20
The OS needs to assign a 16-bit PID for the process. This cop-PID =

needs

Quoted 11 lines

to be updated during context switch. The cop-PID needs to be destroyed when the context is destroyed.
=20

---
=20
This is the v4 patch with a few changes:
=20
- Remove the lazy option. If we see overhead in the context switch =

path

Quoted 1 line

we can add it back in once we have the basic patch working and =

merged.

Quoted 2 lines

=20
- Remove comment and ifdef around spinlock forward declaration. We =

don't

Quoted 1 line

wrap forward declarations in ifdefs and they are common enough that =

we

Quoted 3 lines

don't need to explain them individually.
=20
- Check for CPU_FTR_ICSWX in drop_cop. Even though we shouldn't enter =

with

Quoted 1 line

mm =3D=3D active_mm, we export the function and we should avoid doing =

writes

Quoted 10 lines

to model specific SPRs in any circumstance.
=20
- Convert WARN_ON -> WARN_ON_ONCE in drop_cop.
=20
- Fix comments to be docbook compliant
=20
- Update the Kconfig help text to read a bit better
=20
Index: powerpc.git/arch/powerpc/include/asm/cputable.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

Quoted 1 line

--- powerpc.git.orig/arch/powerpc/include/asm/cputable.h =

2011-03-22 18:19:30.171445251 +1100
Quoted 1 line

+++ powerpc.git/arch/powerpc/include/asm/cputable.h 2011-03-26 =

08:15:44.284009603 +1100

Review extern const char *powerpc_base_platform · line 202

Quoted 2 lines
(quoted diff) +0 -0
@@ -202,6 +202,7 @@ extern const char *powerpc_base_platform
 #define CPU_FTR_STCX_CHECKS_ADDRESS	=

LONG_ASM_CONST(0x0200000000000000)

Review extern const char *powerpc_base_platform · line 203

Quoted 1 line
(quoted diff) +0 -0
 #define CPU_FTR_POPCNTB			=

LONG_ASM_CONST(0x0400000000000000)

Review extern const char *powerpc_base_platform · line 204

Quoted 1 line
(quoted diff) +0 -0
 #define CPU_FTR_POPCNTD			=

LONG_ASM_CONST(0x0800000000000000)

Review extern const char *powerpc_base_platform · line 205

Quoted 1 line
(quoted diff) +1 -0
+#define CPU_FTR_ICSWX			=

LONG_ASM_CONST(0x1000000000000000)

arch/powerpc/include/asm/cputable.h extern const char *powerpc_base_platform · line 424

Quoted 8 lines

=20
#ifndef __ASSEMBLY__
=20

arch/powerpc/include/asm/cputable.h +0 -1
@@ -421,7 +422,8 @@ extern const char *powerpc_base_platform
 	    CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
 	    CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
 	    CPU_FTR_DSCR | CPU_FTR_SAO  | CPU_FTR_ASYM_SMT | \
-	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | =

CPU_FTR_POPCNTD)

Review extern const char *powerpc_base_platform · line 425

Quoted 1 line
(quoted diff) +1 -0
+	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | =

CPU_FTR_POPCNTD | \

Quoted 6 lines
arch/powerpc/include/asm/cputable.h +1 -0
+	    CPU_FTR_ICSWX)
 #define CPU_FTRS_CELL	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \

Index: powerpc.git/arch/powerpc/include/asm/mmu-hash64.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

Quoted 1 line

--- powerpc.git.orig/arch/powerpc/include/asm/mmu-hash64.h =

2011-03-22 18:19:30.201446386 +1100
Quoted 1 line

+++ powerpc.git/arch/powerpc/include/asm/mmu-hash64.h 2011-03-26 =

08:15:44.284009603 +1100

arch/powerpc/include/asm/mmu-hash64.h typedef struct { · line 427

Quoted 13 lines
(quoted diff) +0 -0
@@ -408,6 +408,7 @@ static inline void subpage_prot_init_new
 #endif /* CONFIG_PPC_SUBPAGE_PROT */

=20
typedef unsigned long mm_context_id_t;
+struct spinlock;
=20

typedef struct {
	mm_context_id_t id;
arch/powerpc/include/asm/mmu-hash64.h +1 -0
@@ -423,6 +424,11 @@ typedef struct {
 #ifdef CONFIG_PPC_SUBPAGE_PROT
 	struct subpage_prot_table spt;
 #endif /* CONFIG_PPC_SUBPAGE_PROT */
+#ifdef CONFIG_ICSWX

Seems like this really should be CONFIG_PPC_ICSWX

Quoted 7 lines
arch/powerpc/include/asm/mmu-hash64.h +4 -0
+	struct spinlock *cop_lockp; /* guard acop and cop_pid */
+	unsigned long acop;	/* mask of enabled coprocessor types */
+	unsigned int cop_pid;	/* pid value used with coprocessors */
+#endif /* CONFIG_ICSWX */
 } mm_context_t;

=20
=20

- k

#2 lore raw

PATCH 1/1 powerpc: Add Initiate Coprocessor Store Word (icswx) support

From: Tseng-Hui (Frank) Lin <[email protected]>

Icswx is a PowerPC instruction to send data to a co-processor. On Book-S processors the LPAR_ID and process ID (PID) of the owning process are registered in the window context of the co-processor at initialization time. When the icswx instruction is executed the L2 generates a cop-reg transaction on PowerBus. The transaction has no address and the processor does not perform an MMU access to authenticate the transaction. The co-processor compares the LPAR_ID and the PID included in the transaction and the LPAR_ID and PID held in the window context to determine if the process is authorized to generate the transaction.

The OS needs to assign a 16-bit PID for the process. This cop-PID needs to be updated during context switch. The cop-PID needs to be destroyed when the context is destroyed.

---

- Changed CONFIG_ICSWX to CONFIG_PPC_ICSWX

arch/powerpc/include/asm/cputable.h +3 -1
Index: powerpc.git/arch/powerpc/include/asm/cputable.h
===================================================================
@@ -202,6 +202,7 @@ extern const char *powerpc_base_platform
 #define CPU_FTR_STCX_CHECKS_ADDRESS	LONG_ASM_CONST(0x0200000000000000)
 #define CPU_FTR_POPCNTB			LONG_ASM_CONST(0x0400000000000000)
 #define CPU_FTR_POPCNTD			LONG_ASM_CONST(0x0800000000000000)
+#define CPU_FTR_ICSWX			LONG_ASM_CONST(0x1000000000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -421,7 +422,8 @@ extern const char *powerpc_base_platform
 	    CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
 	    CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
 	    CPU_FTR_DSCR | CPU_FTR_SAO  | CPU_FTR_ASYM_SMT | \
-	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD)
+	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
+	    CPU_FTR_ICSWX)
 #define CPU_FTRS_CELL	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
arch/powerpc/include/asm/mmu-hash64.h +6 -0
Index: powerpc.git/arch/powerpc/include/asm/mmu-hash64.h
===================================================================
@@ -408,6 +408,7 @@ static inline void subpage_prot_init_new
 #endif /* CONFIG_PPC_SUBPAGE_PROT */
 
 typedef unsigned long mm_context_id_t;
+struct spinlock;
 
 typedef struct {
 	mm_context_id_t id;
@@ -423,6 +424,11 @@ typedef struct {
 #ifdef CONFIG_PPC_SUBPAGE_PROT
 	struct subpage_prot_table spt;
 #endif /* CONFIG_PPC_SUBPAGE_PROT */
+#ifdef CONFIG_PPC_ICSWX
+	struct spinlock *cop_lockp; /* guard acop and cop_pid */
+	unsigned long acop;	/* mask of enabled coprocessor types */
+	unsigned int cop_pid;	/* pid value used with coprocessors */
+#endif /* CONFIG_PPC_ICSWX */
 } mm_context_t;
 
 
arch/powerpc/include/asm/mmu_context.h +10 -0
Index: powerpc.git/arch/powerpc/include/asm/mmu_context.h
===================================================================
@@ -32,6 +32,10 @@ extern void __destroy_context(unsigned l
 extern void mmu_context_init(void);
 #endif
 
+extern void switch_cop(struct mm_struct *next);
+extern int use_cop(unsigned long acop, struct mm_struct *mm);
+extern void drop_cop(unsigned long acop, struct mm_struct *mm);
+
 /*
  * switch_mm is the entry point called from the architecture independent
  * code in kernel/sched.c
@@ -55,6 +59,12 @@ static inline void switch_mm(struct mm_s
 	if (prev == next)
 		return;
 
+#ifdef CONFIG_PPC_ICSWX
+	/* Switch coprocessor context only if prev or next uses a coprocessor */
+	if (prev->context.acop || next->context.acop)
+		switch_cop(next);
+#endif /* CONFIG_PPC_ICSWX */
+
 	/* We must stop all altivec streams before changing the HW
 	 * context
 	 */
arch/powerpc/include/asm/reg.h +1 -0
Index: powerpc.git/arch/powerpc/include/asm/reg.h
===================================================================
@@ -182,6 +182,7 @@
 
 #define SPRN_CTR	0x009	/* Count Register */
 #define SPRN_DSCR	0x11
+#define SPRN_ACOP	0x1F	/* Available Coprocessor Register */
 #define SPRN_CTRLF	0x088
 #define SPRN_CTRLT	0x098
 #define   CTRL_CT	0xc0000000	/* current thread */
arch/powerpc/mm/mmu_context_hash64.c +172 -0

193 lines not on this page · raw message

arch/powerpc/platforms/Kconfig.cputype +18 -0
Index: powerpc.git/arch/powerpc/platforms/Kconfig.cputype
===================================================================
@@ -226,6 +226,24 @@ config VSX
 
 	  If in doubt, say Y here.
 
+config PPC_ICSWX
+	bool "Support for PowerPC icswx coprocessor instruction"
+	depends on POWER4
+	default n
+	---help---
+
+	  This option enables kernel support for the PowerPC Initiate
+	  Coprocessor Store Word (icswx) coprocessor instruction on POWER7
+	  or newer processors.
+
+	  This option is only useful if you have a processor that supports
+	  the icswx coprocessor instruction. It does not have any effect
+	  on processors without the icswx coprocessor instruction.
+
+	  This option slightly increases kernel memory usage.
+
+	  If in doubt, say N here.
+
 config SPE
 	bool "SPE Support"
 	depends on E200 || (E500 && !PPC_E500MC)