LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V7 2/8] powerpc, process: Add the function flush_tmregs_to_thread
From: Anshuman Khandual @ 2015-01-14  7:08 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev
  Cc: shuahkh, mikey, james.hogan, avagin, Paul.Clothier, peterz,
	palves, oleg, davem, dhowells, kirjanov, davej, akpm, sukadev,
	tglx, sam.bobroff
In-Reply-To: <1421219330-19984-1-git-send-email-khandual@linux.vnet.ibm.com>

This patch creates a function flush_tmregs_to_thread which
will then be used by subsequent patches in this series. The
function checks for self tracing ptrace interface attempts
while in the TM context and logs appropriate warning message.

Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/switch_to.h |  8 ++++++++
 arch/powerpc/kernel/process.c        | 20 ++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h
index 58abeda..23752a9 100644
--- a/arch/powerpc/include/asm/switch_to.h
+++ b/arch/powerpc/include/asm/switch_to.h
@@ -82,6 +82,14 @@ static inline void flush_spe_to_thread(struct task_struct *t)
 }
 #endif
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+extern void flush_tmregs_to_thread(struct task_struct *);
+#else
+static inline void flush_tmregs_to_thread(struct task_struct *t)
+{
+}
+#endif
+
 static inline void clear_task_ebb(struct task_struct *t)
 {
 #ifdef CONFIG_PPC_BOOK3S_64
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index b4cc7be..a6f7ca5 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -745,6 +745,26 @@ void restore_tm_state(struct pt_regs *regs)
 #define __switch_to_tm(prev)
 #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+void flush_tmregs_to_thread(struct task_struct *tsk)
+{
+	/*
+	 * Process self tracing is not yet supported through
+	 * ptrace interface. Ptrace generic code should have
+	 * prevented this from happening in the first place.
+	 * Warn once here with the message, if some how it
+	 * is attempted.
+	 */
+	WARN_ONCE(tsk == current,
+		"Not expecting ptrace on self: TM regs may be incorrect\n");
+
+	/*
+	 * If task is not current, it should have been flushed
+	 * already to it's thread_struct during __switch_to().
+	 */
+}
+#endif
+
 struct task_struct *__switch_to(struct task_struct *prev,
 	struct task_struct *new)
 {
-- 
1.9.3

^ permalink raw reply related

* [PATCH V7 3/8] powerpc, ptrace: Enable fpr_(get/set) for transactional memory
From: Anshuman Khandual @ 2015-01-14  7:08 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev
  Cc: shuahkh, mikey, james.hogan, avagin, Paul.Clothier, peterz,
	palves, oleg, davem, dhowells, kirjanov, davej, akpm, sukadev,
	tglx, sam.bobroff
In-Reply-To: <1421219330-19984-1-git-send-email-khandual@linux.vnet.ibm.com>

This patch enables the fpr_get which gets the running value of all
the FPR registers and the fpr_set which sets the running value of
of all the FPR registers to accommodate in transaction ptrace
interface based requests.

Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
 arch/powerpc/kernel/ptrace.c | 103 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 97 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index f21897b..fd36b32 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -357,6 +357,33 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset,
 	return ret;
 }
 
+
+/*
+ * fpr_get
+ *
+ * When the transaction is active, 'transact_fp' holds the current running
+ * value of all FPR registers and 'fp_state' holds the last checkpointed
+ * value of all FPR registers for the current transaction. When transaction
+ * is not active 'fp_state' holds the current running state of all the FPR
+ * registers. So this function which returns the current running values of
+ * all the FPR registers, needs to know whether any transaction is active
+ * or not.
+ *
+ * Userspace interface buffer layout:
+ *
+ * struct data {
+ *	u64	fpr[32];
+ *	u64	fpscr;
+ * };
+ *
+ * There are two config options CONFIG_VSX and CONFIG_PPC_TRANSACTIONAL_MEM
+ * which determines the final code in this function. All the combinations of
+ * these two config options are possible except the one below as transactional
+ * memory config pulls in CONFIG_VSX automatically.
+ *
+ *	!defined(CONFIG_VSX) && defined(CONFIG_PPC_TRANSACTIONAL_MEM)
+ *
+ */
 static int fpr_get(struct task_struct *target, const struct user_regset *regset,
 		   unsigned int pos, unsigned int count,
 		   void *kbuf, void __user *ubuf)
@@ -367,22 +394,64 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset,
 #endif
 	flush_fp_to_thread(target);
 
-#ifdef CONFIG_VSX
+#if defined(CONFIG_VSX) && defined(CONFIG_PPC_TRANSACTIONAL_MEM)
+	/* copy to local buffer then write that out */
+	if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+		flush_altivec_to_thread(target);
+		flush_tmregs_to_thread(target);
+		for (i = 0; i < 32 ; i++)
+			buf[i] = target->thread.TS_TRANS_FPR(i);
+		buf[32] = target->thread.transact_fp.fpscr;
+	} else {
+		for (i = 0; i < 32 ; i++)
+			buf[i] = target->thread.TS_FPR(i);
+		buf[32] = target->thread.fp_state.fpscr;
+	}
+	return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
+#endif
+
+#if defined(CONFIG_VSX) && !defined(CONFIG_PPC_TRANSACTIONAL_MEM)
 	/* copy to local buffer then write that out */
 	for (i = 0; i < 32 ; i++)
 		buf[i] = target->thread.TS_FPR(i);
 	buf[32] = target->thread.fp_state.fpscr;
 	return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
+#endif
 
-#else
+
+#if !defined(CONFIG_VSX) && !defined(CONFIG_PPC_TRANSACTIONAL_MEM)
 	BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
 		     offsetof(struct thread_fp_state, fpr[32][0]));
-
 	return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
 				   &target->thread.fp_state, 0, -1);
 #endif
 }
 
+/*
+ * fpr_set
+ *
+ * When the transaction is active, 'transact_fp' holds the current running
+ * value of all FPR registers and 'fp_state' holds the last checkpointed
+ * value of all FPR registers for the current transaction. When transaction
+ * is not active 'fp_state' holds the current running state of all the FPR
+ * registers. So this function which setss the current running values of
+ * all the FPR registers, needs to know whether any transaction is active
+ * or not.
+ *
+ * Userspace interface buffer layout:
+ *
+ * struct data {
+ *	u64	fpr[32];
+ *	u64	fpscr;
+ * };
+ *
+ * There are two config options CONFIG_VSX and CONFIG_PPC_TRANSACTIONAL_MEM
+ * which determines the final code in this function. All the combinations of
+ * these two config options are possible except the one below as transactional
+ * memory config pulls in CONFIG_VSX automatically.
+ *
+ *	!defined(CONFIG_VSX) && defined(CONFIG_PPC_TRANSACTIONAL_MEM)
+ */
 static int fpr_set(struct task_struct *target, const struct user_regset *regset,
 		   unsigned int pos, unsigned int count,
 		   const void *kbuf, const void __user *ubuf)
@@ -393,7 +462,27 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
 #endif
 	flush_fp_to_thread(target);
 
-#ifdef CONFIG_VSX
+#if defined(CONFIG_VSX) && defined(CONFIG_PPC_TRANSACTIONAL_MEM)
+	/* copy to local buffer then write that out */
+	i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
+	if (i)
+		return i;
+
+	if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+		flush_altivec_to_thread(target);
+		flush_tmregs_to_thread(target);
+		for (i = 0; i < 32 ; i++)
+			target->thread.TS_TRANS_FPR(i) = buf[i];
+		target->thread.transact_fp.fpscr = buf[32];
+	} else {
+		for (i = 0; i < 32 ; i++)
+			target->thread.TS_FPR(i) = buf[i];
+		target->thread.fp_state.fpscr = buf[32];
+	}
+	return 0;
+#endif
+
+#if defined(CONFIG_VSX) && !defined(CONFIG_PPC_TRANSACTIONAL_MEM)
 	/* copy to local buffer then write that out */
 	i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
 	if (i)
@@ -402,12 +491,14 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
 		target->thread.TS_FPR(i) = buf[i];
 	target->thread.fp_state.fpscr = buf[32];
 	return 0;
-#else
+#endif
+
+#if !defined(CONFIG_VSX) && !defined(CONFIG_PPC_TRANSACTIONAL_MEM)
 	BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
 		     offsetof(struct thread_fp_state, fpr[32][0]));
-
 	return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
 				  &target->thread.fp_state, 0, -1);
+
 #endif
 }
 
-- 
1.9.3

^ permalink raw reply related

* [PATCH V7 4/8] powerpc, ptrace: Enable vr_(get/set) for transactional memory
From: Anshuman Khandual @ 2015-01-14  7:08 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev
  Cc: shuahkh, mikey, james.hogan, avagin, Paul.Clothier, peterz,
	palves, oleg, davem, dhowells, kirjanov, davej, akpm, sukadev,
	tglx, sam.bobroff
In-Reply-To: <1421219330-19984-1-git-send-email-khandual@linux.vnet.ibm.com>

This patch enables the vr_get which gets the running value of all
the VMX registers and the vr_set which sets the running value of
of all the VMX registers to accommodate in transaction ptrace
interface based requests.

Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
 arch/powerpc/kernel/ptrace.c | 94 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 91 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index fd36b32..2bbbd10 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -523,10 +523,30 @@ static int vr_active(struct task_struct *target,
 	return target->thread.used_vr ? regset->n : 0;
 }
 
+/*
+ * vr_get
+ *
+ * When the transaction is active, 'transact_vr' holds the current running
+ * value of all the VMX registers and 'vr_state' holds the last checkpointed
+ * value of all the VMX registers for the current transaction to fall back
+ * on in case it aborts. When transaction is not active 'vr_state' holds
+ * the current running state of all the VMX registers. So this function which
+ * gets the current running values of all the VMX registers, needs to know
+ * whether any transaction is active or not.
+ *
+ * Userspace interface buffer layout:
+ *
+ * struct data {
+ *	vector128	vr[32];
+ *	vector128	vscr;
+ *	vector128	vrsave;
+ * };
+ */
 static int vr_get(struct task_struct *target, const struct user_regset *regset,
 		  unsigned int pos, unsigned int count,
 		  void *kbuf, void __user *ubuf)
 {
+	struct thread_vr_state *addr;
 	int ret;
 
 	flush_altivec_to_thread(target);
@@ -534,8 +554,19 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset,
 	BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
 		     offsetof(struct thread_vr_state, vr[32]));
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+	if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+		flush_fp_to_thread(target);
+		flush_tmregs_to_thread(target);
+		addr = &target->thread.transact_vr;
+	} else {
+		addr = &target->thread.vr_state;
+	}
+#else
+	addr = &target->thread.vr_state;
+#endif
 	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-				  &target->thread.vr_state, 0,
+				  addr, 0,
 				  33 * sizeof(vector128));
 	if (!ret) {
 		/*
@@ -546,7 +577,16 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset,
 			u32 word;
 		} vrsave;
 		memset(&vrsave, 0, sizeof(vrsave));
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+		if (MSR_TM_ACTIVE(target->thread.regs->msr))
+			vrsave.word = target->thread.transact_vrsave;
+		else
+			vrsave.word = target->thread.vrsave;
+#else
 		vrsave.word = target->thread.vrsave;
+#endif
+
 		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
 					  33 * sizeof(vector128), -1);
 	}
@@ -554,10 +594,30 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset,
 	return ret;
 }
 
+/*
+ * vr_set
+ *
+ * When the transaction is active, 'transact_vr' holds the current running
+ * value of all the VMX registers and 'vr_state' holds the last checkpointed
+ * value of all the VMX registers for the current transaction to fall back
+ * on in case it aborts. When transaction is not active 'vr_state' holds
+ * the current running state of all the VMX registers. So this function which
+ * sets the current running values of all the VMX registers, needs to know
+ * whether any transaction is active or not.
+ *
+ * Userspace interface buffer layout:
+ *
+ * struct data {
+ *	vector128	vr[32];
+ *	vector128	vscr;
+ *	vector128	vrsave;
+ * };
+ */
 static int vr_set(struct task_struct *target, const struct user_regset *regset,
 		  unsigned int pos, unsigned int count,
 		  const void *kbuf, const void __user *ubuf)
 {
+	struct thread_vr_state *addr;
 	int ret;
 
 	flush_altivec_to_thread(target);
@@ -565,8 +625,19 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
 	BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
 		     offsetof(struct thread_vr_state, vr[32]));
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+	if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+		flush_fp_to_thread(target);
+		flush_tmregs_to_thread(target);
+		addr = &target->thread.transact_vr;
+	} else {
+		addr = &target->thread.vr_state;
+	}
+#else
+	addr = &target->thread.vr_state;
+#endif
 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-				 &target->thread.vr_state, 0,
+				 addr, 0,
 				 33 * sizeof(vector128));
 	if (!ret && count > 0) {
 		/*
@@ -577,11 +648,28 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
 			u32 word;
 		} vrsave;
 		memset(&vrsave, 0, sizeof(vrsave));
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+		if (MSR_TM_ACTIVE(target->thread.regs->msr))
+			vrsave.word = target->thread.transact_vrsave;
+		else
+			vrsave.word = target->thread.vrsave;
+#else
 		vrsave.word = target->thread.vrsave;
+#endif
 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
 					 33 * sizeof(vector128), -1);
-		if (!ret)
+		if (!ret) {
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+			if (MSR_TM_ACTIVE(target->thread.regs->msr))
+				target->thread.transact_vrsave = vrsave.word;
+			else
+				target->thread.vrsave = vrsave.word;
+#else
 			target->thread.vrsave = vrsave.word;
+#endif
+		}
 	}
 
 	return ret;
-- 
1.9.3

^ permalink raw reply related

* [PATCH V7 5/8] powerpc, ptrace: Enable support for transactional memory register sets
From: Anshuman Khandual @ 2015-01-14  7:08 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev
  Cc: shuahkh, mikey, james.hogan, avagin, Paul.Clothier, peterz,
	palves, oleg, davem, dhowells, kirjanov, davej, akpm, sukadev,
	tglx, sam.bobroff
In-Reply-To: <1421219330-19984-1-git-send-email-khandual@linux.vnet.ibm.com>

This patch enables get and set of transactional memory related register
sets through PTRACE_GETREGSET-PTRACE_SETREGSET interface by implementing
four new powerpc specific register sets i.e REGSET_TM_SPR, REGSET_TM_CGPR,
REGSET_TM_CFPR, REGSET_CVMX support corresponding to these following new
ELF core note types added previously in this regard.

	(1) NT_PPC_TM_SPR
	(2) NT_PPC_TM_CGPR
	(3) NT_PPC_TM_CFPR
	(4) NT_PPC_TM_CVMX

Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
 arch/powerpc/include/uapi/asm/elf.h |   2 +
 arch/powerpc/kernel/ptrace.c        | 714 +++++++++++++++++++++++++++++++++++-
 2 files changed, 701 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h
index 59dad11..fdc8e2f 100644
--- a/arch/powerpc/include/uapi/asm/elf.h
+++ b/arch/powerpc/include/uapi/asm/elf.h
@@ -91,6 +91,8 @@
 
 #define ELF_NGREG	48	/* includes nip, msr, lr, etc. */
 #define ELF_NFPREG	33	/* includes fpscr */
+#define ELF_NVMX	34	/* includes all vector registers */
+#define ELF_NTMSPRREG	7	/* includes TM sprs, org_msr, dscr, tar, ppr */
 
 typedef unsigned long elf_greg_t64;
 typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG];
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 2bbbd10..b14397c 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -63,6 +63,11 @@ struct pt_regs_offset {
 	{.name = STR(gpr##num), .offset = offsetof(struct pt_regs, gpr[num])}
 #define REG_OFFSET_END {.name = NULL, .offset = 0}
 
+/* Some common structure offsets */
+#define TSO(f)	(offsetof(struct thread_struct, f))
+#define TVSO(f)	(offsetof(struct thread_vr_state, f))
+#define TFSO(f)	(offsetof(struct thread_fp_state, f))
+
 static const struct pt_regs_offset regoffset_table[] = {
 	GPR_OFFSET_NAME(0),
 	GPR_OFFSET_NAME(1),
@@ -792,6 +797,579 @@ static int evr_set(struct task_struct *target, const struct user_regset *regset,
 }
 #endif /* CONFIG_SPE */
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+/**
+ * tm_spr_active - get active number of registers in TM SPR
+ * @target:	The target task.
+ * @regset:	The user regset structure.
+ *
+ * This function checks the active number of available
+ * regisers in the transactional memory SPR category.
+ */
+static int tm_spr_active(struct task_struct *target,
+			 const struct user_regset *regset)
+{
+	if (!cpu_has_feature(CPU_FTR_TM))
+		return -ENODEV;
+
+	if (!MSR_TM_ACTIVE(target->thread.regs->msr))
+		return 0;
+
+	return regset->n;
+}
+
+/**
+ * tm_spr_get - get the TM related SPR registers
+ * @target:	The target task.
+ * @regset:	The user regset structure.
+ * @pos:	The buffer position.
+ * @count:	Number of bytes to copy.
+ * @kbuf:	Kernel buffer to copy from.
+ * @ubuf:	User buffer to copy into.
+ *
+ * This function gets transactional memory related SPR registers.
+ * The userspace interface buffer layout is as follows.
+ *
+ * struct {
+ *	u64		tm_tfhar;
+ *	u64		tm_texasr;
+ *	u64		tm_tfiar;
+ *	unsigned long	tm_orig_msr;
+ *	unsigned long	tm_tar;
+ *	unsigned long	tm_ppr;
+ *	unsigned long	tm_dscr;
+ * };
+ */
+static int tm_spr_get(struct task_struct *target,
+		      const struct user_regset *regset,
+		      unsigned int pos, unsigned int count,
+		      void *kbuf, void __user *ubuf)
+{
+	int ret;
+
+	/* Build tests */
+	BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr));
+	BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar));
+	BUILD_BUG_ON(TSO(tm_tfiar) + sizeof(u64) != TSO(tm_orig_msr));
+	BUILD_BUG_ON(TSO(ckpt_regs) + sizeof(struct pt_regs) != TSO(tm_tar));
+	BUILD_BUG_ON(TSO(tm_tar) + sizeof(unsigned long) != TSO(tm_ppr));
+	BUILD_BUG_ON(TSO(tm_ppr) + sizeof(unsigned long) != TSO(tm_dscr));
+
+	if (!cpu_has_feature(CPU_FTR_TM))
+		return -ENODEV;
+
+	if (!MSR_TM_ACTIVE(target->thread.regs->msr))
+		return -ENODATA;
+
+	/* Flush the states */
+	flush_fp_to_thread(target);
+	flush_altivec_to_thread(target);
+	flush_tmregs_to_thread(target);
+
+	/* TFHAR register */
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				&target->thread.tm_tfhar, 0, sizeof(u64));
+
+	/* TEXASR register */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				&target->thread.tm_texasr, sizeof(u64),
+				2 * sizeof(u64));
+
+	/* TFIAR register */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				&target->thread.tm_tfiar,
+				2 * sizeof(u64), 3 * sizeof(u64));
+
+	/* TM checkpointed original MSR */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				&target->thread.tm_orig_msr, 3 * sizeof(u64),
+				3 * sizeof(u64) + sizeof(unsigned long));
+
+	/* TM checkpointed TAR register */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				&target->thread.tm_tar, 3 * sizeof(u64) +
+				sizeof(unsigned long),
+				3 * sizeof(u64) + 2 * sizeof(unsigned long));
+
+	/* TM checkpointed PPR register */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				&target->thread.tm_ppr, 3 * sizeof(u64) +
+				2 * sizeof(unsigned long),
+				3 * sizeof(u64) + 3 * sizeof(unsigned long));
+
+	/* TM checkpointed DSCR register */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				&target->thread.tm_dscr, 3 * sizeof(u64) +
+				3 * sizeof(unsigned long),
+				3 * sizeof(u64) + 4 * sizeof(unsigned long));
+	return ret;
+}
+
+/**
+ * tm_spr_set - set the TM related SPR registers
+ * @target:	The target task.
+ * @regset:	The user regset structure.
+ * @pos:	The buffer position.
+ * @count:	Number of bytes to copy.
+ * @kbuf:	Kernel buffer to copy into.
+ * @ubuf:	User buffer to copy from.
+ *
+ * This function sets transactional memory related SPR registers.
+ * The userspace interface buffer layout is as follows.
+ *
+ * struct {
+ *	u64		tm_tfhar;
+ *	u64		tm_texasr;
+ *	u64		tm_tfiar;
+ *	unsigned long	tm_orig_msr;
+ *	unsigned long	tm_tar;
+ *	unsigned long	tm_ppr;
+ *	unsigned long	tm_dscr;
+ * };
+ */
+static int tm_spr_set(struct task_struct *target,
+		      const struct user_regset *regset,
+		      unsigned int pos, unsigned int count,
+		      const void *kbuf, const void __user *ubuf)
+{
+	int ret;
+
+	/* Build tests */
+	BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr));
+	BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar));
+	BUILD_BUG_ON(TSO(tm_tfiar) + sizeof(u64) != TSO(tm_orig_msr));
+	BUILD_BUG_ON(TSO(ckpt_regs) + sizeof(struct pt_regs) != TSO(tm_tar));
+	BUILD_BUG_ON(TSO(tm_tar) + sizeof(unsigned long) != TSO(tm_ppr));
+	BUILD_BUG_ON(TSO(tm_ppr) + sizeof(unsigned long) != TSO(tm_dscr));
+
+	if (!cpu_has_feature(CPU_FTR_TM))
+		return -ENODEV;
+
+	if (!MSR_TM_ACTIVE(target->thread.regs->msr))
+		return -ENODATA;
+
+	/* Flush the states */
+	flush_fp_to_thread(target);
+	flush_altivec_to_thread(target);
+	flush_tmregs_to_thread(target);
+
+	/* TFHAR register */
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				&target->thread.tm_tfhar, 0, sizeof(u64));
+
+	/* TEXASR register */
+	if (!ret)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				&target->thread.tm_texasr, sizeof(u64),
+				2 * sizeof(u64));
+
+	/* TFIAR register */
+	if (!ret)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				&target->thread.tm_tfiar,
+				 2 * sizeof(u64), 3 * sizeof(u64));
+
+
+	/* TM checkpointed orig MSR */
+	if (!ret)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				&target->thread.tm_orig_msr, 3 * sizeof(u64),
+				3 * sizeof(u64) + sizeof(unsigned long));
+
+
+	/* TM checkpointed TAR register */
+	if (!ret)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				&target->thread.tm_tar, 3 * sizeof(u64) +
+				sizeof(unsigned long), 3 * sizeof(u64) +
+				2 * sizeof(unsigned long));
+
+	/* TM checkpointed PPR register */
+	if (!ret)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				&target->thread.tm_ppr, 3 * sizeof(u64) +
+				2 * sizeof(unsigned long), 3 * sizeof(u64) +
+				3 * sizeof(unsigned long));
+
+	/* TM checkpointed DSCR register */
+	if (!ret)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				&target->thread.tm_dscr, 3 * sizeof(u64) +
+				3 * sizeof(unsigned long), 3 * sizeof(u64) +
+				4 * sizeof(unsigned long));
+	return ret;
+}
+
+/**
+ * tm_cgpr_active - get active number of registers in CGPR
+ * @target:	The target task.
+ * @regset:	The user regset structure.
+ *
+ * This function checks for the active number of available
+ * regisers in transaction checkpointed GPR category.
+ */
+static int tm_cgpr_active(struct task_struct *target,
+			  const struct user_regset *regset)
+{
+	if (!cpu_has_feature(CPU_FTR_TM))
+		return -ENODEV;
+
+	if (!MSR_TM_ACTIVE(target->thread.regs->msr))
+		return 0;
+
+	return regset->n;
+}
+
+/**
+ * tm_cgpr_get - get CGPR registers
+ * @target:	The target task.
+ * @regset:	The user regset structure.
+ * @pos:	The buffer position.
+ * @count:	Number of bytes to copy.
+ * @kbuf:	Kernel buffer to copy from.
+ * @ubuf:	User buffer to copy into.
+ *
+ * This function gets transaction checkpointed GPR registers.
+ *
+ * When the transaction is active, 'ckpt_regs' holds all the checkpointed
+ * GPR register values for the current transaction to fall back on if it
+ * aborts in between. This function gets those checkpointed GPR registers.
+ * The userspace interface buffer layout is as follows.
+ *
+ * struct data {
+ *	struct pt_regs ckpt_regs;
+ * };
+ */
+static int tm_cgpr_get(struct task_struct *target,
+			const struct user_regset *regset,
+			unsigned int pos, unsigned int count,
+			void *kbuf, void __user *ubuf)
+{
+	int ret;
+
+	if (!cpu_has_feature(CPU_FTR_TM))
+		return -ENODEV;
+
+	if (!MSR_TM_ACTIVE(target->thread.regs->msr))
+		return -ENODATA;
+
+	flush_fp_to_thread(target);
+	flush_altivec_to_thread(target);
+	flush_tmregs_to_thread(target);
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					&target->thread.ckpt_regs, 0,
+					sizeof(struct pt_regs));
+	return ret;
+}
+
+/*
+ * tm_cgpr_set - set the CGPR registers
+ * @target:	The target task.
+ * @regset:	The user regset structure.
+ * @pos:	The buffer position.
+ * @count:	Number of bytes to copy.
+ * @kbuf:	Kernel buffer to copy into.
+ * @ubuf:	User buffer to copy from.
+ *
+ * This function sets in transaction checkpointed GPR registers.
+ *
+ * When the transaction is active, 'ckpt_regs' holds the checkpointed
+ * GPR register values for the current transaction to fall back on if it
+ * aborts in between. This function sets those checkpointed GPR registers.
+ * The userspace interface buffer layout is as follows.
+ *
+ * struct data {
+ *	struct pt_regs ckpt_regs;
+ * };
+ */
+static int tm_cgpr_set(struct task_struct *target,
+			const struct user_regset *regset,
+			unsigned int pos, unsigned int count,
+			const void *kbuf, const void __user *ubuf)
+{
+	int ret;
+
+	if (!cpu_has_feature(CPU_FTR_TM))
+		return -ENODEV;
+
+	if (!MSR_TM_ACTIVE(target->thread.regs->msr))
+		return -ENODATA;
+
+	flush_fp_to_thread(target);
+	flush_altivec_to_thread(target);
+	flush_tmregs_to_thread(target);
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					&target->thread.ckpt_regs, 0,
+					sizeof(struct pt_regs));
+	return ret;
+}
+
+/**
+ * tm_cfpr_active - get active number of registers in CFPR
+ * @target:	The target task.
+ * @regset:	The user regset structure.
+ *
+ * This function checks for the active number of available
+ * regisers in transaction checkpointed FPR category.
+ */
+static int tm_cfpr_active(struct task_struct *target,
+				const struct user_regset *regset)
+{
+	if (!cpu_has_feature(CPU_FTR_TM))
+		return -ENODEV;
+
+	if (!MSR_TM_ACTIVE(target->thread.regs->msr))
+		return 0;
+
+	return regset->n;
+}
+
+/**
+ * tm_cfpr_get - get CFPR registers
+ * @target:	The target task.
+ * @regset:	The user regset structure.
+ * @pos:	The buffer position.
+ * @count:	Number of bytes to copy.
+ * @kbuf:	Kernel buffer to copy from.
+ * @ubuf:	User buffer to copy into.
+ *
+ * This function gets in transaction checkpointed FPR registers.
+ *
+ * When the transaction is active 'fp_state' holds the checkpointed
+ * values for the current transaction to fall back on if it aborts
+ * in between. This function gets those checkpointed FPR registers.
+ * The userspace interface buffer layout is as follows.
+ *
+ * struct data {
+ *	u64	fpr[32];
+ *	u64	fpscr;
+ *};
+ */
+static int tm_cfpr_get(struct task_struct *target,
+			const struct user_regset *regset,
+			unsigned int pos, unsigned int count,
+			void *kbuf, void __user *ubuf)
+{
+	u64 buf[33];
+	int i;
+
+	if (!cpu_has_feature(CPU_FTR_TM))
+		return -ENODEV;
+
+	if (!MSR_TM_ACTIVE(target->thread.regs->msr))
+		return -ENODATA;
+
+	flush_fp_to_thread(target);
+	flush_altivec_to_thread(target);
+	flush_tmregs_to_thread(target);
+
+	/* copy to local buffer then write that out */
+	for (i = 0; i < 32 ; i++)
+		buf[i] = target->thread.TS_FPR(i);
+	buf[32] = target->thread.fp_state.fpscr;
+	return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
+}
+
+/**
+ * tm_cfpr_set - set CFPR registers
+ * @target:	The target task.
+ * @regset:	The user regset structure.
+ * @pos:	The buffer position.
+ * @count:	Number of bytes to copy.
+ * @kbuf:	Kernel buffer to copy into.
+ * @ubuf:	User buffer to copy from.
+ *
+ * This function sets in transaction checkpointed FPR registers.
+ *
+ * When the transaction is active 'fp_state' holds the checkpointed
+ * FPR register values for the current transaction to fall back on
+ * if it aborts in between. This function sets these checkpointed
+ * FPR registers. The userspace interface buffer layout is as follows.
+ *
+ * struct data {
+ *	u64	fpr[32];
+ *	u64	fpscr;
+ *};
+ */
+static int tm_cfpr_set(struct task_struct *target,
+			const struct user_regset *regset,
+			unsigned int pos, unsigned int count,
+			const void *kbuf, const void __user *ubuf)
+{
+	u64 buf[33];
+	int i;
+
+	if (!cpu_has_feature(CPU_FTR_TM))
+		return -ENODEV;
+
+	if (!MSR_TM_ACTIVE(target->thread.regs->msr))
+		return -ENODATA;
+
+	flush_fp_to_thread(target);
+	flush_altivec_to_thread(target);
+	flush_tmregs_to_thread(target);
+
+	/* copy to local buffer then write that out */
+	i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
+	if (i)
+		return i;
+	for (i = 0; i < 32 ; i++)
+		target->thread.TS_FPR(i) = buf[i];
+	target->thread.fp_state.fpscr = buf[32];
+	return 0;
+}
+
+/**
+ * tm_cvmx_active - get active number of registers in CVMX
+ * @target:	The target task.
+ * @regset:	The user regset structure.
+ *
+ * This function checks for the active number of available
+ * regisers in checkpointed VMX category.
+ */
+static int tm_cvmx_active(struct task_struct *target,
+				const struct user_regset *regset)
+{
+	if (!cpu_has_feature(CPU_FTR_TM))
+		return -ENODEV;
+
+	if (!MSR_TM_ACTIVE(target->thread.regs->msr))
+		return 0;
+
+	return regset->n;
+}
+
+/**
+ * tm_cvmx_get - get CMVX registers
+ * @target:	The target task.
+ * @regset:	The user regset structure.
+ * @pos:	The buffer position.
+ * @count:	Number of bytes to copy.
+ * @kbuf:	Kernel buffer to copy from.
+ * @ubuf:	User buffer to copy into.
+ *
+ * This function gets in transaction checkpointed VMX registers.
+ *
+ * When the transaction is active 'vr_state' and 'vr_save' hold
+ * the checkpointed values for the current transaction to fall
+ * back on if it aborts in between. The userspace interface buffer
+ * layout is as follows.
+ *
+ * struct data {
+ *	vector128	vr[32];
+ *	vector128	vscr;
+ *	vector128	vrsave;
+ *};
+ */
+static int tm_cvmx_get(struct task_struct *target,
+			const struct user_regset *regset,
+			unsigned int pos, unsigned int count,
+			void *kbuf, void __user *ubuf)
+{
+	int ret;
+
+	BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32]));
+
+	if (!cpu_has_feature(CPU_FTR_TM))
+		return -ENODEV;
+
+	if (!MSR_TM_ACTIVE(target->thread.regs->msr))
+		return -ENODATA;
+
+	/* Flush the state */
+	flush_fp_to_thread(target);
+	flush_altivec_to_thread(target);
+	flush_tmregs_to_thread(target);
+
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					&target->thread.vr_state, 0,
+					33 * sizeof(vector128));
+	if (!ret) {
+		/*
+		 * Copy out only the low-order word of vrsave.
+		 */
+		union {
+			elf_vrreg_t reg;
+			u32 word;
+		} vrsave;
+		memset(&vrsave, 0, sizeof(vrsave));
+		vrsave.word = target->thread.vrsave;
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
+						33 * sizeof(vector128), -1);
+	}
+
+	return ret;
+}
+
+/**
+ * tm_cvmx_set - set CMVX registers
+ * @target:	The target task.
+ * @regset:	The user regset structure.
+ * @pos:	The buffer position.
+ * @count:	Number of bytes to copy.
+ * @kbuf:	Kernel buffer to copy into.
+ * @ubuf:	User buffer to copy from.
+ *
+ * This function sets in transaction checkpointed VMX registers.
+ *
+ * When the transaction is active 'vr_state' and 'vr_save' hold
+ * the checkpointed values for the current transaction to fall
+ * back on if it aborts in between. The userspace interface buffer
+ * layout is as follows.
+ *
+ * struct data {
+ *	vector128	vr[32];
+ *	vector128	vscr;
+ *	vector128	vrsave;
+ *};
+ */
+static int tm_cvmx_set(struct task_struct *target,
+			const struct user_regset *regset,
+			unsigned int pos, unsigned int count,
+			const void *kbuf, const void __user *ubuf)
+{
+	int ret;
+
+	BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32]));
+
+	if (!cpu_has_feature(CPU_FTR_TM))
+		return -ENODEV;
+
+	if (!MSR_TM_ACTIVE(target->thread.regs->msr))
+		return -ENODATA;
+
+	flush_fp_to_thread(target);
+	flush_altivec_to_thread(target);
+	flush_tmregs_to_thread(target);
+
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					&target->thread.vr_state, 0,
+					33 * sizeof(vector128));
+	if (!ret && count > 0) {
+		/*
+		 * We use only the low-order word of vrsave.
+		 */
+		union {
+			elf_vrreg_t reg;
+			u32 word;
+		} vrsave;
+		memset(&vrsave, 0, sizeof(vrsave));
+		vrsave.word = target->thread.vrsave;
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
+						33 * sizeof(vector128), -1);
+		if (!ret)
+			target->thread.vrsave = vrsave.word;
+	}
+
+	return ret;
+}
+#endif	/* CONFIG_PPC_TRANSACTIONAL_MEM */
 
 /*
  * These are our native regset flavors.
@@ -808,6 +1386,12 @@ enum powerpc_regset {
 #ifdef CONFIG_SPE
 	REGSET_SPE,
 #endif
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+	REGSET_TM_SPR,		/* TM specific SPR registers */
+	REGSET_TM_CGPR,		/* TM checkpointed GPR registers */
+	REGSET_TM_CFPR,		/* TM checkpointed FPR registers */
+	REGSET_TM_CVMX,		/* TM checkpointed VMX registers */
+#endif
 };
 
 static const struct user_regset native_regsets[] = {
@@ -842,6 +1426,28 @@ static const struct user_regset native_regsets[] = {
 		.active = evr_active, .get = evr_get, .set = evr_set
 	},
 #endif
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+	[REGSET_TM_SPR] = {
+		.core_note_type = NT_PPC_TM_SPR, .n = ELF_NTMSPRREG,
+		.size = sizeof(u64), .align = sizeof(u64),
+		.active = tm_spr_active, .get = tm_spr_get, .set = tm_spr_set
+	},
+	[REGSET_TM_CGPR] = {
+		.core_note_type = NT_PPC_TM_CGPR, .n = ELF_NGREG,
+		.size = sizeof(long), .align = sizeof(long),
+		.active = tm_cgpr_active, .get = tm_cgpr_get, .set = tm_cgpr_set
+	},
+	[REGSET_TM_CFPR] = {
+		.core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG,
+		.size = sizeof(double), .align = sizeof(double),
+		.active = tm_cfpr_active, .get = tm_cfpr_get, .set = tm_cfpr_set
+	},
+	[REGSET_TM_CVMX] = {
+		.core_note_type = NT_PPC_TM_CVMX, .n = ELF_NVMX,
+		.size = sizeof(vector128), .align = sizeof(vector128),
+		.active = tm_cvmx_active, .get = tm_cvmx_get, .set = tm_cvmx_set
+	},
+#endif
 };
 
 static const struct user_regset_view user_ppc_native_view = {
@@ -852,26 +1458,38 @@ static const struct user_regset_view user_ppc_native_view = {
 #ifdef CONFIG_PPC64
 #include <linux/compat.h>
 
-static int gpr32_get(struct task_struct *target,
+static int common_gpr32_get(struct task_struct *target,
 		     const struct user_regset *regset,
 		     unsigned int pos, unsigned int count,
-		     void *kbuf, void __user *ubuf)
+			    void *kbuf, void __user *ubuf, bool in_tm)
 {
-	const unsigned long *regs = &target->thread.regs->gpr[0];
+	const unsigned long *regs = NULL;
 	compat_ulong_t *k = kbuf;
 	compat_ulong_t __user *u = ubuf;
 	compat_ulong_t reg;
 	int i;
 
-	if (target->thread.regs == NULL)
-		return -EIO;
+	if (in_tm) {
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+		regs = &target->thread.ckpt_regs.gpr[0];
+#endif
+	} else {
+		regs = &target->thread.regs->gpr[0];
 
-	if (!FULL_REGS(target->thread.regs)) {
-		/* We have a partial register set.  Fill 14-31 with bogus values */
-		for (i = 14; i < 32; i++)
-			target->thread.regs->gpr[i] = NV_REG_POISON; 
+		if (target->thread.regs == NULL)
+			return -EIO;
+
+		if (!FULL_REGS(target->thread.regs)) {
+			/*
+			 * We have a partial register set.
+			 * Fill 14-31 with bogus values.
+			 */
+			for (i = 14; i < 32; i++)
+				target->thread.regs->gpr[i] = NV_REG_POISON;
+		}
 	}
 
+	BUG_ON(!regs);
 	pos /= sizeof(reg);
 	count /= sizeof(reg);
 
@@ -909,21 +1527,30 @@ static int gpr32_get(struct task_struct *target,
 					PT_REGS_COUNT * sizeof(reg), -1);
 }
 
-static int gpr32_set(struct task_struct *target,
+static int common_gpr32_set(struct task_struct *target,
 		     const struct user_regset *regset,
 		     unsigned int pos, unsigned int count,
-		     const void *kbuf, const void __user *ubuf)
+		     const void *kbuf, const void __user *ubuf, bool in_tm)
 {
-	unsigned long *regs = &target->thread.regs->gpr[0];
+	unsigned long *regs = NULL;
 	const compat_ulong_t *k = kbuf;
 	const compat_ulong_t __user *u = ubuf;
 	compat_ulong_t reg;
 
-	if (target->thread.regs == NULL)
-		return -EIO;
+	if (in_tm) {
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+		regs = &target->thread.ckpt_regs.gpr[0];
+#endif
+	} else {
+		regs = &target->thread.regs->gpr[0];
 
-	CHECK_FULL_REGS(target->thread.regs);
+		if (target->thread.regs == NULL)
+			return -EIO;
 
+		CHECK_FULL_REGS(target->thread.regs);
+	}
+
+	BUG_ON(!regs);
 	pos /= sizeof(reg);
 	count /= sizeof(reg);
 
@@ -982,6 +1609,40 @@ static int gpr32_set(struct task_struct *target,
 					 (PT_TRAP + 1) * sizeof(reg), -1);
 }
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+static int tm_cgpr32_get(struct task_struct *target,
+		     const struct user_regset *regset,
+		     unsigned int pos, unsigned int count,
+		     void *kbuf, void __user *ubuf)
+{
+	return common_gpr32_get(target, regset, pos, count, kbuf, ubuf, 1);
+}
+
+static int tm_cgpr32_set(struct task_struct *target,
+		     const struct user_regset *regset,
+		     unsigned int pos, unsigned int count,
+		     const void *kbuf, const void __user *ubuf)
+{
+	return common_gpr32_set(target, regset, pos, count, kbuf, ubuf, 1);
+}
+#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
+
+static int gpr32_get(struct task_struct *target,
+		     const struct user_regset *regset,
+		     unsigned int pos, unsigned int count,
+		     void *kbuf, void __user *ubuf)
+{
+	return common_gpr32_get(target, regset, pos, count, kbuf, ubuf, 0);
+}
+
+static int gpr32_set(struct task_struct *target,
+		     const struct user_regset *regset,
+		     unsigned int pos, unsigned int count,
+		     const void *kbuf, const void __user *ubuf)
+{
+	return common_gpr32_set(target, regset, pos, count, kbuf, ubuf, 0);
+}
+
 /*
  * These are the regset flavors matching the CONFIG_PPC32 native set.
  */
@@ -1010,6 +1671,29 @@ static const struct user_regset compat_regsets[] = {
 		.active = evr_active, .get = evr_get, .set = evr_set
 	},
 #endif
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+	[REGSET_TM_SPR] = {
+		.core_note_type = NT_PPC_TM_SPR, .n = ELF_NTMSPRREG,
+		.size = sizeof(u64), .align = sizeof(u64),
+		.active = tm_spr_active, .get = tm_spr_get, .set = tm_spr_set
+	},
+	[REGSET_TM_CGPR] = {
+		.core_note_type = NT_PPC_TM_CGPR, .n = ELF_NGREG,
+		.size = sizeof(long), .align = sizeof(long),
+		.active = tm_cgpr_active,
+		.get = tm_cgpr32_get, .set = tm_cgpr32_set
+	},
+	[REGSET_TM_CFPR] = {
+		.core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG,
+		.size = sizeof(double), .align = sizeof(double),
+		.active = tm_cfpr_active, .get = tm_cfpr_get, .set = tm_cfpr_set
+	},
+	[REGSET_TM_CVMX] = {
+		.core_note_type = NT_PPC_TM_CVMX, .n = ELF_NVMX,
+		.size = sizeof(vector128), .align = sizeof(vector128),
+		.active = tm_cvmx_active, .get = tm_cvmx_get, .set = tm_cvmx_set
+	},
+#endif
 };
 
 static const struct user_regset_view user_ppc_compat_view = {
-- 
1.9.3

^ permalink raw reply related

* [PATCH V7 6/8] powerpc, ptrace: Enable support for miscellaneous debug registers
From: Anshuman Khandual @ 2015-01-14  7:08 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev
  Cc: shuahkh, mikey, james.hogan, avagin, Paul.Clothier, peterz,
	palves, oleg, davem, dhowells, kirjanov, davej, akpm, sukadev,
	tglx, sam.bobroff
In-Reply-To: <1421219330-19984-1-git-send-email-khandual@linux.vnet.ibm.com>

This patch enables get and set of miscellaneous debug registers through
ptrace PTRACE_GETREGSET-PTRACE_SETREGSET interface by implementing new
powerpc specific register set REGSET_MISC support corresponding to the
new ELF core note NT_PPC_MISC added previously in this regard.

Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
 arch/powerpc/include/uapi/asm/elf.h |   1 +
 arch/powerpc/kernel/ptrace.c        | 133 ++++++++++++++++++++++++++++++++++++
 2 files changed, 134 insertions(+)

diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h
index fdc8e2f..a41bd98 100644
--- a/arch/powerpc/include/uapi/asm/elf.h
+++ b/arch/powerpc/include/uapi/asm/elf.h
@@ -93,6 +93,7 @@
 #define ELF_NFPREG	33	/* includes fpscr */
 #define ELF_NVMX	34	/* includes all vector registers */
 #define ELF_NTMSPRREG	7	/* includes TM sprs, org_msr, dscr, tar, ppr */
+#define ELF_NMISCREG	3	/* includes dscr, tar, ppr */
 
 typedef unsigned long elf_greg_t64;
 typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG];
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index b14397c..38a1147 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1371,6 +1371,122 @@ static int tm_cvmx_set(struct task_struct *target,
 }
 #endif	/* CONFIG_PPC_TRANSACTIONAL_MEM */
 
+#ifdef CONFIG_PPC64
+/**
+ * get_misc_dbg() - get MISC debug registers
+ * @target:	The target task.
+ * @regset:	The user regset structure.
+ * @pos:	The buffer position.
+ * @count:	Number of bytes to copy.
+ * @kbuf:	Kernel buffer to copy from.
+ * @ubuf:	User buffer to copy into.
+ *
+ * This function gets various miscellaneous debug registers which includes
+ * DSCR, PPR and TAR. The userspace intarface buffer layout is as follows.
+ *
+ * struct {
+ *	unsigned long dscr;
+ *	unsigned long ppr;
+ *	unsigned long tar;
+ * };
+ *
+ * The data element 'tar' in the structure will be valid only if the kernel
+ * has CONFIG_PPC_BOOK3S_64 config option enabled.
+ */
+static int get_misc_dbg(struct task_struct *target,
+			const struct user_regset *regset, unsigned int pos,
+			unsigned int count, void *kbuf, void __user *ubuf)
+{
+	int ret;
+
+	/* Build test */
+	BUILD_BUG_ON(TSO(dscr) + 2 * sizeof(unsigned long) != TSO(ppr));
+
+#ifdef CONFIG_PPC_BOOK3S_64
+	BUILD_BUG_ON(TSO(ppr) + sizeof(unsigned long) != TSO(tar));
+#endif
+
+	/* DSCR register */
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					&target->thread.dscr, 0,
+					sizeof(unsigned long));
+
+	/* PPR register */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+						&target->thread.ppr,
+						sizeof(unsigned long),
+						2 * sizeof(unsigned long));
+
+#ifdef CONFIG_PPC_BOOK3S_64
+	/* TAR register */
+	if (!ret)
+		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+						&target->thread.tar,
+						2 * sizeof(unsigned long),
+						3 * sizeof(unsigned long));
+#endif
+	return ret;
+}
+
+/**
+ * set_misc_dbg() - set MISC debug registers
+ * @target:	The target task.
+ * @regset:	The user regset structure.
+ * @pos:	The buffer position.
+ * @count:	Number of bytes to copy.
+ * @kbuf:	Kernel buffer to copy into.
+ * @ubuf:	User buffer to copy from.
+ *
+ * This function sets various miscellaneous debug registers which includes
+ * DSCR, PPR and TAR. The userspace intarface buffer layout is as follows.
+ *
+ * struct {
+ *	unsigned long dscr;
+ *	unsigned long ppr;
+ *	unsigned long tar;
+ * };
+ *
+ * The data element 'tar' in the structure will be valid only if the kernel
+ * has CONFIG_PPC_BOOK3S_64 config option enabled.
+ */
+static int set_misc_dbg(struct task_struct *target,
+			const struct user_regset *regset, unsigned int pos,
+			unsigned int count, const void *kbuf,
+			const void __user *ubuf)
+{
+	int ret;
+
+	/* Build test */
+	BUILD_BUG_ON(TSO(dscr) + 2 * sizeof(unsigned long) != TSO(ppr));
+
+#ifdef CONFIG_PPC_BOOK3S_64
+	BUILD_BUG_ON(TSO(ppr) + sizeof(unsigned long) != TSO(tar));
+#endif
+
+	/* DSCR register */
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					&target->thread.dscr, 0,
+					sizeof(unsigned long));
+
+	/* PPR register */
+	if (!ret)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+						&target->thread.ppr,
+						sizeof(unsigned long),
+						2 * sizeof(unsigned long));
+#ifdef CONFIG_PPC_BOOK3S_64
+	/* TAR register */
+	if (!ret)
+		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+						&target->thread.tar,
+						2 * sizeof(unsigned long),
+						3 * sizeof(unsigned long));
+#endif
+	return ret;
+}
+#endif /* CONFIG_PPC64 */
+
 /*
  * These are our native regset flavors.
  */
@@ -1392,6 +1508,9 @@ enum powerpc_regset {
 	REGSET_TM_CFPR,		/* TM checkpointed FPR registers */
 	REGSET_TM_CVMX,		/* TM checkpointed VMX registers */
 #endif
+#ifdef CONFIG_PPC64
+	REGSET_MISC		/* Miscellaneous debug registers */
+#endif
 };
 
 static const struct user_regset native_regsets[] = {
@@ -1448,6 +1567,13 @@ static const struct user_regset native_regsets[] = {
 		.active = tm_cvmx_active, .get = tm_cvmx_get, .set = tm_cvmx_set
 	},
 #endif
+#ifdef CONFIG_PPC64
+	[REGSET_MISC] = {
+		.core_note_type = NT_PPC_MISC, .n = ELF_NMISCREG,
+		.size = sizeof(u64), .align = sizeof(u64),
+		.get = get_misc_dbg, .set = set_misc_dbg
+	},
+#endif
 };
 
 static const struct user_regset_view user_ppc_native_view = {
@@ -1694,6 +1820,13 @@ static const struct user_regset compat_regsets[] = {
 		.active = tm_cvmx_active, .get = tm_cvmx_get, .set = tm_cvmx_set
 	},
 #endif
+#ifdef CONFIG_PPC64
+	[REGSET_MISC] = {
+		.core_note_type = NT_PPC_MISC, .n = ELF_NMISCREG,
+		.size = sizeof(u64), .align = sizeof(u64),
+		.get = get_misc_dbg, .set = set_misc_dbg
+	},
+#endif
 };
 
 static const struct user_regset_view user_ppc_compat_view = {
-- 
1.9.3

^ permalink raw reply related

* [PATCH V7 7/8] selftests, powerpc: Add test case for TM related ptrace interface
From: Anshuman Khandual @ 2015-01-14  7:08 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev
  Cc: shuahkh, mikey, james.hogan, avagin, Paul.Clothier, peterz,
	palves, oleg, davem, dhowells, kirjanov, davej, akpm, sukadev,
	tglx, sam.bobroff
In-Reply-To: <1421219330-19984-1-git-send-email-khandual@linux.vnet.ibm.com>

This patch adds one more test case called 'tm-ptrace' targeting TM
related ptrace interface. This test creates one child process to
run some basic TM transactions and the parent process attaches the
child to do some ptrace probing using the recently added regset
interfaces. The parent process then compares the received values
against the expected values to verify whether it has passed the
given test or not.

Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
 tools/testing/selftests/powerpc/tm/Makefile    |   2 +-
 tools/testing/selftests/powerpc/tm/tm-ptrace.c | 542 +++++++++++++++++++++++++
 2 files changed, 543 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/powerpc/tm/tm-ptrace.c

diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile
index 2cede23..71d400a 100644
--- a/tools/testing/selftests/powerpc/tm/Makefile
+++ b/tools/testing/selftests/powerpc/tm/Makefile
@@ -1,4 +1,4 @@
-PROGS := tm-resched-dscr
+PROGS := tm-resched-dscr tm-ptrace
 
 all: $(PROGS)
 
diff --git a/tools/testing/selftests/powerpc/tm/tm-ptrace.c b/tools/testing/selftests/powerpc/tm/tm-ptrace.c
new file mode 100644
index 0000000..7a6c7d3
--- /dev/null
+++ b/tools/testing/selftests/powerpc/tm/tm-ptrace.c
@@ -0,0 +1,542 @@
+/*
+ * Test program for TM ptrace interface
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Copyright 2014 IBM Corporation
+ *
+ * Author: Anshuman Khandual <khandual@linux.vnet.ibm.com>
+ */
+#include <inttypes.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include <errno.h>
+#include <sys/ptrace.h>
+#include <sys/uio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/signal.h>
+#include <sys/user.h>
+#include <linux/elf.h>
+#include <linux/types.h>
+
+#include "utils.h"
+
+#define TEST_PASS 0
+#define TEST_FAIL 1
+
+#define MAX_STR_LENGTH 100
+
+/* ELF core notes */
+#define NT_PPC_TM_SPR  0x103	/* PowerPC TM special registers */
+#define NT_PPC_TM_CGPR 0x104	/* PowerpC TM checkpointed GPR */
+#define NT_PPC_TM_CFPR 0x105	/* PowerPC TM checkpointed FPR */
+#define NT_PPC_TM_CVMX 0x106	/* PowerPC TM checkpointed VMX */
+#define NT_PPC_MISC    0x107	/* PowerPC miscellaneous registers */
+
+/* TM instructions */
+#define TBEGIN		".long 0x7C00051D ;"
+#define TEND		".long 0x7C00055D ;"
+
+/* SPR number */
+#define SPRN_DSCR	3
+#define SPRN_TAR	815
+#define SPRN_PPR	896
+
+#define C_DSCR	10		/* TM checkpointed DSCR */
+#define C_TAR	20		/* TM checkpointed TAR */
+#define C_PPR	0x8000000000000	/* TM checkpointed PPR */
+
+#define DSCR	50		/* TM running DSCR */
+#define TAR	60		/* TM running TAR */
+#define PPR	0x4000000000000	/* TM running PPR */
+
+/* Values for GPR-FPR[0..31] */
+#define VAL0	0
+#define VAL1	1
+#define VAL2	2
+#define VAL3	3
+#define VAL4	4
+#define VAL5	5
+#define VAL6	6
+#define VAL7	7
+#define VAL8	8
+#define VAL9	9
+#define VAL10	10
+#define VAL11	11
+#define VAL12	12
+#define VAL13	13
+#define VAL14	14
+#define VAL15	15
+#define VAL_MAX	16
+
+/* Standard data types */
+typedef unsigned int u32;
+typedef __vector128 vector128;
+
+/* NT_PPC_TM_SPR buffer layout */
+struct tm_spr_regs {
+	u64	tm_tfhar;
+	u64	tm_texasr;
+	u64	tm_tfiar;
+	u64	tm_orig_msr;
+	u64	tm_tar;
+	u64	tm_ppr;
+	u64	tm_dscr;
+};
+
+/*
+ * NT_PPC_TM_CGPR buffer layout
+ *
+ * Same as that of struct pt_regs
+ */
+
+/* NT_PPC_TM_CFPR buffer layout */
+struct tm_cfpr {
+	u64	fpr[32];
+	u64	fpscr;
+};
+
+/* NT_PPC_TM_CVMX buffer layout */
+struct tm_cvmx {
+	vector128	vr[32] __attribute__((aligned(16)));
+	vector128	vscr __attribute__((aligned(16)));
+	u32		vrsave;
+};
+
+/* NT_PPC_MISC buffer layout */
+struct misc_regs {
+	u64	dscr;
+	u64	ppr;
+	u64	tar;
+};
+
+/*
+ * do_tm_transaction
+ *
+ * This functions sets the values for TAR, DSCR, PPR, GPR[0..31],
+ * FPR[0..31] registers before starting the trasanction which will
+ * enable the kernel to save them as checkpointed values. Then it
+ * starts the transaction where it loads a different set of values
+ * into the same registers again thus enabling the kernel to save
+ * them off as running values for this transaction. Then the function
+ * gets stuck forcing the process to loop at one single instruction.
+ * The transaction never finishes, thus giving the parent process
+ * the opportunity to trace the running and checkpointed values of
+ * various registers.
+ */
+void do_tm_transaction(void)
+{
+	asm __volatile__(
+		/* TM checkpointed values */
+
+		/* SPR */
+		"li 0, %[c_tar];"	/* TAR */
+		"mtspr %[sprn_tar], 0;"
+		"li 0, %[c_dscr];"	/* DSCR */
+		"mtspr %[sprn_dscr], 0;"
+		"or	1,1,1;"		/* PPR (0x8000000000000) */
+
+		/* GPR[0..31] */
+		"li 0, %[val0];"	/* GPR[0] */
+		"li 1, %[val1];"	/* GPR[1] */
+		"li 2, %[val2];"	/* GPR[2] */
+		"li 3, %[val3];"	/* GPR[3] */
+		"li 4, %[val4];"	/* GPR[4] */
+		"li 5, %[val5];"	/* GPR[5] */
+		"li 6, %[val6];"	/* GPR[6] */
+		"li 7, %[val7];"	/* GPR[7] */
+		"li 8, %[val8];"	/* GPR[8] */
+		"li 9, %[val9];"	/* GPR[9] */
+		"li 10, %[val10];"	/* GPR[10] */
+		"li 11, %[val11];"	/* GPR[11] */
+		"li 12, %[val12];"	/* GPR[12] */
+		"li 13, %[val13];"	/* GPR[13] */
+		"li 14, %[val14];"	/* GPR[14] */
+		"li 15, %[val15];"	/* GPR[15] */
+		"li 16, %[val0];"	/* GPR[16] */
+		"li 17, %[val1];"	/* GPR[17] */
+		"li 18, %[val2];"	/* GPR[18] */
+		"li 19, %[val3];"	/* GPR[19] */
+		"li 20, %[val4];"	/* GPR[20] */
+		"li 21, %[val5];"	/* GPR[21] */
+		"li 22, %[val6];"	/* GPR[22] */
+		"li 23, %[val7];"	/* GPR[23] */
+		"li 24, %[val8];"	/* GPR[24] */
+		"li 25, %[val9];"	/* GPR[25] */
+		"li 26, %[val10];"	/* GPR[26] */
+		"li 27, %[val11];"	/* GPR[27] */
+		"li 28, %[val12];"	/* GPR[28] */
+		"li 29, %[val13];"	/* GPR[29] */
+		"li 30, %[val14];"	/* GPR[30] */
+		"li 31, %[val15];"	/* GPR[31] */
+
+		/* FPR[0..31] */
+		".long 0x7C000166;"	/* GPR[0] --> FPR[0] */
+		".long 0x7C210166;"	/* GPR[1] --> FPR[1] */
+		".long 0x7C420166;"	/* GPR[0] --> FPR[2] */
+		".long 0x7C630166;"	/* GPR[3] --> FPR[3] */
+		".long 0x7C840166;"	/* GPR[4] --> FPR[4] */
+		".long 0x7CA50166;"	/* GPR[5] --> FPR[5] */
+		".long 0x7CC60166;"	/* GPR[6] --> FPR[6] */
+		".long 0x7CE70166;"	/* GPR[7] --> FPR[7] */
+		".long 0x7D080166;"	/* GPR[8] --> FPR[8] */
+		".long 0x7D290166;"	/* GPR[9] --> FPR[9] */
+		".long 0x7d4a0166;"	/* GPR[10] --> FPR[10] */
+		".long 0x7d6b0166;"	/* GPR[11] --> FPR[11] */
+		".long 0x7d8c0166;"	/* GPR[12] --> FPR[12] */
+		".long 0x7dad0166;"	/* GPR[13] --> FPR[13] */
+		".long 0x7dce0166;"	/* GPR[14] --> FPR[14] */
+		".long 0x7def0166;"	/* GPR[15] --> FPR[15] */
+		".long 0x7e100166;"	/* GPR[16] --> FPR[16] */
+		".long 0x7e310166;"	/* GPR[17] --> FPR[17] */
+		".long 0x7e520166;"	/* GPR[18] --> FPR[18] */
+		".long 0x7e730166;"	/* GPR[19] --> FPR[19] */
+		".long 0x7e940166;"	/* GPR[20] --> FPR[20] */
+		".long 0x7eb50166;"	/* GPR[21] --> FPR[21] */
+		".long 0x7ed60166;"	/* GPR[22] --> FPR[22] */
+		".long 0x7ef70166;"	/* GPR[23] --> FPR[23] */
+		".long 0x7f180166;"	/* GPR[24] --> FPR[24] */
+		".long 0x7f390166;"	/* GPR[25] --> FPR[25] */
+		".long 0x7f5a0166;"	/* GPR[26] --> FPR[26] */
+		".long 0x7f7b0166;"	/* GPR[27] --> FPR[27] */
+		".long 0x7f9c0166;"	/* GPR[28] --> FPR[28] */
+		".long 0x7fbd0166;"	/* GPR[29] --> FPR[29] */
+		".long 0x7fde0166;"	/* GPR[30] --> FPR[30] */
+		".long 0x7fff0166;"	/* GPR[31] --> FPR[31] */
+
+		/* TM running values */
+
+		"1: ;"
+		TBEGIN
+		"beq 2f;"
+
+		/* SPR */
+		"li 0, %[tar];"		/* TAR */
+		"mtspr %[sprn_tar], 0;"
+		"li 0, %[dscr];"	/* DSCR */
+		"mtspr %[sprn_dscr], 0;"
+		"or	31,31,31;"	/* PPR (0x4000000000000) */
+
+		/* GPR[0..31] */
+		"li 0, %[val15];"	/* GPR[0] */
+		"li 1, %[val14];"	/* GPR[1] */
+		"li 2, %[val13];"	/* GPR[2] */
+		"li 3, %[val12];"	/* GPR[3] */
+		"li 4, %[val11];"	/* GPR[4] */
+		"li 5, %[val10];"	/* GPR[5] */
+		"li 6, %[val9];"	/* GPR[6] */
+		"li 7, %[val8];"	/* GPR[7] */
+		"li 8, %[val7];"	/* GPR[8] */
+		"li 9, %[val6];"	/* GPR[9] */
+		"li 10, %[val5];"	/* GPR[10] */
+		"li 11, %[val4];"	/* GPR[11] */
+		"li 12, %[val3];"	/* GPR[12] */
+		"li 13, %[val2];"	/* GPR[13] */
+		"li 14, %[val1];"	/* GPR[14] */
+		"li 15, %[val0];"	/* GPR[15] */
+		"li 16, %[val15];"	/* GPR[16] */
+		"li 17, %[val14];"	/* GPR[17] */
+		"li 18, %[val13];"	/* GPR[18] */
+		"li 19, %[val12];"	/* GPR[19] */
+		"li 20, %[val11];"	/* GPR[20] */
+		"li 21, %[val10];"	/* GPR[21] */
+		"li 22, %[val9];"	/* GPR[22] */
+		"li 23, %[val8];"	/* GPR[23] */
+		"li 24, %[val7];"	/* GPR[24] */
+		"li 25, %[val6];"	/* GPR[25] */
+		"li 26, %[val5];"	/* GPR[26] */
+		"li 27, %[val4];"	/* GPR[27] */
+		"li 28, %[val3];"	/* GPR[28] */
+		"li 29, %[val2];"	/* GPR[29] */
+		"li 30, %[val1];"	/* GPR[30] */
+		"li 31, %[val0];"	/* GPR[31] */
+
+		/* FPR[0..31] */
+		".long 0x7C000166;"	/* GPR[0] --> FPR[0] */
+		".long 0x7C210166;"	/* GPR[1] --> FPR[1] */
+		".long 0x7C420166;"	/* GPR[2] --> FPR[2] */
+		".long 0x7C630166;"	/* GPR[3] --> FPR[3] */
+		".long 0x7C840166;"	/* GPR[4] --> FPR[4] */
+		".long 0x7CA50166;"	/* GPR[5] --> FPR[5] */
+		".long 0x7CC60166;"	/* GPR[6] --> FPR[6] */
+		".long 0x7CE70166;"	/* GPR[7] --> FPR[7] */
+		".long 0x7D080166;"	/* GPR[8] --> FPR[8] */
+		".long 0x7D290166;"	/* GPR[9] --> FPR[9] */
+		".long 0x7d4a0166;"	/* GPR[10] --> FPR[10] */
+		".long 0x7d6b0166;"	/* GPR[11] --> FPR[11] */
+		".long 0x7d8c0166;"	/* GPR[12] --> FPR[12] */
+		".long 0x7dad0166;"	/* GPR[13] --> FPR[13] */
+		".long 0x7dce0166;"	/* GPR[14] --> FPR[14] */
+		".long 0x7def0166;"	/* GPR[15] --> FPR[15] */
+		".long 0x7e100166;"	/* GPR[16] --> FPR[16] */
+		".long 0x7e310166;"	/* GPR[17] --> FPR[17] */
+		".long 0x7e520166;"	/* GPR[18] --> FPR[18] */
+		".long 0x7e730166;"	/* GPR[19] --> FPR[19] */
+		".long 0x7e940166;"	/* GPR[20] --> FPR[20] */
+		".long 0x7eb50166;"	/* GPR[21] --> FPR[21] */
+		".long 0x7ed60166;"	/* GPR[22] --> FPR[22] */
+		".long 0x7ef70166;"	/* GPR[23] --> FPR[23] */
+		".long 0x7f180166;"	/* GPR[24] --> FPR[24] */
+		".long 0x7f390166;"	/* GPR[25] --> FPR[25] */
+		".long 0x7f5a0166;"	/* GPR[26] --> FPR[26] */
+		".long 0x7f7b0166;"	/* GPR[27] --> FPR[27] */
+		".long 0x7f9c0166;"	/* GPR[28] --> FPR[28] */
+		".long 0x7fbd0166;"	/* GPR[29] --> FPR[29] */
+		".long 0x7fde0166;"	/* GPR[30] --> FPR[30] */
+		".long 0x7fff0166;"	/* GPR[31] --> FPR[31] */
+
+		"b .;"			/* Get stuck here */
+		TEND
+
+		/* Transaction abort handler */
+		"2: ;"
+		"b 1b;"			/* Start from TBEGIN */
+
+		:: [sprn_dscr]"i"(SPRN_DSCR), [sprn_tar]"i"(SPRN_TAR),
+		[sprn_ppr]"i"(SPRN_PPR), [val0]"i"(VAL0),
+		[val1]"i"(VAL1), [val2]"i"(VAL2), [val3]"i"(VAL3),
+		[val4]"i"(VAL4), [val5]"i"(VAL5), [val6]"i"(VAL6),
+		[val7]"i"(VAL7), [val8]"i"(VAL8), [val9]"i"(VAL9),
+		[val10]"i"(VAL10), [val11]"i"(VAL11), [val12]"i"(VAL12),
+		[val13]"i"(VAL13), [val14]"i"(VAL14), [val15]"i"(VAL15),
+		[c_tar]"i"(C_TAR), [c_dscr]"i"(C_DSCR), [tar]"i"(TAR),
+		[dscr]"i"(DSCR), [ppr]"i"(PPR), [c_ppr]"i"(C_PPR)
+		: "memory", "r7");
+}
+
+void test_result(const u64 variable, const u64 value, const char *str)
+{
+	if (variable == value)
+		printf("%s: %llx (PASSED)\n", str, variable);
+	else
+		printf("%s: %llx (FAILED)\n", str, variable);
+}
+
+int trace_tm_transaction(pid_t child)
+{
+	struct tm_spr_regs *tmspr;
+	struct pt_regs *cregs, *regs;
+	struct tm_cfpr *cfpr, *fpr;
+	struct misc_regs *mregs;
+	struct iovec iov;
+	char str[MAX_STR_LENGTH];
+	int ret, i, j;
+
+	regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
+	fpr = (struct tm_cfpr *) malloc(sizeof(struct tm_cfpr));
+
+	/* Wait till the tracee hits "b ." instruction */
+	sleep(3);
+
+	ret = ptrace(PTRACE_ATTACH, child, NULL, NULL);
+	if (ret) {
+		printf("ptrace(PTRACE_ATTACH) Failed: %s\n", strerror(errno));
+		return TEST_FAIL;
+	}
+
+	ret = waitpid(child, NULL, 0);
+	if (ret != child) {
+		printf("PID mismatch: %s\n", strerror(errno));
+		return TEST_FAIL;
+	}
+
+	/* TM specific SPR */
+	printf("Testing TM specific SPR:\n");
+	iov.iov_base = (struct tm_spr_regs *)
+				malloc(sizeof(struct tm_spr_regs));
+	iov.iov_len = sizeof(struct tm_spr_regs);
+	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_SPR, &iov);
+	if (ret) {
+		printf("ptrace(NT_PPC_TM_SPR) Failed: %s\n", strerror(errno));
+		return TEST_FAIL;
+	}
+
+	if (iov.iov_len != sizeof(struct tm_spr_regs)) {
+		printf("ptrace(NT_PPC_TM_SPR): Returned wrong length\n");
+		return TEST_FAIL;
+	}
+
+	tmspr = iov.iov_base;
+
+	printf("TFHAR: %llx\n", tmspr->tm_tfhar);
+	printf("TEXASR: %llx\n", tmspr->tm_texasr);
+	printf("TFIAR: %llx\n", tmspr->tm_tfiar);
+	printf("TM ORIG_MSR: %llx\n", tmspr->tm_orig_msr);
+
+	test_result(tmspr->tm_dscr, C_DSCR, "TM CH DSCR");
+	test_result(tmspr->tm_tar, C_TAR, "TM CH TAR");
+	test_result(tmspr->tm_ppr, C_PPR, "TM CH PPR");
+
+	/* TM checkpointed GPR */
+	printf("Testing TM checkpointed GPR:\n");
+	iov.iov_base = (struct pt_regs *) malloc(sizeof(struct pt_regs));
+	iov.iov_len = sizeof(struct pt_regs);
+	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
+	if (ret) {
+		printf("ptrace(NT_PPC_TM_CGPR) Failed: %s\n", strerror(errno));
+		return TEST_FAIL;
+	}
+
+	if (iov.iov_len != sizeof(struct pt_regs)) {
+		printf("ptrace(NT_PPC_TM_CGPR): Returned wrong length\n");
+		return TEST_FAIL;
+	}
+
+	cregs = iov.iov_base;
+
+	printf("TM CH NIP: %lx\n", cregs->nip);
+	printf("TM CH LINK: %lx\n", cregs->link);
+	printf("TM CH CCR: %lx\n", cregs->ccr);
+
+	for (i = 0; i < VAL_MAX; i++) {
+		sprintf(str, "TM CH GPR[%d]", i);
+		test_result(cregs->gpr[i], i, str);
+	}
+
+	for (j = 0; i < VAL_MAX * 2; j++, i++) {
+		sprintf(str, "TM CH GPR[%d]", i);
+		test_result(cregs->gpr[i], j, str);
+	}
+
+	/* TM checkpointed FPR */
+	printf("Testing TM checkpointed FPR:\n");
+	iov.iov_base = (struct tm_cfpr *) malloc(sizeof(struct tm_cfpr));
+	iov.iov_len = sizeof(struct tm_cfpr);
+	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
+	if (ret) {
+		printf("ptrace(NT_PPC_TM_CFPR) Failed: %s\n", strerror(errno));
+		return TEST_FAIL;
+	}
+
+	if (iov.iov_len != sizeof(struct tm_cfpr)) {
+		printf("ptrace(NT_PPC_TM_CFPR): Returned wrong length\n");
+		return TEST_FAIL;
+	}
+
+	cfpr = iov.iov_base;
+	printf("TM CH FPSCR: %llx\n", cfpr->fpscr);
+
+	for (i = 0; i < VAL_MAX; i++) {
+		sprintf(str, "TM CH FPR[%d]", i);
+		test_result(cfpr->fpr[i], i, str);
+	}
+
+	for (j = 0; i < VAL_MAX * 2; j++, i++) {
+		sprintf(str, "TM CH FPR[%d]", i);
+		test_result(cfpr->fpr[i], j, str);
+	}
+
+	/* TM running GPR */
+	printf("Testing TM running GPR:\n");
+	ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
+	if (ret) {
+		printf("ptrace(PTRACE_GETREGS) Failed: %s\n", strerror(errno));
+		return TEST_FAIL;
+	}
+
+	printf("TM RN NIP: %lx\n", regs->nip);
+	printf("TM RN LINK: %lx\n", regs->link);
+	printf("TM RN CCR: %lx\n", regs->ccr);
+
+	for (i = 0, j = VAL_MAX - 1; i < VAL_MAX; i++, j--) {
+		sprintf(str, "TM RN GPR[%d]", i);
+		test_result(regs->gpr[i], j, str);
+	}
+
+	for (j = VAL_MAX - 1 ; i < VAL_MAX * 2; i++, j--) {
+		sprintf(str, "TM RN GPR[%d]", i);
+		test_result(regs->gpr[i], j, str);
+	}
+
+	/* TM running FPR */
+	printf("Testing TM running FPR:\n");
+	ret = ptrace(PTRACE_GETFPREGS, child, NULL, fpr);
+	if (ret) {
+		printf("ptrace(PTRACE_GETFPREGS) Failed: %s\n",
+							strerror(errno));
+		return TEST_FAIL;
+	}
+
+	printf("TM RN FPSCR: %llx\n", fpr->fpscr);
+
+	for (i = 0, j = VAL_MAX - 1; i < VAL_MAX; i++, j--) {
+		sprintf(str, "TM RN FPR[%d]", i);
+		test_result(fpr->fpr[i], j, str);
+	}
+
+	for (j = VAL_MAX - 1; i < VAL_MAX * 2; i++, j--) {
+		sprintf(str, "TM RN FPR[%d]", i);
+		test_result(fpr->fpr[i], j, str);
+	}
+
+	/* TM running MISC debug registers */
+	printf("Testing TM running MISC debug registers:\n");
+	iov.iov_base = (struct misc_regs *) malloc(sizeof(struct misc_regs));
+	iov.iov_len = sizeof(struct misc_regs);
+	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_MISC, &iov);
+	if (ret) {
+		printf("ptrace(NT_PPC_MISC): Failed: %s\n", strerror(errno));
+		return TEST_FAIL;
+	}
+
+	if (iov.iov_len != sizeof(struct misc_regs)) {
+		printf("ptrace(NT_PPC_TM_MISC): Returned wrong length\n");
+		return TEST_FAIL;
+	}
+
+	mregs = iov.iov_base;
+	test_result(mregs->dscr, DSCR, "TM RN DSCR");
+	test_result(mregs->tar, TAR, "TM RN TAR");
+	test_result(mregs->ppr, PPR, "TM RN PPR");
+
+	ret = ptrace(PTRACE_DETACH, child, NULL, NULL);
+	if (ret) {
+		printf("ptrace(PTRACE_DETACH) Failed: %s\n", strerror(errno));
+		return 1;
+	}
+
+	if (kill(child, SIGTERM)) {
+		printf("kill() Failed\n");
+		return TEST_FAIL;
+	}
+
+	ret = waitpid(child, NULL, 0);
+	if (ret != child) {
+		printf("PID mismatch: %s\n", strerror(errno));
+		return TEST_FAIL;
+	}
+	return TEST_PASS;
+}
+
+int tm_ptrace_test(void)
+{
+	pid_t child;
+
+	printf("===Testing TM based PTRACE Interface===\n");
+	fflush(stdout);
+	child = fork();
+	if (child < 0) {
+		printf("fork() Failed: %s\n", strerror(errno));
+		return TEST_FAIL;
+	}
+
+	/* Child to run the transaction */
+	if (child == 0)
+		do_tm_transaction();
+
+	/* Parent to trace the child */
+	if (child)
+		trace_tm_transaction(child);
+	return TEST_PASS;
+}
+
+int main(void)
+{
+	return test_harness(tm_ptrace_test, "tm_ptrace");
+}
-- 
1.9.3

^ permalink raw reply related

* [PATCH V7 8/8] selftests: Make GIT ignore all binaries in powerpc test suite
From: Anshuman Khandual @ 2015-01-14  7:08 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev
  Cc: shuahkh, mikey, james.hogan, avagin, Paul.Clothier, peterz,
	palves, oleg, davem, dhowells, kirjanov, davej, akpm, sukadev,
	tglx, sam.bobroff
In-Reply-To: <1421219330-19984-1-git-send-email-khandual@linux.vnet.ibm.com>

This patch includes all of the powerpc test binaries into the
.gitignore file listing in their respective directories. This
will make sure that GIT ignores all of these test binaries while
displaying status.

Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
NOTE: As Michael had mentioned (https://lkml.org/lkml/2015/1/13/868)
adding binaries into different .gitignore file in their respective
test directories under powerpc.

 .../testing/selftests/powerpc/copyloops/.gitignore |  4 ++++
 tools/testing/selftests/powerpc/mm/.gitignore      |  1 +
 tools/testing/selftests/powerpc/pmu/.gitignore     |  3 +++
 tools/testing/selftests/powerpc/pmu/ebb/.gitignore | 22 ++++++++++++++++++++++
 .../selftests/powerpc/primitives/.gitignore        |  1 +
 tools/testing/selftests/powerpc/tm/.gitignore      |  2 ++
 6 files changed, 33 insertions(+)
 create mode 100644 tools/testing/selftests/powerpc/copyloops/.gitignore
 create mode 100644 tools/testing/selftests/powerpc/mm/.gitignore
 create mode 100644 tools/testing/selftests/powerpc/pmu/.gitignore
 create mode 100644 tools/testing/selftests/powerpc/pmu/ebb/.gitignore
 create mode 100644 tools/testing/selftests/powerpc/primitives/.gitignore
 create mode 100644 tools/testing/selftests/powerpc/tm/.gitignore

diff --git a/tools/testing/selftests/powerpc/copyloops/.gitignore b/tools/testing/selftests/powerpc/copyloops/.gitignore
new file mode 100644
index 0000000..25a192f
--- /dev/null
+++ b/tools/testing/selftests/powerpc/copyloops/.gitignore
@@ -0,0 +1,4 @@
+copyuser_64
+copyuser_power7
+memcpy_64
+memcpy_power7
diff --git a/tools/testing/selftests/powerpc/mm/.gitignore b/tools/testing/selftests/powerpc/mm/.gitignore
new file mode 100644
index 0000000..156f4e8
--- /dev/null
+++ b/tools/testing/selftests/powerpc/mm/.gitignore
@@ -0,0 +1 @@
+hugetlb_vs_thp_test
diff --git a/tools/testing/selftests/powerpc/pmu/.gitignore b/tools/testing/selftests/powerpc/pmu/.gitignore
new file mode 100644
index 0000000..e748f33
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/.gitignore
@@ -0,0 +1,3 @@
+count_instructions
+l3_bank_test
+per_event_excludes
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/.gitignore b/tools/testing/selftests/powerpc/pmu/ebb/.gitignore
new file mode 100644
index 0000000..42bddbe
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/ebb/.gitignore
@@ -0,0 +1,22 @@
+reg_access_test
+event_attributes_test
+cycles_test
+cycles_with_freeze_test
+pmc56_overflow_test
+ebb_vs_cpu_event_test
+cpu_event_vs_ebb_test
+cpu_event_pinned_vs_ebb_test
+task_event_vs_ebb_test
+task_event_pinned_vs_ebb_test
+multi_ebb_procs_test
+multi_counter_test
+pmae_handling_test
+close_clears_pmcc_test
+instruction_count_test
+fork_cleanup_test
+ebb_on_child_test
+ebb_on_willing_child_test
+back_to_back_ebbs_test
+lost_exception_test
+no_handler_test
+cycles_with_mmcr2_test
diff --git a/tools/testing/selftests/powerpc/primitives/.gitignore b/tools/testing/selftests/powerpc/primitives/.gitignore
new file mode 100644
index 0000000..4cc4e31
--- /dev/null
+++ b/tools/testing/selftests/powerpc/primitives/.gitignore
@@ -0,0 +1 @@
+load_unaligned_zeropad
diff --git a/tools/testing/selftests/powerpc/tm/.gitignore b/tools/testing/selftests/powerpc/tm/.gitignore
new file mode 100644
index 0000000..71f9f9d
--- /dev/null
+++ b/tools/testing/selftests/powerpc/tm/.gitignore
@@ -0,0 +1,2 @@
+tm-ptrace
+tm-resched-dscr
-- 
1.9.3

^ permalink raw reply related

* [PATCH 3.18 028/150] powerpc/powernv: Switch off MMU before entering nap/sleep/rvwinkle mode
From: Greg Kroah-Hartman @ 2015-01-14  7:21 UTC (permalink / raw)
  To: linux-kernel
  Cc: Shreyas B. Prabhu, Greg Kroah-Hartman, stable, Paul Mackerras,
	linuxppc-dev
In-Reply-To: <20150114072055.842408181@linuxfoundation.org>

3.18-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Paul Mackerras <paulus@samba.org>

commit 8117ac6a6c2fa0f847ff6a21a1f32c8d2c8501d0 upstream.

Currently, when going idle, we set the flag indicating that we are in
nap mode (paca->kvm_hstate.hwthread_state) and then execute the nap
(or sleep or rvwinkle) instruction, all with the MMU on.  This is bad
for two reasons: (a) the architecture specifies that those instructions
must be executed with the MMU off, and in fact with only the SF, HV, ME
and possibly RI bits set, and (b) this introduces a race, because as
soon as we set the flag, another thread can switch the MMU to a guest
context.  If the race is lost, this thread will typically start looping
on relocation-on ISIs at 0xc...4400.

This fixes it by setting the MSR as required by the architecture before
setting the flag or executing the nap/sleep/rvwinkle instruction.

[ shreyas@linux.vnet.ibm.com: Edited to handle LE ]
Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Shreyas B. Prabhu <shreyas@linux.vnet.ibm.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 arch/powerpc/include/asm/reg.h    |    2 ++
 arch/powerpc/kernel/idle_power7.S |   18 +++++++++++++++++-
 2 files changed, 19 insertions(+), 1 deletion(-)

--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -118,8 +118,10 @@
 #define __MSR		(MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF |MSR_HV)
 #ifdef __BIG_ENDIAN__
 #define MSR_		__MSR
+#define MSR_IDLE	(MSR_ME | MSR_SF | MSR_HV)
 #else
 #define MSR_		(__MSR | MSR_LE)
+#define MSR_IDLE	(MSR_ME | MSR_SF | MSR_HV | MSR_LE)
 #endif
 #define MSR_KERNEL	(MSR_ | MSR_64BIT)
 #define MSR_USER32	(MSR_ | MSR_PR | MSR_EE)
--- a/arch/powerpc/kernel/idle_power7.S
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -101,7 +101,23 @@ _GLOBAL(power7_powersave_common)
 	std	r9,_MSR(r1)
 	std	r1,PACAR1(r13)
 
-_GLOBAL(power7_enter_nap_mode)
+	/*
+	 * Go to real mode to do the nap, as required by the architecture.
+	 * Also, we need to be in real mode before setting hwthread_state,
+	 * because as soon as we do that, another thread can switch
+	 * the MMU context to the guest.
+	 */
+	LOAD_REG_IMMEDIATE(r5, MSR_IDLE)
+	li	r6, MSR_RI
+	andc	r6, r9, r6
+	LOAD_REG_ADDR(r7, power7_enter_nap_mode)
+	mtmsrd	r6, 1		/* clear RI before setting SRR0/1 */
+	mtspr	SPRN_SRR0, r7
+	mtspr	SPRN_SRR1, r5
+	rfid
+
+	.globl	power7_enter_nap_mode
+power7_enter_nap_mode:
 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
 	/* Tell KVM we're napping */
 	li	r4,KVM_HWTHREAD_IN_NAP

^ permalink raw reply

* [PATCH 3.14 20/77] powerpc/powernv: Switch off MMU before entering nap/sleep/rvwinkle mode
From: Greg Kroah-Hartman @ 2015-01-14  7:23 UTC (permalink / raw)
  To: linux-kernel
  Cc: Shreyas B. Prabhu, Greg Kroah-Hartman, stable, Paul Mackerras,
	linuxppc-dev
In-Reply-To: <20150114072224.182299947@linuxfoundation.org>

3.14-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Paul Mackerras <paulus@samba.org>

commit 8117ac6a6c2fa0f847ff6a21a1f32c8d2c8501d0 upstream.

Currently, when going idle, we set the flag indicating that we are in
nap mode (paca->kvm_hstate.hwthread_state) and then execute the nap
(or sleep or rvwinkle) instruction, all with the MMU on.  This is bad
for two reasons: (a) the architecture specifies that those instructions
must be executed with the MMU off, and in fact with only the SF, HV, ME
and possibly RI bits set, and (b) this introduces a race, because as
soon as we set the flag, another thread can switch the MMU to a guest
context.  If the race is lost, this thread will typically start looping
on relocation-on ISIs at 0xc...4400.

This fixes it by setting the MSR as required by the architecture before
setting the flag or executing the nap/sleep/rvwinkle instruction.

[ shreyas@linux.vnet.ibm.com: Edited to handle LE ]
Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Shreyas B. Prabhu <shreyas@linux.vnet.ibm.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 arch/powerpc/include/asm/reg.h    |    2 ++
 arch/powerpc/kernel/idle_power7.S |   18 +++++++++++++++++-
 2 files changed, 19 insertions(+), 1 deletion(-)

--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -118,8 +118,10 @@
 #define __MSR		(MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF |MSR_HV)
 #ifdef __BIG_ENDIAN__
 #define MSR_		__MSR
+#define MSR_IDLE	(MSR_ME | MSR_SF | MSR_HV)
 #else
 #define MSR_		(__MSR | MSR_LE)
+#define MSR_IDLE	(MSR_ME | MSR_SF | MSR_HV | MSR_LE)
 #endif
 #define MSR_KERNEL	(MSR_ | MSR_64BIT)
 #define MSR_USER32	(MSR_ | MSR_PR | MSR_EE)
--- a/arch/powerpc/kernel/idle_power7.S
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -84,7 +84,23 @@ _GLOBAL(power7_nap)
 	std	r9,_MSR(r1)
 	std	r1,PACAR1(r13)
 
-_GLOBAL(power7_enter_nap_mode)
+	/*
+	 * Go to real mode to do the nap, as required by the architecture.
+	 * Also, we need to be in real mode before setting hwthread_state,
+	 * because as soon as we do that, another thread can switch
+	 * the MMU context to the guest.
+	 */
+	LOAD_REG_IMMEDIATE(r5, MSR_IDLE)
+	li	r6, MSR_RI
+	andc	r6, r9, r6
+	LOAD_REG_ADDR(r7, power7_enter_nap_mode)
+	mtmsrd	r6, 1		/* clear RI before setting SRR0/1 */
+	mtspr	SPRN_SRR0, r7
+	mtspr	SPRN_SRR1, r5
+	rfid
+
+	.globl	power7_enter_nap_mode
+power7_enter_nap_mode:
 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
 	/* Tell KVM we're napping */
 	li	r4,KVM_HWTHREAD_IN_NAP

^ permalink raw reply

* Re: offlining cpus breakage
From: Shreyas B Prabhu @ 2015-01-14 11:03 UTC (permalink / raw)
  To: Alexey Kardashevskiy, linuxppc-dev@lists.ozlabs.org
  Cc: Preeti U Murthy, Paul Mackerras
In-Reply-To: <54ACFE6D.3070308@ozlabs.ru>



On Wednesday 07 January 2015 03:07 PM, Alexey Kardashevskiy wrote:
> Hi!
> 
> "ppc64_cpu --smt=off" produces multiple error on the latest upstream kernel
> (sha1 bdec419):
> 
> NMI watchdog: BUG: soft lockup - CPU#20 stuck for 23s! [swapper/20:0]
> 
> or
> 
> INFO: rcu_sched detected stalls on CPUs/tasks: { 2 7 8 9 10 11 12 13 14 15
> 16 17 18 19 20 21 22 23 2
> 4 25 26 27 28 29 30 31} (detected by 6, t=2102 jiffies, g=1617, c=1616,
> q=1441)
> 
> and many others, all about lockups
> 
> I did bisecting and found out that reverting these helps:
> 
> 77b54e9f213f76a23736940cf94bcd765fc00f40 powernv/powerpc: Add winkle
> support for offline cpus
> 7cba160ad789a3ad7e68b92bf20eaad6ed171f80 powernv/cpuidle: Redesign idle
> states management
> 8eb8ac89a364305d05ad16be983b7890eb462cc3 powerpc/powernv: Enable Offline
> CPUs to enter deep idle states
> 
> btw reverting just two of them produces a compile error.
> 
> It is pseries_le_defconfig, POWER8 machine:
> timebase        : 512000000
> platform        : PowerNV
> model           : palmetto
> machine         : PowerNV palmetto
> firmware        : OPAL v3
> 
> 

The bug scenario is as follows:

In fastsleep decrementer state is not maintained, thus a cpu entering
fastsleep offloads its timer to a different cpu (lets call this
broadcast cpu). Now in the event that this broadcast cpu is offlined, it
assigns a new cpu with the task to handle broadcasting.

If this new cpu is one of the cpus which had entered fastsleep, its
decrementer will have been in an invalid state. This cpu has been woken
up by a need resched ipi (to take up the task of broadcasting) as
opposed to a broadcast ipi. The decrementer state is fixed only on a
broadcast ipi and not on a need resched ipi. Because of this, its timers
don't fire. Consequently it cannot wake up any cpu relying on broadcast ipi.

This scenario of a cpu that takes up the task of broadcasting being in
fastsleep is a corner case. This almost never happens on machines with
more number of cores. This explains why Alexey was able to hit it easily
on palmetto.

We'll be posting out a fix for this soon.

Thanks,
Shreyas

^ permalink raw reply

* [PATCH] powerpc: powernv: winkle: Restore LPCR with LPCR_PECE1 cleared
From: Shreyas B. Prabhu @ 2015-01-14 11:13 UTC (permalink / raw)
  To: linux-kernel; +Cc: Shreyas B. Prabhu, Paul Mackerras, linuxppc-dev

LPCR_PECE1 bit controls whether decrementer interrupts are allowed to
cause exit from power-saving mode. While waking up from winkle, restoring
LPCR with LPCR_PECE1 set (i.e Decrementer interrupts allowed) can cause
issue in the following scenario:

- All the threads in a core are offlined. The core enters deep winkle.
- Spurious interrupt wakes up a thread in the core. Here LPCR is restored
  with LPCR_PECE1 bit set.
- Since it was a spurious interrupt on a offline thread, the thread clears
  the interrupt and goes back to winkle.
- Here before the thread executes winkle and puts the core into deep winkle,
  if a decrementer interrupt occurs on any of the sibling threads in the core
  that thread wakes up. 
- Since in offline loop we are flushing interrupt only in case of external
  interrupt, the decrementer interrupt does not get flushed. So at this stage
  the thread is stuck in this is loop of waking up at 0x100 due to decrementer
  interrupt, not flushing the interrupt as only external interrupts get flushed,
  entering winkle, waking up at 0x100 again.

Fix this by programming PORE to restore LPCR with LPCR_PECE1 bit 
cleared when waking up from winkle.

Signed-off-by: Shreyas B. Prabhu <shreyas@linux.vnet.ibm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: linuxppc-dev@lists.ozlabs.org
---
This issue is separate from the issue which Alexey has reported. Fix for that is
still pending.

 arch/powerpc/platforms/powernv/setup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index ad0e32e..83067b1 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -298,7 +298,7 @@ int pnv_save_sprs_for_winkle(void)
 	 * all cpus at boot. Get these reg values of current cpu and use the
 	 * same accross all cpus.
 	 */
-	uint64_t lpcr_val = mfspr(SPRN_LPCR);
+	uint64_t lpcr_val = mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1;
 	uint64_t hid0_val = mfspr(SPRN_HID0);
 	uint64_t hid1_val = mfspr(SPRN_HID1);
 	uint64_t hid4_val = mfspr(SPRN_HID4);
-- 
1.9.3

^ permalink raw reply related

* [PATCH] powerpc/mpic: Add DT option to skip readback after EOI
From: Bogdan Purcareata @ 2015-01-14 11:57 UTC (permalink / raw)
  To: benh; +Cc: Scott Wood, linuxppc-dev, linux-kernel, Bogdan Purcareata

The readback is necessary in order to handle PCI posted
writes, or when the MPIC is handling interrupts in a loop
(ppc_md.get_irq). Newer MPIC versions don't require this
readback. Leave the option configurable using a device
tree entry.

This saves a MMIO trap per interrupt.

Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Bogdan Purcareata <bogdan.purcareata@freescale.com>
---
 Documentation/devicetree/bindings/powerpc/fsl/mpic.txt | 13 +++++++++++++
 arch/powerpc/include/asm/mpic.h                        |  2 ++
 arch/powerpc/sysdev/mpic.c                             |  8 +++++++-
 3 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/powerpc/fsl/mpic.txt b/Documentation/devicetree/bindings/powerpc/fsl/mpic.txt
index dc57446..9789094 100644
--- a/Documentation/devicetree/bindings/powerpc/fsl/mpic.txt
+++ b/Documentation/devicetree/bindings/powerpc/fsl/mpic.txt
@@ -77,6 +77,19 @@ PROPERTIES
           in the global feature registers.  If specified, this field will
           override the value read from MPIC_GREG_FEATURE_LAST_SRC.
 
+  - mpic-eoi-no-readback
+      Usage: optional
+      Value type: <empty>
+      Definition: The presence of this property specifies that the
+          MPIC will not issue a readback when delivering the EOI for an
+          external interrupt. The readback operation is done by reading
+          the CPU WHOAMI register after writing to the CPU EOI register.
+          Originally, this was required due to the fact that the MPIC
+          operates at lower frequencies, or in scenarios where the MPIC
+          is connected through PCI with write posting. This is not the
+          case in an emulated environment (e.g. KVM guest), or in scenarios
+          where interrupts are not handled in a loop of get_irq() calls.
+
 INTERRUPT SPECIFIER DEFINITION
 
   Interrupt specifiers consists of 4 cells encoded as
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index 754f93d..e2a4146 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -386,6 +386,8 @@ extern struct bus_type mpic_subsys;
  * from the BRR1 register).
 */
 #define MPIC_FSL_HAS_EIMR		0x00010000
+/* Dont bother with readback after MPIC EOI */
+#define MPIC_EOI_NO_READBACK	0x00020000
 
 /* MPIC HW modification ID */
 #define MPIC_REGSET_MASK		0xf0000000
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index f3e8624..431f68e 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -656,7 +656,9 @@ static inline struct mpic * mpic_from_irq_data(struct irq_data *d)
 static inline void mpic_eoi(struct mpic *mpic)
 {
 	mpic_cpu_write(MPIC_INFO(CPU_EOI), 0);
-	(void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI));
+
+	if (!(mpic->flags & MPIC_EOI_NO_READBACK))
+		(void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI));
 }
 
 /*
@@ -1290,6 +1292,10 @@ struct mpic * __init mpic_alloc(struct device_node *node,
 		flags |= MPIC_SINGLE_DEST_CPU;
 	if (of_device_is_compatible(node, "fsl,mpic"))
 		flags |= MPIC_FSL | MPIC_LARGE_VECTORS;
+	if (of_get_property(node, "mpic-eoi-no-readback", NULL)) {
+		pr_debug("mpic: no readback activated");
+		flags |= MPIC_EOI_NO_READBACK;
+	}
 
 	mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL);
 	if (mpic == NULL)
-- 
2.1.3

^ permalink raw reply related

* [PATCH 1/3] powerpc/pmac: Fix DT refcount imbalance in pmac_pic_probe_oldstyle
From: Geert Uytterhoeven @ 2015-01-14 13:51 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Bryan Wu, Richard Purdie, Jingoo Han,
	Lee Jones
  Cc: devicetree, linuxppc-dev, linux-kernel, Geert Uytterhoeven
In-Reply-To: <1421243519-6257-1-git-send-email-geert+renesas@glider.be>

of_find_node_by_name() calls of_node_put() on its "from" parameter,
which must not be done on "master", as it's still in use, and will be
released manually later.  This may cause a zero kref refcount.
Use of_get_child_by_name() instead to fix this.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: linuxppc-dev@lists.ozlabs.org
---
Compile-tested only
---
 arch/powerpc/platforms/powermac/pic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 4c24bf60d39d2834..90ada1209c118902 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -321,7 +321,7 @@ static void __init pmac_pic_probe_oldstyle(void)
 		max_irqs = max_real_irqs = 64;
 
 		/* We might have a second cascaded heathrow */
-		slave = of_find_node_by_name(master, "mac-io");
+		slave = of_get_child_by_name(master, "mac-io");
 
 		/* Check ordering of master & slave */
 		if (of_device_is_compatible(master, "gatwick")) {
-- 
1.9.1

^ permalink raw reply related

* [patch added to the 3.12 stable tree] powerpc/powernv: Switch off MMU before entering nap/sleep/rvwinkle mode
From: Jiri Slaby @ 2015-01-14 14:40 UTC (permalink / raw)
  To: stable; +Cc: Shreyas B. Prabhu, linuxppc-dev, Paul Mackerras, Jiri Slaby
In-Reply-To: <1421246468-25187-1-git-send-email-jslaby@suse.cz>

From: Paul Mackerras <paulus@samba.org>

This patch has been added to the 3.12 stable tree. If you have any
objections, please let us know.

===============

commit 8117ac6a6c2fa0f847ff6a21a1f32c8d2c8501d0 upstream.

Currently, when going idle, we set the flag indicating that we are in
nap mode (paca->kvm_hstate.hwthread_state) and then execute the nap
(or sleep or rvwinkle) instruction, all with the MMU on.  This is bad
for two reasons: (a) the architecture specifies that those instructions
must be executed with the MMU off, and in fact with only the SF, HV, ME
and possibly RI bits set, and (b) this introduces a race, because as
soon as we set the flag, another thread can switch the MMU to a guest
context.  If the race is lost, this thread will typically start looping
on relocation-on ISIs at 0xc...4400.

This fixes it by setting the MSR as required by the architecture before
setting the flag or executing the nap/sleep/rvwinkle instruction.

[ shreyas@linux.vnet.ibm.com: Edited to handle LE ]
Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Shreyas B. Prabhu <shreyas@linux.vnet.ibm.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 arch/powerpc/include/asm/reg.h    |  1 +
 arch/powerpc/kernel/idle_power7.S | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index cb9c1740cee0..390e09872b77 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -116,6 +116,7 @@
 
 /* Server variant */
 #define MSR_		(MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF |MSR_HV)
+#define MSR_IDLE	(MSR_ME | MSR_SF | MSR_HV)
 #define MSR_KERNEL	(MSR_ | MSR_64BIT)
 #define MSR_USER32	(MSR_ | MSR_PR | MSR_EE)
 #define MSR_USER64	(MSR_USER32 | MSR_64BIT)
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S
index e11863f4e595..df930727f73b 100644
--- a/arch/powerpc/kernel/idle_power7.S
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -84,6 +84,22 @@ _GLOBAL(power7_nap)
 	std	r9,_MSR(r1)
 	std	r1,PACAR1(r13)
 
+	/*
+	 * Go to real mode to do the nap, as required by the architecture.
+	 * Also, we need to be in real mode before setting hwthread_state,
+	 * because as soon as we do that, another thread can switch
+	 * the MMU context to the guest.
+	 */
+	LOAD_REG_IMMEDIATE(r5, MSR_IDLE)
+	li	r6, MSR_RI
+	andc	r6, r9, r6
+	LOAD_REG_ADDR(r7, power7_enter_nap_mode)
+	mtmsrd	r6, 1		/* clear RI before setting SRR0/1 */
+	mtspr	SPRN_SRR0, r7
+	mtspr	SPRN_SRR1, r5
+	rfid
+
+power7_enter_nap_mode:
 #ifdef CONFIG_KVM_BOOK3S_64_HV
 	/* Tell KVM we're napping */
 	li	r4,KVM_HWTHREAD_IN_NAP
-- 
2.2.1

^ permalink raw reply related

* Re: [PATCH] selftests/powerpc: Add .gitignore for powerpc selftests
From: Shuah Khan @ 2015-01-14 17:20 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1421201759.10748.8.camel@ellerman.id.au>

On 01/13/2015 07:15 PM, Michael Ellerman wrote:
> On Tue, 2015-01-13 at 17:16 -0700, Shuah Khan wrote:
>> Please add a commit log.
>  
> What does it need to say?

Explain the change the patch is making. Please see
Documentation/SubmittingPatches for details.

Looks like this patch is no longer needed as I see a new
patch added to the series from Anshuman Khandual.

> 
>> On 01/13/2015 04:49 PM, Michael Ellerman wrote:
>>> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
>>> ---
>>>  .../testing/selftests/powerpc/copyloops/.gitignore |  4 ++++
>>>  tools/testing/selftests/powerpc/mm/.gitignore      |  1 +
>>>  tools/testing/selftests/powerpc/pmu/.gitignore     |  3 +++
>>>  tools/testing/selftests/powerpc/pmu/ebb/.gitignore | 22 ++++++++++++++++++++++
>>>  .../selftests/powerpc/primitives/.gitignore        |  1 +
>>>  tools/testing/selftests/powerpc/tm/.gitignore      |  1 +
>>>  6 files changed, 32 insertions(+)
>>>  create mode 100644 tools/testing/selftests/powerpc/copyloops/.gitignore
>>>  create mode 100644 tools/testing/selftests/powerpc/mm/.gitignore
>>>  create mode 100644 tools/testing/selftests/powerpc/pmu/.gitignore
>>>  create mode 100644 tools/testing/selftests/powerpc/pmu/ebb/.gitignore
>>>  create mode 100644 tools/testing/selftests/powerpc/primitives/.gitignore
>>>  create mode 100644 tools/testing/selftests/powerpc/tm/.gitignore
>>
>> Please create a single .gitignore for all targets right under
>> tools/testing/selftests/powerpc instead of multiple .gitignore
>> files.
> 
> Why? Having separate files makes it less likely we'll get merge conflicts
> between different test subdirectores, it also makes it more likely someone
> adding a test will notice they need to update the .gitignore in the same
> directory.
> 

It is a matter of reducing the number of files. I am fine with creating
one per directory, if that fits in better with powerpc tests.

-- Shuah


-- 
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
shuahkh@osg.samsung.com | (970) 217-8978

^ permalink raw reply

* Re: [PATCH] powerpc/mpic: Add DT option to skip readback after EOI
From: Scott Wood @ 2015-01-14 17:58 UTC (permalink / raw)
  To: Bogdan Purcareata; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1421236622-29366-1-git-send-email-bogdan.purcareata@freescale.com>

On Wed, 2015-01-14 at 11:57 +0000, Bogdan Purcareata wrote:
> The readback is necessary in order to handle PCI posted
> writes,

That is unclear.

>  or when the MPIC is handling interrupts in a loop
> (ppc_md.get_irq).

I'm questioning this one as well -- if reading WHOAMI is sufficient to
sync with the EOI, why wouldn't reading INTACK work as well?

>  Newer MPIC versions don't require this readback. Leave the option
> configurable using a device tree entry.
> 
> This saves a MMIO trap per interrupt.
> 
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> Signed-off-by: Bogdan Purcareata <bogdan.purcareata@freescale.com>

You should note changes (e.g. with a [] note between signoffs) if it
differs from the original...

-Scott

^ permalink raw reply

* Re: [PATCH v3 1/3] powerpc/nvram: move generic code for nvram and pstore
From: Hari Bathini @ 2015-01-14 18:05 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, Mahesh J Salgaonkar
In-Reply-To: <1421209860.10748.10.camel@ellerman.id.au>

[-- Attachment #1: Type: text/plain, Size: 2178 bytes --]

On 01/14/2015 10:01 AM, Michael Ellerman wrote:
> On Wed, 2014-12-24 at 17:28 +0530, Hari Bathini wrote:
>> With minor checks, we can move most of the code for nvram
>> under pseries to a common place to be re-used by other
>> powerpc platforms like powernv. This patch moves such
>> common code to arch/powerpc/kernel/nvram_64.c file.
> As I said in my reply to the previous version:
>
>      ... you need to keep in mind that it is very common for us to build kernels
>      with both POWERNV=y and PSERIES=y.
>      
>      So you need to make sure you're only using CONFIG_PPC_PSERIES to protect things
>      that are optional on pseries. Not things that we *shouldn't* be doing on
>      powernv.

we could as well do away with the PPC_PSERIES flag in a couple of places in
arch/powerpc/kernel/nvram_64.c, but doing that will unnecessarily add
few extra variables for !PPC_PSERIES case.

> Please explain in your commit message how you have dealt with that.
>

Sure. Will update the changelog

> Also, you broke the build for every config that doesn't have
> CONFIG_PPC_PSERIES, all 95 of them. This is pasemi_defconfig for example:

My bad!clobbering_unread_rtas_event should have been static inline
while defining under !PPC_PSERIES

Thanks
Hari

>        LD      arch/powerpc/mm/built-in.o
>      arch/powerpc/mm/init_64.o: In function `clobbering_unread_rtas_event':
>      init_64.c:(.opd+0x48): multiple definition of `clobbering_unread_rtas_event'
>      arch/powerpc/mm/mem.o:mem.c:(.opd+0x90): first defined here
>      arch/powerpc/mm/init_64.o: In function `.clobbering_unread_rtas_event':
>      init_64.c:(.text+0x80): multiple definition of `.clobbering_unread_rtas_event'
>      arch/powerpc/mm/mem.o:mem.c:(.text+0x2c0): first defined here
>        CC      arch/powerpc/kernel/udbg.o
>      /home/kisskb/slave/src/scripts/Makefile.build:336: recipe for target 'arch/powerpc/mm/built-in.o' failed
>      make[2]: *** [arch/powerpc/mm/built-in.o] Error 1
>      /home/kisskb/slave/src/Makefile:938: recipe for target 'arch/powerpc/mm' failed
>      make[1]: *** [arch/powerpc/mm] Error 2
>      make[1]: *** Waiting for unfinished jobs....
>
>
> cheers
>
>


[-- Attachment #2: Type: text/html, Size: 3109 bytes --]

^ permalink raw reply

* Re: [PATCH] powerpc/fsl: Add empty ranges to etsec2 dts files
From: Martin Hicks @ 2015-01-14 18:36 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <1421098314.4961.109.camel@freescale.com>

[-- Attachment #1: Type: text/plain, Size: 1592 bytes --]

Perfect.  I'm glad there's a patch.
mh

On Mon, Jan 12, 2015 at 4:31 PM, Scott Wood <scottwood@freescale.com> wrote:

> On Mon, 2015-01-12 at 10:27 -0500, Martin Hicks wrote:
> >
> > With an earlier change (746c9e9f - Fix PowerPC address parsing hack),
> ethernet
> > has broken on Freescale boards such as the P1022.  All ranges used by the
> > ethernet controllers are also covered by sub-devices that properly
> > declared the used ranges.  The error shown is:
> >
> > fsl-gianfar: probe of soc@ffe00000:ethernet@b0000 failed with error -12
> >
> > Signed-off-by: Martin Hicks <mort@bork.org>
> > ---
> >  arch/powerpc/boot/dts/fsl/pq3-etsec2-0.dtsi |    1 +
> >  arch/powerpc/boot/dts/fsl/pq3-etsec2-1.dtsi |    1 +
> >  arch/powerpc/boot/dts/fsl/pq3-etsec2-2.dtsi |    1 +
> >  3 files changed, 3 insertions(+)
>
> http://patchwork.ozlabs.org/patch/422446/
>
> > diff --git a/arch/powerpc/boot/dts/fsl/pq3-etsec2-0.dtsi
> b/arch/powerpc/boot/dts/fsl/pq3-etsec2-0.dtsi
> > index 1382fec..d1a6c48 100644
> > --- a/arch/powerpc/boot/dts/fsl/pq3-etsec2-0.dtsi
> > +++ b/arch/powerpc/boot/dts/fsl/pq3-etsec2-0.dtsi
> > @@ -43,6 +43,7 @@ mdio@24000 {
> >  ethernet@b0000 {
> >       #address-cells = <1>;
> >       #size-cells = <1>;
> > +     ranges = <>;
>
> The " = <>" is usually omitted for empty properties.
>
> -Scott
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>



-- 
Martin Hicks P.Eng.      |         mort@bork.org
Bork Consulting Inc.     |   +1 (613) 266-2296

[-- Attachment #2: Type: text/html, Size: 2716 bytes --]

^ permalink raw reply

* Re: [PATCH 1/2] MAINTAINERS: ibmvscsi driver maintainer change
From: Nathan Fontenot @ 2015-01-14 20:06 UTC (permalink / raw)
  To: Tyrel Datwyler, linux-scsi; +Cc: brking, linux-kernel, linuxppc-dev
In-Reply-To: <1421109095-18613-1-git-send-email-tyreld@linux.vnet.ibm.com>

On 01/12/2015 06:31 PM, Tyrel Datwyler wrote:
> Change maintainer of ibmvscsi driver to Tyrel Datwyler.
> 
> Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
> Cc: Nathan Fontenot <nfont@linux.vnet.ibm.com>
> Cc: Brian King <brking@linux.vnet.ibm.com>

Acked-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>

> ---
>  MAINTAINERS | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 79b2e4b..a646b94 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -4754,7 +4754,7 @@ S:	Supported
>  F:	drivers/net/ethernet/ibm/ibmveth.*
>  
>  IBM Power Virtual SCSI Device Drivers
> -M:	Nathan Fontenot <nfont@linux.vnet.ibm.com>
> +M:	Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
>  L:	linux-scsi@vger.kernel.org
>  S:	Supported
>  F:	drivers/scsi/ibmvscsi/ibmvscsi*
> 

^ permalink raw reply

* Re: [PATCH] powerpc/fsl: Add empty ranges to etsec2 dts files
From: jeclark2006 @ 2015-01-14 20:45 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <CAJUS3Xk0DjCvjn4RAPdsAQAuZOUp0SvWoSsxk78YO=cwRtp1PA@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 2908 bytes --]

This was a sort of unfortunate revelation on how things ‘change’.

While as it is, I found this problem, and ‘fixed’ my device tree source, had this been for units ‘fielded’, I have to sleuth through some amount of kernel
code to find where the OF tree was parsed, and then ‘fix’ the kernel, as changing the FDT eeprom image is not really a ‘good’ option for
units that are in use, and need a firmware update.

John Clark.


On Jan 14, 2015, at 12:35 PM, Martin Hicks [via linuxppc] <ml-node+s10917n88773h8@n7.nabble.com> wrote:

> Perfect.  I'm glad there's a patch.
> mh
> 
> On Mon, Jan 12, 2015 at 4:31 PM, Scott Wood <[hidden email]> wrote:
> On Mon, 2015-01-12 at 10:27 -0500, Martin Hicks wrote:
> >
> > With an earlier change (746c9e9f - Fix PowerPC address parsing hack), ethernet
> > has broken on Freescale boards such as the P1022.  All ranges used by the
> > ethernet controllers are also covered by sub-devices that properly
> > declared the used ranges.  The error shown is:
> >
> > fsl-gianfar: probe of soc@ffe00000:ethernet@b0000 failed with error -12
> >
> > Signed-off-by: Martin Hicks <[hidden email]>
> > ---
> >  arch/powerpc/boot/dts/fsl/pq3-etsec2-0.dtsi |    1 +
> >  arch/powerpc/boot/dts/fsl/pq3-etsec2-1.dtsi |    1 +
> >  arch/powerpc/boot/dts/fsl/pq3-etsec2-2.dtsi |    1 +
> >  3 files changed, 3 insertions(+)
> 
> http://patchwork.ozlabs.org/patch/422446/
> 
> > diff --git a/arch/powerpc/boot/dts/fsl/pq3-etsec2-0.dtsi b/arch/powerpc/boot/dts/fsl/pq3-etsec2-0.dtsi
> > index 1382fec..d1a6c48 100644
> > --- a/arch/powerpc/boot/dts/fsl/pq3-etsec2-0.dtsi
> > +++ b/arch/powerpc/boot/dts/fsl/pq3-etsec2-0.dtsi
> > @@ -43,6 +43,7 @@ mdio@24000 {
> >  ethernet@b0000 {
> >       #address-cells = <1>;
> >       #size-cells = <1>;
> > +     ranges = <>;
> 
> The " = <>" is usually omitted for empty properties.
> 
> -Scott
> 
> 
> _______________________________________________
> Linuxppc-dev mailing list
> [hidden email]
> https://lists.ozlabs.org/listinfo/linuxppc-dev
> 
> 
> 
> -- 
> Martin Hicks P.Eng.      |         [hidden email]
> Bork Consulting Inc.     |   +1 (613) 266-2296
> 
> _______________________________________________ 
> Linuxppc-dev mailing list 
> [hidden email] 
> https://lists.ozlabs.org/listinfo/linuxppc-dev 
> 
> If you reply to this email, your message will be added to the discussion below:
> http://linuxppc.10917.n7.nabble.com/PATCH-powerpc-fsl-Add-empty-ranges-to-etsec2-dts-files-tp88699p88773.html
> To start a new topic under linuxppc-dev, email ml-node+s10917n3h38@n7.nabble.com 
> To unsubscribe from linuxppc, click here.
> NAML





--
View this message in context: http://linuxppc.10917.n7.nabble.com/PATCH-powerpc-fsl-Add-empty-ranges-to-etsec2-dts-files-tp88699p88774.html
Sent from the linuxppc-dev mailing list archive at Nabble.com.

[-- Attachment #2: Type: text/html, Size: 6657 bytes --]

^ permalink raw reply

* Re: [PATCH v3 1/3] powerpc/nvram: move generic code for nvram and pstore
From: Michael Ellerman @ 2015-01-14 22:28 UTC (permalink / raw)
  To: Hari Bathini; +Cc: linuxppc-dev, Mahesh J Salgaonkar
In-Reply-To: <54B6AFE8.4000104@linux.vnet.ibm.com>

On Wed, 2015-01-14 at 23:35 +0530, Hari Bathini wrote:
> On 01/14/2015 10:01 AM, Michael Ellerman wrote:
> 
> > On Wed, 2014-12-24 at 17:28 +0530, Hari Bathini wrote:
> > > With minor checks, we can move most of the code for nvram
> > > under pseries to a common place to be re-used by other
> > > powerpc platforms like powernv. This patch moves such
> > > common code to arch/powerpc/kernel/nvram_64.c file.
> > As I said in my reply to the previous version:
> > 
> >     ... you need to keep in mind that it is very common for us to build kernels
> >     with both POWERNV=y and PSERIES=y.
> >     
> >     So you need to make sure you're only using CONFIG_PPC_PSERIES to protect things
> >     that are optional on pseries. Not things that we *shouldn't* be doing on
> >     powernv.
> 
> we could as well do away with the PPC_PSERIES flag in a couple of
> places in
> arch/powerpc/kernel/nvram_64.c, but doing that will unnecessarily add
> few extra variables for !PPC_PSERIES case. 

Yep. I'm happy for them to be there, I just want you to explain in the
changelog that you've thought about the PSERIES=y POWERNV=y case and why the
code makes sense for that configuration.

> > Please explain in your commit message how you have dealt with that.
> 
> Sure. Will update the changelog

Thanks.
 
> > Also, you broke the build for every config that doesn't have
> > CONFIG_PPC_PSERIES, all 95 of them. This is pasemi_defconfig for example:
> 
> My bad! clobbering_unread_rtas_event should have been static inline
> while defining under !PPC_PSERIES

Correct.

Please make sure you test build at least some of the other configurations in
future. I realise it's too time consuming to build all of them, but ideally for
every config symbol you use in your patch you need to build a kernel config
where that symbol =y and =n (and =m if it's tristate).

cheers

^ permalink raw reply

* [PATCH] powerpc: Rename _TIF_SYSCALL_T_OR_A to _TIF_SYSCALL_DOTRACE
From: Michael Ellerman @ 2015-01-15  1:01 UTC (permalink / raw)
  To: linuxppc-dev

Once upon a time, at least 9 years ago (< 2.6.12), _TIF_SYSCALL_T_OR_A
meant "TRACE or AUDIT". But these days it means TRACE or AUDIT or
SECCOMP or TRACEPOINT or NOHZ.

All of those are implemented via syscall_dotrace() so rename the flag to
that to try and clarify things.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/include/asm/thread_info.h | 2 +-
 arch/powerpc/kernel/entry_32.S         | 6 +++---
 arch/powerpc/kernel/entry_64.S         | 6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
index ebc4f165690a..c1efa05613f0 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -124,7 +124,7 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_SYSCALL_TRACEPOINT	(1<<TIF_SYSCALL_TRACEPOINT)
 #define _TIF_EMULATE_STACK_STORE	(1<<TIF_EMULATE_STACK_STORE)
 #define _TIF_NOHZ		(1<<TIF_NOHZ)
-#define _TIF_SYSCALL_T_OR_A	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
+#define _TIF_SYSCALL_DOTRACE	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
 				 _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT | \
 				 _TIF_NOHZ)
 
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 10a093579191..da6379550fd2 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -337,7 +337,7 @@ _GLOBAL(DoSyscall)
 #endif /* CONFIG_TRACE_IRQFLAGS */
 	CURRENT_THREAD_INFO(r10, r1)
 	lwz	r11,TI_FLAGS(r10)
-	andi.	r11,r11,_TIF_SYSCALL_T_OR_A
+	andi.	r11,r11,_TIF_SYSCALL_DOTRACE
 	bne-	syscall_dotrace
 syscall_dotrace_cont:
 	cmplwi	0,r0,NR_syscalls
@@ -364,7 +364,7 @@ ret_from_syscall:
 	MTMSRD(r10)
 	lwz	r9,TI_FLAGS(r12)
 	li	r8,-_LAST_ERRNO
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
+	andi.	r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
 	bne-	syscall_exit_work
 	cmplw	0,r3,r8
 	blt+	syscall_exit_cont
@@ -501,7 +501,7 @@ syscall_exit_work:
 	subi	r12,r12,TI_FLAGS
 	
 4:	/* Anything which requires enabling interrupts? */
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
+	andi.	r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP)
 	beq	ret_from_except
 
 	/* Re-enable interrupts. There is no need to trace that with
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 194e46dcf08d..3291ed148bdf 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -151,7 +151,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
 #endif
 	CURRENT_THREAD_INFO(r11, r1)
 	ld	r10,TI_FLAGS(r11)
-	andi.	r11,r10,_TIF_SYSCALL_T_OR_A
+	andi.	r11,r10,_TIF_SYSCALL_DOTRACE
 	bne	syscall_dotrace
 .Lsyscall_dotrace_cont:
 	cmpldi	0,r0,NR_syscalls
@@ -214,7 +214,7 @@ syscall_exit:
 
 	ld	r9,TI_FLAGS(r12)
 	li	r11,-_LAST_ERRNO
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
+	andi.	r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
 	bne-	syscall_exit_work
 	cmpld	r3,r11
 	ld	r5,_CCR(r1)
@@ -307,7 +307,7 @@ syscall_exit_work:
 
 4:	/* Anything else left to do? */
 	SET_DEFAULT_THREAD_PPR(r3, r10)		/* Set thread.ppr = 3 */
-	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
+	andi.	r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP)
 	beq	ret_from_except_lite
 
 	/* Re-enable interrupts */
-- 
2.1.0

^ permalink raw reply related

* Re: [PATCH] powerpc: powernv: winkle: Restore LPCR with LPCR_PECE1 cleared
From: Michael Ellerman @ 2015-01-15  1:14 UTC (permalink / raw)
  To: Shreyas B. Prabhu; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel
In-Reply-To: <1421234001-24886-1-git-send-email-shreyas@linux.vnet.ibm.com>

On Wed, 2015-01-14 at 16:43 +0530, Shreyas B. Prabhu wrote:
> LPCR_PECE1 bit controls whether decrementer interrupts are allowed to
> cause exit from power-saving mode. While waking up from winkle, restoring
> LPCR with LPCR_PECE1 set (i.e Decrementer interrupts allowed) can cause
> issue in the following scenario:
> 
> - All the threads in a core are offlined. The core enters deep winkle.
> - Spurious interrupt wakes up a thread in the core. Here LPCR is restored
>   with LPCR_PECE1 bit set.
> - Since it was a spurious interrupt on a offline thread, the thread clears
>   the interrupt and goes back to winkle.
> - Here before the thread executes winkle and puts the core into deep winkle,
>   if a decrementer interrupt occurs on any of the sibling threads in the core
>   that thread wakes up. 
> - Since in offline loop we are flushing interrupt only in case of external
>   interrupt, the decrementer interrupt does not get flushed. So at this stage
>   the thread is stuck in this is loop of waking up at 0x100 due to decrementer
>   interrupt, not flushing the interrupt as only external interrupts get flushed,
>   entering winkle, waking up at 0x100 again.
> 
> Fix this by programming PORE to restore LPCR with LPCR_PECE1 bit 
> cleared when waking up from winkle.

That sounds good.

But this makes the third place where we clear LPCR_PECE1, in addition to:

    static int fastsleep_loop(struct cpuidle_device *dev,
    				struct cpuidle_driver *drv,
    				int index)
    {
    	...
    
    	new_lpcr = old_lpcr;
    	/* Do not exit powersave upon decrementer as we've setup the timer
    	 * offload.
    	 */
    	new_lpcr &= ~LPCR_PECE1;
    
    	mtspr(SPRN_LPCR, new_lpcr);

And:

    static void pnv_smp_cpu_kill_self(void)
    {
    	...
    
    	/* We don't want to take decrementer interrupts while we are offline,
    	 * so clear LPCR:PECE1. We keep PECE2 enabled.
    	 */
    	mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);


So perhaps we can capture that logic in one place somehow?

cheers

^ permalink raw reply

* [PATCH] powerpc: Remove unused CPU_FTR_IABR
From: Michael Ellerman @ 2015-01-15  1:24 UTC (permalink / raw)
  To: linuxppc-dev

We removed the last usage of CPU_FTR_IABR in commit 1ad7d70562ee
"powerpc/xmon: Enable HW instruction breakpoint on POWER8".

Mark it as free.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/include/asm/cputable.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 22d5a7da9e68..5cf5a6d10685 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -165,7 +165,7 @@ extern const char *powerpc_base_platform;
 #define CPU_FTR_ARCH_201		LONG_ASM_CONST(0x0000000200000000)
 #define CPU_FTR_ARCH_206		LONG_ASM_CONST(0x0000000400000000)
 #define CPU_FTR_ARCH_207S		LONG_ASM_CONST(0x0000000800000000)
-#define CPU_FTR_IABR			LONG_ASM_CONST(0x0000001000000000)
+/* Free					LONG_ASM_CONST(0x0000001000000000) */
 #define CPU_FTR_MMCRA			LONG_ASM_CONST(0x0000002000000000)
 #define CPU_FTR_CTRL			LONG_ASM_CONST(0x0000004000000000)
 #define CPU_FTR_SMT			LONG_ASM_CONST(0x0000008000000000)
-- 
2.1.0

^ permalink raw reply related

* [PATCH V11 00/17] Enable SRIOV on Power8
From: Wei Yang @ 2015-01-15  2:27 UTC (permalink / raw)
  To: bhelgaas, benh, gwshan; +Cc: linux-pci, Wei Yang, linuxppc-dev
In-Reply-To: <20150113180502.GC2776@google.com>

This patchset enables the SRIOV on POWER8.

The gerneral idea is put each VF into one individual PE and allocate required
resources like MMIO/DMA/MSI. The major difficulty comes from the MMIO
allocation and adjustment for PF's IOV BAR.

On P8, we use M64BT to cover a PF's IOV BAR, which could make an individual VF
sit in its own PE. This gives more flexiblity, while at the mean time it
brings on some restrictions on the PF's IOV BAR size and alignment.

To achieve this effect, we need to do some hack on pci devices's resources.
1. Expand the IOV BAR properly.
   Done by pnv_pci_ioda_fixup_iov_resources().
2. Shift the IOV BAR properly.
   Done by pnv_pci_vf_resource_shift().
3. IOV BAR alignment is calculated by arch dependent function instead of an
   individual VF BAR size.
   Done by pnv_pcibios_sriov_resource_alignment().
4. Take the IOV BAR alignment into consideration in the sizing and assigning.
   This is achieved by commit: "PCI: Take additional IOV BAR alignment in
   sizing and assigning"

Test Environment:
       The SRIOV device tested is Emulex Lancer(10df:e220) and
       Mellanox ConnectX-3(15b3:1003) on POWER8.

Examples on pass through a VF to guest through vfio:
	1. unbind the original driver and bind to vfio-pci driver
	   echo 0000:06:0d.0 > /sys/bus/pci/devices/0000:06:0d.0/driver/unbind
	   echo  1102 0002 > /sys/bus/pci/drivers/vfio-pci/new_id
	   Note: this should be done for each device in the same iommu_group
	2. Start qemu and pass device through vfio
	   /home/ywywyang/git/qemu-impreza/ppc64-softmmu/qemu-system-ppc64 \
		   -M pseries -m 2048 -enable-kvm -nographic \
		   -drive file=/home/ywywyang/kvm/fc19.img \
		   -monitor telnet:localhost:5435,server,nowait -boot cd \
		   -device "spapr-pci-vfio-host-bridge,id=CXGB3,iommu=26,index=6"

Verify this is the exact VF response:
	1. ping from a machine in the same subnet(the broadcast domain)
	2. run arp -n on this machine
	   9.115.251.20             ether   00:00:c9:df:ed:bf   C eth0
	3. ifconfig in the guest
	   # ifconfig eth1
	   eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
	        inet 9.115.251.20  netmask 255.255.255.0  broadcast 9.115.251.255
		inet6 fe80::200:c9ff:fedf:edbf  prefixlen 64  scopeid 0x20<link>
	        ether 00:00:c9:df:ed:bf  txqueuelen 1000 (Ethernet)
	        RX packets 175  bytes 13278 (12.9 KiB)
	        RX errors 0  dropped 0  overruns 0  frame 0
		TX packets 58  bytes 9276 (9.0 KiB)
	        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
	4. They have the same MAC address

	Note: make sure you shutdown other network interfaces in guest.

---
v11:
   * fix some compile warning
v10:
   * remove weak function pcibios_iov_resource_size()
     the VF BAR size is stored in pci_sriov structure and retrieved from
     pci_iov_resource_size()
   * Use "Reserve additional" instead of "Expand" to be more acurate in the
     change log
   * add log message to show the PF's IOV BAR final size
   * add pcibios_sriov_enable/disable() weak funcion in sriov_enable/disable()
     for arch setup before enable VFs. Like the arch could fix up the BDF for
     VFs, since the change of NumVFs would affect the BDF of VFs.
   * Add some explanation of PE on Power arch in the documentation
v9:
   * make the change log consistent in the terminology
     PF's IOV BAR -> the SRIOV BAR in PF
     VF's BAR -> the normal BAR in VF's view
   * rename all newly introduced function from _sriov_ to _iov_
   * rename the document to Documentation/powerpc/pci_iov_resource_on_powernv.txt
   * add the vendor id and device id of the tested devices
   * change return value from EINVAL to ENOSYS for pci_iov_virtfn_bus() and
     pci_iov_virtfn_devfn() when it is called on PF or SRIOV is not configured
   * rebase on 3.18-rc2 and tested
v8:
   * use weak funcion pcibios_sriov_resource_size() instead of some flag to
     retrieve the IOV BAR size.
   * add a document Documentation/powerpc/pci_resource.txt to explain the
     design.
   * make pci_iov_virtfn_bus()/pci_iov_virtfn_devfn() not inline.
   * extract a function res_to_dev_res(), so that it is more general to get
     additional size and alignment
   * fix one contention which is introduced in "powrepc/pci: Refactor pci_dn".
     the root cause is pci_get_slot() takes pci_bus_sem and leads to dead
     lock.
v7:
   * add IORESOURCE_ARCH flag for IOV BAR on powernv platform.
   * when IOV BAR has IORESOURCE_ARCH flag, the size is retrieved from
     hardware directly. If not, calculate as usual.
   * reorder the patch set, group them by subsystem:
     PCI, powerpc, powernv
   * rebase it on 3.16-rc6
v6:
   * remove pcibios_enable_sriov()/pcibios_disable_sriov() weak function
     similar function is moved to
     pnv_pci_enable_device_hook()/pnv_pci_disable_device_hook(). When PF is
     enabled, platform will try best to allocate resources for VFs.
   * remove pcibios_sriov_resource_size weak function
   * VF BAR size is retrieved from hardware directly in virtfn_add()
v5:
   * merge those SRIOV related platform functions in machdep_calls
     wrap them in one CONFIG_PCI_IOV marco
   * define IODA_INVALID_M64 to replace (-1)
     use this value to represent the m64_wins is not used
   * rename pnv_pci_release_dev_dma() to pnv_pci_ioda2_release_dma_pe()
     this function is a conterpart to pnv_pci_ioda2_setup_dma_pe()
   * change dev_info() to dev_dgb() in pnv_pci_ioda_fixup_iov_resources()
     reduce some log in kernel
   * release M64 window in pnv_pci_ioda2_release_dma_pe()
v4:
   * code format fix, eg. not exceed 80 chars
   * in commit "ppc/pnv: Add function to deconfig a PE"
     check the bus has a bridge before print the name
     remove a PE from its own PELTV
   * change the function name for sriov resource size/alignment
   * rebase on 3.16-rc3
   * VFs will not rely on device node
     As Grant Likely's comments, kernel should have the ability to handle the
     lack of device_node gracefully. Gavin restructure the pci_dn, which
     makes the VF will have pci_dn even when VF's device_node is not provided
     by firmware.
   * clean all the patch title to make them comply with one style
   * fix return value for pci_iov_virtfn_bus/pci_iov_virtfn_devfn
v3:
   * change the return type of virtfn_bus/virtfn_devfn to int
     change the name of these two functions to pci_iov_virtfn_bus/pci_iov_virtfn_devfn
   * reduce the second parameter or pcibios_sriov_disable()
   * use data instead of pe in "ppc/pnv: allocate pe->iommu_table dynamically"
   * rename __pci_sriov_resource_size to pcibios_sriov_resource_size
   * rename __pci_sriov_resource_alignment to pcibios_sriov_resource_alignment
v2:
   * change the return value of virtfn_bus/virtfn_devfn to 0
   * move some TCE related marco definition to
     arch/powerpc/platforms/powernv/pci.h
   * fix the __pci_sriov_resource_alignment on powernv platform
     During the sizing stage, the IOV BAR is truncated to 0, which will
     effect the order of allocation. Fix this, so that make sure BAR will be
     allocated ordered by their alignment.
v1:
   * improve the change log for
     "PCI: Add weak __pci_sriov_resource_size() interface"
     "PCI: Add weak __pci_sriov_resource_alignment() interface"
     "PCI: take additional IOV BAR alignment in sizing and assigning"
   * wrap VF PE code in CONFIG_PCI_IOV
   * did regression test on P7.

Gavin Shan (1):
  powrepc/pci: Refactor pci_dn

Wei Yang (16):
  PCI/IOV: Export interface for retrieve VF's BDF
  PCI/IOV: add VF enable/disable hook
  PCI: Add weak pcibios_iov_resource_alignment() interface
  PCI: Store VF BAR size in pci_sriov
  PCI: Take additional PF's IOV BAR alignment in sizing and assigning
  powerpc/pci: Add PCI resource alignment documentation
  powerpc/pci: Don't unset pci resources for VFs
  powerpc/pci: remove pci_dn->pcidev field
  powerpc/powernv: Use pci_dn in PCI config accessor
  powerpc/powernv: Allocate pe->iommu_table dynamically
  powerpc/powernv: Reserve additional space for IOV BAR according to
    the number of total_pe
  powerpc/powernv: Implement pcibios_iov_resource_alignment() on
    powernv
  powerpc/powernv: Shift VF resource with an offset
  powerpc/powernv: Allocate VF PE
  powerpc/powernv: Reserve additional space for IOV BAR, with
    m64_per_iov supported
  powerpc/powernv: Group VF PE when IOV BAR is big on PHB3

 .../powerpc/pci_iov_resource_on_powernv.txt        |  215 ++++++
 arch/powerpc/include/asm/device.h                  |    3 +
 arch/powerpc/include/asm/iommu.h                   |    3 +
 arch/powerpc/include/asm/machdep.h                 |    7 +
 arch/powerpc/include/asm/pci-bridge.h              |   24 +-
 arch/powerpc/kernel/pci-common.c                   |   23 +
 arch/powerpc/kernel/pci_dn.c                       |  253 ++++++-
 arch/powerpc/platforms/powernv/eeh-powernv.c       |   14 +-
 arch/powerpc/platforms/powernv/pci-ioda.c          |  739 +++++++++++++++++++-
 arch/powerpc/platforms/powernv/pci.c               |   87 +--
 arch/powerpc/platforms/powernv/pci.h               |   13 +-
 drivers/pci/iov.c                                  |   80 ++-
 drivers/pci/pci.h                                  |    2 +
 drivers/pci/setup-bus.c                            |   85 ++-
 include/linux/pci.h                                |   17 +
 15 files changed, 1451 insertions(+), 114 deletions(-)
 create mode 100644 Documentation/powerpc/pci_iov_resource_on_powernv.txt

-- 
1.7.9.5

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox