[PATCH 1/1] KVM: PPC: Book3S: correct width in XER handling

2015-05-19 Thread Sam Bobroff
In 64 bit kernels, the Fixed Point Exception Register (XER) is a 64
bit field (e.g. in kvm_regs and kvm_vcpu_arch) and in most places it is
accessed as such.

This patch corrects places where it is accessed as a 32 bit field by a
64 bit kernel.  In some cases this is via a 32 bit load or store
instruction which, depending on endianness, will cause either the
lower or upper 32 bits to be missed.  In another case it is cast as a
u32, causing the upper 32 bits to be cleared.

This patch corrects those places by extending the access methods to
64 bits.

Signed-off-by: Sam Bobroff 
---

 arch/powerpc/include/asm/kvm_book3s.h   |4 ++--
 arch/powerpc/kvm/book3s_hv_rmhandlers.S |6 +++---
 arch/powerpc/kvm/book3s_segment.S   |4 ++--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_book3s.h 
b/arch/powerpc/include/asm/kvm_book3s.h
index b91e74a..05a875a 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -225,12 +225,12 @@ static inline u32 kvmppc_get_cr(struct kvm_vcpu *vcpu)
return vcpu->arch.cr;
 }
 
-static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, u32 val)
+static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, ulong val)
 {
vcpu->arch.xer = val;
 }
 
-static inline u32 kvmppc_get_xer(struct kvm_vcpu *vcpu)
+static inline ulong kvmppc_get_xer(struct kvm_vcpu *vcpu)
 {
return vcpu->arch.xer;
 }
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S 
b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 4d70df2..d75be59 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -870,7 +870,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
blt hdec_soon
 
ld  r6, VCPU_CTR(r4)
-   lwz r7, VCPU_XER(r4)
+   ld  r7, VCPU_XER(r4)
 
mtctr   r6
mtxer   r7
@@ -1103,7 +1103,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
mfctr   r3
mfxer   r4
std r3, VCPU_CTR(r9)
-   stw r4, VCPU_XER(r9)
+   std r4, VCPU_XER(r9)
 
/* If this is a page table miss then see if it's theirs or ours */
cmpwi   r12, BOOK3S_INTERRUPT_H_DATA_STORAGE
@@ -1675,7 +1675,7 @@ kvmppc_hdsi:
bl  kvmppc_msr_interrupt
 fast_interrupt_c_return:
 6: ld  r7, VCPU_CTR(r9)
-   lwz r8, VCPU_XER(r9)
+   ld  r8, VCPU_XER(r9)
mtctr   r7
mtxer   r8
mr  r4, r9
diff --git a/arch/powerpc/kvm/book3s_segment.S 
b/arch/powerpc/kvm/book3s_segment.S
index acee37c..ca8f174 100644
--- a/arch/powerpc/kvm/book3s_segment.S
+++ b/arch/powerpc/kvm/book3s_segment.S
@@ -123,7 +123,7 @@ no_dcbz32_on:
PPC_LL  r8, SVCPU_CTR(r3)
PPC_LL  r9, SVCPU_LR(r3)
lwz r10, SVCPU_CR(r3)
-   lwz r11, SVCPU_XER(r3)
+   PPC_LL  r11, SVCPU_XER(r3)
 
mtctr   r8
mtlrr9
@@ -237,7 +237,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
mfctr   r8
mflrr9
 
-   stw r5, SVCPU_XER(r13)
+   PPC_STL r5, SVCPU_XER(r13)
PPC_STL r6, SVCPU_FAULT_DAR(r13)
stw r7, SVCPU_FAULT_DSISR(r13)
PPC_STL r8, SVCPU_CTR(r13)
-- 
1.7.10.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH kernel] commit 4fbdf9cb ("lpfc: Fix for lun discovery issue with saturn adapter.")

2015-05-19 Thread Alexey Kardashevskiy

On 05/06/2015 07:46 AM, Sebastian Herbszt wrote:

James Smart wrote:


Reviewed-By: James Smart 


Alexey, Sebastian,

Yes - this section needs to be reverted.  This patch is good.

-- james s


Reviewed-by: Sebastian Herbszt 



Unfortunately, just this revert is not enough, it fixed one of my machines 
but I have another machine with "Emulex Corporation Saturn-X: LightPulse 
Fibre Channel Host Adapter (rev 03)" which does not boot - the booting 
process stops at "[  OK  ] Reached target Basic System."


Any quick idea what else to revert between 4.0 and current upstream before 
I dig further? Thanks!




--
Alexey
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 2/3 v2] powerpc/powernv: Expose OPAL APIs required by PRD interface

2015-05-19 Thread Jeremy Kerr
The (upcoming) opal-prd driver needs to access the message notifier and
xscom code, so add EXPORT_SYMBOL_GPL macros for these.

Signed-off-by: Jeremy Kerr 

---
 arch/powerpc/platforms/powernv/opal.c |4 
 1 file changed, 4 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index b03ac9e..b40624d 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -317,6 +317,7 @@ int opal_message_notifier_register(enum opal_msg_type 
msg_type,
return atomic_notifier_chain_register(
&opal_msg_notifier_head[msg_type], nb);
 }
+EXPORT_SYMBOL_GPL(opal_message_notifier_register);
 
 int opal_message_notifier_unregister(enum opal_msg_type msg_type,
 struct notifier_block *nb)
@@ -324,6 +325,7 @@ int opal_message_notifier_unregister(enum opal_msg_type 
msg_type,
return atomic_notifier_chain_unregister(
&opal_msg_notifier_head[msg_type], nb);
 }
+EXPORT_SYMBOL_GPL(opal_message_notifier_unregister);
 
 static void opal_message_do_notify(uint32_t msg_type, void *msg)
 {
@@ -867,6 +869,8 @@ void opal_shutdown(void)
 
 /* Export this so that test modules can use it */
 EXPORT_SYMBOL_GPL(opal_invalid_call);
+EXPORT_SYMBOL_GPL(opal_xscom_read);
+EXPORT_SYMBOL_GPL(opal_xscom_write);
 EXPORT_SYMBOL_GPL(opal_ipmi_send);
 EXPORT_SYMBOL_GPL(opal_ipmi_recv);
 EXPORT_SYMBOL_GPL(opal_flash_read);
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 3/3 v2] powerpc/powernv: Add opal-prd channel

2015-05-19 Thread Jeremy Kerr
This change adds a char device to access the "PRD" (processor runtime
diagnostics) channel to OPAL firmware.

Includes contributions from Vaidyanathan Srinivasan, Neelesh Gupta &
Vishal Kulkarni.

Signed-off-by: Neelesh Gupta 
Signed-off-by: Jeremy Kerr 

---
 arch/powerpc/include/asm/opal-api.h|   21 
 arch/powerpc/include/asm/opal.h|1 
 arch/powerpc/include/uapi/asm/opal-prd.h   |   47 +
 arch/powerpc/platforms/powernv/Kconfig |7 
 arch/powerpc/platforms/powernv/Makefile|1 
 arch/powerpc/platforms/powernv/opal-prd.c  |  440 +
 arch/powerpc/platforms/powernv/opal-wrappers.S |1 
 arch/powerpc/platforms/powernv/opal.c  |4 
 8 files changed, 520 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/opal-api.h 
b/arch/powerpc/include/asm/opal-api.h
index 0321a90..2407f12 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -153,7 +153,8 @@
 #define OPAL_FLASH_READ110
 #define OPAL_FLASH_WRITE   111
 #define OPAL_FLASH_ERASE   112
-#define OPAL_LAST  112
+#define OPAL_PRD_MSG   113
+#define OPAL_LAST  113
 
 /* Device tree flags */
 
@@ -352,6 +353,7 @@ enum opal_msg_type {
OPAL_MSG_SHUTDOWN,  /* params[0] = 1 reboot, 0 shutdown */
OPAL_MSG_HMI_EVT,
OPAL_MSG_DPO,
+   OPAL_MSG_PRD,
OPAL_MSG_TYPE_MAX,
 };
 
@@ -674,6 +676,23 @@ typedef struct oppanel_line {
__be64 line_len;
 } oppanel_line_t;
 
+enum opal_prd_msg_type {
+   OPAL_PRD_MSG_TYPE_INIT = 0, /* HBRT --> OPAL */
+   OPAL_PRD_MSG_TYPE_FINI, /* HBRT/kernel --> OPAL */
+   OPAL_PRD_MSG_TYPE_ATTN, /* HBRT <-- OPAL */
+   OPAL_PRD_MSG_TYPE_ATTN_ACK, /* HBRT --> OPAL */
+   OPAL_PRD_MSG_TYPE_OCC_ERROR,/* HBRT <-- OPAL */
+   OPAL_PRD_MSG_TYPE_OCC_RESET,/* HBRT <-- OPAL */
+};
+
+struct opal_prd_msg_header {
+   uint8_t type;
+   uint8_t pad[1];
+   __be16  size;
+};
+
+struct opal_prd_msg;
+
 /*
  * SG entries
  *
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 042af1a..93704af 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -193,6 +193,7 @@ int64_t opal_ipmi_recv(uint64_t interface, struct 
opal_ipmi_msg *msg,
uint64_t *msg_len);
 int64_t opal_i2c_request(uint64_t async_token, uint32_t bus_id,
 struct opal_i2c_request *oreq);
+int64_t opal_prd_msg(struct opal_prd_msg *msg);
 
 int64_t opal_flash_read(uint64_t id, uint64_t offset, uint64_t buf,
uint64_t size, uint64_t token);
diff --git a/arch/powerpc/include/uapi/asm/opal-prd.h 
b/arch/powerpc/include/uapi/asm/opal-prd.h
new file mode 100644
index 000..86c5640
--- /dev/null
+++ b/arch/powerpc/include/uapi/asm/opal-prd.h
@@ -0,0 +1,47 @@
+/*
+ * OPAL Runtime Diagnostics interface driver
+ * Supported on POWERNV platform
+ *
+ * (C) Copyright IBM 2015
+ *
+ * Author: Vaidyanathan Srinivasan 
+ * Author: Jeremy Kerr 
+ *
+ * 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, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _UAPI_ASM_POWERPC_OPAL_PRD_H_
+#define _UAPI_ASM_POWERPC_OPAL_PRD_H_
+
+#include 
+
+#define OPAL_PRD_KERNEL_VERSION1
+
+#define OPAL_PRD_GET_INFO  _IOR('o', 0x01, struct opal_prd_info)
+#define OPAL_PRD_SCOM_READ _IOR('o', 0x02, struct opal_prd_scom)
+#define OPAL_PRD_SCOM_WRITE_IOW('o', 0x03, struct opal_prd_scom)
+
+#ifndef __ASSEMBLY__
+
+struct opal_prd_info {
+   __u64   version;
+};
+
+struct opal_prd_scom {
+   __u64   chip;
+   __u64   addr;
+   __u64   data;
+   __s64   rc;
+};
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _UAPI_ASM_POWERPC_OPAL_PRD_H */
diff --git a/arch/powerpc/platforms/powernv/Kconfig 
b/arch/powerpc/platforms/powernv/Kconfig
index 4b044d8..604190c 100644
--- a/arch/powerpc/platforms/powernv/Kconfig
+++ b/arch/powerpc/platforms/powernv/Kconfig
@@ -19,3 +19,10 @@ config PPC_POWERNV
select CPU_FREQ_GOV_CONSERVATIVE
select PPC_DOORBELL
default y
+
+config OPAL_PRD
+   tristate 'OPAL PRD driver'
+   depends on PPC_POWERNV
+   help
+ This enables the opal-prd driver, a facility to run processor
+ recovery diagnostics on OpenPower machines
diff --git a/arch/powerpc/platforms/

[PATCH 1/3 v2] powerpc/powernv: Merge common platform device initialisation

2015-05-19 Thread Jeremy Kerr
opal_ipmi_init and opal_flash_init are equivalent, except for the
compatbile string. Merge these two into a common opal_pdev_init
function.

Signed-off-by: Jeremy Kerr 

---
 arch/powerpc/platforms/powernv/opal.c |   21 ++---
 1 file changed, 6 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c 
b/arch/powerpc/platforms/powernv/opal.c
index 2241565..b03ac9e 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -693,21 +693,13 @@ static void __init opal_dump_region_init(void)
"rc = %d\n", rc);
 }
 
-static void opal_flash_init(struct device_node *opal_node)
+static void opal_pdev_init(struct device_node *opal_node,
+   const char *compatible)
 {
struct device_node *np;
 
for_each_child_of_node(opal_node, np)
-   if (of_device_is_compatible(np, "ibm,opal-flash"))
-   of_platform_device_create(np, NULL, NULL);
-}
-
-static void opal_ipmi_init(struct device_node *opal_node)
-{
-   struct device_node *np;
-
-   for_each_child_of_node(opal_node, np)
-   if (of_device_is_compatible(np, "ibm,opal-ipmi"))
+   if (of_device_is_compatible(np, compatible))
of_platform_device_create(np, NULL, NULL);
 }
 
@@ -835,10 +827,9 @@ static int __init opal_init(void)
opal_msglog_init();
}
 
-   /* Initialize OPAL IPMI backend */
-   opal_ipmi_init(opal_node);
-
-   opal_flash_init(opal_node);
+   /* Initialize platform devices: IPMI backend & flash interface */
+   opal_pdev_init(opal_node, "ibm,opal-ipmi");
+   opal_pdev_init(opal_node, "ibm,opal-flash");
 
return 0;
 }
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH] powerpc: Make doorbell check preemption safe

2015-05-19 Thread Michael Neuling
On Wed, 2015-05-20 at 00:30 +0530, Shreyas B. Prabhu wrote:
> Doorbell can be used to cause ipi on cpus which are sibling threads on
> the same core. So icp_native_cause_ipi checks if the destination cpu
> is a sibling thread of the current cpu and uses doorbell in such cases.
> 
> But while running with CONFIG_PREEMPT=y, since this section is
> preemtible, we can run into issues if after we check if the destination
> cpu is a sibling cpu, the task gets migrated from a sibling cpu to a
> cpu on another core.
> 
> Fix this by using get_cpu()/ put_cpu()

Thanks.  Looks good and it's boots for me.

Signed-off-by: Michael Neuling 

> Signed-off-by: Shreyas B. Prabhu 
> ---
>  arch/powerpc/sysdev/xics/icp-native.c | 14 +-
>  1 file changed, 9 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/powerpc/sysdev/xics/icp-native.c 
> b/arch/powerpc/sysdev/xics/icp-native.c
> index 2fc4cf1..62fd478 100644
> --- a/arch/powerpc/sysdev/xics/icp-native.c
> +++ b/arch/powerpc/sysdev/xics/icp-native.c
> @@ -147,12 +147,16 @@ static void icp_native_cause_ipi(int cpu, unsigned long 
> data)
>  {
>   kvmppc_set_host_ipi(cpu, 1);
>  #ifdef CONFIG_PPC_DOORBELL
> - if (cpu_has_feature(CPU_FTR_DBELL) &&
> - (cpumask_test_cpu(cpu, cpu_sibling_mask(smp_processor_id()
> - doorbell_cause_ipi(cpu, data);
> - else
> + if (cpu_has_feature(CPU_FTR_DBELL)) {
> + if (cpumask_test_cpu(cpu, cpu_sibling_mask(get_cpu( {
> + doorbell_cause_ipi(cpu, data);
> + put_cpu();
> + return;
> + }
> + put_cpu();
> + }
>  #endif
> - icp_native_set_qirr(cpu, IPI_PRIORITY);
> + icp_native_set_qirr(cpu, IPI_PRIORITY);
>  }
>  
>  /*

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 3/4] perf: Use pmu_events_map table to create event aliases

2015-05-19 Thread Sukadev Bhattiprolu
At run time, (i.e when perf is starting up), locate the specific events
table for the current CPU and create event aliases for each of the events.

Use these aliases to parse user's specified perf event.

Signed-off-by: Sukadev Bhattiprolu 
---
 tools/perf/arch/powerpc/util/header.c |   33 +++
 tools/perf/util/header.h  |4 +-
 tools/perf/util/pmu.c |  104 -
 3 files changed, 127 insertions(+), 14 deletions(-)

diff --git a/tools/perf/arch/powerpc/util/header.c 
b/tools/perf/arch/powerpc/util/header.c
index 6c1b8a7..8325012 100644
--- a/tools/perf/arch/powerpc/util/header.c
+++ b/tools/perf/arch/powerpc/util/header.c
@@ -32,3 +32,36 @@ get_cpuid(char *buffer, size_t sz)
}
return -1;
 }
+
+static char *
+get_cpu_str(void)
+{
+char *bufp;
+
+if (asprintf(&bufp, "%.8lx", mfspr(SPRN_PVR)) < 0)
+bufp = NULL;
+
+return bufp;
+}
+
+/*
+ * Return TRUE if the CPU identified by @vfm, @version, and @type
+ * matches the current CPU.  vfm refers to [Vendor, Family, Model],
+ *
+ * Return FALSE otherwise.
+ *
+ * For Powerpc, we only compare @version to the processor PVR.
+ */
+bool arch_pmu_events_match_cpu(const char *vfm __maybe_unused,
+   const char *version,
+   const char *type __maybe_unused)
+{
+   char *cpustr;
+   bool rc;
+
+   cpustr = get_cpu_str();
+   rc = !strcmp(version, cpustr);
+   free(cpustr);
+
+   return rc;
+}
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 3bb90ac..207c5b8 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -8,7 +8,6 @@
 #include 
 #include "event.h"
 
-
 enum {
HEADER_RESERVED = 0,/* always cleared */
HEADER_FIRST_FEATURE= 1,
@@ -156,4 +155,7 @@ int write_padded(int fd, const void *bf, size_t count, 
size_t count_aligned);
  */
 int get_cpuid(char *buffer, size_t sz);
 
+bool arch_pmu_events_match_cpu(const char *vfm, const char *version, 
+   const char *type);
+
 #endif /* __PERF_HEADER_H */
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 4841167..7665f0f 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -10,7 +10,9 @@
 #include "util.h"
 #include "pmu.h"
 #include "parse-events.h"
+#include "pmu-events/pmu-events.h" // Move to global file???
 #include "cpumap.h"
+#include "header.h"
 
 struct perf_pmu_format {
char *name;
@@ -198,17 +200,11 @@ static int perf_pmu__parse_snapshot(struct perf_pmu_alias 
*alias,
return 0;
 }
 
-static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, 
FILE *file)
+static int __perf_pmu__new_alias(struct list_head *list, char *name, char 
*dir, char *desc __maybe_unused, char *val)
 {
struct perf_pmu_alias *alias;
-   char buf[256];
int ret;
 
-   ret = fread(buf, 1, sizeof(buf), file);
-   if (ret == 0)
-   return -EINVAL;
-   buf[ret] = 0;
-
alias = malloc(sizeof(*alias));
if (!alias)
return -ENOMEM;
@@ -218,26 +214,47 @@ static int perf_pmu__new_alias(struct list_head *list, 
char *dir, char *name, FI
alias->unit[0] = '\0';
alias->per_pkg = false;
 
-   ret = parse_events_terms(&alias->terms, buf);
+   ret = parse_events_terms(&alias->terms, val);
if (ret) {
+   pr_err("Cannot parse alias %s: %d\n", val, ret);
free(alias);
return ret;
}
 
alias->name = strdup(name);
+   if (dir) {
+   /*
+* load unit name and scale if available
+*/
+   perf_pmu__parse_unit(alias, dir, name);
+   perf_pmu__parse_scale(alias, dir, name);
+   perf_pmu__parse_per_pkg(alias, dir, name);
+   perf_pmu__parse_snapshot(alias, dir, name);
+   }
+
/*
-* load unit name and scale if available
+* TODO: pickup description from Andi's patchset
 */
-   perf_pmu__parse_unit(alias, dir, name);
-   perf_pmu__parse_scale(alias, dir, name);
-   perf_pmu__parse_per_pkg(alias, dir, name);
-   perf_pmu__parse_snapshot(alias, dir, name);
+   //alias->desc = desc ? strdpu(desc) : NULL;
 
list_add_tail(&alias->list, list);
 
return 0;
 }
 
+static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, 
FILE *file)
+{
+   char buf[256];
+   int ret;
+
+   ret = fread(buf, 1, sizeof(buf), file);
+   if (ret == 0)
+   return -EINVAL;
+   buf[ret] = 0;
+   
+   return __perf_pmu__new_alias(list, name, dir, NULL, buf);
+}
+
 static inline bool pmu_alias_info_file(char *name)
 {
size_t len;
@@ -435,6 +452,65 @@ perf_pmu__get_default_config(struct perf_pmu *pmu 
__maybe_unused)
return NULL;
 }
 
+/*
+ * Return TRUE

[PATCH 2/4] perf: jevents: Program to convert JSON file to C style file

2015-05-19 Thread Sukadev Bhattiprolu
From: Andi Kleen 

This is a modified version of an earlier patch by Andi Kleen.

We expect architectures to describe the performance monitoring events
for each CPU in a corresponding JSON file, which look like:

[
{
"EventCode": "0x00",
"UMask": "0x01",
"EventName": "INST_RETIRED.ANY",
"BriefDescription": "Instructions retired from execution.",
"PublicDescription": "Instructions retired from execution.",
"Counter": "Fixed counter 1",
"CounterHTOff": "Fixed counter 1",
"SampleAfterValue": "203",
"SampleAfterValue": "203",
"MSRIndex": "0",
"MSRValue": "0",
"TakenAlone": "0",
"CounterMask": "0",
"Invert": "0",
"AnyThread": "0",
"EdgeDetect": "0",
"PEBS": "0",
"PRECISE_STORE": "0",
"Errata": "null",
"Offcore": "0"
}
]

We also expect the architectures to provide a mapping between individual
CPUs to their JSON files. Eg:

GenuineIntel-6-1E,V1,/NHM-EP/NehalemEP_core_V1.json,core

which maps each CPU, identified by [vendor, family, model, version, type]
to a JSON file.

Given these files, the program, jevents::
- locates all JSON files for the architecture,
- parses each JSON file and generates a C-style "PMU-events table"
  (pmu-events.c)
- locates a mapfile for the architecture
- builds a global table, mapping each model of CPU to the
  corresponding PMU-events table.

The 'pmu-events.c' is generated when building perf and added to libperf.a.
The global table pmu_events_map[] table in this pmu-events.c will be used
in perf in a follow-on patch.

If the architecture does not have any JSON files or there is an error in
processing them, an empty mapping file is created. This would allow the
build of perf to proceed even if we are not able to provide aliases for
events.

The parser for JSON files allows parsing Intel style JSON event files. This
allows to use an Intel event list directly with perf. The Intel event lists
can be quite large and are too big to store in unswappable kernel memory.

The conversion from JSON to C-style is straight forward.  The parser knows
(very little) Intel specific information, and can be easily extended to
handle fields for other CPUs.

The parser code is partially shared with an independent parsing library,
which is 2-clause BSD licenced. To avoid any conflicts I marked those
files as BSD licenced too. As part of perf they become GPLv2.

Signed-off-by: Andi Kleen 
Signed-off-by: Sukadev Bhattiprolu 

v2: Address review feedback. Rename option to --event-files
v3: Add JSON example
v4: Update manpages.
v5: Don't remove dot in fixname. Fix compile error. Add include
protection. Comment realloc.
v6: Include debug/util.h
v7: (Sukadev Bhattiprolu)
Rebase to 4.0 and fix some conflicts.
v8: (Sukadev Bhattiprolu)
Move jevents.[hc] to tools/perf/pmu-events/
Rewrite to locate and process arch specific JSON and "map" files;
and generate a C file.
(Removed acked-by Namhyung Kim due to modest changes to patch)
Compile the generated pmu-events.c and add the pmu-events.o to
libperf.a
---
 tools/perf/Build   |1 +
 tools/perf/Makefile.perf   |4 +-
 tools/perf/pmu-events/Build|   38 ++
 tools/perf/pmu-events/README   |   67 
 tools/perf/pmu-events/jevents.c|  700 
 tools/perf/pmu-events/jevents.h|   17 +
 tools/perf/pmu-events/pmu-events.h |   39 ++
 7 files changed, 865 insertions(+), 1 deletion(-)
 create mode 100644 tools/perf/pmu-events/Build
 create mode 100644 tools/perf/pmu-events/README
 create mode 100644 tools/perf/pmu-events/jevents.c
 create mode 100644 tools/perf/pmu-events/jevents.h
 create mode 100644 tools/perf/pmu-events/pmu-events.h

diff --git a/tools/perf/Build b/tools/perf/Build
index b77370e..40bffa0 100644
--- a/tools/perf/Build
+++ b/tools/perf/Build
@@ -36,6 +36,7 @@ CFLAGS_builtin-help.o  += $(paths)
 CFLAGS_builtin-timechart.o += $(paths)
 CFLAGS_perf.o  += -DPERF_HTML_PATH="BUILD_STR($(htmldir_SQ))" 
-include $(OUTPUT)PERF-VERSION-FILE
 
+libperf-y += pmu-events/
 libperf-y += util/
 libperf-y += arch/
 libperf-y += ui/
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index c43a205..d078c71 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -306,6 +306,8 @@ perf.spec $(SCRIPTS) \
 ifneq ($(OUTPUT),)
 %.o: $(OUTPUT)%.o
@echo "# Redirected target $@ => $(OUTPUT)$@"
+pmu-events/%.o: $(OUTPUT)pmu-events/%.o
+   @echo "# Redirected target $@ => $(OUTPUT)$@"
 util/%.o: $(OUTPUT)util/%.o
@echo "# Redirected target $@ => $(OUTPUT)$@"
 bench/%.o: $(OUTPUT)bench/%.o
@@ -529,7 +531,7 @@ clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean config-clean
$(call QUIET_CLEAN, core-objs)  $(RM) $(LIB_

[PATCH 0/4] perf: Add support for PMU events in JSON format

2015-05-19 Thread Sukadev Bhattiprolu
CPUs support a large number of performance monitoring events (PMU events)
and often these events are very specific to an architecture/model of the
CPU. To use most of these PMU events with perf we currently have to identify
the events by their raw codes:

perf stat -e r100f2 sleep 1

This patchset allows architectures to specify these PMU events in a JSON
files which are defined in the tools/perf/pmu-events/arch/ directory of
the mainline tree

Eg: snippet from 004d0100.json (in patch 4)
[

  {
"EventCode": "0x100f2",
"EventName": "PM_1PLUS_PPC_CMPL",
"BriefDescription": "1 or more ppc insts finished,",
"PublicDescription": "1 or more ppc insts finished (completed).,"
  },
]

When building the perf tool, this patchset, first builds/uses a 'jevents'
which locates all the JSON files for the architecture (currently Powerpc).
The jevents binary then translates the JSON files into into a C-style
"PMU events table":

struct pmu_event pme_004d0100_core[] = {

...

{
.name = "pm_1plus_ppc_cmpl",
.event = "event=0x100f2",
.desc = "1 or more ppc insts finished,",
},

...
}

The jevents binary also looks for a "mapfile" to map a processor model/
version to a specific events table:

$ cat mapfile.csv
IBM-Power8-9188,004d0100,004d0100-core.json,core

and uses this to build a mapping table:

struct pmu_events_map pmu_events_map[] = {
{
.vfm = "IBM-Power8-9188",
.version = "004d0100",
.type = "core",
.table = pme_004d0100_core
},

This mapping and events tables for the architecture are then included in
the perf binary during build.

At run time, perf identifies the specific events table, based on the model
of the CPU perf is running on. Perf uses that table to create event aliases
which would allow the user to specify the event as:

perf stat -e pm_1plus_ppc_cmpl sleep 1

Note:
- All known events tables for the architecture are included in the
  perf binary.

- Inconsistencies between the JSON files and the mapfile can result
  in build failures in perf (although jevents try to recover from
  some and continue the build by leaving out event aliases).

- For architectures that don't have any JSON files, an empty mapping
  table is created and they should continue to build)

Andi Kleen (2):
  perf, tools: Add jsmn `jasmine' JSON parser
  jevents: Program to convert JSON file to C style file

Sukadev Bhattiprolu (2):
  Use pmu_events_map table to create event aliases
  perf: Add power8 PMU events in json format

 tools/perf/Build   |1 +
 tools/perf/Makefile.perf   |4 +-
 tools/perf/arch/powerpc/util/header.c  |   33 +
 tools/perf/pmu-events/Build|   38 +
 tools/perf/pmu-events/README   |   67 +
 .../pmu-events/arch/powerpc/004d0100-core.json | 5766 
 tools/perf/pmu-events/arch/powerpc/mapfile.csv |1 +
 tools/perf/pmu-events/arch/powerpc/power8.json | 5766 
 tools/perf/pmu-events/jevents.c|  700 +++
 tools/perf/pmu-events/jevents.h|   17 +
 tools/perf/pmu-events/jsmn.c   |  313 ++
 tools/perf/pmu-events/jsmn.h   |   67 +
 tools/perf/pmu-events/json.c   |  162 +
 tools/perf/pmu-events/json.h   |   36 +
 tools/perf/pmu-events/pmu-events.h |   39 +
 tools/perf/util/header.h   |4 +-
 tools/perf/util/pmu.c  |  104 +-
 17 files changed, 13103 insertions(+), 15 deletions(-)
 create mode 100644 tools/perf/pmu-events/Build
 create mode 100644 tools/perf/pmu-events/README
 create mode 100644 tools/perf/pmu-events/arch/powerpc/004d0100-core.json
 create mode 100644 tools/perf/pmu-events/arch/powerpc/mapfile.csv
 create mode 100644 tools/perf/pmu-events/arch/powerpc/power8.json
 create mode 100644 tools/perf/pmu-events/jevents.c
 create mode 100644 tools/perf/pmu-events/jevents.h
 create mode 100644 tools/perf/pmu-events/jsmn.c
 create mode 100644 tools/perf/pmu-events/jsmn.h
 create mode 100644 tools/perf/pmu-events/json.c
 create mode 100644 tools/perf/pmu-events/json.h
 create mode 100644 tools/perf/pmu-events/pmu-events.h

-- 
1.7.9.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 1/4] perf: Add jsmn `jasmine' JSON parser

2015-05-19 Thread Sukadev Bhattiprolu
From: Andi Kleen 

I need a JSON parser. This adds the simplest JSON
parser I could find -- Serge Zaitsev's jsmn `jasmine' --
to the perf library. I merely converted it to (mostly)
Linux style and added support for non 0 terminated input.

The parser is quite straight forward and does not
copy any data, just returns tokens with offsets
into the input buffer. So it's relatively efficient
and simple to use.

The code is not fully checkpatch clean, but I didn't
want to completely fork the upstream code.

Original source: http://zserge.bitbucket.org/jsmn.html

In addition I added a simple wrapper that mmaps a json
file and provides some straight forward access functions.

Used in follow-on patches to parse event files.

Acked-by: Namhyung Kim 
Signed-off-by: Andi Kleen 
Signed-off-by: Sukadev Bhattiprolu 
---

v2: Address review feedback.
v3: Minor checkpatch fixes.
v4 (by Sukadev Bhattiprolu)
- Rebase to 4.0 and fix minor conflicts in tools/perf/Makefile.perf
- Report error if specified events file is invalid.
v5 (Sukadev Bhattiprolu)
- Move files to tools/perf/pmu-events/ since parsing of JSON file
now occurs when _building_ rather than running perf.
---
 tools/perf/pmu-events/jsmn.c |  313 ++
 tools/perf/pmu-events/jsmn.h |   67 +
 tools/perf/pmu-events/json.c |  162 ++
 tools/perf/pmu-events/json.h |   36 +
 4 files changed, 578 insertions(+)
 create mode 100644 tools/perf/pmu-events/jsmn.c
 create mode 100644 tools/perf/pmu-events/jsmn.h
 create mode 100644 tools/perf/pmu-events/json.c
 create mode 100644 tools/perf/pmu-events/json.h

diff --git a/tools/perf/pmu-events/jsmn.c b/tools/perf/pmu-events/jsmn.c
new file mode 100644
index 000..11d1fa1
--- /dev/null
+++ b/tools/perf/pmu-events/jsmn.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2010 Serge A. Zaitsev
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * Slightly modified by AK to not assume 0 terminated input.
+ */
+
+#include 
+#include "jsmn.h"
+
+/*
+ * Allocates a fresh unused token from the token pool.
+ */
+static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
+  jsmntok_t *tokens, size_t num_tokens)
+{
+   jsmntok_t *tok;
+
+   if ((unsigned)parser->toknext >= num_tokens)
+   return NULL;
+   tok = &tokens[parser->toknext++];
+   tok->start = tok->end = -1;
+   tok->size = 0;
+   return tok;
+}
+
+/*
+ * Fills token type and boundaries.
+ */
+static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
+   int start, int end)
+{
+   token->type = type;
+   token->start = start;
+   token->end = end;
+   token->size = 0;
+}
+
+/*
+ * Fills next available token with JSON primitive.
+ */
+static jsmnerr_t jsmn_parse_primitive(jsmn_parser *parser, const char *js,
+ size_t len,
+ jsmntok_t *tokens, size_t num_tokens)
+{
+   jsmntok_t *token;
+   int start;
+
+   start = parser->pos;
+
+   for (; parser->pos < len; parser->pos++) {
+   switch (js[parser->pos]) {
+#ifndef JSMN_STRICT
+   /*
+* In strict mode primitive must be followed by ","
+* or "}" or "]"
+*/
+   case ':':
+#endif
+   case '\t':
+   case '\r':
+   case '\n':
+   case ' ':
+   case ',':
+   case ']':
+   case '}':
+   goto found;
+   default:
+   break;
+   }
+   if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
+   parser->pos = start;
+   return JSMN_ERROR_INVAL;
+   }
+   }
+#ifdef JSMN_STRICT
+   /*
+* In strict mode primitive must be fol

Re: [PATCH V5 0/3] THP related cleanups

2015-05-19 Thread Andrew Morton
On Fri, 15 May 2015 21:12:27 +0530 "Aneesh Kumar K.V" 
 wrote:

> Changes from V4:
> * Folded patches in -mm
>   mm-thp-split-out-pmd-collpase-flush-into-a-separate-functions-fix.patch
>   mm-thp-split-out-pmd-collpase-flush-into-a-separate-functions-fix-2.patch
>   mm-clarify-that-the-function-operateds-on-hugepage-pte-fix.patch
> * Fix VM_BUG_ON on x86.
>  the default implementation of pmdp_collapse_flush used the hugepage variant
>  and hence can be called on pmd_t pointing to pgtable. This resulting in us
>  hitting VM_BUG_ON in pmdp_clear_flush. Update powerpc/mm: Use generic 
> version of pmdp_clear_flush
>  to handle this.
> 
> 
> NOTE: Can we get this tested on s390 ?

fwiw, I build tested s390 allmodconfig in mm/ and arch/s390, no issues.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH 0/3] Allow user to request memory to be locked on page fault

2015-05-19 Thread Eric B Munson
On Fri, 15 May 2015, Eric B Munson wrote:

> On Thu, 14 May 2015, Michal Hocko wrote:
> 
> > On Wed 13-05-15 11:00:36, Eric B Munson wrote:
> > > On Mon, 11 May 2015, Eric B Munson wrote:
> > > 
> > > > On Fri, 08 May 2015, Andrew Morton wrote:
> > > > 
> > > > > On Fri,  8 May 2015 15:33:43 -0400 Eric B Munson  
> > > > > wrote:
> > > > > 
> > > > > > mlock() allows a user to control page out of program memory, but 
> > > > > > this
> > > > > > comes at the cost of faulting in the entire mapping when it is
> > > > > > allocated.  For large mappings where the entire area is not 
> > > > > > necessary
> > > > > > this is not ideal.
> > > > > > 
> > > > > > This series introduces new flags for mmap() and mlockall() that 
> > > > > > allow a
> > > > > > user to specify that the covered are should not be paged out, but 
> > > > > > only
> > > > > > after the memory has been used the first time.
> > > > > 
> > > > > Please tell us much much more about the value of these changes: the 
> > > > > use
> > > > > cases, the behavioural improvements and performance results which the
> > > > > patchset brings to those use cases, etc.
> > > > > 
> > > > 
> > > > To illustrate the proposed use case I wrote a quick program that mmaps
> > > > a 5GB file which is filled with random data and accesses 150,000 pages
> > > > from that mapping.  Setup and processing were timed separately to
> > > > illustrate the differences between the three tested approaches.  the
> > > > setup portion is simply the call to mmap, the processing is the
> > > > accessing of the various locations in  that mapping.  The following
> > > > values are in milliseconds and are the averages of 20 runs each with a
> > > > call to echo 3 > /proc/sys/vm/drop_caches between each run.
> > > > 
> > > > The first mapping was made with MAP_PRIVATE | MAP_LOCKED as a baseline:
> > > > Startup average:9476.506
> > > > Processing average: 3.573
> > > > 
> > > > The second mapping was simply MAP_PRIVATE but each page was passed to
> > > > mlock() before being read:
> > > > Startup average:0.051
> > > > Processing average: 721.859
> > > > 
> > > > The final mapping was MAP_PRIVATE | MAP_LOCKONFAULT:
> > > > Startup average:0.084
> > > > Processing average: 42.125
> > > > 
> > > 
> > > Michal's suggestion of changing protections and locking in a signal
> > > handler was better than the locking as needed, but still significantly
> > > more work required than the LOCKONFAULT case.
> > > 
> > > Startup average:0.047
> > > Processing average: 86.431
> > 
> > Have you played with batching? Has it helped? Anyway it is to be
> > expected that the overhead will be higher than a single mmap call. The
> > question is whether you can live with it because adding a new semantic
> > to mlock sounds trickier and MAP_LOCKED is tricky enough already...
> > 
> 
> I reworked the experiment to better cover the batching solution.  The
> same 5GB data file is used, however instead of 150,000 accesses at
> regular intervals, the test program now does 15,000,000 accesses to
> random pages in the mapping.  The rest of the setup remains the same.
> 
> mmap with MAP_LOCKED:
> Setup avg:  11821.193
> Processing avg: 3404.286
> 
> mmap with mlock() before each access:
> Setup avg:  0.054
> Processing avg: 34263.201
> 
> mmap with PROT_NONE and signal handler and batch size of 1 page:
> With the default value in max_map_count, this gets ENOMEM as I attempt
> to change the permissions, after upping the sysctl significantly I get:
> Setup avg:  0.050
> Processing avg: 67690.625
> 
> mmap with PROT_NONE and signal handler and batch size of 8 pages:
> Setup avg:  0.098
> Processing avg: 37344.197
> 
> mmap with PROT_NONE and signal handler and batch size of 16 pages:
> Setup avg:  0.0548
> Processing avg: 29295.669
> 
> mmap with MAP_LOCKONFAULT:
> Setup avg:  0.073
> Processing avg: 18392.136
> 
> The signal handler in the batch cases faulted in memory in two steps to
> avoid having to know the start and end of the faulting mapping.  The
> first step covers the page that caused the fault as we know that it will
> be possible to lock.  The second step speculatively tries to mlock and
> mprotect the batch size - 1 pages that follow.  There may be a clever
> way to avoid this without having the program track each mapping to be
> covered by this handeler in a globally accessible structure, but I could
> not find it.
> 
> These results show that if the developer knows that a majority of the
> mapping will be used, it is better to try and fault it in at once,
> otherwise MAP_LOCKONFAULT is significantly faster.
> 
> Eric

Is there anything else I can add to the discussion here?



signature.asc
Description: Digital signature
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH] powerpc: Make doorbell check preemption safe

2015-05-19 Thread Shreyas B. Prabhu
Doorbell can be used to cause ipi on cpus which are sibling threads on
the same core. So icp_native_cause_ipi checks if the destination cpu
is a sibling thread of the current cpu and uses doorbell in such cases.

But while running with CONFIG_PREEMPT=y, since this section is
preemtible, we can run into issues if after we check if the destination
cpu is a sibling cpu, the task gets migrated from a sibling cpu to a
cpu on another core.

Fix this by using get_cpu()/ put_cpu()

Signed-off-by: Shreyas B. Prabhu 
---
 arch/powerpc/sysdev/xics/icp-native.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/sysdev/xics/icp-native.c 
b/arch/powerpc/sysdev/xics/icp-native.c
index 2fc4cf1..62fd478 100644
--- a/arch/powerpc/sysdev/xics/icp-native.c
+++ b/arch/powerpc/sysdev/xics/icp-native.c
@@ -147,12 +147,16 @@ static void icp_native_cause_ipi(int cpu, unsigned long 
data)
 {
kvmppc_set_host_ipi(cpu, 1);
 #ifdef CONFIG_PPC_DOORBELL
-   if (cpu_has_feature(CPU_FTR_DBELL) &&
-   (cpumask_test_cpu(cpu, cpu_sibling_mask(smp_processor_id()
-   doorbell_cause_ipi(cpu, data);
-   else
+   if (cpu_has_feature(CPU_FTR_DBELL)) {
+   if (cpumask_test_cpu(cpu, cpu_sibling_mask(get_cpu( {
+   doorbell_cause_ipi(cpu, data);
+   put_cpu();
+   return;
+   }
+   put_cpu();
+   }
 #endif
-   icp_native_set_qirr(cpu, IPI_PRIORITY);
+   icp_native_set_qirr(cpu, IPI_PRIORITY);
 }
 
 /*
-- 
1.9.3

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3 2/2] powerpc: add support for csum_add()

2015-05-19 Thread Christophe Leroy
The C version of csum_add() as defined in include/net/checksum.h gives the
following assembly in ppc32:
   0:   7c 04 1a 14 add r0,r4,r3
   4:   7c 64 00 10 subfc   r3,r4,r0
   8:   7c 63 19 10 subfe   r3,r3,r3
   c:   7c 63 00 50 subfr3,r3,r0
and the following in ppc64:
   0xc0001af8 <+0>: add r3,r3,r4
   0xc0001afc <+4>: cmplw   cr7,r3,r4
   0xc0001b00 <+8>: mfcrr4
   0xc0001b04 <+12>:rlwinm  r4,r4,29,31,31
   0xc0001b08 <+16>:add r3,r4,r3
   0xc0001b0c <+20>:clrldi  r3,r3,32
   0xc0001b10 <+24>:blr

include/net/checksum.h also offers the possibility to define an arch specific
function.
This patch provides a specific csum_add() inline function.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/checksum.h | 16 
 1 file changed, 16 insertions(+)

diff --git a/arch/powerpc/include/asm/checksum.h 
b/arch/powerpc/include/asm/checksum.h
index 5e43d2d..e8d9ef4 100644
--- a/arch/powerpc/include/asm/checksum.h
+++ b/arch/powerpc/include/asm/checksum.h
@@ -130,6 +130,22 @@ static inline __sum16 csum_tcpudp_magic(__be32 saddr, 
__be32 daddr,
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
 }
 
+#define HAVE_ARCH_CSUM_ADD
+static inline __wsum csum_add(__wsum csum, __wsum addend)
+{
+#ifdef __powerpc64__
+   u64 res = (__force u64)csum;
+
+   res += (__force u64)addend;
+   return (__force __wsum)((u32)res + (res >> 32));
+#else
+   asm("addc %0,%0,%1;"
+   "addze %0,%0;"
+   : "+r" (csum) : "r" (addend));
+   return csum;
+#endif
+}
+
 #endif
 #endif /* __KERNEL__ */
 #endif
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3 1/2] powerpc: put csum_tcpudp_magic inline

2015-05-19 Thread Christophe Leroy
csum_tcpudp_magic() is only a few instructions, and does modify
really few registers. So it is not worth having it as a separate
function and suffer function branching and saving of volatile
registers.

This patch makes it inline by use of the already existing
csum_tcpudp_nofold() function.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/checksum.h | 21 -
 arch/powerpc/lib/checksum_32.S  | 16 
 arch/powerpc/lib/checksum_64.S  | 21 -
 3 files changed, 12 insertions(+), 46 deletions(-)

diff --git a/arch/powerpc/include/asm/checksum.h 
b/arch/powerpc/include/asm/checksum.h
index 8251a3b..5e43d2d 100644
--- a/arch/powerpc/include/asm/checksum.h
+++ b/arch/powerpc/include/asm/checksum.h
@@ -20,15 +20,6 @@
 extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
 
 /*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-extern __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
-   unsigned short len,
-   unsigned short proto,
-   __wsum sum);
-
-/*
  * computes the checksum of a memory block at buff, length len,
  * and adds in "sum" (32-bit)
  *
@@ -127,6 +118,18 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, 
__be32 daddr,
 #endif
 }
 
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
+   unsigned short len,
+   unsigned short proto,
+   __wsum sum)
+{
+   return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
+}
+
 #endif
 #endif /* __KERNEL__ */
 #endif
diff --git a/arch/powerpc/lib/checksum_32.S b/arch/powerpc/lib/checksum_32.S
index e23a436..d6fab08 100644
--- a/arch/powerpc/lib/checksum_32.S
+++ b/arch/powerpc/lib/checksum_32.S
@@ -41,22 +41,6 @@ _GLOBAL(ip_fast_csum)
blr
 
 /*
- * Compute checksum of TCP or UDP pseudo-header:
- *   csum_tcpudp_magic(saddr, daddr, len, proto, sum)
- */
-_GLOBAL(csum_tcpudp_magic)
-   rlwimi  r5,r6,16,0,15   /* put proto in upper half of len */
-   addcr0,r3,r4/* add 4 32-bit words together */
-   adder0,r0,r5
-   adder0,r0,r7
-   addze   r0,r0   /* add in final carry */
-   rlwinm  r3,r0,16,0,31   /* fold two halves together */
-   add r3,r0,r3
-   not r3,r3
-   srwir3,r3,16
-   blr
-
-/*
  * computes the checksum of a memory block at buff, length len,
  * and adds in "sum" (32-bit)
  *
diff --git a/arch/powerpc/lib/checksum_64.S b/arch/powerpc/lib/checksum_64.S
index 57a0720..f3ef354 100644
--- a/arch/powerpc/lib/checksum_64.S
+++ b/arch/powerpc/lib/checksum_64.S
@@ -45,27 +45,6 @@ _GLOBAL(ip_fast_csum)
blr
 
 /*
- * Compute checksum of TCP or UDP pseudo-header:
- *   csum_tcpudp_magic(r3=saddr, r4=daddr, r5=len, r6=proto, r7=sum)
- * No real gain trying to do this specially for 64 bit, but
- * the 32 bit addition may spill into the upper bits of
- * the doubleword so we still must fold it down from 64.
- */
-_GLOBAL(csum_tcpudp_magic)
-   rlwimi  r5,r6,16,0,15   /* put proto in upper half of len */
-   addcr0,r3,r4/* add 4 32-bit words together */
-   adder0,r0,r5
-   adder0,r0,r7
-rldicl  r4,r0,32,0  /* fold 64 bit value */
-add r0,r4,r0
-srdir0,r0,32
-   rlwinm  r3,r0,16,0,31   /* fold two halves together */
-   add r3,r0,r3
-   not r3,r3
-   srwir3,r3,16
-   blr
-
-/*
  * Computes the checksum of a memory block at buff, length len,
  * and adds in "sum" (32-bit).
  *
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v3 0/2] Optimise some IP checksum functions.

2015-05-19 Thread Christophe Leroy
This patchset provides a few optimisations related to IP checksum functions.

Christophe Leroy (2):
  powerpc: put csum_tcpudp_magic inline
  powerpc: add support for csum_add()

 arch/powerpc/include/asm/checksum.h | 37 -
 arch/powerpc/lib/checksum_32.S  | 16 
 arch/powerpc/lib/checksum_64.S  | 21 -
 3 files changed, 28 insertions(+), 46 deletions(-)

-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH V8 13/28] powerpc, ptrace: Enable support for NT_PPPC_TAR, NT_PPC_PPR, NT_PPC_DSCR

2015-05-19 Thread Anshuman Khandual
This patch enables support for running TAR, PPR, DSCR registers
related ELF core notes NT_PPPC_TAR, NT_PPC_PPR, NT_PPC_DSCR based
ptrace requests through PTRACE_GETREGSET, PTRACE_SETREGSET calls.
This is achieved through adding three new register sets REGSET_TAR,
REGSET_PPR, REGSET_DSCR in powerpc corresponding to the ELF core
note sections added in this regad. It implements the get, set and
active functions for all these new register sets added.

Signed-off-by: Anshuman Khandual 
---
 arch/powerpc/kernel/ptrace.c | 117 +++
 1 file changed, 117 insertions(+)

diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 774f5c20..533c787 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1688,6 +1688,78 @@ static int tm_dscr_set(struct task_struct *target,
 }
 #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
 
+#ifdef CONFIG_PPC64
+static int ppr_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+   int ret;
+
+   ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+   &target->thread.ppr, 0, sizeof(u64));
+   return ret;
+}
+
+static int ppr_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;
+
+   ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+   &target->thread.ppr, 0, sizeof(u64));
+   return ret;
+}
+
+static int dscr_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+   int ret;
+
+   ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+   &target->thread.dscr, 0, sizeof(u64));
+   return ret;
+}
+static int dscr_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;
+
+   ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+   &target->thread.dscr, 0, sizeof(u64));
+   return ret;
+}
+#endif
+#ifdef CONFIG_PPC_BOOK3S_64
+static int tar_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+   int ret;
+
+   ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+   &target->thread.tar, 0, sizeof(u64));
+   return ret;
+}
+static int tar_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;
+
+   ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+   &target->thread.tar, 0, sizeof(u64));
+   return ret;
+}
+#endif
 /*
  * These are our native regset flavors.
  */
@@ -1713,6 +1785,13 @@ enum powerpc_regset {
REGSET_TM_CPPR, /* TM checkpointed PPR register */
REGSET_TM_CDSCR,/* TM checkpointed DSCR register */
 #endif
+#ifdef CONFIG_PPC64
+   REGSET_PPR, /* PPR register */
+   REGSET_DSCR,/* DSCR register */
+#endif
+#ifdef CONFIG_PPC_BOOK3S_64
+   REGSET_TAR, /* TAR register */
+#endif
 };
 
 static const struct user_regset native_regsets[] = {
@@ -1789,6 +1868,25 @@ static const struct user_regset native_regsets[] = {
.active = tm_dscr_active, .get = tm_dscr_get, .set = tm_dscr_set
},
 #endif
+#ifdef CONFIG_PPC64
+   [REGSET_PPR] = {
+   .core_note_type = NT_PPC_PPR, .n = 1,
+   .size = sizeof(u64), .align = sizeof(u64),
+   .get = ppr_get, .set = ppr_set
+   },
+   [REGSET_DSCR] = {
+   .core_note_type = NT_PPC_DSCR, .n = 1,
+   .size = sizeof(u64), .align = sizeof(u64),
+   .get = dscr_get, .set = dscr_set
+   },
+#endif
+#ifdef CONFIG_PPC_BOOK3S_64
+   [REGSET_TAR] = {
+   .core_note_type = NT_PPC_TAR, .n = 1,
+   .size = sizeof(u64), .align = sizeof(u64),
+   .get = tar_get, .set = tar_set
+   },
+#endif
 };
 
 static const struct user_regset_view user_ppc_native_view = {
@@ -2056,6 +2154,25 @@ static const struct user_regset compat_regsets[] = {
.active = tm_dscr_active, .get = tm_dscr_get, .set = tm_dscr_set
},
 #endif
+#ifdef CONFIG_PPC64
+   

[PATCH V8 20/28] selftests, powerpc: Add ptrace tests for GPR/FPR registers in suspended TM

2015-05-19 Thread Anshuman Khandual
This patch adds ptrace interface test for GPR/FPR registers
inside suspended TM context.

Signed-off-by: Anshuman Khandual 
---
 tools/testing/selftests/powerpc/ptrace/Makefile|   2 +-
 .../selftests/powerpc/ptrace/ptrace-tm-spd-gpr.c   | 318 +
 2 files changed, 319 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-gpr.c

diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile 
b/tools/testing/selftests/powerpc/ptrace/Makefile
index 4d7cbe8..a8fa080 100644
--- a/tools/testing/selftests/powerpc/ptrace/Makefile
+++ b/tools/testing/selftests/powerpc/ptrace/Makefile
@@ -1,4 +1,4 @@
-TEST_PROGS := ptrace-ebb ptrace-gpr ptrace-tm-gpr
+TEST_PROGS := ptrace-ebb ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr
 
 all: $(TEST_PROGS)
 
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-gpr.c 
b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-gpr.c
new file mode 100644
index 000..a8d656b
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-gpr.c
@@ -0,0 +1,318 @@
+/*
+ * Ptrace test for GPR/FPR registers in TM Suspend context
+ *
+ * Copyright 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * 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.
+ */
+#include "ptrace.h"
+#include "ptrace-gpr.h"
+
+/* Tracer and Tracee Shared Data */
+int shm_id;
+volatile int *cptr, *pptr;
+
+extern void store_gpr(unsigned long *addr);
+extern void store_fpr(float *addr);
+
+float a = FPR_1;
+float b = FPR_2;
+float c = FPR_3;
+float d = FPR_4;
+
+__attribute__((used)) void wait_parent(void)
+{
+   while(!cptr[1]);
+}
+
+void tm_spd_gpr(void)
+{
+   unsigned long gpr_buf[18];
+   unsigned long result, texasr;
+   float fpr_buf[32];
+
+   cptr = (int *)shmat(shm_id, NULL, 0);
+
+trans:
+   asm __volatile__(
+
+   "li 14, %[gpr_1];"
+   "li 15, %[gpr_1];"
+   "li 16, %[gpr_1];"
+   "li 17, %[gpr_1];"
+   "li 18, %[gpr_1];"
+   "li 19, %[gpr_1];"
+   "li 20, %[gpr_1];"
+   "li 21, %[gpr_1];"
+   "li 22, %[gpr_1];"
+   "li 23, %[gpr_1];"
+   "li 24, %[gpr_1];"
+   "li 25, %[gpr_1];"
+   "li 26, %[gpr_1];"
+   "li 27, %[gpr_1];"
+   "li 28, %[gpr_1];"
+   "li 29, %[gpr_1];"
+   "li 30, %[gpr_1];"
+   "li 31, %[gpr_1];"
+
+   "lfs 0, 0(%[flt_1]);"
+   "lfs 1, 0(%[flt_1]);"
+   "lfs 2, 0(%[flt_1]);"
+   "lfs 3, 0(%[flt_1]);"
+   "lfs 4, 0(%[flt_1]);"
+   "lfs 5, 0(%[flt_1]);"
+   "lfs 6, 0(%[flt_1]);"
+   "lfs 7, 0(%[flt_1]);"
+   "lfs 8, 0(%[flt_1]);"
+   "lfs 9, 0(%[flt_1]);"
+   "lfs 10, 0(%[flt_1]);"
+   "lfs 11, 0(%[flt_1]);"
+   "lfs 12, 0(%[flt_1]);"
+   "lfs 13, 0(%[flt_1]);"
+   "lfs 14, 0(%[flt_1]);"
+   "lfs 15, 0(%[flt_1]);"
+   "lfs 16, 0(%[flt_1]);"
+   "lfs 17, 0(%[flt_1]);"
+   "lfs 18, 0(%[flt_1]);"
+   "lfs 19, 0(%[flt_1]);"
+   "lfs 20, 0(%[flt_1]);"
+   "lfs 21, 0(%[flt_1]);"
+   "lfs 22, 0(%[flt_1]);"
+   "lfs 23, 0(%[flt_1]);"
+   "lfs 24, 0(%[flt_1]);"
+   "lfs 25, 0(%[flt_1]);"
+   "lfs 26, 0(%[flt_1]);"
+   "lfs 27, 0(%[flt_1]);"
+   "lfs 28, 0(%[flt_1]);"
+   "lfs 29, 0(%[flt_1]);"
+   "lfs 30, 0(%[flt_1]);"
+   "lfs 31, 0(%[flt_1]);"
+
+   "1: ;"
+   TBEGIN
+   "beq 2f;"
+
+   "li 14, %[gpr_2];"
+   "li 15, %[gpr_2];"
+   "li 16, %[gpr_2];"
+   "li 17, %[gpr_2];"
+   "li 18, %[gpr_2];"
+   "li 19, %[gpr_2];"
+   "li 20, %[gpr_2];"
+   "li 21, %[gpr_2];"
+   "li 22, %[gpr_2];"
+   "li 23, %[gpr_2];"
+   "li 24, %[gpr_2];"
+   "li 25, %[gpr_2];"
+   "li 26, %[gpr_2];"
+   "li 27, %[gpr_2];"
+   "li 28, %[gpr_2];"
+   "li 29, %[gpr_2];"
+   "li 30, %[gpr_2];"
+   "li 31, %[gpr_2];"
+
+   TSUSPEND
+
+   "li 14, %[gpr_4];"
+   "li 15, %[gpr_4];"
+   "li 16, %[gpr_4];"
+   "li 17, %[gpr_4];"
+   "li 18, %[gpr_4];"
+   "li 19, %[gpr_4];"
+   "li 20, %[gpr_4];"
+   "li 21, %[gpr_4];"
+   "li 22, %[gpr_4];"
+   "li 23, %[gpr

[PATCH V8 19/28] selftests, powerpc: Add ptrace tests for GPR/FPR registers in TM

2015-05-19 Thread Anshuman Khandual
This patch adds ptrace interface test for GPR/FPR registers
inside TM context. This adds ptrace interface based helper
functions related to checkpointed GPR/FPR access.

Signed-off-by: Anshuman Khandual 
---
 tools/testing/selftests/powerpc/ptrace/Makefile|   3 +-
 .../selftests/powerpc/ptrace/ptrace-tm-gpr.c   | 287 +
 2 files changed, 289 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tm-gpr.c

diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile 
b/tools/testing/selftests/powerpc/ptrace/Makefile
index dfeb36e..4d7cbe8 100644
--- a/tools/testing/selftests/powerpc/ptrace/Makefile
+++ b/tools/testing/selftests/powerpc/ptrace/Makefile
@@ -1,8 +1,9 @@
-TEST_PROGS := ptrace-ebb ptrace-gpr
+TEST_PROGS := ptrace-ebb ptrace-gpr ptrace-tm-gpr
 
 all: $(TEST_PROGS)
 
 $(TEST_PROGS): ../harness.c ptrace.S
 ptrace-ebb: ../pmu/event.c ../pmu/lib.c ../pmu/ebb/ebb_handler.S 
../pmu/ebb/busy_loop.S
+
 clean:
rm -f $(TEST_PROGS) *.o
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-gpr.c 
b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-gpr.c
new file mode 100644
index 000..a94c413
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-gpr.c
@@ -0,0 +1,287 @@
+/*
+ * Ptrace test for GPR/FPR registers in TM context
+ *
+ * Copyright 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * 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.
+ */
+#include "ptrace.h"
+#include "ptrace-gpr.h"
+
+/* Tracer and Tracee Shared Data */
+int shm_id;
+volatile int *cptr, *pptr;
+
+extern void store_gpr(unsigned long *addr);
+extern void store_fpr(float *addr);
+
+float a = FPR_1;
+float b = FPR_2;
+float c = FPR_3;
+
+void tm_gpr(void)
+{
+   unsigned long gpr_buf[18];
+   unsigned long result, texasr;
+   float fpr_buf[32];
+
+   printf("Starting the child\n");
+   cptr = (int *)shmat(shm_id, NULL, 0);
+
+trans:
+   asm __volatile__(
+
+   "li 14, %[gpr_1];"
+   "li 15, %[gpr_1];"
+   "li 16, %[gpr_1];"
+   "li 17, %[gpr_1];"
+   "li 18, %[gpr_1];"
+   "li 19, %[gpr_1];"
+   "li 20, %[gpr_1];"
+   "li 21, %[gpr_1];"
+   "li 22, %[gpr_1];"
+   "li 23, %[gpr_1];"
+   "li 24, %[gpr_1];"
+   "li 25, %[gpr_1];"
+   "li 26, %[gpr_1];"
+   "li 27, %[gpr_1];"
+   "li 28, %[gpr_1];"
+   "li 29, %[gpr_1];"
+   "li 30, %[gpr_1];"
+   "li 31, %[gpr_1];"
+
+   "lfs 0, 0(%[flt_1]);"
+   "lfs 1, 0(%[flt_1]);"
+   "lfs 2, 0(%[flt_1]);"
+   "lfs 3, 0(%[flt_1]);"
+   "lfs 4, 0(%[flt_1]);"
+   "lfs 5, 0(%[flt_1]);"
+   "lfs 6, 0(%[flt_1]);"
+   "lfs 7, 0(%[flt_1]);"
+   "lfs 8, 0(%[flt_1]);"
+   "lfs 9, 0(%[flt_1]);"
+   "lfs 10, 0(%[flt_1]);"
+   "lfs 11, 0(%[flt_1]);"
+   "lfs 12, 0(%[flt_1]);"
+   "lfs 13, 0(%[flt_1]);"
+   "lfs 14, 0(%[flt_1]);"
+   "lfs 15, 0(%[flt_1]);"
+   "lfs 16, 0(%[flt_1]);"
+   "lfs 17, 0(%[flt_1]);"
+   "lfs 18, 0(%[flt_1]);"
+   "lfs 19, 0(%[flt_1]);"
+   "lfs 20, 0(%[flt_1]);"
+   "lfs 21, 0(%[flt_1]);"
+   "lfs 22, 0(%[flt_1]);"
+   "lfs 23, 0(%[flt_1]);"
+   "lfs 24, 0(%[flt_1]);"
+   "lfs 25, 0(%[flt_1]);"
+   "lfs 26, 0(%[flt_1]);"
+   "lfs 27, 0(%[flt_1]);"
+   "lfs 28, 0(%[flt_1]);"
+   "lfs 29, 0(%[flt_1]);"
+   "lfs 30, 0(%[flt_1]);"
+   "lfs 31, 0(%[flt_1]);"
+
+   "1: ;"
+   TBEGIN
+   "beq 2f;"
+
+   "li 14, %[gpr_2];"
+   "li 15, %[gpr_2];"
+   "li 16, %[gpr_2];"
+   "li 17, %[gpr_2];"
+   "li 18, %[gpr_2];"
+   "li 19, %[gpr_2];"
+   "li 20, %[gpr_2];"
+   "li 21, %[gpr_2];"
+   "li 22, %[gpr_2];"
+   "li 23, %[gpr_2];"
+   "li 24, %[gpr_2];"
+   "li 25, %[gpr_2];"
+   "li 26, %[gpr_2];"
+   "li 27, %[gpr_2];"
+   "li 28, %[gpr_2];"
+   "li 29, %[gpr_2];"
+   "li 30, %[gpr_2];"
+   "li 31, %[gpr_2];"
+
+
+   "lfs 0, 0(%[flt_2]);"
+   "lfs 1, 0(%[flt_2]);"
+   "lfs 2, 0(%[flt_2]);"
+   "lfs 3, 0(%[flt_2]);"
+   "lfs 4, 0(%[flt_2]);"
+   "lfs 5, 0(%[flt_2]);"
+   

[PATCH V8 08/28] powerpc, ptrace: Enable support for NT_PPC_CFPR

2015-05-19 Thread Anshuman Khandual
This patch enables support for TM checkpointed FPR register
set ELF core note NT_PPC_CFPR based ptrace requests through
PTRACE_GETREGSET, PTRACE_SETREGSET calls. This is achieved
through adding a register set REGSET_CFPR in powerpc
corresponding to the ELF core note section added. It
implements the get, set and active functions for this new
register set added.

Signed-off-by: Anshuman Khandual 
---
 arch/powerpc/kernel/ptrace.c | 126 +++
 1 file changed, 126 insertions(+)

diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 28b788b..35df932 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1031,6 +1031,121 @@ static int tm_cgpr_set(struct task_struct *target,
 
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;
+}
 #endif
 
 /*
@@ -1050,6 +1165,7 @@ enum powerpc_regset {
 #endif
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
REGSET_TM_CGPR, /* TM checkpointed GPR registers */
+   REGSET_TM_CFPR, /* TM checkpointed FPR registers */
 #endif
 };
 
@@ -1091,6 +1207,11 @@ static const struct user_regset native_regsets[] = {
.size = sizeof(long), .align = sizeof(long),
.active = tm_cgpr_active, .get = tm_cgpr_get, .set = tm_cgpr_set
},
+   [REGSET_TM_CFPR]

[PATCH V8 11/28] powerpc, ptrace: Enable support for TM SPR state

2015-05-19 Thread Anshuman Khandual
This patch enables support for TM SPR state related ELF core
note NT_PPC_TM_SPR based ptrace requests through PTRACE_GETREGSET,
PTRACE_SETREGSET calls. This is achieved through adding a register
set REGSET_TM_SPR in powerpc corresponding to the ELF core note
section added. It implements the get, set and active functions for
this new register set added.

Signed-off-by: Anshuman Khandual 
---
 arch/powerpc/include/uapi/asm/elf.h |   1 +
 arch/powerpc/kernel/ptrace.c| 143 +++-
 2 files changed, 143 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/uapi/asm/elf.h 
b/arch/powerpc/include/uapi/asm/elf.h
index 4477318..9e6b6e3 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_NVSX   32  /* includes all VSX registers */
+#define ELF_NTMSPRREG  3   /* include tfhar, tfiar, texasr */
 
 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 3497d26..228cdcf 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -65,6 +65,7 @@ struct pt_regs_offset {
 
 #define TVSO(f)(offsetof(struct thread_vr_state, f))
 #define TFSO(f)(offsetof(struct thread_fp_state, f))
+#define TSO(f) (offsetof(struct thread_struct, f))
 
 static const struct pt_regs_offset regoffset_table[] = {
GPR_OFFSET_NAME(0),
@@ -1411,7 +1412,136 @@ static int tm_cvsx_set(struct task_struct *target,
 
return ret;
 }
-#endif
+
+/**
+ * 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;
+
+   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;
+ * };
+ */
+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));
+
+   if (!cpu_has_feature(CPU_FTR_TM))
+   return -ENODEV;
+
+   /* 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));
+   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;
+ * };
+ */
+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_

[PATCH V8 10/28] powerpc, ptrace: Enable support for NT_PPC_CVSX

2015-05-19 Thread Anshuman Khandual
This patch enables support for TM checkpointed VSX register
set ELF core note NT_PPC_CVSX based ptrace requests through
PTRACE_GETREGSET, PTRACE_SETREGSET calls. This is achieved
through adding a register set REGSET_CVSX in powerpc
corresponding to the ELF core note section added. It
implements the get, set and active functions for this new
register set added.

Signed-off-by: Anshuman Khandual 
---
 arch/powerpc/include/uapi/asm/elf.h |   1 +
 arch/powerpc/kernel/ptrace.c| 129 
 2 files changed, 130 insertions(+)

diff --git a/arch/powerpc/include/uapi/asm/elf.h 
b/arch/powerpc/include/uapi/asm/elf.h
index 6c900be..4477318 100644
--- a/arch/powerpc/include/uapi/asm/elf.h
+++ b/arch/powerpc/include/uapi/asm/elf.h
@@ -92,6 +92,7 @@
 #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_NVSX   32  /* includes all VSX registers */
 
 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 4faad8c..3497d26 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -64,6 +64,7 @@ struct pt_regs_offset {
 #define REG_OFFSET_END {.name = NULL, .offset = 0}
 
 #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),
@@ -1293,6 +1294,123 @@ static int tm_cvmx_set(struct task_struct *target,
 
return ret;
 }
+
+/**
+ * tm_cvsx_active - get active number of registers in CVSX
+ * @target:The target task.
+ * @regset:The user regset structure.
+ *
+ * This function checks for the active number of available
+ * regisers in transaction checkpointed VSX category.
+ */
+static int tm_cvsx_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;
+
+   flush_vsx_to_thread(target);
+   return target->thread.used_vsr ? regset->n : 0;
+}
+
+/**
+ * tm_cvsx_get - get CVSX 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 VSX 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 VSX registers.
+ * The userspace interface buffer layout is as follows.
+ *
+ * struct data {
+ * u64 vsx[32];
+ *};
+ */
+static int tm_cvsx_get(struct task_struct *target,
+   const struct user_regset *regset,
+   unsigned int pos, unsigned int count,
+   void *kbuf, void __user *ubuf)
+{
+   u64 buf[32];
+   int ret, i;
+
+   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);
+   flush_vsx_to_thread(target);
+
+   for (i = 0; i < 32 ; i++)
+   buf[i] = target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
+   ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ buf, 0, 32 * sizeof(double));
+
+   return ret;
+}
+
+/**
+ * tm_cvsx_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 VSX registers.
+ *
+ * When the transaction is active 'fp_state' holds the checkpointed
+ * VSX 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 vsx[32];
+ *};
+ */
+static int tm_cvsx_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[32];
+   int ret, i;
+
+   if (!cpu_has_feature(CPU_FTR_TM))
+   return -ENODEV;
+
+   if (!MSR_TM_ACTIVE(target

[PATCH V8 06/28] powerpc, ptrace: Adapt gpr32_get, gpr32_set functions for transaction

2015-05-19 Thread Anshuman Khandual
This patch splits gpr32_get, gpr32_set functions to accommodate
in transaction ptrace requests implemented in patches later in
the series.

Signed-off-by: Anshuman Khandual 
---
 arch/powerpc/kernel/ptrace.c | 64 +++-
 1 file changed, 51 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 015f284..a8e4d19 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -906,24 +906,35 @@ static const struct user_regset_view user_ppc_native_view 
= {
 #ifdef CONFIG_PPC64
 #include 
 
-static int gpr32_get(struct task_struct *target,
+static int gpr32_get_common(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 tm_active)
 {
const unsigned long *regs = &target->thread.regs->gpr[0];
+   const unsigned long *ckpt_regs;
compat_ulong_t *k = kbuf;
compat_ulong_t __user *u = ubuf;
compat_ulong_t reg;
int i;
 
-   if (target->thread.regs == NULL)
-   return -EIO;
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+   ckpt_regs = &target->thread.ckpt_regs.gpr[0];
+#endif
+   if (tm_active) {
+   regs = ckpt_regs;
+   } else {
+   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; 
+   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;
+   }
}
 
pos /= sizeof(reg);
@@ -963,20 +974,31 @@ static int gpr32_get(struct task_struct *target,
PT_REGS_COUNT * sizeof(reg), -1);
 }
 
-static int gpr32_set(struct task_struct *target,
+static int gpr32_set_common(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 tm_active)
 {
unsigned long *regs = &target->thread.regs->gpr[0];
+   unsigned long *ckpt_regs;
const compat_ulong_t *k = kbuf;
const compat_ulong_t __user *u = ubuf;
compat_ulong_t reg;
 
-   if (target->thread.regs == NULL)
-   return -EIO;
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+   ckpt_regs = &target->thread.ckpt_regs.gpr[0];
+#endif
 
-   CHECK_FULL_REGS(target->thread.regs);
+   if (tm_active) {
+   regs = ckpt_regs;
+   } else {
+   regs = &target->thread.regs->gpr[0];
+
+   if (target->thread.regs == NULL)
+   return -EIO;
+
+   CHECK_FULL_REGS(target->thread.regs);
+   }
 
pos /= sizeof(reg);
count /= sizeof(reg);
@@ -1036,6 +1058,22 @@ static int gpr32_set(struct task_struct *target,
 (PT_TRAP + 1) * sizeof(reg), -1);
 }
 
+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 gpr32_get_common(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 gpr32_set_common(target, regset, pos, count, kbuf, ubuf, 0);
+}
+
 /*
  * These are the regset flavors matching the CONFIG_PPC32 native set.
  */
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH V8 09/28] powerpc, ptrace: Enable support for NT_PPC_CVMX

2015-05-19 Thread Anshuman Khandual
This patch enables support for TM checkpointed VMX register
set ELF core note NT_PPC_CVMX based ptrace requests through
PTRACE_GETREGSET, PTRACE_SETREGSET calls. This is achieved
through adding a register set REGSET_CVMX in powerpc
corresponding to the ELF core note section added. It
implements the get, set and active functions for this new
register set added.

Signed-off-by: Anshuman Khandual 
---
 arch/powerpc/include/uapi/asm/elf.h |   1 +
 arch/powerpc/kernel/ptrace.c| 158 
 2 files changed, 159 insertions(+)

diff --git a/arch/powerpc/include/uapi/asm/elf.h 
b/arch/powerpc/include/uapi/asm/elf.h
index 59dad11..6c900be 100644
--- a/arch/powerpc/include/uapi/asm/elf.h
+++ b/arch/powerpc/include/uapi/asm/elf.h
@@ -91,6 +91,7 @@
 
 #define ELF_NGREG  48  /* includes nip, msr, lr, etc. */
 #define ELF_NFPREG 33  /* includes fpscr */
+#define ELF_NVMX   34  /* includes all vector registers */
 
 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 35df932..4faad8c 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -63,6 +63,8 @@ struct pt_regs_offset {
{.name = STR(gpr##num), .offset = offsetof(struct pt_regs, gpr[num])}
 #define REG_OFFSET_END {.name = NULL, .offset = 0}
 
+#define TVSO(f)(offsetof(struct thread_vr_state, f))
+
 static const struct pt_regs_offset regoffset_table[] = {
GPR_OFFSET_NAME(0),
GPR_OFFSET_NAME(1),
@@ -1146,6 +1148,151 @@ static int tm_cfpr_set(struct task_struct *target,
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];
+ * 

[PATCH V8 22/28] selftests, powerpc: Add ptrace tests for TAR, PPR, DSCR in TM

2015-05-19 Thread Anshuman Khandual
This patch adds ptrace interface test for TAR, PPR, DSCR
registers inside TM context. This also adds ptrace
interface based helper functions related to checkpointed
TAR, PPR, DSCR register access.

Signed-off-by: Anshuman Khandual 
---
 tools/testing/selftests/powerpc/ptrace/Makefile|   2 +-
 .../selftests/powerpc/ptrace/ptrace-tm-tar.c   | 169 +
 2 files changed, 170 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tm-tar.c

diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile 
b/tools/testing/selftests/powerpc/ptrace/Makefile
index 28d4465..a5d177b 100644
--- a/tools/testing/selftests/powerpc/ptrace/Makefile
+++ b/tools/testing/selftests/powerpc/ptrace/Makefile
@@ -1,5 +1,5 @@
 TEST_PROGS := ptrace-ebb ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \
-ptrace-tar
+ptrace-tar ptrace-tm-tar
 
 all: $(TEST_PROGS)
 
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-tar.c 
b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-tar.c
new file mode 100644
index 000..2ae5b25
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-tar.c
@@ -0,0 +1,169 @@
+/*
+ * Ptrace test for TAR, PPR, DSCR registers in the TM context
+ *
+ * Copyright 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * 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.
+ */
+#include "ptrace.h"
+#include "ptrace-tar.h"
+
+int shm_id;
+volatile int *cptr, *pptr;
+
+
+void tm_tar(void)
+{
+   unsigned long result, texasr;
+   unsigned long regs[3];
+   int ret;
+
+   cptr = (int *)shmat(shm_id, NULL, 0);
+trans:
+   asm __volatile__(
+   "li 4, %[tar_1];"
+   "mtspr %[sprn_tar],  4;"/* TAR_1 */
+   "li 4, %[dscr_1];"
+   "mtspr %[sprn_dscr], 4;"/* DSCR_1 */
+   "or 31,31,31;"  /* PPR_1*/
+
+   "1: ;"
+   TBEGIN
+   "beq 2f;"
+
+   "li 4, %[tar_2];"
+   "mtspr %[sprn_tar],  4;"/* TAR_2 */
+   "li 4, %[dscr_2];"
+   "mtspr %[sprn_dscr], 4;"/* DSCR_2 */
+   "or 1,1,1;" /* PPR_2 */
+   TSUSPEND
+   TRESUME
+   "b .;"
+
+   TEND
+   "li 0, 0;"
+   "ori %[res], 0, 0;"
+   "b 3f;"
+
+   /* Transaction abort handler */
+   "2: ;"
+   "li 0, 1;"
+   "ori %[res], 0, 0;"
+   "mfspr %[texasr], %[sprn_texasr];"
+
+   "3: ;"
+
+   :[res] "=r" (result), [texasr] "=r" (texasr)
+   :[sprn_dscr]"i"(SPRN_DSCR), [sprn_tar]"i"(SPRN_TAR), 
[sprn_ppr]"i"(SPRN_PPR), [sprn_texasr]"i"(SPRN_TEXASR),
+   [tar_1]"i"(TAR_1), [dscr_1]"i"(DSCR_1),
+   [tar_2]"i"(TAR_2), [dscr_2]"i"(DSCR_2)
+   : "memory", "r0", "r1", "r3", "r4", "r5", "r6"
+   );
+
+   /* TM failed, analyse */
+   if (result) {
+   if (!cptr[0])
+   goto trans;
+   shmdt(&cptr);
+
+   regs[0] = mfspr(SPRN_TAR);
+   regs[1] = mfspr(SPRN_PPR);
+   regs[2] = mfspr(SPRN_DSCR);
+
+   printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n", user_read, 
regs[0], regs[1], regs[2]);
+
+   ret = validate_tar_registers(regs, TAR_4, PPR_4, DSCR_4);
+   if (ret)
+   exit(1);
+   exit(0);
+   }
+   shmdt(&cptr);
+   exit(1);
+}
+
+int trace_tm_tar(pid_t child)
+{
+   unsigned long regs[3];
+   int ret;
+
+   sleep(1);
+   ret = start_trace(child);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = show_tar_registers(child, regs);
+   if (ret)
+   return TEST_FAIL;
+
+   printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n", ptrace_read_running, 
regs[0], regs[1], regs[2]);
+
+   ret = validate_tar_registers(regs, TAR_2, PPR_2, DSCR_2);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = show_tm_checkpointed_state(child, regs);
+   if (ret)
+   return TEST_FAIL;
+
+   printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n", ptrace_read_ckpt, 
regs[0], regs[1], regs[2]);
+
+   ret = validate_tar_registers(regs, TAR_1, PPR_1, DSCR_1);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = write_ckpt_tar_registers(child, TAR_4, PPR_4, DSCR_4);
+   if (ret)
+   return TEST_FAIL;
+
+   printf("%-30s TAR: %u PPR: %lx DSCR: %u\n", ptrace_write_ckpt, TAR_4, 
PPR_4, DSCR_4);
+
+   ret = stop_trace(child);
+   if (ret)
+   return TEST_FAIL;
+   return TEST_PASS;
+}
+
+int ptrace_

[PATCH V8 24/28] selftests, powerpc: Add ptrace tests for VSX, VMX registers

2015-05-19 Thread Anshuman Khandual
This patch adds ptrace interface test for VSX, VMX registers.
This also adds ptrace interface based helper functions related
to VSX, VMX registers access. This also adds some assembly
helper functions related to VSX and VMX registers.

Signed-off-by: Anshuman Khandual 
---
 tools/testing/selftests/powerpc/ptrace/Makefile|   2 +-
 .../testing/selftests/powerpc/ptrace/ptrace-vsx.c  | 138 +++
 .../testing/selftests/powerpc/ptrace/ptrace-vsx.h  |  83 +++
 tools/testing/selftests/powerpc/ptrace/ptrace.S| 263 +
 tools/testing/selftests/powerpc/ptrace/ptrace.h| 119 ++
 5 files changed, 604 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-vsx.c
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-vsx.h

diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile 
b/tools/testing/selftests/powerpc/ptrace/Makefile
index f058083..1c5437e 100644
--- a/tools/testing/selftests/powerpc/ptrace/Makefile
+++ b/tools/testing/selftests/powerpc/ptrace/Makefile
@@ -1,5 +1,5 @@
 TEST_PROGS := ptrace-ebb ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \
-ptrace-tar ptrace-tm-tar ptrace-tm-spd-tar
+ptrace-tar ptrace-tm-tar ptrace-tm-spd-tar ptrace-vsx
 
 all: $(TEST_PROGS)
 
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-vsx.c 
b/tools/testing/selftests/powerpc/ptrace/ptrace-vsx.c
new file mode 100644
index 000..5d75be5
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-vsx.c
@@ -0,0 +1,138 @@
+/*
+ * Ptrace test for VMX/VSX registers
+ *
+ * Copyright 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * 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.
+ */
+#include "ptrace.h"
+#include "ptrace-vsx.h"
+
+/* Tracer and Tracee Shared Data */
+int shm_id;
+volatile int *cptr, *pptr;
+
+extern void loadvsx(void *p, int tmp);
+extern void storevsx(void *p, int tmp);
+
+unsigned long fp_load[VEC_MAX];
+unsigned long fp_load_new[VEC_MAX];
+unsigned long fp_store[VEC_MAX];
+
+void vsx(void)
+{
+   int ret;
+
+   cptr = (int *)shmat(shm_id, NULL, 0);
+   loadvsx(fp_load, 0);
+
+   while(!cptr[0]);
+   shmdt((void *) cptr);
+
+   storevsx(fp_store, 0);
+   ret = compare_vsx_vmx(fp_store, fp_load_new);
+   if (ret)
+   exit(1);
+   exit(0);
+}
+
+int trace_vsx(pid_t child)
+{
+   unsigned long vsx[VSX_MAX];
+   unsigned long vmx[VMX_MAX + 2][2];
+   int ret;
+
+   sleep(1);
+   ret = start_trace(child);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = show_vsx(child, vsx);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = validate_vsx(vsx, fp_load);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = show_vmx(child, vmx);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = validate_vmx(vmx, fp_load);
+   if (ret)
+   return TEST_FAIL;
+
+   memset(vsx, 0, sizeof(vsx));
+   memset(vmx, 0, sizeof(vmx));
+   load_vsx_vmx(fp_load_new, vsx, vmx);
+
+   ret = write_vsx(child, vsx);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = write_vmx(child, vmx);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = stop_trace(child);
+   if (ret)
+   return TEST_FAIL;
+
+   return TEST_PASS;
+}
+
+int ptrace_vsx(void)
+{
+   pid_t pid;
+   int ret, status, i;
+
+   shm_id = shmget(IPC_PRIVATE, sizeof(int) * 1, 0777|IPC_CREAT);
+
+   for(i = 0; i < VEC_MAX; i++)
+   fp_load[i] = i + rand();
+
+   for(i = 0; i < VEC_MAX; i++)
+   fp_load_new[i] = i + 2 * rand();
+
+   pid = fork();
+   if (pid < 0) {
+   perror("fork() failed");
+   return TEST_FAIL;
+   }
+
+   if (pid == 0)
+   vsx();
+
+   if (pid) {
+   pptr = (int *)shmat(shm_id, NULL, 0);
+   ret = trace_vsx(pid);
+   if (ret) {
+   kill(pid, SIGTERM);
+   return TEST_FAIL;
+   }
+
+   pptr[0] = 1;
+   shmdt((void *)pptr);
+
+   ret = wait(&status);
+   if (ret != pid) {
+   printf("Child's exit status not captured\n");
+   return TEST_FAIL;
+   }
+
+   if (WIFEXITED(status)) {
+   if(WEXITSTATUS(status))
+   return TEST_FAIL;
+   }
+   }
+   return TEST_PASS;
+}
+
+int main(int argc, char *argv[])
+{
+   return test_harness(ptrace_vsx, "ptrace_vsx");
+}
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-vsx.h 
b/tools/testing/selftests/powerpc/ptrace/ptrace-vsx.h
new file mode 100644
in

[PATCH V8 07/28] powerpc, ptrace: Enable support for NT_PPC_CGPR

2015-05-19 Thread Anshuman Khandual
This patch enables support for TM checkpointed GPR register
set ELF core note NT_PPC_CGPR based ptrace requests through
PTRACE_GETREGSET, PTRACE_SETREGSET calls. This is achieved
through adding a register set REGSET_CGPR in powerpc
corresponding to the ELF core note section added. It
implements the get, set and active functions for this new
register set added.

Signed-off-by: Anshuman Khandual 
---
 arch/powerpc/kernel/ptrace.c | 222 +++
 1 file changed, 222 insertions(+)

diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index a8e4d19..28b788b 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -180,6 +180,26 @@ static int set_user_msr(struct task_struct *task, unsigned 
long msr)
return 0;
 }
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+static unsigned long get_user_ckpt_msr(struct task_struct *task)
+{
+   return task->thread.ckpt_regs.msr | task->thread.fpexc_mode;
+}
+
+static int set_user_ckpt_msr(struct task_struct *task, unsigned long msr)
+{
+   task->thread.ckpt_regs.msr &= ~MSR_DEBUGCHANGE;
+   task->thread.ckpt_regs.msr |= msr & MSR_DEBUGCHANGE;
+   return 0;
+}
+
+static int set_user_ckpt_trap(struct task_struct *task, unsigned long trap)
+{
+   task->thread.ckpt_regs.trap = trap & 0xfff0;
+   return 0;
+}
+#endif
+
 #ifdef CONFIG_PPC64
 static int get_user_dscr(struct task_struct *task, unsigned long *data)
 {
@@ -846,6 +866,172 @@ static int evr_set(struct task_struct *target, const 
struct user_regset *regset,
 }
 #endif /* CONFIG_SPE */
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+/**
+ * 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, offsetof(struct pt_regs, msr));
+   if (!ret) {
+   unsigned long msr = get_user_ckpt_msr(target);
+
+   ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &msr,
+ offsetof(struct pt_regs, msr),
+ offsetof(struct pt_regs, msr) +
+ sizeof(msr));
+   }
+
+   BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
+offsetof(struct pt_regs, msr) + sizeof(long));
+
+   if (!ret)
+   ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.ckpt_regs.orig_gpr3,
+ offsetof(struct pt_regs, orig_gpr3),
+ sizeof(struct pt_regs));
+   if (!ret)
+   ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+  sizeof(struct pt_regs), -1);
+
+   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 regis

[PATCH V8 16/28] selftests, powerpc: Add more SPR numbers, TM & VMX instructions to 'reg.h'

2015-05-19 Thread Anshuman Khandual
This patch adds SPR number for TAR, PPR, DSCR special
purpose registers. It also adds TM, VSX, VMX related
instructions which will then be used by patches later
in the series.

Signed-off-by: Anshuman Khandual 
---
 tools/testing/selftests/powerpc/reg.h | 21 +
 1 file changed, 21 insertions(+)

diff --git a/tools/testing/selftests/powerpc/reg.h 
b/tools/testing/selftests/powerpc/reg.h
index 5921b0d..76f170d 100644
--- a/tools/testing/selftests/powerpc/reg.h
+++ b/tools/testing/selftests/powerpc/reg.h
@@ -18,6 +18,19 @@
 
 #define mb()   asm volatile("sync" : : : "memory");
 
+/* Vector Instructions */
+#define VSX_XX1(xs, ra, rb)(((xs) & 0x1f) << 21 | ((ra) << 16) |  \
+((rb) << 11) | (((xs) >> 5)))
+#define STXVD2X(xs, ra, rb).long (0x7c000798 | VSX_XX1((xs), (ra), (rb)))
+#define LXVD2X(xs, ra, rb) .long (0x7c000698 | VSX_XX1((xs), (ra), (rb)))
+
+/* TM instructions */
+#define TBEGIN ".long 0x7C00051D;"
+#define TABORT ".long 0x7C00071D;"
+#define TEND   ".long 0x7C00055D;"
+#define TSUSPEND   ".long 0x7C0005DD;"
+#define TRESUME".long 0x7C2005DD;"
+
 #define SPRN_MMCR2 769
 #define SPRN_MMCRA 770
 #define SPRN_MMCR0 779
@@ -46,4 +59,12 @@
 #define SPRN_SDAR  781
 #define SPRN_SIER  768
 
+#define SPRN_DSCR  3   /* Data Stream Control Register */
+#define SPRN_TAR   815 /* Target Address Register */
+#define SPRN_PPR   896 /* Program Priority Register */
+
+#define SPRN_TFHAR 0x80/* TM Failure Handle Register */
+#define SPRN_TFIAR 0x81/* TM Failure Instruction Address Register */
+#define SPRN_TEXASR0x82/* TM Exception and Status Register */
+
 #endif /* _SELFTESTS_POWERPC_REG_H */
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH V8 02/28] powerpc, process: Add the function flush_tmregs_to_thread

2015-05-19 Thread Anshuman Khandual
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 
---
 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 febb50d..4e685042 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)
 {
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH V8 12/28] powerpc, ptrace: Enable NT_PPC_TM_CTAR, NT_PPC_TM_CPPR, NT_PPC_TM_CDSCR

2015-05-19 Thread Anshuman Khandual
This patch enables support for all three TM checkpointed SPR
states related ELF core note  NT_PPC_TM_CTAR, NT_PPC_TM_CPPR,
NT_PPC_TM_CDSCR based ptrace requests through PTRACE_GETREGSET,
PTRACE_SETREGSET calls. This is achieved through adding three
new register sets REGSET_TM_CTAR, REGSET_TM_CPPR and
REGSET_TM_CDSCR in powerpc corresponding to the ELF core note
sections added. It implements the get, set and active functions
for all these new register sets added.

Signed-off-by: Anshuman Khandual 
---
 arch/powerpc/kernel/ptrace.c | 178 +++
 1 file changed, 178 insertions(+)

diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 228cdcf..774f5c20 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1541,6 +1541,151 @@ static int tm_spr_set(struct task_struct *target,
 2 * sizeof(u64), 3 * sizeof(u64));
return ret;
 }
+
+static int tm_tar_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 regset->n;
+
+   return 0;
+}
+
+static int tm_tar_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;
+
+   ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+   &target->thread.tm_tar, 0, sizeof(u64));
+   return ret;
+}
+
+static int tm_tar_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;
+
+   ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+   &target->thread.tm_tar, 0, sizeof(u64));
+   return ret;
+}
+
+static int tm_ppr_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 regset->n;
+
+   return 0;
+}
+
+
+static int tm_ppr_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;
+
+   ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+   &target->thread.tm_ppr, 0, sizeof(u64));
+   return ret;
+}
+
+static int tm_ppr_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;
+
+   ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+   &target->thread.tm_ppr, 0, sizeof(u64));
+   return ret;
+}
+
+static int tm_dscr_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 regset->n;
+
+   return 0;
+}
+
+static int tm_dscr_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;
+
+   ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+   &target->thread.tm_dscr, 0, sizeof(u64));
+   return ret;
+}
+
+static int tm_dscr_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;
+
+  

[PATCH V8 28/28] selftests, powerpc: Add .gitignore file for ptrace executables

2015-05-19 Thread Anshuman Khandual
This patch adds a .gitignore file for all the executables in
the ptrace test directory thus making invisible with git status
query.

Signed-off-by: Anshuman Khandual 
---
 tools/testing/selftests/powerpc/ptrace/.gitignore | 11 +++
 1 file changed, 11 insertions(+)
 create mode 100644 tools/testing/selftests/powerpc/ptrace/.gitignore

diff --git a/tools/testing/selftests/powerpc/ptrace/.gitignore 
b/tools/testing/selftests/powerpc/ptrace/.gitignore
new file mode 100644
index 000..bdf3566
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/.gitignore
@@ -0,0 +1,11 @@
+ptrace-ebb
+ptrace-gpr
+ptrace-tm-gpr
+ptrace-tm-spd-gpr
+ptrace-tar
+ptrace-tm-tar
+ptrace-tm-spd-tar
+ptrace-vsx
+ptrace-tm-vsx
+ptrace-tm-spd-vsx
+ptrace-tm-spr
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH V8 25/28] selftests, powerpc: Add ptrace tests for VSX, VMX registers in TM

2015-05-19 Thread Anshuman Khandual
This patch adds ptrace interface test for VSX, VMX registers
inside TM context. This also adds ptrace interface based helper
functions related to chckpointed VSX, VMX registers access.

Signed-off-by: Anshuman Khandual 
---
 tools/testing/selftests/powerpc/ptrace/Makefile|   3 +-
 .../selftests/powerpc/ptrace/ptrace-tm-vsx.c   | 195 +
 2 files changed, 197 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tm-vsx.c

diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile 
b/tools/testing/selftests/powerpc/ptrace/Makefile
index 1c5437e..092fbef 100644
--- a/tools/testing/selftests/powerpc/ptrace/Makefile
+++ b/tools/testing/selftests/powerpc/ptrace/Makefile
@@ -1,5 +1,6 @@
 TEST_PROGS := ptrace-ebb ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \
-ptrace-tar ptrace-tm-tar ptrace-tm-spd-tar ptrace-vsx
+ptrace-tar ptrace-tm-tar ptrace-tm-spd-tar ptrace-vsx ptrace-tm-vsx
+
 
 all: $(TEST_PROGS)
 
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-vsx.c 
b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-vsx.c
new file mode 100644
index 000..2d218c9
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-vsx.c
@@ -0,0 +1,195 @@
+/*
+ * Ptrace test for VMX/VSX registers in the TM context
+ *
+ * Copyright 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * 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.
+ */
+#include "ptrace.h"
+#include "ptrace-vsx.h"
+
+int shm_id;
+volatile int *cptr, *pptr;
+
+extern void loadvsx(void *p, int tmp);
+extern void storevsx(void *p, int tmp);
+
+unsigned long fp_load[VEC_MAX];
+unsigned long fp_store[VEC_MAX];
+unsigned long fp_load_ckpt[VEC_MAX];
+unsigned long fp_load_ckpt_new[VEC_MAX];
+
+__attribute__((used)) void load_vsx(void)
+{
+   loadvsx(fp_load, 0);
+}
+
+__attribute__((used)) void load_vsx_ckpt(void)
+{
+   loadvsx(fp_load_ckpt, 0);
+}
+
+void tm_vsx(void)
+{
+   unsigned long result, texasr;
+   int ret;
+
+   cptr = (int *)shmat(shm_id, NULL, 0);
+trans:
+   asm __volatile__(
+   "bl load_vsx_ckpt;"
+
+   "1: ;"
+   TBEGIN
+   "beq 2f;"
+
+   "bl load_vsx;"
+   "b .;"
+
+   TEND
+   "li 0, 0;"
+   "ori %[res], 0, 0;"
+   "b 3f;"
+
+   "2: ;"
+   "li 0, 1;"
+   "ori %[res], 0, 0;"
+   "mfspr %[texasr], %[sprn_texasr];"
+
+   "3: ;"
+   : [res] "=r" (result), [texasr] "=r" (texasr)
+   : [fp_load] "r" (fp_load), [fp_load_ckpt] "r" (fp_load_ckpt), 
[sprn_texasr] "i"  (SPRN_TEXASR)
+   : "memory", "r0", "r1", "r2", "r3", "r4", "r8", "r9", "r10", 
"r11"
+   );
+
+   if (result) {
+   if (!cptr[0])
+   goto trans;
+   shmdt((void *)cptr);
+
+   storevsx(fp_store, 0);
+   ret = compare_vsx_vmx(fp_store, fp_load_ckpt_new);
+   if (ret)
+   exit(1);
+   exit(0);
+   }
+   exit(1);
+}
+
+int trace_tm_vsx(pid_t child)
+{
+   unsigned long vsx[VSX_MAX];
+   unsigned long vmx[VMX_MAX + 2][2];
+   int ret;
+
+   sleep(1);
+   ret = start_trace(child);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = show_vsx(child, vsx);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = validate_vsx(vsx, fp_load);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = show_vmx(child, vmx);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = validate_vmx(vmx, fp_load);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = show_vsx_ckpt(child, vsx);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = validate_vsx(vsx, fp_load_ckpt);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = show_vmx_ckpt(child, vmx);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = validate_vmx(vmx, fp_load_ckpt);
+   if (ret)
+   return TEST_FAIL;
+
+   memset(vsx, 0, sizeof(vsx));
+   memset(vmx, 0, sizeof(vmx));
+
+   load_vsx_vmx(fp_load_ckpt_new, vsx, vmx);
+
+   ret = write_vsx_ckpt(child, vsx);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = write_vmx_ckpt(child, vmx);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = stop_trace(child);
+   if (ret)
+   return TEST_FAIL;
+
+   return TEST_PASS;
+}
+
+int ptrace_tm_vsx(void)
+{
+   pid_t pid;
+   int ret, status, i;
+
+   shm_id = shmget(IPC_PRIVATE, sizeof(int) * 1, 0777|IPC_CREAT);
+
+   for(i = 0; i < 128; i++) {
+   fp_load[i] = 1 + rand();

[PATCH V8 23/28] selftests, powerpc: Add ptrace tests for TAR, PPR, DSCR in suspended TM

2015-05-19 Thread Anshuman Khandual
This patch adds ptrace interface test for TAR, PPR, DSCR
registers inside suspended TM context.

Signed-off-by: Anshuman Khandual 
---
 tools/testing/selftests/powerpc/ptrace/Makefile|   2 +-
 .../selftests/powerpc/ptrace/ptrace-tm-spd-tar.c   | 184 +
 2 files changed, 185 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-tar.c

diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile 
b/tools/testing/selftests/powerpc/ptrace/Makefile
index a5d177b..f058083 100644
--- a/tools/testing/selftests/powerpc/ptrace/Makefile
+++ b/tools/testing/selftests/powerpc/ptrace/Makefile
@@ -1,5 +1,5 @@
 TEST_PROGS := ptrace-ebb ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \
-ptrace-tar ptrace-tm-tar
+ptrace-tar ptrace-tm-tar ptrace-tm-spd-tar
 
 all: $(TEST_PROGS)
 
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-tar.c 
b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-tar.c
new file mode 100644
index 000..3584d18
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-tar.c
@@ -0,0 +1,184 @@
+/*
+ * Ptrace test for TAR, PPR, DSCR registers in the TM Suspend context
+ *
+ * Copyright 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * 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.
+ */
+#include "ptrace.h"
+#include "ptrace-tar.h"
+
+int shm_id;
+volatile int *cptr, *pptr;
+
+__attribute__((used)) void wait_parent(void)
+{
+   while(!cptr[1]);
+}
+
+void tm_spd_tar(void)
+{
+   unsigned long result, texasr;
+   unsigned long regs[3];
+   int ret;
+
+   cptr = (int *)shmat(shm_id, NULL, 0);
+trans:
+   asm __volatile__(
+   "li 4, %[tar_1];"
+   "mtspr %[sprn_tar],  4;"/* TAR_1 */
+   "li 4, %[dscr_1];"
+   "mtspr %[sprn_dscr], 4;"/* DSCR_1 */
+   "or 31,31,31;"  /* PPR_1*/
+
+   "1: ;"
+   TBEGIN
+   "beq 2f;"
+
+   "li 4, %[tar_2];"
+   "mtspr %[sprn_tar],  4;"/* TAR_2 */
+   "li 4, %[dscr_2];"
+   "mtspr %[sprn_dscr], 4;"/* DSCR_2 */
+   "or 1,1,1;" /* PPR_2 */
+
+   TSUSPEND
+   "li 4, %[tar_3];"
+   "mtspr %[sprn_tar],  4;"/* TAR_3 */
+   "li 4, %[dscr_3];"
+   "mtspr %[sprn_dscr], 4;"/* DSCR_3 */
+   "or 6,6,6;" /* PPR_3 */
+   "bl wait_parent;"
+   TRESUME
+
+   TEND
+   "li 0, 0;"
+   "ori %[res], 0, 0;"
+   "b 3f;"
+
+   /* Transaction abort handler */
+   "2: ;"
+   "li 0, 1;"
+   "ori %[res], 0, 0;"
+   "mfspr %[texasr], %[sprn_texasr];"
+
+   "3: ;"
+
+   :[res] "=r" (result), [texasr] "=r" (texasr)
+   :[val] "r" (cptr[1]), [sprn_dscr]"i"(SPRN_DSCR), 
[sprn_tar]"i"(SPRN_TAR), [sprn_ppr]"i"(SPRN_PPR), [sprn_texasr]"i"(SPRN_TEXASR),
+   [tar_1]"i"(TAR_1), [dscr_1]"i"(DSCR_1),
+   [tar_2]"i"(TAR_2), [dscr_2]"i"(DSCR_2),
+   [tar_3]"i"(TAR_3), [dscr_3]"i"(DSCR_3)
+   : "memory", "r0", "r1", "r3", "r4", "r5", "r6"
+   );
+
+   /* TM failed, analyse */
+   if (result) {
+   if (!cptr[0])
+   goto trans;
+   shmdt(&cptr);
+   analyse_texasr(texasr);
+
+   regs[0] = mfspr(SPRN_TAR);
+   regs[1] = mfspr(SPRN_PPR);
+   regs[2] = mfspr(SPRN_DSCR);
+
+   printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n", user_read, 
regs[0], regs[1], regs[2]);
+
+   ret = validate_tar_registers(regs, TAR_4, PPR_4, DSCR_4);
+   if (ret)
+   exit(1);
+   exit(0);
+   }
+   shmdt(&cptr);
+   exit(1);
+}
+
+int trace_tm_spd_tar(pid_t child)
+{
+   unsigned long regs[3];
+   int ret;
+
+   sleep(1);
+   ret = start_trace(child);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = show_tar_registers(child, regs);
+   if (ret)
+   return TEST_FAIL;
+
+   printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n", ptrace_read_running, 
regs[0], regs[1], regs[2]);
+
+   ret = validate_tar_registers(regs, TAR_3, PPR_3, DSCR_3);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = show_tm_checkpointed_state(child, regs);
+   if (ret)
+   return TEST_FAIL;
+
+   printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n", ptrace_read_ckpt, 
regs[0], regs[1], regs[2]);
+
+   ret = validate_tar_registers(

[PATCH V8 17/28] selftests, powerpc: Add ptrace tests for EBB

2015-05-19 Thread Anshuman Khandual
This patch adds ptrace interface test for EBB specific
registers. This also adds some generic ptrace interface
based helper functions to be used by other patches later
on in the series.

Signed-off-by: Anshuman Khandual 
---
 tools/testing/selftests/powerpc/Makefile   |   2 +-
 tools/testing/selftests/powerpc/ptrace/Makefile|   7 +
 .../testing/selftests/powerpc/ptrace/ptrace-ebb.c  | 144 +
 .../testing/selftests/powerpc/ptrace/ptrace-ebb.h  |  98 +
 tools/testing/selftests/powerpc/ptrace/ptrace.h| 224 +
 5 files changed, 474 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/powerpc/ptrace/Makefile
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-ebb.c
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-ebb.h
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace.h

diff --git a/tools/testing/selftests/powerpc/Makefile 
b/tools/testing/selftests/powerpc/Makefile
index 5ad0423..8a5ba16 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -12,7 +12,7 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror 
-DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR
 
 export CFLAGS
 
-SUB_DIRS = pmu copyloops mm tm primitives stringloops vphn switch_endian
+SUB_DIRS = pmu copyloops mm tm primitives stringloops vphn switch_endian ptrace
 
 endif
 
diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile 
b/tools/testing/selftests/powerpc/ptrace/Makefile
new file mode 100644
index 000..59386ba
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/Makefile
@@ -0,0 +1,7 @@
+TEST_PROGS := ptrace-ebb
+all: $(TEST_PROGS)
+
+$(TEST_PROGS): ../harness.c
+ptrace-ebb: ../pmu/event.c ../pmu/lib.c ../pmu/ebb/ebb_handler.S 
../pmu/ebb/busy_loop.S
+clean:
+   rm -f $(TEST_PROGS) *.o
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-ebb.c 
b/tools/testing/selftests/powerpc/ptrace/ptrace-ebb.c
new file mode 100644
index 000..56218c5
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-ebb.c
@@ -0,0 +1,144 @@
+/*
+ * Ptrace interface test for EBB
+ *
+ * Copyright 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * 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.
+ */
+#include "../pmu/ebb/ebb.h"
+#include "ptrace.h"
+#include "ptrace-ebb.h"
+
+void ebb(void)
+{
+   struct event event;
+
+   event_init_named(&event, 0x1001e, "cycles");
+   event.attr.config |= (1ull << 63);
+event.attr.exclusive = 1;
+event.attr.pinned = 1;
+   event.attr.exclude_kernel = 1;
+   event.attr.exclude_hv = 1;
+   event.attr.exclude_idle = 1;
+
+   if (event_open(&event)) {
+   perror("event_open() failed");
+   exit(1);
+   }
+
+   setup_ebb_handler(standard_ebb_callee);
+   mtspr(SPRN_BESCR, 0x8001ull);
+
+   mb();
+
+   if (ebb_event_enable(&event)) {
+   perror("ebb_event_handler() failed");
+   exit(1);
+   }
+
+   mtspr(SPRN_PMC1, pmc_sample_period(SAMPLE_PERIOD));
+   while(1)
+   core_busy_loop();
+   exit(0);
+}
+
+int validate_ebb(struct ebb_regs *regs)
+{
+   struct opd *opd;
+
+   printf("EBBRR: %lx\n", regs->ebbrr);
+   printf("EBBHR: %lx\n", regs->ebbhr);
+   printf("BESCR: %lx\n", regs->bescr);
+   printf("SIAR:  %lx\n", regs->siar);
+   printf("SDAR:  %lx\n", regs->sdar);
+   printf("SIER:  %lx\n", regs->sier);
+   printf("MMCR2: %lx\n", regs->mmcr2);
+   printf("MMCR0: %lx\n", regs->mmcr0);
+
+   /* Validate EBBHR */
+   opd= (struct opd *) ebb_handler;
+   if (regs->ebbhr != opd->entry)
+   return TEST_FAIL;
+
+   /* Validate SIER */
+   if (regs->sier != SIER_EXP)
+   return TEST_FAIL;
+
+   /* Validate MMCR2 */
+   if (regs->mmcr2 != MMCR2_EXP)
+   return TEST_FAIL;
+
+   /* Validate MMCR0 */
+   if (regs->mmcr0 != MMCR0_EXP)
+   return TEST_FAIL;
+
+   return TEST_PASS;
+}
+
+int trace_ebb(pid_t child)
+{
+   struct ebb_regs regs;
+   int ret;
+
+   sleep(2);
+   ret = start_trace(child);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = show_ebb_registers(child, ®s);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = validate_ebb(®s);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = stop_trace(child);
+   if (ret)
+   return TEST_FAIL;
+
+   return TEST_PASS;
+}
+
+int ptrace_ebb(void)
+{
+   pid_t pid;
+   int ret, status;
+
+   pid = fork();
+   if (pid < 0) {
+   perror("fork() failed");
+   return TEST_FAIL;
+   }
+
+   if (pid == 0)
+

[PATCH V8 26/28] selftests, powerpc: Add ptrace tests for VSX, VMX registers in suspended TM

2015-05-19 Thread Anshuman Khandual
This patch adds ptrace interface test for VSX, VMX registers
inside suspended TM context.

Signed-off-by: Anshuman Khandual 
---
 tools/testing/selftests/powerpc/ptrace/Makefile|   3 +-
 .../selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c   | 211 +
 2 files changed, 213 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c

diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile 
b/tools/testing/selftests/powerpc/ptrace/Makefile
index 092fbef..ea57351 100644
--- a/tools/testing/selftests/powerpc/ptrace/Makefile
+++ b/tools/testing/selftests/powerpc/ptrace/Makefile
@@ -1,5 +1,6 @@
 TEST_PROGS := ptrace-ebb ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \
-ptrace-tar ptrace-tm-tar ptrace-tm-spd-tar ptrace-vsx ptrace-tm-vsx
+ptrace-tar ptrace-tm-tar ptrace-tm-spd-tar ptrace-vsx ptrace-tm-vsx \
+ptrace-tm-spd-vsx
 
 
 all: $(TEST_PROGS)
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c 
b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c
new file mode 100644
index 000..1861199
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c
@@ -0,0 +1,211 @@
+/*
+ * Ptrace test for VMX/VSX registers in the TM Suspend context
+ *
+ * Copyright 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * 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.
+ */
+#include "ptrace.h"
+#include "ptrace-vsx.h"
+
+int shm_id;
+volatile int *cptr, *pptr;
+
+extern void loadvsx(void *p, int tmp);
+extern void storevsx(void *p, int tmp);
+
+unsigned long fp_load[VEC_MAX];
+unsigned long fp_load_new[VEC_MAX];
+unsigned long fp_store[VEC_MAX];
+unsigned long fp_load_ckpt[VEC_MAX];
+unsigned long fp_load_ckpt_new[VEC_MAX];
+
+__attribute__((used)) void load_vsx(void)
+{
+   loadvsx(fp_load, 0);
+}
+
+__attribute__((used)) void load_vsx_new(void)
+{
+   loadvsx(fp_load_new, 0);
+}
+
+__attribute__((used)) void load_vsx_ckpt(void)
+{
+   loadvsx(fp_load_ckpt, 0);
+}
+
+__attribute__((used)) void wait_parent(void)
+{
+   while(!cptr[1]);
+}
+
+void tm_spd_vsx(void)
+{
+   unsigned long result, texasr;
+   int ret;
+
+   cptr = (int *)shmat(shm_id, NULL, 0);
+trans:
+   asm __volatile__(
+   "bl load_vsx_ckpt;"
+
+   "1: ;"
+   TBEGIN
+   "beq 2f;"
+
+   "bl load_vsx_new;"
+   TSUSPEND
+   "bl load_vsx;"
+   "bl wait_parent;"
+   TRESUME
+
+   TEND
+   "li 0, 0;"
+   "ori %[res], 0, 0;"
+   "b 3f;"
+
+   "2: ;"
+   "li 0, 1;"
+   "ori %[res], 0, 0;"
+   "mfspr %[texasr], %[sprn_texasr];"
+
+   "3: ;"
+   : [res] "=r" (result), [texasr] "=r" (texasr)
+   : [fp_load] "r" (fp_load), [fp_load_ckpt] "r" (fp_load_ckpt), 
[sprn_texasr] "i"  (SPRN_TEXASR)
+   : "memory", "r0", "r1", "r2", "r3", "r4", "r8", "r9", "r10", 
"r11"
+   );
+
+   if (result) {
+   if (!cptr[0])
+   goto trans;
+   shmdt((void *)cptr);
+
+   storevsx(fp_store, 0);
+   ret = compare_vsx_vmx(fp_store, fp_load_ckpt_new);
+   if (ret)
+   exit(1);
+   exit(0);
+   }
+   exit(1);
+}
+
+int trace_tm_spd_vsx(pid_t child)
+{
+   unsigned long vsx[VSX_MAX];
+   unsigned long vmx[VMX_MAX + 2][2];
+   int ret;
+
+   sleep(1);
+   ret = start_trace(child);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = show_vsx(child, vsx);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = validate_vsx(vsx, fp_load);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = show_vmx(child, vmx);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = validate_vmx(vmx, fp_load);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = show_vsx_ckpt(child, vsx);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = validate_vsx(vsx, fp_load_ckpt);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = show_vmx_ckpt(child, vmx);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = validate_vmx(vmx, fp_load_ckpt);
+   if (ret)
+   return TEST_FAIL;
+
+   memset(vsx, 0, sizeof(vsx));
+   memset(vmx, 0, sizeof(vmx));
+
+   load_vsx_vmx(fp_load_ckpt_new, vsx, vmx);
+
+   ret = write_vsx_ckpt(child, vsx);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = write_vmx_ckpt(child, vmx);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = stop_trace(child);
+   if (ret)
+   return T

[PATCH V8 21/28] selftests, powerpc: Add ptrace tests for TAR, PPR, DSCR registers

2015-05-19 Thread Anshuman Khandual
This patch adds ptrace interface test for TAR, PPR, DSCR
registers. This also adds ptrace interface based helper
functions related to TAR, PPR, DSCR register access.

Signed-off-by: Anshuman Khandual 
---
 tools/testing/selftests/powerpc/ptrace/Makefile|   3 +-
 .../testing/selftests/powerpc/ptrace/ptrace-tar.c  | 151 +
 .../testing/selftests/powerpc/ptrace/ptrace-tar.h  |  50 ++
 tools/testing/selftests/powerpc/ptrace/ptrace.h| 179 +
 4 files changed, 382 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tar.c
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tar.h

diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile 
b/tools/testing/selftests/powerpc/ptrace/Makefile
index a8fa080..28d4465 100644
--- a/tools/testing/selftests/powerpc/ptrace/Makefile
+++ b/tools/testing/selftests/powerpc/ptrace/Makefile
@@ -1,4 +1,5 @@
-TEST_PROGS := ptrace-ebb ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr
+TEST_PROGS := ptrace-ebb ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \
+ptrace-tar
 
 all: $(TEST_PROGS)
 
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tar.c 
b/tools/testing/selftests/powerpc/ptrace/ptrace-tar.c
new file mode 100644
index 000..7b10e81
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tar.c
@@ -0,0 +1,151 @@
+/*
+ * Ptrace test for TAR, PPR, DSCR registers
+ *
+ * Copyright 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * 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.
+ */
+#include "ptrace.h"
+#include "ptrace-tar.h"
+
+/* Tracer and Tracee Shared Data */
+int shm_id;
+volatile int *cptr;
+volatile int *pptr;
+
+void tar(void)
+{
+   unsigned long reg[3];
+   int ret;
+
+   cptr = (int *)shmat(shm_id, NULL, 0);
+   mtspr(SPRN_TAR, TAR_1);
+   mtspr(SPRN_PPR, PPR_1);
+   mtspr(SPRN_DSCR, DSCR_1);
+
+   printf("%-30s TAR: %u PPR: %lx DSCR: %u\n", user_write, TAR_1, PPR_1, 
DSCR_1);
+
+   /* Wait on parent */
+   while (!cptr[0]);
+
+   reg[0] = mfspr(SPRN_TAR);
+   reg[1] = mfspr(SPRN_PPR);
+   reg[2] = mfspr(SPRN_DSCR);
+
+   printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n", user_read, reg[0], 
reg[1], reg[2]);
+
+   /* Unblock the parent now */
+   cptr[1] = 1;
+   shmdt((int *)cptr);
+
+   ret = validate_tar_registers(reg, TAR_2, PPR_2, DSCR_2);
+   if (ret)
+   exit(1);
+   exit(0);
+}
+
+int trace_tar(pid_t child)
+{
+   unsigned long reg[3];
+   int ret;
+
+   sleep(1);
+   ret = start_trace(child);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = show_tar_registers(child, reg);
+   if (ret)
+   return TEST_FAIL;
+
+   printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n", ptrace_read_running, 
reg[0], reg[1], reg[2]);
+
+   ret = validate_tar_registers(reg, TAR_1, PPR_1, DSCR_1);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = stop_trace(child);
+   if (ret)
+   return TEST_FAIL;
+
+   return TEST_PASS;
+}
+
+int trace_tar_write(pid_t child)
+{
+   int ret;
+
+   ret = start_trace(child);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = write_tar_registers(child, TAR_2, PPR_2, DSCR_2);
+   if (ret)
+   return TEST_FAIL;
+
+   printf("%-30s TAR: %u PPR: %lx DSCR: %u\n", ptrace_write_running, 
TAR_2, PPR_2, DSCR_2);
+
+   ret = stop_trace(child);
+   if (ret)
+   return TEST_FAIL;
+
+   return TEST_PASS;
+}
+
+int ptrace_tar(void)
+{
+   pid_t pid;
+   int ret, status;
+
+   shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT);
+   pid = fork();
+   if (pid < 0) {
+   perror("fork() failed");
+   return TEST_FAIL;
+   }
+
+   if (pid == 0)
+   tar();
+
+   if (pid) {
+   pptr = (int *)shmat(shm_id, NULL, 0);
+   pptr[0] = 0;
+   pptr[1] = 0;
+   ret = trace_tar(pid);
+   if (ret)
+   return ret;
+
+   ret = trace_tar_write(pid);
+   if (ret)
+   return ret;
+
+   /* Unblock the child now */
+   pptr[0] = 1;
+
+   /* Wait on child */
+   while(!pptr[1]);
+
+   shmdt((int *)pptr);
+
+   ret = wait(&status);
+   if (ret != pid) {
+   printf("Child's exit status not captured\n");
+   return TEST_PASS;
+   }
+
+   if (WIFEXITED(status)) {
+   if(WEXITSTATUS(status))
+   return TEST_FAIL;
+   }
+   return TES

[PATCH V8 03/28] powerpc, ptrace: Enable in transaction NT_PRFPREG ptrace requests

2015-05-19 Thread Anshuman Khandual
This patch enables in transaction NT_PRFPREG ptrace requests.
The function fpr_get which gets the running value of all FPR
registers and the function fpr_set which sets the running
value of of all FPR registers work on the running set of FPR
registers whose location will be different if transaction is
active. This patch makes these functions adapt to situations
when the transaction is active.

Signed-off-by: Anshuman Khandual 
---
 arch/powerpc/kernel/ptrace.c | 93 ++--
 1 file changed, 89 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index f21897b..d8a1388 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -357,6 +357,29 @@ static int gpr_set(struct task_struct *target, const 
struct user_regset *regset,
return ret;
 }
 
+/*
+ * 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,14 +390,31 @@ 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]));
 
@@ -383,6 +423,29 @@ static int fpr_get(struct task_struct *target, const 
struct user_regset *regset,
 #endif
 }
 
+/*
+ * 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 +456,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 wr

[PATCH V8 15/28] selftests, powerpc: Move 'reg.h' file outside of 'ebb' sub directory

2015-05-19 Thread Anshuman Khandual
This patch moves 'reg.h' file from pmu 'ebb' sub directory
to the powerpc root directory to make all the register
definitions and instructions available for tests present
in other subsystems.

Signed-off-by: Anshuman Khandual 
---
 tools/testing/selftests/powerpc/pmu/ebb/ebb.c  |  2 +-
 tools/testing/selftests/powerpc/pmu/ebb/ebb.h  |  2 +-
 .../selftests/powerpc/pmu/ebb/ebb_handler.S|  2 +-
 tools/testing/selftests/powerpc/pmu/ebb/reg.h  | 49 --
 .../selftests/powerpc/pmu/ebb/reg_access_test.c|  2 +-
 tools/testing/selftests/powerpc/reg.h  | 49 ++
 6 files changed, 53 insertions(+), 53 deletions(-)
 delete mode 100644 tools/testing/selftests/powerpc/pmu/ebb/reg.h
 create mode 100644 tools/testing/selftests/powerpc/reg.h

diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb.c 
b/tools/testing/selftests/powerpc/pmu/ebb/ebb.c
index d7a72ce..f98eda0 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/ebb.c
+++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb.c
@@ -15,7 +15,7 @@
 #include 
 
 #include "trace.h"
-#include "reg.h"
+#include "../../reg.h"
 #include "ebb.h"
 
 
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb.h 
b/tools/testing/selftests/powerpc/pmu/ebb/ebb.h
index e44eee5..7b38c3d 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/ebb.h
+++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb.h
@@ -9,7 +9,7 @@
 #include "../event.h"
 #include "../lib.h"
 #include "trace.h"
-#include "reg.h"
+#include "../../reg.h"
 
 #define PMC_INDEX(pmc) ((pmc)-1)
 
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb_handler.S 
b/tools/testing/selftests/powerpc/pmu/ebb/ebb_handler.S
index 14274ea..42cd367 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/ebb_handler.S
+++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb_handler.S
@@ -4,7 +4,7 @@
  */
 
 #include 
-#include "reg.h"
+#include "../../reg.h"
 
 
 /* ppc-asm.h defines most of the reg aliases, but not r1/r2. */
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/reg.h 
b/tools/testing/selftests/powerpc/pmu/ebb/reg.h
deleted file mode 100644
index 5921b0d..000
--- a/tools/testing/selftests/powerpc/pmu/ebb/reg.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2014, Michael Ellerman, IBM Corp.
- * Licensed under GPLv2.
- */
-
-#ifndef _SELFTESTS_POWERPC_REG_H
-#define _SELFTESTS_POWERPC_REG_H
-
-#define __stringify_1(x)#x
-#define __stringify(x)  __stringify_1(x)
-
-#define mfspr(rn)   ({unsigned long rval; \
- asm volatile("mfspr %0," __stringify(rn) \
- : "=r" (rval)); rval; })
-#define mtspr(rn, v)asm volatile("mtspr " __stringify(rn) ",%0" : \
-: "r" ((unsigned long)(v)) \
-: "memory")
-
-#define mb()   asm volatile("sync" : : : "memory");
-
-#define SPRN_MMCR2 769
-#define SPRN_MMCRA 770
-#define SPRN_MMCR0 779
-#define   MMCR0_PMAO   0x0080
-#define   MMCR0_PMAE   0x0400
-#define   MMCR0_FC 0x8000
-#define SPRN_EBBHR 804
-#define SPRN_EBBRR 805
-#define SPRN_BESCR 806 /* Branch event status & control register */
-#define SPRN_BESCRS800 /* Branch event status & control set (1 bits 
set to 1) */
-#define SPRN_BESCRSU   801 /* Branch event status & control set upper */
-#define SPRN_BESCRR802 /* Branch event status & control REset (1 bits 
set to 0) */
-#define SPRN_BESCRRU   803 /* Branch event status & control REset upper */
-
-#define BESCR_PMEO 0x1 /* PMU Event-based exception Occurred */
-#define BESCR_PME  (0x1ul << 32) /* PMU Event-based exception Enable */
-
-#define SPRN_PMC1  771
-#define SPRN_PMC2  772
-#define SPRN_PMC3  773
-#define SPRN_PMC4  774
-#define SPRN_PMC5  775
-#define SPRN_PMC6  776
-
-#define SPRN_SIAR  780
-#define SPRN_SDAR  781
-#define SPRN_SIER  768
-
-#endif /* _SELFTESTS_POWERPC_REG_H */
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/reg_access_test.c 
b/tools/testing/selftests/powerpc/pmu/ebb/reg_access_test.c
index 0cae66f..ebdc595 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/reg_access_test.c
+++ b/tools/testing/selftests/powerpc/pmu/ebb/reg_access_test.c
@@ -7,7 +7,7 @@
 #include 
 
 #include "ebb.h"
-#include "reg.h"
+#include "../../reg.h"
 
 
 /*
diff --git a/tools/testing/selftests/powerpc/reg.h 
b/tools/testing/selftests/powerpc/reg.h
new file mode 100644
index 000..5921b0d
--- /dev/null
+++ b/tools/testing/selftests/powerpc/reg.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2014, Michael Ellerman, IBM Corp.
+ * Licensed under GPLv2.
+ */
+
+#ifndef _SELFTESTS_POWERPC_REG_H
+#define _SELFTESTS_POWERPC_REG_H
+
+#define __stringify_1(x)#x
+#define __stringify(x)  __stringify_1(x)
+
+#define mfspr(rn)   ({unsigned long rval; \
+ asm volatile("mfspr %0," __stringify(rn) \
+

[PATCH V8 14/28] powerpc, ptrace: Enable support for EBB registers

2015-05-19 Thread Anshuman Khandual
This patch enables support for EBB state registers related
ELF core note NT_PPC_EBB based ptrace requests through
PTRACE_GETREGSET, PTRACE_SETREGSET calls. This is achieved
through adding one new register sets REGSET_EBB in powerpc
corresponding to the ELF core note sections added in this
regard. It also implements the get, set and active functions
for this new register sets added.

Signed-off-by: Anshuman Khandual 
---
 arch/powerpc/include/uapi/asm/elf.h |   2 +
 arch/powerpc/kernel/ptrace.c| 147 
 2 files changed, 149 insertions(+)

diff --git a/arch/powerpc/include/uapi/asm/elf.h 
b/arch/powerpc/include/uapi/asm/elf.h
index 9e6b6e3..80876ff 100644
--- a/arch/powerpc/include/uapi/asm/elf.h
+++ b/arch/powerpc/include/uapi/asm/elf.h
@@ -94,6 +94,8 @@
 #define ELF_NVMX   34  /* includes all vector registers */
 #define ELF_NVSX   32  /* includes all VSX registers */
 #define ELF_NTMSPRREG  3   /* include tfhar, tfiar, texasr */
+#define ELF_NEBB   8   /* includes ebbrr, ebbhr, bescr, siar,
+  sdar, sier, mmcr2, mmcr0 */
 
 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 533c787..1db88a5 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1759,6 +1759,142 @@ static int tar_set(struct task_struct *target,
&target->thread.tar, 0, sizeof(u64));
return ret;
 }
+
+static int ebb_active(struct task_struct *target,
+const struct user_regset *regset)
+{
+   if (!cpu_has_feature(CPU_FTR_ARCH_207S))
+   return -ENODEV;
+
+   if (target->thread.used_ebb)
+   return regset->n;
+
+   return 0;
+}
+
+static int ebb_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(ebbrr) + sizeof(unsigned long) != TSO(ebbhr));
+   BUILD_BUG_ON(TSO(ebbhr) + sizeof(unsigned long) != TSO(bescr));
+   BUILD_BUG_ON(TSO(bescr) + sizeof(unsigned long) != TSO(siar));
+   BUILD_BUG_ON(TSO(siar) + sizeof(unsigned long) != TSO(sdar));
+   BUILD_BUG_ON(TSO(sdar) + sizeof(unsigned long) != TSO(sier));
+   BUILD_BUG_ON(TSO(sier) + sizeof(unsigned long) != TSO(mmcr2));
+   BUILD_BUG_ON(TSO(mmcr2) + sizeof(unsigned long) != TSO(mmcr0));
+
+   if (!cpu_has_feature(CPU_FTR_ARCH_207S))
+   return -ENODEV;
+
+   if (!target->thread.used_ebb)
+   return -ENODATA;
+
+   ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+   &target->thread.ebbrr, 0, sizeof(unsigned long));
+
+   if (!ret)
+   ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+   &target->thread.ebbhr, sizeof(unsigned long),
+   2 * sizeof(unsigned long));
+
+   if (!ret)
+   ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+   &target->thread.bescr,
+   2 * sizeof(unsigned long), 3 * sizeof(unsigned long));
+
+   if (!ret)
+   ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+   &target->thread.siar, 3 * sizeof(unsigned long),
+   4 * sizeof(unsigned long));
+
+   if (!ret)
+   ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+   &target->thread.sdar, 4 * sizeof(unsigned long),
+   5 * sizeof(unsigned long));
+
+   if (!ret)
+   ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+   &target->thread.sier, 5 * sizeof(unsigned long),
+   6 * sizeof(unsigned long));
+
+   if (!ret)
+   ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+   &target->thread.mmcr2, 6 * sizeof(unsigned long),
+   7 * sizeof(unsigned long));
+
+   if (!ret)
+   ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+   &target->thread.mmcr0, 7 * sizeof(unsigned long),
+   8 * sizeof(unsigned long));
+   return ret;
+}
+
+static int ebb_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 = 0;
+
+   /* Build tests */
+   BUILD_BUG_ON(TSO(ebbrr) + sizeof(unsigned long) != TSO(ebbhr));
+   BUILD_BUG_ON(TSO(ebbhr) + sizeof(unsigned long) != TSO(bescr));
+   BUILD_BUG_ON(TSO(bescr) + sizeof(unsigned long) != TSO(siar));
+   BUILD_BUG_ON(TSO(siar) + sizeof(unsigned long) !

[PATCH V8 18/28] selftests, powerpc: Add ptrace tests for GPR/FPR registers

2015-05-19 Thread Anshuman Khandual
This patch adds ptrace interface test for GPR/FPR registers.
This adds ptrace interface based helper functions related to
GPR/FPR access and some assembly helper functions related to
GPR/FPR registers.

Signed-off-by: Anshuman Khandual 
---
 tools/testing/selftests/powerpc/ptrace/Makefile|   5 +-
 .../testing/selftests/powerpc/ptrace/ptrace-gpr.c  | 191 +++
 .../testing/selftests/powerpc/ptrace/ptrace-gpr.h  |  73 
 tools/testing/selftests/powerpc/ptrace/ptrace.S| 140 ++
 tools/testing/selftests/powerpc/ptrace/ptrace.h| 208 +
 5 files changed, 615 insertions(+), 2 deletions(-)
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-gpr.c
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-gpr.h
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace.S

diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile 
b/tools/testing/selftests/powerpc/ptrace/Makefile
index 59386ba..dfeb36e 100644
--- a/tools/testing/selftests/powerpc/ptrace/Makefile
+++ b/tools/testing/selftests/powerpc/ptrace/Makefile
@@ -1,7 +1,8 @@
-TEST_PROGS := ptrace-ebb
+TEST_PROGS := ptrace-ebb ptrace-gpr
+
 all: $(TEST_PROGS)
 
-$(TEST_PROGS): ../harness.c
+$(TEST_PROGS): ../harness.c ptrace.S
 ptrace-ebb: ../pmu/event.c ../pmu/lib.c ../pmu/ebb/ebb_handler.S 
../pmu/ebb/busy_loop.S
 clean:
rm -f $(TEST_PROGS) *.o
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-gpr.c 
b/tools/testing/selftests/powerpc/ptrace/ptrace-gpr.c
new file mode 100644
index 000..1ee644f
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-gpr.c
@@ -0,0 +1,191 @@
+/*
+ * Ptrace test for GPR/FPR registers
+ *
+ * Copyright 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * 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.
+ */
+#include "ptrace.h"
+#include "ptrace-gpr.h"
+
+/* Tracer and Tracee Shared Data */
+int shm_id;
+volatile int *cptr, *pptr;
+
+extern void store_gpr(unsigned long *addr);
+extern void store_fpr(float *addr);
+
+float a = FPR_1;
+float b = FPR_2;
+float c = FPR_3;
+
+void gpr(void)
+{
+   unsigned long gpr_buf[18];
+   float fpr_buf[32];
+
+   cptr = (int *)shmat(shm_id, NULL, 0);
+
+   asm __volatile__(
+   "li 14, %[gpr_1];"
+   "li 15, %[gpr_1];"
+   "li 16, %[gpr_1];"
+   "li 17, %[gpr_1];"
+   "li 18, %[gpr_1];"
+   "li 19, %[gpr_1];"
+   "li 20, %[gpr_1];"
+   "li 21, %[gpr_1];"
+   "li 22, %[gpr_1];"
+   "li 23, %[gpr_1];"
+   "li 24, %[gpr_1];"
+   "li 25, %[gpr_1];"
+   "li 26, %[gpr_1];"
+   "li 27, %[gpr_1];"
+   "li 28, %[gpr_1];"
+   "li 29, %[gpr_1];"
+   "li 30, %[gpr_1];"
+   "li 31, %[gpr_1];"
+
+   "lfs 0, 0(%[flt_1]);"
+   "lfs 1, 0(%[flt_1]);"
+   "lfs 2, 0(%[flt_1]);"
+   "lfs 3, 0(%[flt_1]);"
+   "lfs 4, 0(%[flt_1]);"
+   "lfs 5, 0(%[flt_1]);"
+   "lfs 6, 0(%[flt_1]);"
+   "lfs 7, 0(%[flt_1]);"
+   "lfs 8, 0(%[flt_1]);"
+   "lfs 9, 0(%[flt_1]);"
+   "lfs 10, 0(%[flt_1]);"
+   "lfs 11, 0(%[flt_1]);"
+   "lfs 12, 0(%[flt_1]);"
+   "lfs 13, 0(%[flt_1]);"
+   "lfs 14, 0(%[flt_1]);"
+   "lfs 15, 0(%[flt_1]);"
+   "lfs 16, 0(%[flt_1]);"
+   "lfs 17, 0(%[flt_1]);"
+   "lfs 18, 0(%[flt_1]);"
+   "lfs 19, 0(%[flt_1]);"
+   "lfs 20, 0(%[flt_1]);"
+   "lfs 21, 0(%[flt_1]);"
+   "lfs 22, 0(%[flt_1]);"
+   "lfs 23, 0(%[flt_1]);"
+   "lfs 24, 0(%[flt_1]);"
+   "lfs 25, 0(%[flt_1]);"
+   "lfs 26, 0(%[flt_1]);"
+   "lfs 27, 0(%[flt_1]);"
+   "lfs 28, 0(%[flt_1]);"
+   "lfs 29, 0(%[flt_1]);"
+   "lfs 30, 0(%[flt_1]);"
+   "lfs 31, 0(%[flt_1]);"
+
+   :
+   :[gpr_1]"i"(GPR_1), [flt_1] "r" (&a)
+   : "memory", "r6", "r7", "r8", "r9", "r10",
+   "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", 
"r20",
+   "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", 
"r30", "r31"
+   );
+
+   while(!cptr[0]);
+
+   store_gpr(gpr_buf);
+   store_fpr(fpr_buf);
+
+   if (validate_gpr(gpr_buf, GPR_3))
+   exit(1);
+
+   if (validate_fpr_float(fpr_buf, c))
+   exit(1);
+
+   exit(0);
+}
+
+int trace_gpr(pid_t child)
+{
+   unsigned long gpr[18];
+   unsigned long fpr[3

[PATCH V8 27/28] selftests, powerpc: Add ptrace tests for TM SPR registers

2015-05-19 Thread Anshuman Khandual
This patch adds ptrace interface test for TM SPR registers. This
also adds ptrace interface based helper functions related to TM
SPR registers access.

Signed-off-by: Anshuman Khandual 
---
 tools/testing/selftests/powerpc/ptrace/Makefile|   2 +-
 .../selftests/powerpc/ptrace/ptrace-tm-spr.c   | 156 +
 tools/testing/selftests/powerpc/ptrace/ptrace.h|  35 +
 3 files changed, 192 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c

diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile 
b/tools/testing/selftests/powerpc/ptrace/Makefile
index ea57351..a46a0e5 100644
--- a/tools/testing/selftests/powerpc/ptrace/Makefile
+++ b/tools/testing/selftests/powerpc/ptrace/Makefile
@@ -1,6 +1,6 @@
 TEST_PROGS := ptrace-ebb ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \
 ptrace-tar ptrace-tm-tar ptrace-tm-spd-tar ptrace-vsx ptrace-tm-vsx \
-ptrace-tm-spd-vsx
+ptrace-tm-spd-vsx ptrace-tm-spr
 
 
 all: $(TEST_PROGS)
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c 
b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c
new file mode 100644
index 000..36b9722
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c
@@ -0,0 +1,156 @@
+/*
+ * Ptrace test TM SPR registers
+ *
+ * Copyright 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * 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.
+ */
+#include "ptrace.h"
+
+/* Tracee and tracer shared data */
+struct shared {
+   int flag;
+   struct tm_spr_regs regs;
+};
+unsigned long tfhar;
+
+int shm_id;
+volatile struct shared *cptr, *pptr;
+
+#define TM_SCHED   0xde018c01
+#define TM_KVM_SCHED   0xe001ac01
+
+int validate_tm_spr(struct tm_spr_regs *regs)
+{
+   if (regs->tm_tfhar != (tfhar - 32))
+   return TEST_FAIL;
+
+   if ((regs->tm_texasr != TM_SCHED) && (regs->tm_texasr != TM_KVM_SCHED))
+   return TEST_FAIL;
+
+   if ((regs->tm_texasr == TM_KVM_SCHED) && (regs->tm_tfiar != 0))
+   return TEST_FAIL;
+
+   return TEST_PASS;
+}
+
+void tm_spr(void)
+{
+   unsigned long result, texasr;
+   int ret;
+
+   cptr = (struct shared *)shmat(shm_id, NULL, 0);
+trans:
+   asm __volatile__(
+   "1: ;"
+   TBEGIN
+   "beq 2f;"
+
+   "b .;"
+
+   TEND
+   "li 0, 0;"
+   "ori %[res], 0, 0;"
+   "b 3f;"
+
+   "2: ;"
+   "mflr 31;"
+   "bl 4f;"/* $ = TFHAR + 2 */
+   "4: ;"
+   "mflr %[tfhar];"
+   "mtlr 31;"
+
+   "li 0, 1;"
+   "ori %[res], 0, 0;"
+   "mfspr %[texasr], %[sprn_texasr];"
+
+   "3: ;"
+   : [tfhar] "=r" (tfhar), [res] "=r" (result), [texasr] "=r" 
(texasr)
+   : [sprn_texasr] "i"  (SPRN_TEXASR)
+   : "memory", "r0", "r1", "r2", "r3", "r4", "r8", "r9", "r10", 
"r11"
+   );
+
+   if (result) {
+   if (!cptr->flag)
+   goto trans;
+
+   ret = validate_tm_spr((struct tm_spr_regs *)&cptr->regs);
+   shmdt((void *)cptr);
+   if (ret)
+   exit(1);
+   exit(0);
+   }
+   shmdt((void *)cptr);
+   exit(1);
+}
+
+int trace_tm_spr(pid_t child)
+{
+   int ret;
+
+   sleep(1);
+   ret = start_trace(child);
+   if (ret)
+   return TEST_FAIL;
+
+   ret = show_tm_spr(child, (struct tm_spr_regs *)&pptr->regs);
+   if (ret)
+   return TEST_FAIL;
+
+   printf("TFHAR: %lx TEXASR: %lx TFIAR: %lx\n", pptr->regs.tm_tfhar,
+   pptr->regs.tm_texasr, pptr->regs.tm_tfiar);
+
+   ret = stop_trace(child);
+   if (ret)
+   return TEST_FAIL;
+
+   return TEST_PASS;
+}
+
+int ptrace_tm_spr(void)
+{
+   pid_t pid;
+   int ret, status;
+
+   shm_id = shmget(IPC_PRIVATE, sizeof(struct shared), 0777|IPC_CREAT);
+   pid = fork();
+   if (pid < 0) {
+   perror("fork() failed");
+   return TEST_FAIL;
+   }
+
+   if (pid == 0)
+   tm_spr();
+
+   if (pid) {
+   pptr = (struct shared *)shmat(shm_id, NULL, 0);
+   ret = trace_tm_spr(pid);
+   if (ret) {
+   kill(pid, SIGKILL);
+   return TEST_FAIL;
+   }
+
+   pptr->flag = 1;
+   shmdt((void *)pptr);
+   ret = wait(&status);
+   if (ret != pid) {
+   printf("Child's exit status not captured\n");
+   return TEST_FAIL;
+ 

[PATCH V8 04/28] powerpc, ptrace: Enable in transaction NT_PPC_VMX ptrace requests

2015-05-19 Thread Anshuman Khandual
This patch enables in transaction NT_PPC_VMX ptrace requests. The
function vr_get which gets the running value of all VMX registers
and the function vr_set which sets the running value of of all VMX
registers work on the running set of VMX registers whose location
will be different if transaction is active. This patch makes these
functions adapt to situations when the transaction is active.

Signed-off-by: Anshuman Khandual 
---
 arch/powerpc/kernel/ptrace.c | 90 ++--
 1 file changed, 87 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index d8a1388..1e6bff5 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -517,10 +517,28 @@ static int vr_active(struct task_struct *target,
return target->thread.used_vr ? regset->n : 0;
 }
 
+/*
+ * 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);
@@ -528,8 +546,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) {
/*
@@ -540,7 +569,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);
}
@@ -548,10 +586,28 @@ static int vr_get(struct task_struct *target, const 
struct user_regset *regset,
return ret;
 }
 
+/*
+ * 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);
@@ -559,8 +615,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 {
+   

[PATCH V8 00/28] Add new powerpc specific ELF core notes

2015-05-19 Thread Anshuman Khandual
From: Anshuman Khandual 

This patch series adds twelve new ELF core note sections which can
be used with existing ptrace request PTRACE_GETREGSET-SETREGSET for accessing
various transactional memory and other miscellaneous debug register sets on
powerpc platform.

Previous versions:
==
RFC: https://lkml.org/lkml/2014/4/1/292
V1:  https://lkml.org/lkml/2014/4/2/43
V2:  https://lkml.org/lkml/2014/5/5/88
V3:  https://lkml.org/lkml/2014/5/23/486
V4:  https://lkml.org/lkml/2014/11/11/6
V5:  https://lkml.org/lkml/2014/11/25/134
V6:  https://lkml.org/lkml/2014/12/2/98
V7:  https://lkml.org/lkml/2015/1/14/19

Changes in V8:
--
- Split the misc register set into individual ELF core notes
- Implemented support for VSX register set (on and off TM)
- Implemented support for EBB register set
- Implemented review comments on previous versions
- Some code re-arrangements, re-writes and documentation
- Added comprehensive list of test cases into selftests

Changes in V7:
--
- Fixed a config directive in the MISC code
- Merged the two gitignore patches into a single one

Changes in V6:
--
- Added two git ignore patches for powerpc selftests
- Re-formatted all in-code function definitions in kernel-doc format

Changes in V5:
--
- Changed flush_tmregs_to_thread, so not to take into account self tracing
- Dropped the 3rd patch in the series which had merged two functions
- Fixed one build problem for the misc debug register patch
- Accommodated almost all the review comments from Suka on the 6th patch
- Minor changes to the self test program
- Changed commit messages for some of the patches

Changes in V4:
--
- Added one test program into the powerpc selftest bucket in this regard
- Split the 2nd patch in the previous series into four different patches
- Accommodated most of the review comments on the previous patch series
- Added a patch to merge functions __switch_to_tm and tm_reclaim_task

Changes in V3:
--
- Added two new error paths in every TM related get/set functions when regset
  support is not present on the system (ENODEV) or when the process does not
  have any transaction active (ENODATA) in the context
- Installed the active hooks for all the newly added regset core note types

Changes in V2:
--
- Removed all the power specific ptrace requests corresponding to new NT_PPC_*
  elf core note types. Now all the register sets can be accessed from ptrace
  through PTRACE_GETREGSET/PTRACE_SETREGSET using the individual NT_PPC* core
  note type instead
- Fixed couple of attribute values for REGSET_TM_CGPR register set
- Renamed flush_tmreg_to_thread as flush_tmregs_to_thread
- Fixed 32 bit checkpointed GPR support
- Changed commit messages accordingly

Test Result
---
ptrace-ebb  PASS
ptrace-gpr  PASS
ptrace-tm-gpr   PASS
ptrace-tm-spd-gpr   PASS
ptrace-tar  FAIL
ptrace-tm-tar   FAIL
ptrace-tm-spd-tar   FAIL
ptrace-vsx  PASS
ptrace-tm-vsx   PASS
ptrace-tm-spd-vsx   PASS
ptrace-tm-spr   PASS

NOTE: The above three test case failures are due to PPR context save/restore
in various paths. Still continue to debug the issue.

Anshuman Khandual (28):
  elf: Add powerpc specific core note sections
  powerpc, process: Add the function flush_tmregs_to_thread
  powerpc, ptrace: Enable in transaction NT_PRFPREG ptrace requests
  powerpc, ptrace: Enable in transaction NT_PPC_VMX ptrace requests
  powerpc, ptrace: Enable in transaction NT_PPC_VSX ptrace requests
  powerpc, ptrace: Adapt gpr32_get, gpr32_set functions for transaction
  powerpc, ptrace: Enable support for NT_PPC_CGPR
  powerpc, ptrace: Enable support for NT_PPC_CFPR
  powerpc, ptrace: Enable support for NT_PPC_CVMX
  powerpc, ptrace: Enable support for NT_PPC_CVSX
  powerpc, ptrace: Enable support for TM SPR state
  powerpc, ptrace: Enable NT_PPC_TM_CTAR, NT_PPC_TM_CPPR, NT_PPC_TM_CDSCR
  powerpc, ptrace: Enable support for NT_PPPC_TAR, NT_PPC_PPR, NT_PPC_DSCR
  powerpc, ptrace: Enable support for EBB registers
  selftests, powerpc: Move 'reg.h' file outside of 'ebb' sub directory
  selftests, powerpc: Add more SPR numbers, TM & VMX instructions to 'reg.h'
  selftests, powerpc: Add ptrace tests for EBB
  selftests, powerpc: Add ptrace tests for GPR/FPR registers
  selftests, powerpc: Add ptrace tests for GPR/FPR registers in TM
  selftests, powerpc: Add ptrace tests for GPR/FPR registers in suspended TM
  selftests, powerpc: Add ptrace tests for TAR, PPR, DSCR registers
  selftests, powerpc: Add ptrace tests for TAR, PPR, DSCR in TM
  selftests, powerpc: Add ptrace tests for TAR, PPR, DSCR in suspended TM
  selftests, powerpc: Add ptrace tests for VSX, VMX registers
  selftests, powerpc: Add ptrace tests for VSX, VMX registers in TM
  selftests, powerpc: Add ptrace tests for VSX, VMX registers in suspended TM
  selftests, powerpc: Add ptrace tests for TM SPR regis

[PATCH V8 05/28] powerpc, ptrace: Enable in transaction NT_PPC_VSX ptrace requests

2015-05-19 Thread Anshuman Khandual
This patch enables in transaction NT_PPC_VSX ptrace requests. The
function vsr_get which gets the running value of all VSX registers
and the function vsr_set which sets the running value of of all VSX
registers work on the running set of VMX registers whose location
will be different if transaction is active. This patch makes these
functions adapt to situations when the transaction is active.

Signed-off-by: Anshuman Khandual 
---
 arch/powerpc/kernel/ptrace.c | 64 
 1 file changed, 64 insertions(+)

diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 1e6bff5..015f284 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -680,6 +680,21 @@ static int vsr_active(struct task_struct *target,
return target->thread.used_vsr ? regset->n : 0;
 }
 
+/*
+ * 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 vsx[32];
+ * };
+ */
 static int vsr_get(struct task_struct *target, const struct user_regset 
*regset,
   unsigned int pos, unsigned int count,
   void *kbuf, void __user *ubuf)
@@ -687,16 +702,47 @@ static int vsr_get(struct task_struct *target, const 
struct user_regset *regset,
u64 buf[32];
int ret, i;
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+   flush_fp_to_thread(target);
+   flush_altivec_to_thread(target);
+   flush_tmregs_to_thread(target);
+#endif
flush_vsx_to_thread(target);
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+   if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+   for (i = 0; i < 32 ; i++)
+   buf[i] = target->thread.
+   transact_fp.fpr[i][TS_VSRLOWOFFSET];
+   } else {
+   for (i = 0; i < 32 ; i++)
+   buf[i] = target->thread.
+   fp_state.fpr[i][TS_VSRLOWOFFSET];
+   }
+#else
for (i = 0; i < 32 ; i++)
buf[i] = target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
+#endif
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
  buf, 0, 32 * sizeof(double));
 
return ret;
 }
 
+/*
+ * 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 sets 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 vsx[32];
+ * };
+ */
 static int vsr_set(struct task_struct *target, const struct user_regset 
*regset,
   unsigned int pos, unsigned int count,
   const void *kbuf, const void __user *ubuf)
@@ -704,12 +750,30 @@ static int vsr_set(struct task_struct *target, const 
struct user_regset *regset,
u64 buf[32];
int ret,i;
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+   flush_fp_to_thread(target);
+   flush_altivec_to_thread(target);
+   flush_tmregs_to_thread(target);
+#endif
flush_vsx_to_thread(target);
 
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
 buf, 0, 32 * sizeof(double));
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+   if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+   for (i = 0; i < 32 ; i++)
+   target->thread.transact_fp.
+   fpr[i][TS_VSRLOWOFFSET] = buf[i];
+   } else {
+   for (i = 0; i < 32 ; i++)
+   target->thread.fp_state.
+   fpr[i][TS_VSRLOWOFFSET] = buf[i];
+   }
+#else
for (i = 0; i < 32 ; i++)
target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
+#endif
 
 
return ret;
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH V8 01/28] elf: Add powerpc specific core note sections

2015-05-19 Thread Anshuman Khandual
This patch adds twelve ELF core note sections for powerpc
architecture for various registers and register sets which
need to be accessed from ptrace interface and then gdb.
These additions include special purpose registers like TAR,
PPR, DSCR, TM running and checkpointed state for various
register sets, EBB related register set etc. Addition of
these new ELF core note sections extends the existing ELF
ABI on powerpc arch without affecting it in any manner.

Signed-off-by: Anshuman Khandual 
---
 include/uapi/linux/elf.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index 71e1d0e..58654c2 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -379,6 +379,18 @@ typedef struct elf64_shdr {
 #define NT_PPC_VMX 0x100   /* PowerPC Altivec/VMX registers */
 #define NT_PPC_SPE 0x101   /* PowerPC SPE/EVR registers */
 #define NT_PPC_VSX 0x102   /* PowerPC VSX registers */
+#define NT_PPC_TAR 0x103   /* Target Address Register */
+#define NT_PPC_PPR 0x104   /* Program Priority Register */
+#define NT_PPC_DSCR0x105   /* Data Stream Control Register */
+#define NT_PPC_EBB 0x106   /* Event Based Branch Registers */
+#define NT_PPC_TM_CGPR 0x107   /* TM checkpointed GPR Registers */
+#define NT_PPC_TM_CFPR 0x108   /* TM checkpointed FPR Registers */
+#define NT_PPC_TM_CVMX 0x109   /* TM checkpointed VMX Registers */
+#define NT_PPC_TM_CVSX 0x10a   /* TM checkpointed VSX Registers */
+#define NT_PPC_TM_SPR  0x10b   /* TM Special Purpose Registers */
+#define NT_PPC_TM_CTAR 0x10c   /* TM checkpointed Target Address 
Register */
+#define NT_PPC_TM_CPPR 0x10d   /* TM checkpointed Program Priority 
Register */
+#define NT_PPC_TM_CDSCR0x10e   /* TM checkpointed Data Stream 
Control Register */
 #define NT_386_TLS 0x200   /* i386 TLS slots (struct user_desc) */
 #define NT_386_IOPERM  0x201   /* x86 io permission bitmap (1=deny) */
 #define NT_X86_XSTATE  0x202   /* x86 extended state using xsave */
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v5] powerpc/powernv: Add poweroff (EPOW, DPO) events support for PowerNV platform

2015-05-19 Thread trigg


> On 18-May-2015, at 20:48, Vipin K Parashar  wrote:
> 
> This patch adds support for FSP EPOW (Early Power Off Warning) and
> DPO (Delayed Power Off) events for PowerNV platform. EPOW events are
> generated by SPCN/FSP due to various critical system conditions that
> need system shutdown. Few examples of these conditions are high
> ambient temperature or system running on UPS power with low UPS battery.
> DPO event is generated in response to admin initiated system request.
>   Upon receipt of EPOW and DPO events host kernel invokes
> orderly_poweroff for performing graceful system shutdown. System admin
> can also add systemd service shutdown scripts to perform any specific
> actions like graceful guest shutdown upon system poweroff. libvirt-guests
> is systemd service available on recent distros for management of guests
> at system start/shutdown time.
> 
> Signed-off-by: Vipin K Parashar 

Acked-by: trigg 
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

RE: [PATCH v2 0/6] powerpc32: replace memcpy and memset by cacheable alternatives

2015-05-19 Thread David Laight
From: Christophe Leroy
> Sent: 19 May 2015 11:08
>
> This patchset implements use of cacheable versions of memset and
> memcpy since when the destination is not cacheable, memset_io
> and memcpy_toio are used.

This isn't the right list to ask, but:

Can someone fix the x86 versions of memset/memcpy (and the _io variants)
so that they don't end up being 'rep movsb' on new intel cpus?

I've a C2558 Atom which has the optimised 'rep movsb' hardware.
Copies to/from uncached locations are now done 'byte by byte'.
As well as kernel code this affects userpace copying to/from
mmap()ed PCIe space.
64bit reads are slow enough, making it 8 times slower is horrid.

I suspect this affect some network drivers as well.

David

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [v2,2/2] powerpc32: add support for csum_add()

2015-05-19 Thread leroy christophe



Le 05/05/2015 00:10, Segher Boessenkool a écrit :

On Fri, May 01, 2015 at 08:00:14PM -0500, Scott Wood wrote:

On Tue, 2015-04-28 at 21:01 +0200, christophe leroy wrote:

The generated code is most likely different on ppc64. I have no ppc64
compiler

For reference: yes you do.  Just add -m64.

[root@localhost knl]# LANG= ppc-linux-gcc -m64 test.c
test.c:1:0: error: -m64 not supported in this configuration

Christophe
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 19/19] cxl: Add AFU virtual PHB and kernel API

2015-05-19 Thread Michael Neuling
This patch does two things.

Firstly it presents the Accelerator Function Unit (AFUs) behind the POWER
Service Layer (PSL) as PCI devices on a virtual PCI Host Bridge (vPHB).  This
in in addition to the PSL being a PCI device itself.

As part of the Coherent Accelerator Interface Architecture (CAIA) AFUs can
provide an AFU configuration.  This AFU configuration recored is architected to
be the same as a PCI config space.

This patch sets discovers the AFU configuration records, provides AFU config
space read/write functions to these configuration records.  It then enumerates
the PCI bus.  It also hooks in PCI ops where appropriate.  It also destroys the
vPHB when the physical card is removed.

Secondly, it add an in kernel API for AFU to use CXL.  AFUs must present a
driver that firstly binds as a PCI device.  This PCI device can then be using
to do CXL specific operations (that can't sit in the PCI ops) using this API.

Signed-off-by: Michael Neuling 
---
 drivers/misc/cxl/Makefile |   1 +
 drivers/misc/cxl/api.c| 326 ++
 drivers/misc/cxl/cxl.h|   5 +
 drivers/misc/cxl/pci.c|  17 ++-
 drivers/misc/cxl/vphb.c   | 268 +
 include/misc/cxl.h| 201 
 6 files changed, 814 insertions(+), 4 deletions(-)
 create mode 100644 drivers/misc/cxl/api.c
 create mode 100644 drivers/misc/cxl/vphb.c
 create mode 100644 include/misc/cxl.h

diff --git a/drivers/misc/cxl/Makefile b/drivers/misc/cxl/Makefile
index f9f5514..14e3f82 100644
--- a/drivers/misc/cxl/Makefile
+++ b/drivers/misc/cxl/Makefile
@@ -1,5 +1,6 @@
 cxl-y  += main.o file.o irq.o fault.o native.o
 cxl-y  += context.o sysfs.o debugfs.o pci.o trace.o
+cxl-y  += vphb.o api.o
 obj-$(CONFIG_CXL)  += cxl.o
 obj-$(CONFIG_CXL_BASE) += base.o
 
diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c
new file mode 100644
index 000..09901ff
--- /dev/null
+++ b/drivers/misc/cxl/api.c
@@ -0,0 +1,326 @@
+/*
+ * Copyright 2014 IBM Corp.
+ *
+ * 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.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "cxl.h"
+
+struct cxl_context *cxl_dev_context_init(struct pci_dev *dev)
+{
+   struct cxl_afu *afu;
+   struct cxl_context  *ctx;
+   int rc;
+
+   afu = cxl_pci_to_afu(dev);
+
+   ctx = cxl_context_alloc();
+   if (IS_ERR(ctx))
+   return ctx;
+
+   /* Make it a slave context.  We can promote it later? */
+   rc = cxl_context_init(ctx, afu, false, NULL);
+   if (rc) {
+   kfree(ctx);
+   return ERR_PTR(-ENOMEM);
+   }
+   assign_psn_space(ctx);
+
+   return ctx;
+}
+EXPORT_SYMBOL_GPL(cxl_dev_context_init);
+
+struct cxl_context *cxl_get_context(struct pci_dev *dev)
+{
+   return dev->dev.archdata.cxl_ctx;
+}
+EXPORT_SYMBOL_GPL(cxl_get_context);
+
+struct device *cxl_get_phys_dev(struct pci_dev *dev)
+{
+   struct cxl_afu *afu;
+
+   afu = cxl_pci_to_afu(dev);
+
+   return afu->adapter->dev.parent;
+}
+EXPORT_SYMBOL_GPL(cxl_get_phys_dev);
+
+int cxl_release_context(struct cxl_context *ctx)
+{
+   if (ctx->status != CLOSED)
+   return -EBUSY;
+
+   cxl_context_free(ctx);
+
+   cxl_ctx_put();
+   return 0;
+}
+EXPORT_SYMBOL_GPL(cxl_release_context);
+
+int cxl_allocate_afu_irqs(struct cxl_context *ctx, int num)
+{
+   if (num == 0)
+   num = ctx->afu->pp_irqs;
+   return afu_allocate_irqs(ctx, num);
+}
+EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs);
+
+void cxl_free_afu_irqs(struct cxl_context *ctx)
+{
+   cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
+}
+EXPORT_SYMBOL_GPL(cxl_free_afu_irqs);
+
+static irq_hw_number_t cxl_find_afu_irq(struct cxl_context *ctx, int num)
+{
+   __u16 range;
+   int r;
+
+   WARN_ON(num == 0);
+
+   for (r = 0; r < CXL_IRQ_RANGES; r++) {
+   range = ctx->irqs.range[r];
+   if (num < range) {
+   return ctx->irqs.offset[r] + num;
+   }
+   num -= range;
+   }
+   return 0;
+}
+
+int cxl_map_afu_irq(struct cxl_context *ctx, int num,
+   irq_handler_t handler, void *cookie, char *name)
+{
+   irq_hw_number_t hwirq;
+
+   /*
+* Find interrupt we are to register.
+*/
+   hwirq = cxl_find_afu_irq(ctx, num);
+   if (!hwirq)
+   return -ENOENT;
+
+   return cxl_map_irq(ctx->afu->adapter, hwirq, handler, cookie, name);
+}
+EXPORT_SYMBOL_GPL(cxl_map_afu_irq);
+
+void cxl_unmap_afu_irq(struct cxl_context *ctx, int num, void *cookie)
+{
+   irq_hw_number_t hwirq;
+ 

[PATCH 18/19] cxl: Export file ops for use by API

2015-05-19 Thread Michael Neuling
The cxl kernel API will allow drivers other than cxl to export a file
descriptor which has the same userspace API.  These file descriptors will be
able to be used against libcxl.

This exports those file ops for use by other drivers.

Signed-off-by: Michael Neuling 
---
 drivers/misc/cxl/cxl.h  |  9 +
 drivers/misc/cxl/file.c | 23 ++-
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index bc88823..7c5c014 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -670,4 +671,12 @@ void cxl_stop_trace(struct cxl *cxl);
 extern struct pci_driver cxl_pci_driver;
 int afu_allocate_irqs(struct cxl_context *ctx, u32 count);
 
+int afu_open(struct inode *inode, struct file *file);
+int afu_release(struct inode *inode, struct file *file);
+long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+int afu_mmap(struct file *file, struct vm_area_struct *vm);
+unsigned int afu_poll(struct file *file, struct poll_table_struct *poll);
+ssize_t afu_read(struct file *file, char __user *buf, size_t count, loff_t 
*off);
+extern const struct file_operations afu_fops;
+
 #endif
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
index 5377c8b..6a9fd72 100644
--- a/drivers/misc/cxl/file.c
+++ b/drivers/misc/cxl/file.c
@@ -96,7 +96,8 @@ err_put_adapter:
put_device(&adapter->dev);
return rc;
 }
-static int afu_open(struct inode *inode, struct file *file)
+
+int afu_open(struct inode *inode, struct file *file)
 {
return __afu_open(inode, file, false);
 }
@@ -106,7 +107,7 @@ static int afu_master_open(struct inode *inode, struct file 
*file)
return __afu_open(inode, file, true);
 }
 
-static int afu_release(struct inode *inode, struct file *file)
+int afu_release(struct inode *inode, struct file *file)
 {
struct cxl_context *ctx = file->private_data;
 
@@ -212,7 +213,7 @@ static long afu_ioctl_process_element(struct cxl_context 
*ctx,
return 0;
 }
 
-static long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
struct cxl_context *ctx = file->private_data;
 
@@ -229,13 +230,13 @@ static long afu_ioctl(struct file *file, unsigned int 
cmd, unsigned long arg)
return -EINVAL;
 }
 
-static long afu_compat_ioctl(struct file *file, unsigned int cmd,
+long afu_compat_ioctl(struct file *file, unsigned int cmd,
 unsigned long arg)
 {
return afu_ioctl(file, cmd, arg);
 }
 
-static int afu_mmap(struct file *file, struct vm_area_struct *vm)
+int afu_mmap(struct file *file, struct vm_area_struct *vm)
 {
struct cxl_context *ctx = file->private_data;
 
@@ -246,7 +247,7 @@ static int afu_mmap(struct file *file, struct 
vm_area_struct *vm)
return cxl_context_iomap(ctx, vm);
 }
 
-static unsigned int afu_poll(struct file *file, struct poll_table_struct *poll)
+unsigned int afu_poll(struct file *file, struct poll_table_struct *poll)
 {
struct cxl_context *ctx = file->private_data;
int mask = 0;
@@ -278,7 +279,7 @@ static inline int ctx_event_pending(struct cxl_context *ctx)
ctx->pending_afu_err || (ctx->status == CLOSED));
 }
 
-static ssize_t afu_read(struct file *file, char __user *buf, size_t count,
+ssize_t afu_read(struct file *file, char __user *buf, size_t count,
loff_t *off)
 {
struct cxl_context *ctx = file->private_data;
@@ -359,7 +360,11 @@ out:
return rc;
 }
 
-static const struct file_operations afu_fops = {
+/* 
+ * Note: if this is updated, we need to update api.c to patch the new ones in
+ * too
+ */
+const struct file_operations afu_fops = {
.owner  = THIS_MODULE,
.open   = afu_open,
.poll   = afu_poll,
@@ -370,7 +375,7 @@ static const struct file_operations afu_fops = {
.mmap   = afu_mmap,
 };
 
-static const struct file_operations afu_master_fops = {
+const struct file_operations afu_master_fops = {
.owner  = THIS_MODULE,
.open   = afu_master_open,
.poll   = afu_poll,
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 17/19] cxl: Move include file cxl.h -> cxl-base.h

2015-05-19 Thread Michael Neuling
This moves the current include file from cxl.h -> cxl-base.h.  This current
include file is used only to pass information between the base driver that
needs to be built into the kernel and the cxl module.

This is to make way for a new include/misc/cxl.h which will
contain just the kernel API for other driver to use

Signed-off-by: Michael Neuling 
---
 MAINTAINERS   | 2 +-
 arch/powerpc/include/asm/pnv-pci.h| 2 +-
 arch/powerpc/mm/copro_fault.c | 2 +-
 arch/powerpc/mm/hash_native_64.c  | 2 +-
 arch/powerpc/platforms/powernv/pci-ioda.c | 2 +-
 drivers/misc/cxl/base.c   | 2 +-
 drivers/misc/cxl/cxl.h| 2 +-
 drivers/misc/cxl/irq.c| 2 +-
 drivers/misc/cxl/main.c   | 2 +-
 drivers/misc/cxl/native.c | 2 +-
 include/misc/{cxl.h => cxl-base.h}| 4 ++--
 11 files changed, 12 insertions(+), 12 deletions(-)
 rename include/misc/{cxl.h => cxl-base.h} (95%)

diff --git a/MAINTAINERS b/MAINTAINERS
index f8e0afb..10f6001 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2956,7 +2956,7 @@ M:Michael Neuling 
 L: linuxppc-dev@lists.ozlabs.org
 S: Supported
 F: drivers/misc/cxl/
-F: include/misc/cxl.h
+F: include/misc/cxl*
 F: include/uapi/misc/cxl.h
 F: Documentation/powerpc/cxl.txt
 F: Documentation/powerpc/cxl.txt
diff --git a/arch/powerpc/include/asm/pnv-pci.h 
b/arch/powerpc/include/asm/pnv-pci.h
index f9b4982..6f77f71 100644
--- a/arch/powerpc/include/asm/pnv-pci.h
+++ b/arch/powerpc/include/asm/pnv-pci.h
@@ -11,7 +11,7 @@
 #define _ASM_PNV_PCI_H
 
 #include 
-#include 
+#include 
 
 int pnv_phb_to_cxl_mode(struct pci_dev *dev, uint64_t mode);
 int pnv_cxl_ioda_msi_setup(struct pci_dev *dev, unsigned int hwirq,
diff --git a/arch/powerpc/mm/copro_fault.c b/arch/powerpc/mm/copro_fault.c
index 7a71d7f..6527882 100644
--- a/arch/powerpc/mm/copro_fault.c
+++ b/arch/powerpc/mm/copro_fault.c
@@ -26,7 +26,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 /*
  * This ought to be kept in sync with the powerpc specific do_page_fault
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index 9c4880d..13befa35 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -29,7 +29,7 @@
 #include 
 #include 
 
-#include 
+#include 
 
 #ifdef DEBUG_LOW
 #define DBG_LOW(fmt...) udbg_printf(fmt)
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index bb3c0c4..73e3e08 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -39,7 +39,7 @@
 #include 
 #include 
 
-#include 
+#include 
 
 #include "powernv.h"
 #include "pci.h"
diff --git a/drivers/misc/cxl/base.c b/drivers/misc/cxl/base.c
index 0654ad8..a9f0dd3 100644
--- a/drivers/misc/cxl/base.c
+++ b/drivers/misc/cxl/base.c
@@ -10,7 +10,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include "cxl.h"
 
 /* protected by rcu */
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index f9782a3..bc88823 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -21,7 +21,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include 
 
diff --git a/drivers/misc/cxl/irq.c b/drivers/misc/cxl/irq.c
index 212790b..680cd26 100644
--- a/drivers/misc/cxl/irq.c
+++ b/drivers/misc/cxl/irq.c
@@ -14,7 +14,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include "cxl.h"
 #include "trace.h"
diff --git a/drivers/misc/cxl/main.c b/drivers/misc/cxl/main.c
index de1b19a..403780e 100644
--- a/drivers/misc/cxl/main.c
+++ b/drivers/misc/cxl/main.c
@@ -20,7 +20,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include "cxl.h"
 #include "trace.h"
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index 55078f6..2578ceb 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -15,7 +15,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include "cxl.h"
 #include "trace.h"
diff --git a/include/misc/cxl.h b/include/misc/cxl-base.h
similarity index 95%
rename from include/misc/cxl.h
rename to include/misc/cxl-base.h
index 975cc78..5ae9625 100644
--- a/include/misc/cxl.h
+++ b/include/misc/cxl-base.h
@@ -7,8 +7,8 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#ifndef _MISC_CXL_H
-#define _MISC_CXL_H
+#ifndef _MISC_CXL_BASE_H
+#define _MISC_CXL_BASE_H
 
 #ifdef CONFIG_CXL_BASE
 
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 16/19] cxl: Cleanup Makefile

2015-05-19 Thread Michael Neuling
Cleanup Makefile by fixing line wrapping.

Signed-off-by: Michael Neuling 
---
 drivers/misc/cxl/Makefile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/cxl/Makefile b/drivers/misc/cxl/Makefile
index edb494d..f9f5514 100644
--- a/drivers/misc/cxl/Makefile
+++ b/drivers/misc/cxl/Makefile
@@ -1,4 +1,5 @@
-cxl-y  += main.o file.o irq.o fault.o native.o 
context.o sysfs.o debugfs.o pci.o trace.o
+cxl-y  += main.o file.o irq.o fault.o native.o
+cxl-y  += context.o sysfs.o debugfs.o pci.o trace.o
 obj-$(CONFIG_CXL)  += cxl.o
 obj-$(CONFIG_CXL_BASE) += base.o
 
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 15/19] cxl: Configure PSL for kernel contexts

2015-05-19 Thread Michael Neuling
This updates AFU directed and dedicated modes for contexts attached to the
kernel.

Signed-off-by: Michael Neuling 
---
 drivers/misc/cxl/native.c | 40 ++--
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index f643bb1..55078f6 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -433,6 +433,7 @@ err:
 static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr)
 {
u64 sr;
+   u32 pid;
int r, result;
 
assign_psn_space(ctx);
@@ -447,15 +448,19 @@ static int attach_afu_directed(struct cxl_context *ctx, 
u64 wed, u64 amr)
sr |= CXL_PSL_SR_An_MP;
if (mfspr(SPRN_LPCR) & LPCR_TC)
sr |= CXL_PSL_SR_An_TC;
-   /* HV=0, PR=1, R=1 for userspace
-* For kernel contexts: this would need to change
-*/
-   sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R;
-   set_endian(sr);
-   sr &= ~(CXL_PSL_SR_An_HV);
-   if (!test_tsk_thread_flag(current, TIF_32BIT))
-   sr |= CXL_PSL_SR_An_SF;
-   ctx->elem->common.pid = cpu_to_be32(current->pid);
+
+   if (ctx->kernel) {
+   sr |= CXL_PSL_SR_An_R | (mfmsr() & MSR_SF) | CXL_PSL_SR_An_HV;
+   pid = 0;
+   } else {
+   sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R;
+   set_endian(sr);
+   sr &= ~(CXL_PSL_SR_An_HV);
+   if (!test_tsk_thread_flag(current, TIF_32BIT))
+   sr |= CXL_PSL_SR_An_SF;
+   pid = current->pid;
+   }
+   ctx->elem->common.pid = cpu_to_be32(pid);
ctx->elem->common.tid = 0;
ctx->elem->sr = cpu_to_be64(sr);
 
@@ -530,7 +535,7 @@ static int activate_dedicated_process(struct cxl_afu *afu)
 static int attach_dedicated(struct cxl_context *ctx, u64 wed, u64 amr)
 {
struct cxl_afu *afu = ctx->afu;
-   u64 sr;
+   u64 sr, pid;
int rc;
 
sr = 0;
@@ -539,10 +544,17 @@ static int attach_dedicated(struct cxl_context *ctx, u64 
wed, u64 amr)
sr |= CXL_PSL_SR_An_MP;
if (mfspr(SPRN_LPCR) & LPCR_TC)
sr |= CXL_PSL_SR_An_TC;
-   sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R;
-   if (!test_tsk_thread_flag(current, TIF_32BIT))
-   sr |= CXL_PSL_SR_An_SF;
-   cxl_p2n_write(afu, CXL_PSL_PID_TID_An, (u64)current->pid << 32);
+
+   if (ctx->kernel) {
+   sr |= CXL_PSL_SR_An_R | (mfmsr() & MSR_SF) | CXL_PSL_SR_An_HV;
+   pid = 0;
+   } else { /* User space */
+   sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R;
+   if (!test_tsk_thread_flag(current, TIF_32BIT))
+   sr |= CXL_PSL_SR_An_SF;
+   pid = (u64)current->pid << 32;
+   }
+   cxl_p2n_write(afu, CXL_PSL_PID_TID_An, pid);
cxl_p1n_write(afu, CXL_PSL_SR_An, sr);
 
if ((rc = cxl_write_sstp(afu, ctx->sstp0, ctx->sstp1)))
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 14/19] cxl: Split afu_register_irqs() function

2015-05-19 Thread Michael Neuling
Split the afu_register_irqs() function so that different parts can
be useful elsewhere.

Signed-off-by: Michael Neuling 
---
 drivers/misc/cxl/cxl.h |  1 +
 drivers/misc/cxl/irq.c | 31 ---
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index 15e1077..f9782a3 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -668,5 +668,6 @@ int cxl_psl_purge(struct cxl_afu *afu);
 void cxl_stop_trace(struct cxl *cxl);
 
 extern struct pci_driver cxl_pci_driver;
+int afu_allocate_irqs(struct cxl_context *ctx, u32 count);
 
 #endif
diff --git a/drivers/misc/cxl/irq.c b/drivers/misc/cxl/irq.c
index c740c7b..212790b 100644
--- a/drivers/misc/cxl/irq.c
+++ b/drivers/misc/cxl/irq.c
@@ -416,9 +416,8 @@ void afu_irq_name_free(struct cxl_context *ctx)
}
 }
 
-int afu_register_irqs(struct cxl_context *ctx, u32 count)
+int afu_allocate_irqs(struct cxl_context *ctx, u32 count)
 {
-   irq_hw_number_t hwirq;
int rc, r, i, j = 1;
struct cxl_irq_name *irq_name;
 
@@ -458,6 +457,18 @@ int afu_register_irqs(struct cxl_context *ctx, u32 count)
j++;
}
}
+   return 0;
+
+out:
+   afu_irq_name_free(ctx);
+   return -ENOMEM;
+}
+
+void afu_register_hwirqs(struct cxl_context *ctx)
+{
+   irq_hw_number_t hwirq;
+   struct cxl_irq_name *irq_name;
+   int r,i;
 
/* We've allocated all memory now, so let's do the irq allocations */
irq_name = list_first_entry(&ctx->irq_names, struct cxl_irq_name, list);
@@ -469,13 +480,19 @@ int afu_register_irqs(struct cxl_context *ctx, u32 count)
irq_name = list_next_entry(irq_name, list);
}
}
+}
 
-   return 0;
+int afu_register_irqs(struct cxl_context *ctx, u32 count)
+{
+   int rc;
 
-out:
-   afu_irq_name_free(ctx);
-   return -ENOMEM;
-}
+   rc = afu_allocate_irqs(ctx, count);
+   if (rc)
+   return rc;
+
+   afu_register_hwirqs(ctx);
+   return 0;
+ }
 
 void afu_release_irqs(struct cxl_context *ctx, void *cookie)
 {
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 13/19] cxl: Only check pid for userspace contexts

2015-05-19 Thread Michael Neuling
We only need to check the pid attached to this context for userspace contexts.
Kernel contexts can skip this check.

Signed-off-by: Michael Neuling 
---
 drivers/misc/cxl/fault.c | 34 +++---
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c
index 5286b8b..25a5418 100644
--- a/drivers/misc/cxl/fault.c
+++ b/drivers/misc/cxl/fault.c
@@ -172,8 +172,8 @@ void cxl_handle_fault(struct work_struct *fault_work)
container_of(fault_work, struct cxl_context, fault_work);
u64 dsisr = ctx->dsisr;
u64 dar = ctx->dar;
-   struct task_struct *task;
-   struct mm_struct *mm;
+   struct task_struct *task = NULL;
+   struct mm_struct *mm = NULL;
 
if (cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An) != dsisr ||
cxl_p2n_read(ctx->afu, CXL_PSL_DAR_An) != dar ||
@@ -194,17 +194,19 @@ void cxl_handle_fault(struct work_struct *fault_work)
pr_devel("CXL BOTTOM HALF handling fault for afu pe: %i. "
"DSISR: %#llx DAR: %#llx\n", ctx->pe, dsisr, dar);
 
-   if (!(task = get_pid_task(ctx->pid, PIDTYPE_PID))) {
-   pr_devel("cxl_handle_fault unable to get task %i\n",
-pid_nr(ctx->pid));
-   cxl_ack_ae(ctx);
-   return;
-   }
-   if (!(mm = get_task_mm(task))) {
-   pr_devel("cxl_handle_fault unable to get mm %i\n",
-pid_nr(ctx->pid));
-   cxl_ack_ae(ctx);
-   goto out;
+   if (!ctx->kernel) {
+   if (!(task = get_pid_task(ctx->pid, PIDTYPE_PID))) {
+   pr_devel("cxl_handle_fault unable to get task %i\n",
+pid_nr(ctx->pid));
+   cxl_ack_ae(ctx);
+   return;
+   }
+   if (!(mm = get_task_mm(task))) {
+   pr_devel("cxl_handle_fault unable to get mm %i\n",
+pid_nr(ctx->pid));
+   cxl_ack_ae(ctx);
+   goto out;
+   }
}
 
if (dsisr & CXL_PSL_DSISR_An_DS)
@@ -214,9 +216,11 @@ void cxl_handle_fault(struct work_struct *fault_work)
else
WARN(1, "cxl_handle_fault has nothing to handle\n");
 
-   mmput(mm);
+   if (mm)
+   mmput(mm);
 out:
-   put_task_struct(task);
+   if (task)
+   put_task_struct(task);
 }
 
 static void cxl_prefault_one(struct cxl_context *ctx, u64 ea)
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 12/19] cxl: Export some symbols

2015-05-19 Thread Michael Neuling
These will soon be using elsewhere in the driver.

Signed-off-by: Michael Neuling 
---
 drivers/misc/cxl/cxl.h| 5 +
 drivers/misc/cxl/native.c | 4 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index 8180680..15e1077 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -632,6 +632,9 @@ int cxl_context_init(struct cxl_context *ctx, struct 
cxl_afu *afu, bool master,
 struct address_space *mapping);
 void cxl_context_free(struct cxl_context *ctx);
 int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma);
+unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq,
+irq_handler_t handler, void *cookie, const char *name);
+void cxl_unmap_irq(unsigned int virq, void *cookie);
 int __detach_context(struct cxl_context *ctx);
 
 /* This matches the layout of the H_COLLECT_CA_INT_INFO retbuf */
@@ -646,6 +649,7 @@ struct cxl_irq_info {
u64 padding[3]; /* to match the expected retbuf size for plpar_hcall9 */
 };
 
+void assign_psn_space(struct cxl_context *ctx);
 int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed,
u64 amr);
 int cxl_detach_process(struct cxl_context *ctx);
@@ -658,6 +662,7 @@ int cxl_afu_slbia(struct cxl_afu *afu);
 int cxl_tlb_slb_invalidate(struct cxl *adapter);
 int cxl_afu_disable(struct cxl_afu *afu);
 int __cxl_afu_reset(struct cxl_afu *afu);
+int afu_check_and_enable(struct cxl_afu *afu);
 int cxl_psl_purge(struct cxl_afu *afu);
 
 void cxl_stop_trace(struct cxl *cxl);
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index f85b6ae..f643bb1 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -83,7 +83,7 @@ int __cxl_afu_reset(struct cxl_afu *afu)
   false);
 }
 
-static int afu_check_and_enable(struct cxl_afu *afu)
+int afu_check_and_enable(struct cxl_afu *afu)
 {
if (afu->enabled)
return 0;
@@ -379,7 +379,7 @@ static int remove_process_element(struct cxl_context *ctx)
 }
 
 
-static void assign_psn_space(struct cxl_context *ctx)
+void assign_psn_space(struct cxl_context *ctx)
 {
if (!ctx->afu->pp_size || ctx->master) {
ctx->psn_phys = ctx->afu->psn_phys;
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 11/19] cxl: cxl_afu_reset() -> __cxl_afu_reset()

2015-05-19 Thread Michael Neuling
Rename cxl_afu_reset() to __cxl_afu_reset() to we can reuse this function name
in the API.

Signed-off-by: Michael Neuling 
---
 drivers/misc/cxl/cxl.h| 2 +-
 drivers/misc/cxl/native.c | 8 
 drivers/misc/cxl/pci.c| 4 ++--
 drivers/misc/cxl/sysfs.c  | 2 +-
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index 296a077..8180680 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -657,7 +657,7 @@ int cxl_check_error(struct cxl_afu *afu);
 int cxl_afu_slbia(struct cxl_afu *afu);
 int cxl_tlb_slb_invalidate(struct cxl *adapter);
 int cxl_afu_disable(struct cxl_afu *afu);
-int cxl_afu_reset(struct cxl_afu *afu);
+int __cxl_afu_reset(struct cxl_afu *afu);
 int cxl_psl_purge(struct cxl_afu *afu);
 
 void cxl_stop_trace(struct cxl *cxl);
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index 29185fc..f85b6ae 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -73,7 +73,7 @@ int cxl_afu_disable(struct cxl_afu *afu)
 }
 
 /* This will disable as well as reset */
-int cxl_afu_reset(struct cxl_afu *afu)
+int __cxl_afu_reset(struct cxl_afu *afu)
 {
pr_devel("AFU reset request\n");
 
@@ -495,7 +495,7 @@ static int deactivate_afu_directed(struct cxl_afu *afu)
cxl_sysfs_afu_m_remove(afu);
cxl_chardev_afu_remove(afu);
 
-   cxl_afu_reset(afu);
+   __cxl_afu_reset(afu);
cxl_afu_disable(afu);
cxl_psl_purge(afu);
 
@@ -566,7 +566,7 @@ static int attach_dedicated(struct cxl_context *ctx, u64 
wed, u64 amr)
/* master only context for dedicated */
assign_psn_space(ctx);
 
-   if ((rc = cxl_afu_reset(afu)))
+   if ((rc = __cxl_afu_reset(afu)))
return rc;
 
cxl_p2n_write(afu, CXL_PSL_WED_An, wed);
@@ -629,7 +629,7 @@ int cxl_attach_process(struct cxl_context *ctx, bool 
kernel, u64 wed, u64 amr)
 
 static inline int detach_process_native_dedicated(struct cxl_context *ctx)
 {
-   cxl_afu_reset(ctx->afu);
+   __cxl_afu_reset(ctx->afu);
cxl_afu_disable(ctx->afu);
cxl_psl_purge(ctx->afu);
return 0;
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index 9066a7a..7130c85 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -641,7 +641,7 @@ static int sanitise_afu_regs(struct cxl_afu *afu)
reg = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
if ((reg & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) {
dev_warn(&afu->dev, "WARNING: AFU was not disabled: 
%#.16llx\n", reg);
-   if (cxl_afu_reset(afu))
+   if (__cxl_afu_reset(afu))
return -EIO;
if (cxl_afu_disable(afu))
return -EIO;
@@ -701,7 +701,7 @@ static int cxl_init_afu(struct cxl *adapter, int slice, 
struct pci_dev *dev)
goto err2;
 
/* We need to reset the AFU before we can read the AFU descriptor */
-   if ((rc = cxl_afu_reset(afu)))
+   if ((rc = __cxl_afu_reset(afu)))
goto err2;
 
if (cxl_verbose)
diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c
index d0c38c7..2d6e104 100644
--- a/drivers/misc/cxl/sysfs.c
+++ b/drivers/misc/cxl/sysfs.c
@@ -185,7 +185,7 @@ static ssize_t reset_store_afu(struct device *device,
goto err;
}
 
-   if ((rc = cxl_afu_reset(afu)))
+   if ((rc = __cxl_afu_reset(afu)))
goto err;
 
rc = count;
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 10/19] cxl: Rework detach context functions

2015-05-19 Thread Michael Neuling
Rework __detach_context() and cxl_context_detach() so we can reuse them in the
kernel API.

Signed-off-by: Michael Neuling 
---
 drivers/misc/cxl/context.c | 20 +---
 drivers/misc/cxl/cxl.h |  1 +
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c
index 36bb8e4..7d857b7 100644
--- a/drivers/misc/cxl/context.c
+++ b/drivers/misc/cxl/context.c
@@ -174,7 +174,7 @@ int cxl_context_iomap(struct cxl_context *ctx, struct 
vm_area_struct *vma)
  * return until all outstanding interrupts for this context have completed. The
  * hardware should no longer access *ctx after this has returned.
  */
-static void __detach_context(struct cxl_context *ctx)
+int __detach_context(struct cxl_context *ctx)
 {
enum cxl_context_status status;
 
@@ -183,12 +183,10 @@ static void __detach_context(struct cxl_context *ctx)
ctx->status = CLOSED;
mutex_unlock(&ctx->status_mutex);
if (status != STARTED)
-   return;
+   return -EBUSY;
 
WARN_ON(cxl_detach_process(ctx));
-   afu_release_irqs(ctx, ctx);
-   flush_work(&ctx->fault_work); /* Only needed for dedicated process */
-   wake_up_all(&ctx->wq);
+   return 0;
 }
 
 /*
@@ -199,7 +197,15 @@ static void __detach_context(struct cxl_context *ctx)
  */
 void cxl_context_detach(struct cxl_context *ctx)
 {
-   __detach_context(ctx);
+   int rc;
+
+   rc = __detach_context(ctx);
+   if (rc)
+   return;
+
+   afu_release_irqs(ctx, ctx);
+   flush_work(&ctx->fault_work); /* Only needed for dedicated process */
+   wake_up_all(&ctx->wq);
 }
 
 /*
@@ -216,7 +222,7 @@ void cxl_context_detach_all(struct cxl_afu *afu)
 * Anything done in here needs to be setup before the IDR is
 * created and torn down after the IDR removed
 */
-   __detach_context(ctx);
+   cxl_context_detach(ctx);
 
/*
 * We are force detaching - remove any active PSA mappings so
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index 7c014b8..296a077 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -632,6 +632,7 @@ int cxl_context_init(struct cxl_context *ctx, struct 
cxl_afu *afu, bool master,
 struct address_space *mapping);
 void cxl_context_free(struct cxl_context *ctx);
 int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma);
+int __detach_context(struct cxl_context *ctx);
 
 /* This matches the layout of the H_COLLECT_CA_INT_INFO retbuf */
 struct cxl_irq_info {
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 09/19] cxl: Add cookie parameter to afu_release_irqs()

2015-05-19 Thread Michael Neuling
Add cookie parameter to afu_release_irqs() so that we can pass in a different
cookie than the context structure.  This will be useful for other kernel
drivers that want to call this but get their own cookie back in the interrupt
handler.

Update all existing call sites.

Signed-off-by: Michael Neuling 
---
 drivers/misc/cxl/context.c | 2 +-
 drivers/misc/cxl/cxl.h | 2 +-
 drivers/misc/cxl/file.c| 2 +-
 drivers/misc/cxl/irq.c | 4 ++--
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c
index 78ce990..36bb8e4 100644
--- a/drivers/misc/cxl/context.c
+++ b/drivers/misc/cxl/context.c
@@ -186,7 +186,7 @@ static void __detach_context(struct cxl_context *ctx)
return;
 
WARN_ON(cxl_detach_process(ctx));
-   afu_release_irqs(ctx);
+   afu_release_irqs(ctx, ctx);
flush_work(&ctx->fault_work); /* Only needed for dedicated process */
wake_up_all(&ctx->wq);
 }
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index f0b6727..7c014b8 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -609,7 +609,7 @@ void cxl_release_psl_err_irq(struct cxl *adapter);
 int cxl_register_serr_irq(struct cxl_afu *afu);
 void cxl_release_serr_irq(struct cxl_afu *afu);
 int afu_register_irqs(struct cxl_context *ctx, u32 count);
-void afu_release_irqs(struct cxl_context *ctx);
+void afu_release_irqs(struct cxl_context *ctx, void *cookie);
 irqreturn_t cxl_slice_irq_err(int irq, void *data);
 
 int cxl_debugfs_init(void);
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
index 2364bca..5377c8b 100644
--- a/drivers/misc/cxl/file.c
+++ b/drivers/misc/cxl/file.c
@@ -191,7 +191,7 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
 
if ((rc = cxl_attach_process(ctx, false, work.work_element_descriptor,
 amr))) {
-   afu_release_irqs(ctx);
+   afu_release_irqs(ctx, ctx);
goto out;
}
 
diff --git a/drivers/misc/cxl/irq.c b/drivers/misc/cxl/irq.c
index c8929c5..c740c7b 100644
--- a/drivers/misc/cxl/irq.c
+++ b/drivers/misc/cxl/irq.c
@@ -477,7 +477,7 @@ out:
return -ENOMEM;
 }
 
-void afu_release_irqs(struct cxl_context *ctx)
+void afu_release_irqs(struct cxl_context *ctx, void *cookie)
 {
irq_hw_number_t hwirq;
unsigned int virq;
@@ -488,7 +488,7 @@ void afu_release_irqs(struct cxl_context *ctx)
for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) {
virq = irq_find_mapping(NULL, hwirq);
if (virq)
-   cxl_unmap_irq(virq, ctx);
+   cxl_unmap_irq(virq, cookie);
}
}
 
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 08/19] cxl: Dump debug info on the AFU configuration record

2015-05-19 Thread Michael Neuling
Now that we parse the AFU Configuration record, dump some info on it when in
debug mode.

Signed-off-by: Michael Neuling 
---
 drivers/misc/cxl/pci.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index 1ac2ecf..9066a7a 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -90,6 +90,7 @@
 /* This works a little different than the p1/p2 register accesses to make it
  * easier to pull out individual fields */
 #define AFUD_READ(afu, off)in_be64(afu->afu_desc_mmio + off)
+#define AFUD_READ_LE(afu, off) in_le64(afu->afu_desc_mmio + off)
 #define EXTRACT_PPC_BIT(val, bit)  (!!(val & PPC_BIT(bit)))
 #define EXTRACT_PPC_BITS(val, bs, be)  ((val & PPC_BITMASK(bs, be)) >> 
PPC_BITLSHIFT(be))
 
@@ -286,7 +287,8 @@ static void dump_cxl_config_space(struct pci_dev *dev)
 
 static void dump_afu_descriptor(struct cxl_afu *afu)
 {
-   u64 val;
+   u64 val, afu_cr_num, afu_cr_off, afu_cr_len;
+   int i;
 
 #define show_reg(name, what) \
dev_info(&afu->dev, "afu desc: %30s: %#llx\n", name, what)
@@ -296,6 +298,7 @@ static void dump_afu_descriptor(struct cxl_afu *afu)
show_reg("num_of_processes", AFUD_NUM_PROCS(val));
show_reg("num_of_afu_CRs", AFUD_NUM_CRS(val));
show_reg("req_prog_mode", val & 0xULL);
+   afu_cr_num = AFUD_NUM_CRS(val);
 
val = AFUD_READ(afu, 0x8);
show_reg("Reserved", val);
@@ -307,8 +310,10 @@ static void dump_afu_descriptor(struct cxl_afu *afu)
val = AFUD_READ_CR(afu);
show_reg("Reserved", (val >> (63-7)) & 0xff);
show_reg("AFU_CR_len", AFUD_CR_LEN(val));
+   afu_cr_len = AFUD_CR_LEN(val) * 256;
 
val = AFUD_READ_CR_OFF(afu);
+   afu_cr_off = val;
show_reg("AFU_CR_offset", val);
 
val = AFUD_READ_PPPSA(afu);
@@ -325,6 +330,11 @@ static void dump_afu_descriptor(struct cxl_afu *afu)
val = AFUD_READ_EB_OFF(afu);
show_reg("AFU_EB_offset", val);
 
+   for (i = 0; i < afu_cr_num; i++) {
+   val = AFUD_READ_LE(afu, afu_cr_off + i * afu_cr_len);
+   show_reg("CR Vendor", val & 0x);
+   show_reg("CR Device", (val >> 16) & 0x);
+   }
 #undef show_reg
 }
 
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 07/19] cxl: Re-order card init to check the VSEC earlier

2015-05-19 Thread Michael Neuling
When we expose AFUs as virtual PCI devices, they may look like the physical
CAPI PCI card.  ie they may have the same vendor/device IDs.

We want to avoid these AFUs binding to this driver and any init this driver may
do.

Re-order card init to check the VSEC earlier before assigning BARs or
activating CXL.  Also change the dev used in early prints as the adapter struct
may not be inited at this earlier stage.

Signed-off-by: Michael Neuling 
---
 drivers/misc/cxl/pci.c | 30 +++---
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index a9c90d2..1ac2ecf 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -884,13 +884,13 @@ static int cxl_read_vsec(struct cxl *adapter, struct 
pci_dev *dev)
u16 vseclen;
 
if (!(vsec = find_cxl_vsec(dev))) {
-   dev_err(&adapter->dev, "ABORTING: CXL VSEC not found!\n");
+   dev_err(&dev->dev, "ABORTING: CXL VSEC not found!\n");
return -ENODEV;
}
 
CXL_READ_VSEC_LENGTH(dev, vsec, &vseclen);
if (vseclen < CXL_VSEC_MIN_SIZE) {
-   pr_err("ABORTING: CXL VSEC too short\n");
+   dev_err(&dev->dev, "ABORTING: CXL VSEC too short\n");
return -EINVAL;
}
 
@@ -927,24 +927,24 @@ static int cxl_vsec_looks_ok(struct cxl *adapter, struct 
pci_dev *dev)
return -EBUSY;
 
if (adapter->vsec_status & CXL_UNSUPPORTED_FEATURES) {
-   dev_err(&adapter->dev, "ABORTING: CXL requires unsupported 
features\n");
+   dev_err(&dev->dev, "ABORTING: CXL requires unsupported 
features\n");
return -EINVAL;
}
 
if (!adapter->slices) {
/* Once we support dynamic reprogramming we can use the card if
 * it supports loadable AFUs */
-   dev_err(&adapter->dev, "ABORTING: Device has no AFUs\n");
+   dev_err(&dev->dev, "ABORTING: Device has no AFUs\n");
return -EINVAL;
}
 
if (!adapter->afu_desc_off || !adapter->afu_desc_size) {
-   dev_err(&adapter->dev, "ABORTING: VSEC shows no AFU 
descriptors\n");
+   dev_err(&dev->dev, "ABORTING: VSEC shows no AFU descriptors\n");
return -EINVAL;
}
 
if (adapter->ps_size > p2_size(dev) - adapter->ps_off) {
-   dev_err(&adapter->dev, "ABORTING: Problem state size larger 
than "
+   dev_err(&dev->dev, "ABORTING: Problem state size larger than "
   "available in BAR2: 0x%llx > 0x%llx\n",
 adapter->ps_size, p2_size(dev) - adapter->ps_off);
return -EINVAL;
@@ -993,6 +993,15 @@ static struct cxl *cxl_init_adapter(struct pci_dev *dev)
if (!(adapter = cxl_alloc_adapter(dev)))
return ERR_PTR(-ENOMEM);
 
+   if ((rc = cxl_read_vsec(adapter, dev)))
+   goto err1;
+
+   if ((rc = cxl_vsec_looks_ok(adapter, dev)))
+   goto err1;
+
+   if ((rc = setup_cxl_bars(dev)))
+   goto err1;
+
if ((rc = switch_card_to_cxl(dev)))
goto err1;
 
@@ -1002,12 +1011,6 @@ static struct cxl *cxl_init_adapter(struct pci_dev *dev)
if ((rc = dev_set_name(&adapter->dev, "card%i", adapter->adapter_num)))
goto err2;
 
-   if ((rc = cxl_read_vsec(adapter, dev)))
-   goto err2;
-
-   if ((rc = cxl_vsec_looks_ok(adapter, dev)))
-   goto err2;
-
if ((rc = cxl_update_image_control(adapter)))
goto err2;
 
@@ -1092,9 +1095,6 @@ static int cxl_probe(struct pci_dev *dev, const struct 
pci_device_id *id)
if (cxl_verbose)
dump_cxl_config_space(dev);
 
-   if ((rc = setup_cxl_bars(dev)))
-   return rc;
-
if ((rc = pci_enable_device(dev))) {
dev_err(&dev->dev, "pci_enable_device failed: %i\n", rc);
return rc;
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 06/19] cxl: Add shutdown hook

2015-05-19 Thread Michael Neuling
Signed-off-by: Michael Neuling 
---
 drivers/misc/cxl/pci.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index b80f867..a9c90d2 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -1135,4 +1135,5 @@ struct pci_driver cxl_pci_driver = {
.id_table = cxl_pci_tbl,
.probe = cxl_probe,
.remove = cxl_remove,
+   .shutdown = cxl_remove,
 };
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 05/19] cxl: Document external user of existing API

2015-05-19 Thread Michael Neuling
Now that libcxl is public, let's document it.

Signed-off-by: Michael Neuling 
---
 Documentation/ABI/testing/sysfs-class-cxl | 22 ++
 Documentation/powerpc/cxl.txt |  4 
 2 files changed, 26 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-class-cxl 
b/Documentation/ABI/testing/sysfs-class-cxl
index d46bba8..7cd9f2e 100644
--- a/Documentation/ABI/testing/sysfs-class-cxl
+++ b/Documentation/ABI/testing/sysfs-class-cxl
@@ -15,6 +15,7 @@ Description:read/write
 that hardware can support (eg. 2037). Write values will limit
 userspace applications to that many userspace interrupts. Must
 be >= irqs_min.
+Users: https://github.com/ibm-capi/libcxl
 
 What:   /sys/class/cxl//irqs_min
 Date:   September 2014
@@ -24,6 +25,7 @@ Description:read only
 userspace must request on a CXL_START_WORK ioctl. Userspace may
 omit the num_interrupts field in the START_WORK IOCTL to get
 this minimum automatically.
+Users: https://github.com/ibm-capi/libcxl
 
 What:   /sys/class/cxl//mmio_size
 Date:   September 2014
@@ -31,6 +33,7 @@ Contact:linuxppc-dev@lists.ozlabs.org
 Description:read only
 Decimal value of the size of the MMIO space that may be mmaped
 by userspace.
+Users: https://github.com/ibm-capi/libcxl
 
 What:   /sys/class/cxl//modes_supported
 Date:   September 2014
@@ -38,6 +41,7 @@ Contact:linuxppc-dev@lists.ozlabs.org
 Description:read only
 List of the modes this AFU supports. One per line.
 Valid entries are: "dedicated_process" and "afu_directed"
+Users: https://github.com/ibm-capi/libcxl
 
 What:   /sys/class/cxl//mode
 Date:   September 2014
@@ -46,6 +50,7 @@ Description:read/write
 The current mode the AFU is using. Will be one of the modes
 given in modes_supported. Writing will change the mode
 provided that no user contexts are attached.
+Users: https://github.com/ibm-capi/libcxl
 
 
 What:   /sys/class/cxl//prefault_mode
@@ -59,6 +64,7 @@ Description:read/write
  descriptor as an effective address and
  prefault what it points to.
 all: all segments process calling START_WORK maps.
+Users: https://github.com/ibm-capi/libcxl
 
 What:   /sys/class/cxl//reset
 Date:   September 2014
@@ -66,12 +72,14 @@ Contact:linuxppc-dev@lists.ozlabs.org
 Description:write only
 Writing 1 here will reset the AFU provided there are not
 contexts active on the AFU.
+Users: https://github.com/ibm-capi/libcxl
 
 What:   /sys/class/cxl//api_version
 Date:   September 2014
 Contact:linuxppc-dev@lists.ozlabs.org
 Description:read only
 Decimal value of the current version of the kernel/user API.
+Users: https://github.com/ibm-capi/libcxl
 
 What:   /sys/class/cxl//api_version_compatible
 Date:   September 2014
@@ -79,6 +87,7 @@ Contact:linuxppc-dev@lists.ozlabs.org
 Description:read only
 Decimal value of the the lowest version of the userspace API
 this this kernel supports.
+Users: https://github.com/ibm-capi/libcxl
 
 
 AFU configuration records (eg. /sys/class/cxl/afu0.0/cr0):
@@ -92,6 +101,7 @@ Contact:linuxppc-dev@lists.ozlabs.org
 Description:read only
Hexadecimal value of the vendor ID found in this AFU
configuration record.
+Users: https://github.com/ibm-capi/libcxl
 
 What:   /sys/class/cxl//cr/device
 Date:   February 2015
@@ -99,6 +109,7 @@ Contact:linuxppc-dev@lists.ozlabs.org
 Description:read only
Hexadecimal value of the device ID found in this AFU
configuration record.
+Users: https://github.com/ibm-capi/libcxl
 
 What:   /sys/class/cxl//cr/class
 Date:   February 2015
@@ -106,6 +117,7 @@ Contact:linuxppc-dev@lists.ozlabs.org
 Description:read only
Hexadecimal value of the class code found in this AFU
configuration record.
+Users: https://github.com/ibm-capi/libcxl
 
 What:   /sys/class/cxl//cr/config
 Date:   February 2015
@@ -115,6 +127,7 @@ Description:read only
record. The format is expected to match the either the standard
or extended configuration space defined by the PCIe
specification.
+Users: https://github.com/ibm-capi/libcxl
 
 
 
@@ -126,18 +139,21 @@ Contact:linuxppc-dev@lists.ozlabs.org
 Description:read only
 Decimal value of the s

[PATCH 04/19] powerpc: Add cxl context to device archdata

2015-05-19 Thread Michael Neuling
Add cxl context pointer to archdata.  We'll want to create one of these for cxl
PCI devices.  Put them here until we can get a pci_dev specific private data.

This location was suggested by benh.

Signed-off-by: Michael Neuling 
---
 arch/powerpc/include/asm/device.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/include/asm/device.h 
b/arch/powerpc/include/asm/device.h
index 9f1371b..e9bdda8 100644
--- a/arch/powerpc/include/asm/device.h
+++ b/arch/powerpc/include/asm/device.h
@@ -46,6 +46,9 @@ struct dev_archdata {
 #ifdef CONFIG_FAIL_IOMMU
int fail_iommu;
 #endif
+#ifdef CONFIG_CXL_BASE
+   struct cxl_context  *cxl_ctx;
+#endif
 };
 
 struct pdev_archdata {
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 03/19] powerpc/pci: Add release_device() hook to phb ops

2015-05-19 Thread Michael Neuling
Add release_device() hook to phb ops so we can clean up for specific phbs.

Signed-off-by: Michael Neuling 
---
 arch/powerpc/include/asm/pci-bridge.h | 2 ++
 arch/powerpc/kernel/pci-hotplug.c | 5 +
 2 files changed, 7 insertions(+)

diff --git a/arch/powerpc/include/asm/pci-bridge.h 
b/arch/powerpc/include/asm/pci-bridge.h
index 6d17bb8..4cf0caa 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -27,6 +27,8 @@ struct pci_controller_ops {
 * allow assignment/enabling of the device. */
bool(*enable_device_hook)(struct pci_dev *);
 
+   void(*release_device)(struct pci_dev *);
+
/* Called during PCI resource reassignment */
resource_size_t (*window_alignment)(struct pci_bus *, unsigned long 
type);
void(*reset_secondary_bus)(struct pci_dev *dev);
diff --git a/arch/powerpc/kernel/pci-hotplug.c 
b/arch/powerpc/kernel/pci-hotplug.c
index 7ed85a6..7f9ed0c 100644
--- a/arch/powerpc/kernel/pci-hotplug.c
+++ b/arch/powerpc/kernel/pci-hotplug.c
@@ -29,7 +29,12 @@
  */
 void pcibios_release_device(struct pci_dev *dev)
 {
+   struct pci_controller *phb = pci_bus_to_host(dev->bus);
+
eeh_remove_device(dev);
+
+   if (phb->controller_ops.release_device)
+   phb->controller_ops.release_device(dev);
 }
 
 /**
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 02/19] powerpc/pci: Export symbols for CXL

2015-05-19 Thread Michael Neuling
From: Daniel Axtens 

Export pcibios_claim_one_bus, pcibios_scan_phb and pcibios_alloc_controller.

These will be used by the CXL driver.

Signed-off-by: Daniel Axtens 
---
 arch/powerpc/kernel/pci-common.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 0d05406..2040cd2 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -89,6 +89,7 @@ struct pci_controller *pcibios_alloc_controller(struct 
device_node *dev)
 #endif
return phb;
 }
+EXPORT_SYMBOL_GPL(pcibios_alloc_controller);
 
 void pcibios_free_controller(struct pci_controller *phb)
 {
@@ -1447,6 +1448,7 @@ void pcibios_claim_one_bus(struct pci_bus *bus)
list_for_each_entry(child_bus, &bus->children, node)
pcibios_claim_one_bus(child_bus);
 }
+EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
 
 
 /* pcibios_finish_adding_to_bus
@@ -1680,6 +1682,7 @@ void pcibios_scan_phb(struct pci_controller *hose)
pcie_bus_configure_settings(child);
}
 }
+EXPORT_SYMBOL_GPL(pcibios_scan_phb);
 
 static void fixup_hide_host_resource_fsl(struct pci_dev *dev)
 {
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 01/19] powerpc/copro: Fix faulting kernel segments

2015-05-19 Thread Michael Neuling
This fixes calculating the key bits (KP and KS) in the SLB VSID for kernel
mappings.

I'm not CCing this to stable as there are no uses of this currently.

Signed-off-by: Michael Neuling 
---
 arch/powerpc/mm/copro_fault.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/mm/copro_fault.c b/arch/powerpc/mm/copro_fault.c
index f031a47..7a71d7f 100644
--- a/arch/powerpc/mm/copro_fault.c
+++ b/arch/powerpc/mm/copro_fault.c
@@ -100,7 +100,7 @@ EXPORT_SYMBOL_GPL(copro_handle_mm_fault);
 
 int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb)
 {
-   u64 vsid;
+   u64 vsid, vsidkey;
int psize, ssize;
 
switch (REGION_ID(ea)) {
@@ -109,6 +109,7 @@ int copro_calculate_slb(struct mm_struct *mm, u64 ea, 
struct copro_slb *slb)
psize = get_slice_psize(mm, ea);
ssize = user_segment_size(ea);
vsid = get_vsid(mm->context.id, ea, ssize);
+   vsidkey = SLB_VSID_USER;
break;
case VMALLOC_REGION_ID:
pr_devel("%s: 0x%llx -- VMALLOC_REGION_ID\n", __func__, ea);
@@ -118,19 +119,21 @@ int copro_calculate_slb(struct mm_struct *mm, u64 ea, 
struct copro_slb *slb)
psize = mmu_io_psize;
ssize = mmu_kernel_ssize;
vsid = get_kernel_vsid(ea, mmu_kernel_ssize);
+   vsidkey = SLB_VSID_KERNEL;
break;
case KERNEL_REGION_ID:
pr_devel("%s: 0x%llx -- KERNEL_REGION_ID\n", __func__, ea);
psize = mmu_linear_psize;
ssize = mmu_kernel_ssize;
vsid = get_kernel_vsid(ea, mmu_kernel_ssize);
+   vsidkey = SLB_VSID_KERNEL;
break;
default:
pr_debug("%s: invalid region access at %016llx\n", __func__, 
ea);
return 1;
}
 
-   vsid = (vsid << slb_vsid_shift(ssize)) | SLB_VSID_USER;
+   vsid = (vsid << slb_vsid_shift(ssize)) | vsidkey;
 
vsid |= mmu_psize_defs[psize].sllp |
((ssize == MMU_SEGSIZE_1T) ? SLB_VSID_B_1T : 0);
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 00/19] cxl: Add AFU virtual PHB and in kernel API

2015-05-19 Thread Michael Neuling
This patch series adds the ability to present AFUs as PCI devices on a virtual
PHB.

It also adds an in kernel API (to the existing userspace API) so AFU drivers
can be written as kernel drivers.

Mikey
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH V7 10/10] powerpc/powernv: compound PE for VFs

2015-05-19 Thread Wei Yang
When VF BAR size is larger than 64MB, we group VFs in terms of M64 BAR,
which means those VFs in a group should form a compound PE.

This patch links those VF PEs into compound PE in this case.

[gwshan: code refactoring for a bit]
Signed-off-by: Wei Yang 
Acked-by: Gavin Shan 
---
 arch/powerpc/platforms/powernv/pci-ioda.c |   46 +
 arch/powerpc/platforms/powernv/pci.c  |   17 +--
 2 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index f8bc950..56e7b65 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1363,9 +1363,20 @@ static void pnv_ioda_release_vf_PE(struct pci_dev *pdev, 
u16 num_vfs)
}
 
list_for_each_entry_safe(pe, pe_n, &phb->ioda.pe_list, list) {
+   struct pnv_ioda_pe *s, *sn;
if (pe->parent_dev != pdev)
continue;
 
+   if ((pe->flags & PNV_IODA_PE_MASTER) &&
+   (pe->flags & PNV_IODA_PE_VF)) {
+   list_for_each_entry_safe(s, sn, &pe->slaves, list) {
+   pnv_pci_ioda2_release_dma_pe(pdev, s);
+   list_del(&s->list);
+   pnv_ioda_deconfigure_pe(phb, s);
+   pnv_ioda_free_pe(phb, s->pe_number);
+   }
+   }
+
pnv_pci_ioda2_release_dma_pe(pdev, pe);
 
/* Remove from list */
@@ -1418,7 +1429,7 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, 
u16 num_vfs)
struct pci_bus*bus;
struct pci_controller *hose;
struct pnv_phb*phb;
-   struct pnv_ioda_pe*pe;
+   struct pnv_ioda_pe*pe, *master_pe;
intpe_num;
u16vf_index;
struct pci_dn *pdn;
@@ -1464,10 +1475,13 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, 
u16 num_vfs)
GFP_KERNEL, hose->node);
pe->tce32_table->data = pe;
 
-   /* Put PE to the list */
-   mutex_lock(&phb->ioda.pe_list_mutex);
-   list_add_tail(&pe->list, &phb->ioda.pe_list);
-   mutex_unlock(&phb->ioda.pe_list_mutex);
+   /* Put PE to the list, or postpone it for compound PEs */
+   if ((pdn->m64_per_iov != M64_PER_IOV) ||
+   (num_vfs <= M64_PER_IOV)) {
+   mutex_lock(&phb->ioda.pe_list_mutex);
+   list_add_tail(&pe->list, &phb->ioda.pe_list);
+   mutex_unlock(&phb->ioda.pe_list_mutex);
+   }
 
pnv_pci_ioda2_setup_dma_pe(phb, pe);
}
@@ -1480,10 +1494,32 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, 
u16 num_vfs)
vf_per_group = roundup_pow_of_two(num_vfs) / pdn->m64_per_iov;
 
for (vf_group = 0; vf_group < M64_PER_IOV; vf_group++) {
+   master_pe = NULL;
+
for (vf_index = vf_group * vf_per_group;
 vf_index < (vf_group + 1) * vf_per_group &&
 vf_index < num_vfs;
 vf_index++) {
+
+   /*
+* Figure out the master PE and put all slave
+* PEs to master PE's list.
+*/
+   pe = &phb->ioda.pe_array[pdn->offset + 
vf_index];
+   if (!master_pe) {
+   pe->flags |= PNV_IODA_PE_MASTER;
+   INIT_LIST_HEAD(&pe->slaves);
+   master_pe = pe;
+   mutex_lock(&phb->ioda.pe_list_mutex);
+   list_add_tail(&pe->list, 
&phb->ioda.pe_list);
+   mutex_unlock(&phb->ioda.pe_list_mutex);
+   } else {
+   pe->flags |= PNV_IODA_PE_SLAVE;
+   pe->master = master_pe;
+   list_add_tail(&pe->list,
+   &master_pe->slaves);
+   }
+
for (vf_index1 = vf_group * vf_per_group;
 vf_index1 < (vf_group + 1) * vf_per_group 
&&
 vf_index1 < num_vfs;
diff --git a/arch/powerpc/platforms/powernv/pci.c 
b/arch/powerpc/platforms/powernv/pci.c
index 10bc8c3..717a58e 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -667,7 +667,7 @@ static void pnv_pci_dma_dev_setup(struct pci_dev 

[PATCH V7 09/10] powerpc/eeh: Support error recovery for VF PE

2015-05-19 Thread Wei Yang
Different from PCI bus dependent PE, PE for VFs doesn't have the
primary bus, on which the PCI hotplug is implemented. The patch
supports error recovery, especially the PCI hotplug for VF's PE.
The hotplug on VF's PE is implemented based on VFs, instead of
PCI bus any more.

[gwshan: changelog and code refactoring]
Signed-off-by: Wei Yang 
Acked-by: Gavin Shan 
---
 arch/powerpc/include/asm/eeh.h   |1 +
 arch/powerpc/kernel/eeh.c|8 +++
 arch/powerpc/kernel/eeh_driver.c |  100 ++
 arch/powerpc/kernel/eeh_pe.c |3 +-
 4 files changed, 90 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 3d64cf3..d24382c 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -140,6 +140,7 @@ struct eeh_dev {
struct pci_controller *phb; /* Associated PHB   */
struct pci_dn *pdn; /* Associated PCI device node   */
struct pci_dev *pdev;   /* Associated PCI device*/
+   intin_error;/* Error flag for eeh_dev   */
struct pci_dev *physfn; /* Associated PF PORT   */
struct pci_bus *bus;/* PCI bus for partial hotplug  */
 };
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index 9ee61d1..1207547 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -1229,6 +1229,14 @@ void eeh_remove_device(struct pci_dev *dev)
 * from the parent PE during the BAR resotre.
 */
edev->pdev = NULL;
+
+   /*
+* The flag "in_error" is used to trace EEH devices for VFs
+* in error state or not. It's set in eeh_report_error(). If
+* it's not set, eeh_report_{reset,resume}() won't be called
+* for the VF EEH device.
+*/
+   edev->in_error = 0;
dev->dev.archdata.edev = NULL;
if (!(edev->pe->state & EEH_PE_KEEP))
eeh_rmv_from_parent_pe(edev);
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 24768ff..63a2c33 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -211,6 +211,7 @@ static void *eeh_report_error(void *data, void *userdata)
if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
if (*res == PCI_ERS_RESULT_NONE) *res = rc;
 
+   edev->in_error = 1;
eeh_pcid_put(dev);
return NULL;
 }
@@ -282,7 +283,8 @@ static void *eeh_report_reset(void *data, void *userdata)
 
if (!driver->err_handler ||
!driver->err_handler->slot_reset ||
-   (edev->mode & EEH_DEV_NO_HANDLER)) {
+   (edev->mode & EEH_DEV_NO_HANDLER) ||
+   (!edev->in_error)) {
eeh_pcid_put(dev);
return NULL;
}
@@ -339,14 +341,16 @@ static void *eeh_report_resume(void *data, void *userdata)
 
if (!driver->err_handler ||
!driver->err_handler->resume ||
-   (edev->mode & EEH_DEV_NO_HANDLER)) {
+   (edev->mode & EEH_DEV_NO_HANDLER) ||
+   (!edev->in_error)) {
edev->mode &= ~EEH_DEV_NO_HANDLER;
-   eeh_pcid_put(dev);
-   return NULL;
+   goto out;
}
 
driver->err_handler->resume(dev);
 
+out:
+   edev->in_error = 0;
eeh_pcid_put(dev);
return NULL;
 }
@@ -386,12 +390,38 @@ static void *eeh_report_failure(void *data, void 
*userdata)
return NULL;
 }
 
+static void *eeh_add_virt_device(void *data, void *userdata)
+{
+   struct pci_driver *driver;
+   struct eeh_dev *edev = (struct eeh_dev *)data;
+   struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
+   struct pci_dn *pdn = eeh_dev_to_pdn(edev);
+
+   if (!(edev->physfn)) {
+   pr_warn("%s: EEH dev %04x:%02x:%02x.%01x not for VF\n",
+   __func__, edev->phb->global_number, pdn->busno,
+   PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn));
+   return NULL;
+   }
+
+   driver = eeh_pcid_get(dev);
+   if (driver) {
+   eeh_pcid_put(dev);
+   if (driver->err_handler)
+   return NULL;
+   }
+
+   pci_iov_virtfn_add(edev->physfn, pdn->vf_index, 0);
+   return NULL;
+}
+
 static void *eeh_rmv_device(void *data, void *userdata)
 {
struct pci_driver *driver;
struct eeh_dev *edev = (struct eeh_dev *)data;
struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
int *removed = (int *)userdata;
+   struct pci_dn *pdn = eeh_dev_to_pdn(edev);
 
/*
 * Actually, we should remove the PCI bridges as well.
@@ -416,7 +446,7 @@ static void *eeh_rmv_device(void *data, void *userdata)
driver = eeh_pcid_get(dev);
if (driver) {
eeh_pcid_put(dev);
-   if (driver->err_handler)
+   if (removed && driver-

[PATCH V7 08/10] powerpc/powernv: Support PCI config restore for VFs

2015-05-19 Thread Wei Yang
After PE reset, OPAL API opal_pci_reinit() is called on all devices
contained in the PE to reinitialize them. However, VFs can't be seen
from skiboot firmware. We have to implement the functions, similar
those in skiboot firmware, to reinitialize VFs after reset on PE
for VFs.

[gwshan: changelog and code refactoring]
Signed-off-by: Wei Yang 
Acked-by: Gavin Shan 
---
 arch/powerpc/include/asm/pci-bridge.h|1 +
 arch/powerpc/platforms/powernv/eeh-powernv.c |   70 +-
 arch/powerpc/platforms/powernv/pci.c |   18 +++
 3 files changed, 88 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/pci-bridge.h 
b/arch/powerpc/include/asm/pci-bridge.h
index c324882..ad60263 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -206,6 +206,7 @@ struct pci_dn {
 #define IODA_INVALID_M64(-1)
int m64_wins[PCI_SRIOV_NUM_BARS][M64_PER_IOV];
 #endif /* CONFIG_PCI_IOV */
+   int mps;
 #endif
struct list_head child_list;
struct list_head list;
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c 
b/arch/powerpc/platforms/powernv/eeh-powernv.c
index 7af3c1e..33deb78 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -1612,6 +1612,67 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
return ret;
 }
 
+static int pnv_eeh_restore_vf_config(struct pci_dn *pdn)
+{
+   struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
+   u32 devctl, cmd, cap2, aer_capctl;
+   int old_mps;
+
+   /* Restore MPS */
+   if (edev->pcie_cap) {
+   old_mps = (ffs(pdn->mps) - 8) << 5;
+   eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
+2, &devctl);
+   devctl &= ~PCI_EXP_DEVCTL_PAYLOAD;
+   devctl |= old_mps;
+   eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
+ 2, devctl);
+   }
+
+   /* Disable Completion Timeout */
+   if (edev->pcie_cap) {
+   eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCAP2,
+4, &cap2);
+   if (cap2 & 0x10) {
+   eeh_ops->read_config(pdn,
+   edev->pcie_cap + PCI_EXP_DEVCTL2,
+   4, &cap2);
+   cap2 |= 0x10;
+   eeh_ops->write_config(pdn,
+   edev->pcie_cap + PCI_EXP_DEVCTL2,
+   4, cap2);
+   }
+   }
+
+   /* Enable SERR and parity checking */
+   eeh_ops->read_config(pdn, PCI_COMMAND, 2, &cmd);
+   cmd |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
+   eeh_ops->write_config(pdn, PCI_COMMAND, 2, cmd);
+
+   /* Enable report various errors */
+   if (edev->pcie_cap) {
+   eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
+   2, &devctl);
+   devctl &= ~PCI_EXP_DEVCTL_CERE;
+   devctl |= (PCI_EXP_DEVCTL_NFERE |
+  PCI_EXP_DEVCTL_FERE |
+  PCI_EXP_DEVCTL_URRE);
+   eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
+   2, devctl);
+   }
+
+   /* Enable ECRC generation and check */
+   if (edev->pcie_cap && edev->aer_cap) {
+   eeh_ops->read_config(pdn, edev->aer_cap + PCI_ERR_CAP,
+   4, &aer_capctl);
+   aer_capctl |= (PCI_ERR_CAP_ECRC_GENE | PCI_ERR_CAP_ECRC_CHKE);
+   eeh_ops->write_config(pdn, edev->aer_cap + PCI_ERR_CAP,
+   4, aer_capctl);
+   }
+
+   return 0;
+}
+
 static int pnv_eeh_restore_config(struct pci_dn *pdn)
 {
struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
@@ -1622,7 +1683,14 @@ static int pnv_eeh_restore_config(struct pci_dn *pdn)
return -EEXIST;
 
phb = edev->phb->private_data;
-   ret = opal_pci_reinit(phb->opal_id,
+   /*
+* We have to restore the PCI config space after reset since the
+* firmware can't see SRIOV VFs.
+*/
+   if (edev->physfn)
+   ret = pnv_eeh_restore_vf_config(pdn);
+   else
+   ret = opal_pci_reinit(phb->opal_id,
  OPAL_REINIT_PCI_DEV, edev->config_addr);
if (ret) {
pr_warn("%s: Can't reinit PCI dev 0x%x (%lld)\n",
diff --git a/arch/powerpc/platforms/powernv/pci.c 
b/arch/powerpc/platforms/powernv/pci.c
index bca2aeb..10bc8c3 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -729,6 +729,24 @@ static void pnv_p7ioc_rc_quirk(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IBM, 0x3b9, pnv_p7ioc_rc_quirk);
 
+#ifdef

[PATCH V7 07/10] powerpc/powernv: Support EEH reset for VF PE

2015-05-19 Thread Wei Yang
PEs for VFs don't have primary bus. So they have to have their own reset
backend, which is used during EEH recovery. The patch implements the reset
backend for VF's PE by issuing FLR or AF FLR to the VFs, which are contained
in the PE.

[gwshan: changelog and code refactoring]
Signed-off-by: Wei Yang 
Acked-by: Gavin Shan 
---
 arch/powerpc/include/asm/eeh.h   |1 +
 arch/powerpc/platforms/powernv/eeh-powernv.c |  134 +-
 2 files changed, 134 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index c1fde48..3d64cf3 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -134,6 +134,7 @@ struct eeh_dev {
int pcix_cap;   /* Saved PCIx capability*/
int pcie_cap;   /* Saved PCIe capability*/
int aer_cap;/* Saved AER capability */
+   int af_cap; /* Saved AF capability  */
struct eeh_pe *pe;  /* Associated PE*/
struct list_head list;  /* Form link list in the PE */
struct pci_controller *phb; /* Associated PHB   */
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c 
b/arch/powerpc/platforms/powernv/eeh-powernv.c
index c505036..7af3c1e 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -402,6 +402,7 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data)
edev->pcix_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_PCIX);
edev->pcie_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_EXP);
edev->aer_cap  = pnv_eeh_find_ecap(pdn, PCI_EXT_CAP_ID_ERR);
+   edev->af_cap   = pnv_eeh_find_cap(pdn, PCI_CAP_ID_AF);
if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) {
edev->mode |= EEH_DEV_BRIDGE;
if (edev->pcie_cap) {
@@ -891,6 +892,127 @@ static int pnv_eeh_bridge_reset(struct pci_dev *dev, int 
option)
return 0;
 }
 
+static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, int pos,
+u16 mask, bool af_flr_rst)
+{
+   struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
+   int status, i;
+
+   /* Wait for Transaction Pending bit to be cleared */
+   for (i = 0; i < 4; i++) {
+   eeh_ops->read_config(pdn, pos, 2, &status);
+   if (!(status & mask))
+   return;
+
+   msleep((1 << i) * 100);
+   }
+
+   pr_warn("%s: Pending transaction while issuing %s FLR to "
+   "%04x:%02x:%02x.%01x\n",
+   __func__, af_flr_rst ? "AF" : "",
+   edev->phb->global_number, pdn->busno,
+   PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn));
+}
+
+static int pnv_eeh_do_flr(struct pci_dn *pdn, int option)
+{
+   struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
+   u32 reg;
+
+   if (!edev->pcie_cap)
+   return -ENOTTY;
+
+   eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCAP, 4, ®);
+   if (!(reg & PCI_EXP_DEVCAP_FLR))
+   return -ENOTTY;
+
+   switch (option) {
+   case EEH_RESET_HOT:
+   case EEH_RESET_FUNDAMENTAL:
+   pnv_eeh_wait_for_pending(pdn, edev->pcie_cap + PCI_EXP_DEVSTA,
+PCI_EXP_DEVSTA_TRPND, false);
+   eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
+4, ®);
+   reg |= PCI_EXP_DEVCTL_BCR_FLR;
+   eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
+ 4, reg);
+   msleep(EEH_PE_RST_HOLD_TIME);
+   break;
+   case EEH_RESET_DEACTIVATE:
+   eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
+4, ®);
+   reg &= ~PCI_EXP_DEVCTL_BCR_FLR;
+   eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
+ 4, reg);
+   msleep(EEH_PE_RST_SETTLE_TIME);
+   break;
+   }
+
+   return 0;
+}
+
+static int pnv_eeh_do_af_flr(struct pci_dn *pdn, int option)
+{
+   struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
+   u32 cap;
+
+   if (!edev->af_cap)
+   return -ENOTTY;
+
+   eeh_ops->read_config(pdn, edev->af_cap + PCI_AF_CAP, 1, &cap);
+   if (!(cap & PCI_AF_CAP_TP) || !(cap & PCI_AF_CAP_FLR))
+   return -ENOTTY;
+
+   switch (option) {
+   case EEH_RESET_HOT:
+   case EEH_RESET_FUNDAMENTAL:
+   /*
+* Wait for Transaction Pending bit to clear. A word-aligned
+* test is used, so we use the conrol offset rather than status
+* and shift the test bit to match.
+*/
+   pnv_eeh_wait_for_pending(pdn, edev->af_cap 

[PATCH V7 06/10] powerpc/eeh: Create PE for VFs

2015-05-19 Thread Wei Yang
Current EEH recovery code works with the assumption: the PE has primary
bus. Unfortunately, that's not true to VF PEs, which generally contains
one or multiple VFs (for VF group case). The patch creates PEs for VFs
at PCI final fixup time. Those PEs for VFs are indentified with newly
introduced flag EEH_PE_VF so that we handle them differently during
EEH recovery.

[gwshan: changelog and code refactoring]
Signed-off-by: Wei Yang 
Acked-by: Gavin Shan 
---
 arch/powerpc/include/asm/eeh.h   |1 +
 arch/powerpc/kernel/eeh_pe.c |   10 --
 arch/powerpc/platforms/powernv/eeh-powernv.c |   17 +
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 1b3614d..c1fde48 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -70,6 +70,7 @@ struct pci_dn;
 #define EEH_PE_PHB (1 << 1)/* PHB PE*/
 #define EEH_PE_DEVICE  (1 << 2)/* Device PE */
 #define EEH_PE_BUS (1 << 3)/* Bus PE*/
+#define EEH_PE_VF  (1 << 4)/* VF PE */
 
 #define EEH_PE_ISOLATED(1 << 0)/* Isolated PE  
*/
 #define EEH_PE_RECOVERING  (1 << 1)/* Recovering PE*/
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index 35f0b62..260a701 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -299,7 +299,10 @@ static struct eeh_pe *eeh_pe_get_parent(struct eeh_dev 
*edev)
 * EEH device already having associated PE, but
 * the direct parent EEH device doesn't have yet.
 */
-   pdn = pdn ? pdn->parent : NULL;
+   if (edev->physfn)
+   pdn = pci_get_pdn(edev->physfn);
+   else
+   pdn = pdn ? pdn->parent : NULL;
while (pdn) {
/* We're poking out of PCI territory */
parent = pdn_to_eeh_dev(pdn);
@@ -382,7 +385,10 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
}
 
/* Create a new EEH PE */
-   pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE);
+   if (edev->physfn)
+   pe = eeh_pe_alloc(edev->phb, EEH_PE_VF);
+   else
+   pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE);
if (!pe) {
pr_err("%s: out of memory!\n", __func__);
return -ENOMEM;
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c 
b/arch/powerpc/platforms/powernv/eeh-powernv.c
index ce738ab..c505036 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -1520,6 +1520,23 @@ static struct eeh_ops pnv_eeh_ops = {
.restore_config = pnv_eeh_restore_config
 };
 
+static void pnv_eeh_vf_final_fixup(struct pci_dev *pdev)
+{
+   struct pci_dn *pdn = pci_get_pdn(pdev);
+
+   if (!pdev->is_virtfn)
+   return;
+
+   /*
+* The following operations will fail if VF's sysfs files
+* aren't created or its resources aren't finalized.
+*/
+   eeh_add_device_early(pdn);
+   eeh_add_device_late(pdev);
+   eeh_sysfs_add_device(pdev);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pnv_eeh_vf_final_fixup);
+
 /**
  * eeh_powernv_init - Register platform dependent EEH operations
  *
-- 
1.7.9.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH V7 05/10] powerpc/powernv: EEH device for VF

2015-05-19 Thread Wei Yang
VFs and their corresponding pci_dn instances are created and released
dynamically as their PF's SRIOV capability is enabled and disabled.
The patch creates and releases EEH devices for VFs when creating and
releasing their pci_dn instances, which means EEH devices and pci_dn
instances have same life cycle. Also, VF's EEH device is identified
by (struct eeh_dev::physfn).

[gwshan: changelog and removed CONFIG_PCI_IOV]
Signed-off-by: Wei Yang 
Acked-by: Gavin Shan 
---
 arch/powerpc/include/asm/eeh.h |1 +
 arch/powerpc/kernel/pci_dn.c   |   12 
 2 files changed, 13 insertions(+)

diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index a52db28..1b3614d 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -138,6 +138,7 @@ struct eeh_dev {
struct pci_controller *phb; /* Associated PHB   */
struct pci_dn *pdn; /* Associated PCI device node   */
struct pci_dev *pdev;   /* Associated PCI device*/
+   struct pci_dev *physfn; /* Associated PF PORT   */
struct pci_bus *bus;/* PCI bus for partial hotplug  */
 };
 
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index f771130..f0ddde7 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -180,7 +180,9 @@ static struct pci_dn *add_one_dev_pci_data(struct pci_dn 
*parent,
 struct pci_dn *add_dev_pci_data(struct pci_dev *pdev)
 {
 #ifdef CONFIG_PCI_IOV
+   struct pci_controller *hose = pci_bus_to_host(pdev->bus);
struct pci_dn *parent, *pdn;
+   struct eeh_dev *edev;
int i;
 
/* Only support IOV for now */
@@ -206,6 +208,9 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev)
 __func__, i);
return NULL;
}
+   eeh_dev_init(pdn, hose);
+   edev = pdn_to_eeh_dev(pdn);
+   edev->physfn = pdev;
}
 #endif /* CONFIG_PCI_IOV */
 
@@ -254,10 +259,17 @@ void remove_dev_pci_data(struct pci_dev *pdev)
for (i = 0; i < pci_sriov_get_totalvfs(pdev); i++) {
list_for_each_entry_safe(pdn, tmp,
&parent->child_list, list) {
+   struct eeh_dev *edev;
if (pdn->busno != pci_iov_virtfn_bus(pdev, i) ||
pdn->devfn != pci_iov_virtfn_devfn(pdev, i))
continue;
 
+   edev = pdn_to_eeh_dev(pdn);
+   if (edev) {
+   pdn->edev = NULL;
+   kfree(edev);
+   }
+
if (!list_empty(&pdn->list))
list_del(&pdn->list);
 
-- 
1.7.9.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH V7 04/10] powerpc/eeh: Trace first 7 BARs in address cache

2015-05-19 Thread Wei Yang
EEH address cache, which helps to locate the PCI device according to
the given (physical) MMIO address, didn't cover PCI bridges. Also, it
shouldn't return PF with address in PF's IOV BARs. Instead, the VFs
should be returned.

The patch restricts the address cache to cover first 7 BARs for the
above purposes.

[gwshan: changelog]
Signed-off-by: Wei Yang 
Acked-by: Gavin Shan 
---
 arch/powerpc/kernel/eeh_cache.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/eeh_cache.c b/arch/powerpc/kernel/eeh_cache.c
index eeabeab..f6c5f05 100644
--- a/arch/powerpc/kernel/eeh_cache.c
+++ b/arch/powerpc/kernel/eeh_cache.c
@@ -196,7 +196,7 @@ static void __eeh_addr_cache_insert_dev(struct pci_dev *dev)
}
 
/* Walk resources on this device, poke them into the tree */
-   for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+   for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
unsigned long start = pci_resource_start(dev,i);
unsigned long end = pci_resource_end(dev,i);
unsigned int flags = pci_resource_flags(dev,i);
-- 
1.7.9.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH V7 03/10] powerpc/pci: Remove VFs prior to PF

2015-05-19 Thread Wei Yang
As commit ac205b7b ("PCI: make sriov work with hotplug remove") indicates,
VFs, which might be hooked to same PCI bus as their PF should be removed
before the PF. Otherwise, the PCI hot unplugging on the PCI bus would
cause kernel crash.

The patch applies the above pattern to PowerPC PCI hotplug path.

[gwshan: changelog]
Signed-off-by: Wei Yang 
Acked-by: Gavin Shan 
---
 arch/powerpc/kernel/pci-hotplug.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/pci-hotplug.c 
b/arch/powerpc/kernel/pci-hotplug.c
index 7ed85a6..98f84ed 100644
--- a/arch/powerpc/kernel/pci-hotplug.c
+++ b/arch/powerpc/kernel/pci-hotplug.c
@@ -50,7 +50,7 @@ void pcibios_remove_pci_devices(struct pci_bus *bus)
 
pr_debug("PCI: Removing devices on bus %04x:%02x\n",
 pci_domain_nr(bus),  bus->number);
-   list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
+   list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) {
pr_debug("   Removing %s...\n", pci_name(dev));
pci_stop_and_remove_bus_device(dev);
}
-- 
1.7.9.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH V7 02/10] powerpc/pci: Cache VF index in pci_dn

2015-05-19 Thread Wei Yang
The patch caches the VF index in pci_dn, which can be used to calculate
VF's bus, device and function number. Those information helps to locate
the VF's PCI device instance when doing hotplug during EEH recovery if
necessary.

Signed-off-by: Wei Yang 
Acked-by: Gavin Shan 
---
 arch/powerpc/include/asm/pci-bridge.h |1 +
 arch/powerpc/kernel/pci_dn.c  |4 +++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/pci-bridge.h 
b/arch/powerpc/include/asm/pci-bridge.h
index 1811c44..c324882 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -196,6 +196,7 @@ struct pci_dn {
 #define IODA_INVALID_PE(-1)
 #ifdef CONFIG_PPC_POWERNV
int pe_number;
+   int vf_index;   /* VF index in the PF */
 #ifdef CONFIG_PCI_IOV
u16 vfs_expanded;   /* number of VFs IOV BAR expanded */
u16 num_vfs;/* number of VFs enabled*/
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index b3b4df9..f771130 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -139,6 +139,7 @@ struct pci_dn *pci_get_pdn(struct pci_dev *pdev)
 #ifdef CONFIG_PCI_IOV
 static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent,
   struct pci_dev *pdev,
+  int vf_index,
   int busno, int devfn)
 {
struct pci_dn *pdn;
@@ -157,6 +158,7 @@ static struct pci_dn *add_one_dev_pci_data(struct pci_dn 
*parent,
pdn->parent = parent;
pdn->busno = busno;
pdn->devfn = devfn;
+   pdn->vf_index = vf_index;
 #ifdef CONFIG_PPC_POWERNV
pdn->pe_number = IODA_INVALID_PE;
 #endif
@@ -196,7 +198,7 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev)
return NULL;
 
for (i = 0; i < pci_sriov_get_totalvfs(pdev); i++) {
-   pdn = add_one_dev_pci_data(parent, NULL,
+   pdn = add_one_dev_pci_data(parent, NULL, i,
   pci_iov_virtfn_bus(pdev, i),
   pci_iov_virtfn_devfn(pdev, i));
if (!pdn) {
-- 
1.7.9.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH V7 01/10] PCI/IOV: Rename and export virtfn_add/virtfn_remove

2015-05-19 Thread Wei Yang
During EEH recovery, hotplug is applied to the devices which don't
have drivers or their drivers don't support EEH. However, the hotplug,
which was implemented based on PCI bus, can't be applied to VF directly.

The patch renames virtn_{add,remove}() and exports them so that they
can be used in PCI hotplug during EEH recovery.

[gwshan: changelog]
Signed-off-by: Wei Yang 
Reviewed-by: Gavin Shan 
---
 drivers/pci/iov.c   |   10 +-
 include/linux/pci.h |8 
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index ee0ebff..cc941dd 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -108,7 +108,7 @@ resource_size_t pci_iov_resource_size(struct pci_dev *dev, 
int resno)
return dev->sriov->barsz[resno - PCI_IOV_RESOURCES];
 }
 
-static int virtfn_add(struct pci_dev *dev, int id, int reset)
+int pci_iov_virtfn_add(struct pci_dev *dev, int id, int reset)
 {
int i;
int rc = -ENOMEM;
@@ -183,7 +183,7 @@ failed:
return rc;
 }
 
-static void virtfn_remove(struct pci_dev *dev, int id, int reset)
+void pci_iov_virtfn_remove(struct pci_dev *dev, int id, int reset)
 {
char buf[VIRTFN_ID_LEN];
struct pci_dev *virtfn;
@@ -320,7 +320,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
}
 
for (i = 0; i < initial; i++) {
-   rc = virtfn_add(dev, i, 0);
+   rc = pci_iov_virtfn_add(dev, i, 0);
if (rc)
goto failed;
}
@@ -332,7 +332,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
 
 failed:
for (j = 0; j < i; j++)
-   virtfn_remove(dev, j, 0);
+   pci_iov_virtfn_remove(dev, j, 0);
 
iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE);
pci_cfg_access_lock(dev);
@@ -361,7 +361,7 @@ static void sriov_disable(struct pci_dev *dev)
return;
 
for (i = 0; i < iov->num_VFs; i++)
-   virtfn_remove(dev, i, 0);
+   pci_iov_virtfn_remove(dev, i, 0);
 
pcibios_sriov_disable(dev);
 
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 353db8d..06aa5dd 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1679,6 +1679,8 @@ int pci_iov_virtfn_devfn(struct pci_dev *dev, int id);
 
 int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn);
 void pci_disable_sriov(struct pci_dev *dev);
+int pci_iov_virtfn_add(struct pci_dev *dev, int id, int reset);
+void pci_iov_virtfn_remove(struct pci_dev *dev, int id, int reset);
 int pci_num_vf(struct pci_dev *dev);
 int pci_vfs_assigned(struct pci_dev *dev);
 int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs);
@@ -1696,6 +1698,12 @@ static inline int pci_iov_virtfn_devfn(struct pci_dev 
*dev, int id)
 static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn)
 { return -ENODEV; }
 static inline void pci_disable_sriov(struct pci_dev *dev) { }
+static inline int pci_iov_virtfn_add(struct pci_dev *dev, int id, int reset)
+{
+   return -ENOSYS;
+}
+static inline void pci_iov_virtfn_remove(struct pci_dev *dev, int id, int 
reset)
+{ }
 static inline int pci_num_vf(struct pci_dev *dev) { return 0; }
 static inline int pci_vfs_assigned(struct pci_dev *dev)
 { return 0; }
-- 
1.7.9.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH V7 00/10] VF EEH on Power8

2015-05-19 Thread Wei Yang
This patchset enables EEH on SRIOV VFs. The general idea is to create proper
VF edev and VF PE and handle them properly.

Different from the Bus PE, VF PE just contain one VF. This introduces the
difference of EEH error handling on a VF PE. Generally, it has several
differences.

First, the VF's removal and re-enumerate rely on its PF. VF has a tight
relationship between its PF. This is not proper to enumerate a VF by usual
scan procedure. That's why virtfn_add/virtfn_remove are exported in this patch
set.

Second, the reset/restore of a VF is done in kernel space. FW is not aware of
the VF, this means the usual reset function done in FW will not work. One of
the patch will imitate the reset/restore function in kernel space.

Third, the VF may be removed during the PF's error_detected function. In this
case, the original error_detected->slot_reset->resume sequence is not proper
to those removed VFs, since they are re-created by PF in a fresh state. A flag
in eeh_dev is introduce to mark the eeh_dev is in error state. By doing so, we
track whether this device needs to be reset or not.

This has been tested both on host and in guest on Power8 with latest kernel
version.

v7:
   * fix compile error when PCI_IOV is not set
v6:
   * code / commit log refactor by Gavin
v5:
   * remove the compound field, iterate on Master VF PE instead
   * some code refine on PCI config restore and reset on VF
 the wait time for assert and deassert
 PCI device address format
 check on edev->pcie_cap and edev->aer_cap before access them
v4:
   * refine the change logs, comment and code style
   * change pnv_pci_fixup_vf_eeh() to pnv_eeh_vf_final_fixup() and remove the
 CONFIG_PCI_IOV macro
   * reorder patch 5/6 to make the logic more reasonable
   * remove remove_dev_pci_data()
   * remove the EEH_DEV_VF flag, use edev->physfn to identify a VF EEH DEV and
 remove related CONFIG_PCI_IOV macro
   * add the option for VF reset
   * fix the pnv_eeh_cfg_blocked() logic
   * replace pnv_pci_cfg_{read,write} with eeh_ops->{read,write}_config in
 pnv_eeh_vf_restore_config()
   * rename pnv_eeh_vf_restore_config() to pnv_eeh_restore_vf_config()
   * rename pnv_pci_fixup_vf_caps() to pnv_pci_vf_header_fixup() and move it
 to arch/powerpc/platforms/powernv/pci.c
   * add a field compound in pnv_ioda_pe to link compound PEs
   * handle compound PE for VF PEs
v3:
   * add back vf_index in pci_dn to track the VF's index
   * rename ppdev in eeh_dev to physfn for consistency
   * move edev->physfn assignment before dev->dev.archdata.edev is set
   * move pnv_pci_fixup_vf_eeh() and pnv_pci_fixup_vf_caps() to eeh-powernv.c
   * more clear and detail in commit log and comment in code
   * merge eeh_rmv_virt_device() with eeh_rmv_device()
   * move the cfg_blocked check logic from pnv_eeh_read/write_config() to
 pnv_eeh_cfg_blocked()
   * move the vf reset/restore logic into its own patch, two patches are
 created.
 powerpc/powernv: Support PCI config restore for VFs
 powerpc/powernv: Support EEH reset for VFs
   * simplify the vf reset logic
v2:
   * add prefix pci_iov_ to virtfn_add/virtfn_remove
   * use EEH_DEV_VF as a flag for a VF's eeh_dev
   * use eeh_dev instead of edev in change log
   * remove vf_index in eeh_dev, calculate it from pdn->busno and devfn
   * do eeh_add_device_late() and eeh_sysfs_add_device() both after pci_dev is
 well initialized
   * do FLR to reset a VF PE
   * imitate the restore function in FW for VF
   * remove the reverse order patch, since it is still under discussion

Wei Yang (10):
  PCI/IOV: Rename and export virtfn_add/virtfn_remove
  powerpc/pci: Cache VF index in pci_dn
  powerpc/pci: Remove VFs prior to PF
  powerpc/eeh: Trace first 7 BARs in address cache
  powerpc/powernv: EEH device for VF
  powerpc/eeh: Create PE for VFs
  powerpc/powernv: Support EEH reset for VF PE
  powerpc/powernv: Support PCI config restore for VFs
  powerpc/eeh: Support error recovery for VF PE
  powerpc/powernv: compound PE for VFs

 arch/powerpc/include/asm/eeh.h   |4 +
 arch/powerpc/include/asm/pci-bridge.h|2 +
 arch/powerpc/kernel/eeh.c|8 +
 arch/powerpc/kernel/eeh_cache.c  |2 +-
 arch/powerpc/kernel/eeh_driver.c |  100 +---
 arch/powerpc/kernel/eeh_pe.c |   13 +-
 arch/powerpc/kernel/pci-hotplug.c|2 +-
 arch/powerpc/kernel/pci_dn.c |   16 +-
 arch/powerpc/platforms/powernv/eeh-powernv.c |  221 +-
 arch/powerpc/platforms/powernv/pci-ioda.c|   46 +-
 arch/powerpc/platforms/powernv/pci.c |   35 +++-
 drivers/pci/iov.c|   10 +-
 include/linux/pci.h  |8 +
 13 files changed, 426 insertions(+), 41 deletions(-)

-- 
1.7.9.5

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/list

[PATCH v2 6/6] powerpc32: Few optimisations in memcpy

2015-05-19 Thread Christophe Leroy
This patch adds a few optimisations in memcpy functions by using
lbzu/stbu instead of lxb/stb and by re-ordering insn inside a loop
to reduce latency due to loading

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/lib/copy_32.S | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S
index 1d49c74..2ef50c6 100644
--- a/arch/powerpc/lib/copy_32.S
+++ b/arch/powerpc/lib/copy_32.S
@@ -155,9 +155,9 @@ _GLOBAL(memcpy)
mtctr   r8
beq+61f
 70:lbz r9,4(r4)/* do some bytes */
-   stb r9,4(r6)
addir4,r4,1
addir6,r6,1
+   stb r9,3(r6)
bdnz70b
 61:srwi.   r0,r0,2
mtctr   r0
@@ -199,10 +199,10 @@ _GLOBAL(memcpy)
 64:andi.   r0,r5,3
mtctr   r0
beq+65f
-40:lbz r0,4(r4)
-   stb r0,4(r6)
-   addir4,r4,1
-   addir6,r6,1
+   addir4,r4,3
+   addir6,r6,3
+40:lbzur0,1(r4)
+   stbur0,1(r6)
bdnz40b
 65:blr
 
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 5/6] powerpc32: cacheable_memcpy becomes memcpy

2015-05-19 Thread Christophe Leroy
cacheable_memcpy uses dcbz instruction and is more efficient than
memcpy when the destination is in RAM. If the destination is in an
io area, memcpy_toio() is normally used, not memcpy

This patch renames memcpy as generic_memcpy, and renames
cacheable_memcpy as memcpy

On MPC885, we get approximatly 7% increase of the transfer rate
on an FTP reception

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/lib/copy_32.S | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S
index 9262071..1d49c74 100644
--- a/arch/powerpc/lib/copy_32.S
+++ b/arch/powerpc/lib/copy_32.S
@@ -129,13 +129,18 @@ _GLOBAL(memset)
  * We only use this version if the source and dest don't overlap.
  * -- paulus.
  */
-_GLOBAL(cacheable_memcpy)
+_GLOBAL(memmove)
+   cmplw   0,r3,r4
+   bgt backwards_memcpy
+   /* fall through */
+
+_GLOBAL(memcpy)
add r7,r3,r5/* test if the src & dst overlap */
add r8,r4,r5
cmplw   0,r4,r7
cmplw   1,r3,r8
crand   0,0,4   /* cr0.lt &= cr1.lt */
-   blt memcpy  /* if regions overlap */
+   blt generic_memcpy  /* if regions overlap */
 
addir4,r4,-4
addir6,r3,-4
@@ -201,12 +206,7 @@ _GLOBAL(cacheable_memcpy)
bdnz40b
 65:blr
 
-_GLOBAL(memmove)
-   cmplw   0,r3,r4
-   bgt backwards_memcpy
-   /* fall through */
-
-_GLOBAL(memcpy)
+_GLOBAL(generic_memcpy)
srwi.   r7,r5,3
addir6,r3,-4
addir4,r4,-4
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 4/6] powerpc32: Merge the new memset() with the old one

2015-05-19 Thread Christophe Leroy
cacheable_memzero() which has become the new memset() and the old
memset() are quite similar, so just merge them.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/lib/copy_32.S | 34 +++---
 1 file changed, 7 insertions(+), 27 deletions(-)

diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S
index 0b4f954..9262071 100644
--- a/arch/powerpc/lib/copy_32.S
+++ b/arch/powerpc/lib/copy_32.S
@@ -75,8 +75,9 @@ CACHELINE_MASK = (L1_CACHE_BYTES-1)
  * area is cacheable.  -- paulus
  */
 _GLOBAL(memset)
-   cmplwi  r4,0
-   bne-generic_memset
+   rlwimi  r4,r4,8,16,23
+   rlwimi  r4,r4,16,0,15
+
addir6,r3,-4
cmplwi  0,r5,4
blt 7f
@@ -85,6 +86,9 @@ _GLOBAL(memset)
andi.   r0,r6,3
add r5,r0,r5
subfr6,r0,r6
+   cmplwi  0,r4,0
+   bne 2f  /* Use normal procedure if r4 is not zero */
+
clrlwi  r7,r6,32-LG_CACHELINE_BYTES
add r8,r7,r5
srwir9,r8,LG_CACHELINE_BYTES
@@ -103,32 +107,8 @@ _GLOBAL(memset)
bdnz10b
clrlwi  r5,r8,32-LG_CACHELINE_BYTES
addir5,r5,4
-2: srwir0,r5,2
-   mtctr   r0
-   bdz 6f
-1: stwur4,4(r6)
-   bdnz1b
-6: andi.   r5,r5,3
-7: cmpwi   0,r5,0
-   beqlr
-   mtctr   r5
-   addir6,r6,3
-8: stbur4,1(r6)
-   bdnz8b
-   blr
 
-_GLOBAL(generic_memset)
-   rlwimi  r4,r4,8,16,23
-   rlwimi  r4,r4,16,0,15
-   addir6,r3,-4
-   cmplwi  0,r5,4
-   blt 7f
-   stwur4,4(r6)
-   beqlr
-   andi.   r0,r6,3
-   add r5,r0,r5
-   subfr6,r0,r6
-   srwir0,r5,2
+2: srwir0,r5,2
mtctr   r0
bdz 6f
 1: stwur4,4(r6)
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 3/6] powerpc32: memset(0): use cacheable_memzero

2015-05-19 Thread Christophe Leroy
cacheable_memzero uses dcbz instruction and is more efficient than
memset(0) when the destination is in RAM

This patch renames memset as generic_memset, and defines memset
as a prolog to cacheable_memzero. This prolog checks if the byte
to set is 0. If not, it falls back to generic_memcpy()

cacheable_memzero disappears as it is not referenced anywhere anymore

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/lib/copy_32.S | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S
index 55f19f9..0b4f954 100644
--- a/arch/powerpc/lib/copy_32.S
+++ b/arch/powerpc/lib/copy_32.S
@@ -74,9 +74,9 @@ CACHELINE_MASK = (L1_CACHE_BYTES-1)
  * to set them to zero.  This requires that the destination
  * area is cacheable.  -- paulus
  */
-_GLOBAL(cacheable_memzero)
-   mr  r5,r4
-   li  r4,0
+_GLOBAL(memset)
+   cmplwi  r4,0
+   bne-generic_memset
addir6,r3,-4
cmplwi  0,r5,4
blt 7f
@@ -117,7 +117,7 @@ _GLOBAL(cacheable_memzero)
bdnz8b
blr
 
-_GLOBAL(memset)
+_GLOBAL(generic_memset)
rlwimi  r4,r4,8,16,23
rlwimi  r4,r4,16,0,15
addir6,r3,-4
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 2/6] Partially revert "powerpc: Remove duplicate cacheable_memcpy/memzero functions"

2015-05-19 Thread Christophe Leroy
This partially reverts
commit 'powerpc: Remove duplicate cacheable_memcpy/memzero functions
("b05ae4ee602b7dc90771408ccf0972e1b3801a35")'

Functions cacheable_memcpy/memzero are more efficient than
memcpy/memset as they use the dcbz instruction which avoids refill
of the cacheline with the data that we will overwrite.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/lib/copy_32.S | 127 +
 1 file changed, 127 insertions(+)

diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S
index 6813f80..55f19f9 100644
--- a/arch/powerpc/lib/copy_32.S
+++ b/arch/powerpc/lib/copy_32.S
@@ -69,6 +69,54 @@ CACHELINE_BYTES = L1_CACHE_BYTES
 LG_CACHELINE_BYTES = L1_CACHE_SHIFT
 CACHELINE_MASK = (L1_CACHE_BYTES-1)
 
+/*
+ * Use dcbz on the complete cache lines in the destination
+ * to set them to zero.  This requires that the destination
+ * area is cacheable.  -- paulus
+ */
+_GLOBAL(cacheable_memzero)
+   mr  r5,r4
+   li  r4,0
+   addir6,r3,-4
+   cmplwi  0,r5,4
+   blt 7f
+   stwur4,4(r6)
+   beqlr
+   andi.   r0,r6,3
+   add r5,r0,r5
+   subfr6,r0,r6
+   clrlwi  r7,r6,32-LG_CACHELINE_BYTES
+   add r8,r7,r5
+   srwir9,r8,LG_CACHELINE_BYTES
+   addic.  r9,r9,-1/* total number of complete cachelines */
+   ble 2f
+   xorir0,r7,CACHELINE_MASK & ~3
+   srwi.   r0,r0,2
+   beq 3f
+   mtctr   r0
+4: stwur4,4(r6)
+   bdnz4b
+3: mtctr   r9
+   li  r7,4
+10:dcbzr7,r6
+   addir6,r6,CACHELINE_BYTES
+   bdnz10b
+   clrlwi  r5,r8,32-LG_CACHELINE_BYTES
+   addir5,r5,4
+2: srwir0,r5,2
+   mtctr   r0
+   bdz 6f
+1: stwur4,4(r6)
+   bdnz1b
+6: andi.   r5,r5,3
+7: cmpwi   0,r5,0
+   beqlr
+   mtctr   r5
+   addir6,r6,3
+8: stbur4,1(r6)
+   bdnz8b
+   blr
+
 _GLOBAL(memset)
rlwimi  r4,r4,8,16,23
rlwimi  r4,r4,16,0,15
@@ -94,6 +142,85 @@ _GLOBAL(memset)
bdnz8b
blr
 
+/*
+ * This version uses dcbz on the complete cache lines in the
+ * destination area to reduce memory traffic.  This requires that
+ * the destination area is cacheable.
+ * We only use this version if the source and dest don't overlap.
+ * -- paulus.
+ */
+_GLOBAL(cacheable_memcpy)
+   add r7,r3,r5/* test if the src & dst overlap */
+   add r8,r4,r5
+   cmplw   0,r4,r7
+   cmplw   1,r3,r8
+   crand   0,0,4   /* cr0.lt &= cr1.lt */
+   blt memcpy  /* if regions overlap */
+
+   addir4,r4,-4
+   addir6,r3,-4
+   neg r0,r3
+   andi.   r0,r0,CACHELINE_MASK/* # bytes to start of cache line */
+   beq 58f
+
+   cmplw   0,r5,r0 /* is this more than total to do? */
+   blt 63f /* if not much to do */
+   andi.   r8,r0,3 /* get it word-aligned first */
+   subfr5,r0,r5
+   mtctr   r8
+   beq+61f
+70:lbz r9,4(r4)/* do some bytes */
+   stb r9,4(r6)
+   addir4,r4,1
+   addir6,r6,1
+   bdnz70b
+61:srwi.   r0,r0,2
+   mtctr   r0
+   beq 58f
+72:lwzur9,4(r4)/* do some words */
+   stwur9,4(r6)
+   bdnz72b
+
+58:srwi.   r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
+   clrlwi  r5,r5,32-LG_CACHELINE_BYTES
+   li  r11,4
+   mtctr   r0
+   beq 63f
+53:
+   dcbzr11,r6
+   COPY_16_BYTES
+#if L1_CACHE_BYTES >= 32
+   COPY_16_BYTES
+#if L1_CACHE_BYTES >= 64
+   COPY_16_BYTES
+   COPY_16_BYTES
+#if L1_CACHE_BYTES >= 128
+   COPY_16_BYTES
+   COPY_16_BYTES
+   COPY_16_BYTES
+   COPY_16_BYTES
+#endif
+#endif
+#endif
+   bdnz53b
+
+63:srwi.   r0,r5,2
+   mtctr   r0
+   beq 64f
+30:lwzur0,4(r4)
+   stwur0,4(r6)
+   bdnz30b
+
+64:andi.   r0,r5,3
+   mtctr   r0
+   beq+65f
+40:lbz r0,4(r4)
+   stb r0,4(r6)
+   addir4,r4,1
+   addir6,r6,1
+   bdnz40b
+65:blr
+
 _GLOBAL(memmove)
cmplw   0,r3,r4
bgt backwards_memcpy
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 1/6] powerpc: use memset_io() to clear CPM Muram

2015-05-19 Thread Christophe Leroy
CPM muram is not cached, so use memset_io() instead of memset()

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/sysdev/cpm_common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
index 4f78695..e2ea519 100644
--- a/arch/powerpc/sysdev/cpm_common.c
+++ b/arch/powerpc/sysdev/cpm_common.c
@@ -147,7 +147,7 @@ unsigned long cpm_muram_alloc(unsigned long size, unsigned 
long align)
spin_lock_irqsave(&cpm_muram_lock, flags);
cpm_muram_info.alignment = align;
start = rh_alloc(&cpm_muram_info, size, "commproc");
-   memset(cpm_muram_addr(start), 0, size);
+   memset_io(cpm_muram_addr(start), 0, size);
spin_unlock_irqrestore(&cpm_muram_lock, flags);
 
return start;
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 0/6] powerpc32: replace memcpy and memset by cacheable alternatives

2015-05-19 Thread Christophe Leroy
This patchset implements use of cacheable versions of memset and
memcpy since when the destination is not cacheable, memset_io
and memcpy_toio are used.

On MPC885, we observe a 7% rate increase on FTP transfer

Christophe Leroy (6):
  powerpc: use memset_io() to clear CPM Muram
  Partially revert "powerpc: Remove duplicate cacheable_memcpy/memzero
functions"
  powerpc32: memset(0): use cacheable_memzero
  powerpc32: Merge the new memset() with the old one
  powerpc32: cacheable_memcpy becomes memcpy
  powerpc32: Few optimisations in memcpy

 arch/powerpc/lib/copy_32.S   | 109 ++-
 arch/powerpc/sysdev/cpm_common.c |   2 +-
 2 files changed, 109 insertions(+), 2 deletions(-)

-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH] ppc64 ftrace: mark data_access callees "notrace" (pt.1)

2015-05-19 Thread Jiri Kosina
On Tue, 19 May 2015, Michael Ellerman wrote:

> > ftrace already handles recursion protection by itself (depending on the 
> > per-ftrace-ops FTRACE_OPS_FL_RECURSION_SAFE flag).
> 
> OK, so I wonder why that's not working for us?

The situation when traced function recurses to itself is different from 
the situation when tracing core infrastrcuture would recurse to itself 
while performing tracing.

> > It's however not really well-defined what to do when recursion would 
> > happen. Therefore __notrace__ annotation, that just completely avoid such 
> > situation by making tracing impossible, looks like saner general solution 
> > to me.
> 
> I disagree. Correctly annotating all functions that might be called ever and
> for all time is a maintenance nightmare and is never going to work in the long
> term.

All the functions called by ftrace must be marked as notrace, there is no 
way out of it.

-- 
Jiri Kosina
SUSE Labs
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

RE: [PATCH] powerpc/fsl: Add FMan best effort port compatible

2015-05-19 Thread Liberman Igal
Hi Scott,
I understand your point, let me please explain more about the hardware 
configuration and suggest another solution.
I'm referring only to external ports (TX/RX), not OP.
In FMan V3 we have maximum of 8 Port, it depends on the FMan revision (in B4, 
T2, T4 we have 8 ports, in T1024 and T1040 we have 4).
The following configuration are valid:
- All 8 ports can work as 1G ports. 
- Ports 7, 8 (if available) can work as 10G (with full hardware 
resources).
- Port 1, 2 (1 in T1024; 1, 2 in T2080) can be configured as 10G (with 
limited hardware resources).

Currently we use only "fsl,fm-v3-port-rx/tx".

We can go 2 ways:
1. Having 2 compatibles:
"fsl,fman-v3-port-rx/tx"
"fsl,fman-v3-best-effort-port-rx/tx"

The driver can determine the port type of "fsl,fman-v3-port-rx/tx" by 
reading the HW port id.
"fsl,fman-v3-best-effort-port-rx/tx" will let the driver know about the 
best effort port and it will be used instead of "fsl,fman-v3-port-rx/tx".

In your opinion, should we add "fsl,fman-v3-10g-port-rx/tx" for 10G (with full 
hardware resources)?
In such chase, "fsl,fman-v3-port-rx/tx" will denote 1G explicitly.

In FMan V2, dual ports/MACs are not available, so no need change the 
compatibles.

Igal

> -Original Message-
> From: Wood Scott-B07421
> Sent: Tuesday, May 19, 2015 12:09 AM
> To: Liberman Igal-B31950
> Cc: devicet...@vger.kernel.org; linuxppc-dev@lists.ozlabs.org; Bucur
> Madalin-Cristian-B32716
> Subject: Re: [PATCH] powerpc/fsl: Add FMan best effort port compatible
> 
> On Mon, 2015-05-18 at 11:41 +0300, Igal.Liberman wrote:
> > From: Igal Liberman 
> >
> > This patch adds a compatible which represents FMan V3 best effort ports.
> > FMan best effort port is configured as 10G ports, however, it uses 1G
> > hardware.
> >
> > Signed-off-by: Igal Liberman 
> > ---
> >  .../devicetree/bindings/powerpc/fsl/fman.txt   |5 +
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt
> > b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt
> > index edda55f..c2e3ec3 100644
> > --- a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt
> > +++ b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt
> > @@ -166,6 +166,11 @@ PROPERTIES
> > - "fsl,fman-v3-port-oh" for FManV3 OH ports
> > - "fsl,fman-v3-port-rx" for FManV3 RX ports
> > - "fsl,fman-v3-port-tx" for FManV3 TX ports
> > +   Optional compatible which can be used in addition to the
> > +   compatibles above is:
> > +   - "fsl,fman-v3-best-effort-port"
> > +   This compatible represents 10G best effort ports:
> > +   Port configured as 10G, using 1G hardware.
> 
> What does this mean?  If it's using 1G hardware then it's a 1G port, right?
> How can you configure a 1G port to be 10G?
> 
> Why is this compatible in addition to others (note that this implies such 
> ports
> are 100% backwards compatible with hardware that lacks the new
> compatible)?  You'd have the same compatible on rx and tx nodes (I'm
> assuming this isn't applicable to oh)?
> 
> What are the implications of this that warrant adding a compatible?
> 
> -Scott
> 

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v4 4/9] hvc: Convert to using interrupts instead of opal events

2015-05-19 Thread Michael Ellerman
On Tue, 2015-05-19 at 15:09 +1000, Alistair Popple wrote:
> On Tue, 19 May 2015 14:33:39 Michael Ellerman wrote:
> > On Fri, 2015-05-15 at 14:06 +1000, Alistair Popple wrote:
> > > Convert the opal hvc driver to use the new irqchip to register for
> > > opal events. As older firmware versions may not have device tree
> > > bindings for the interrupt parent we just use a hardcoded hwirq based
> > > on the event number.
> > 
> > This is still breaking the mambo skiboot test for me.
> 
> As in you still can't get to userspace?
> 
> You probably need http://patchwork.ozlabs.org/patch/472202/ which fixes a bug 
> in skiboot.

Yep that fixes it.

cheers


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev