Re: [PATCH] [powerpc] Export memory limit via device tree

2012-07-19 Thread Suzuki K. Poulose

On 07/11/2012 11:06 AM, Benjamin Herrenschmidt wrote:

diff --git a/arch/powerpc/kernel/machine_kexec.c 
b/arch/powerpc/kernel/machine_kexec.c
index c957b12..0c9695d 100644
--- a/arch/powerpc/kernel/machine_kexec.c
+++ b/arch/powerpc/kernel/machine_kexec.c
@@ -207,6 +207,12 @@ static struct property crashk_size_prop = {
.value = crashk_size,
  };

+static struct property memory_limit_prop = {
+   .name = linux,memory-limit,
+   .length = sizeof(phys_addr_t),
+   .value = memory_limit,
+};
+


AFAIK. phys_addr_t can change size, so instead make it point to a known
fixes size quantity (a u64).

Ben,

Sorry for the delay in the response.

Some of the other properties are also of phys_addr_t, (e.g 
linux,crashkernel-base, linux,kernel-end ). Should we fix them as well ?


Or

Should we leave this also a phys_addr_t and let the userspace handle it ?




+
+   /* memory-limit is needed for constructing the crash regions */
+   prop = of_find_property(node, memory_limit_prop.name, NULL);
+   if (prop)
+   prom_remove_property(node, prop);
+
+   if (memory_limit)
+   prom_add_property(node, memory_limit_prop);
+


There's a patch floating around making prom_update_property properly
handle both pre-existing and non-pre-existing props, you should probably
base yourself on top of it. I'm about to stick that patch in powerpc
-next


OK. I am testing the new patch based on the above commit. I will wait
for the clarification on the issue of the type, before I post it here.

Thanks
Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 0/4] uprobes/powerpc: Replace ptrace helpers for single stepping

2012-12-03 Thread Suzuki K. Poulose
The following series replaces the ptrace helpers used for single step
enable/disable for uprobes on powerpc, with uprobe specific code.

We reuse the kprobe code to enable single stepping by making it generic
and save/restore the MSR (and DBCR for BookE) across the single step.

This series applies on top of the patches posted by Oleg at :
https://lkml.org/lkml/2012/10/28/92 


Patches have been verified on Power6 and PPC440 (BookE).

Changes since V1: 

 * Don't disable external interrupts. (Sebastian)
 * Introduced routines for saving/restoring the context for sstep.
 * Restore the context in arch_uprobe_abort_xol() (Oleg)


---

Suzuki K. Poulose (4):
  kprobes/powerpc: Do not disable External interrupts during single step
  powerpc: Move the single step enable code to a generic path
  uprobes/powerpc: Introduce routines for save/restore context
  uprobes/powerpc: Make use of generic routines to enable single step


 arch/powerpc/include/asm/probes.h  |   25 +
 arch/powerpc/include/asm/uprobes.h |4 
 arch/powerpc/kernel/kprobes.c  |   21 +
 arch/powerpc/kernel/uprobes.c  |   32 +---
 4 files changed, 55 insertions(+), 27 deletions(-)

-- 
Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 1/4] kprobes/powerpc: Do not disable External interrupts during single step

2012-12-03 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suz...@in.ibm.com

External/Decrement exceptions have lower priority than the Debug Exception.
So, we don't have to disable the External interrupts before a single step.
However, on BookE, Critical Input Exception(CE) has higher priority than a
Debug Exception. Hence we mask them.

Signed-off-by:  Suzuki K. Poulose suz...@in.ibm.com
Cc: Sebastian Andrzej Siewior bige...@linutronix.de
Cc: Ananth N Mavinakaynahalli ana...@in.ibm.com
Cc: Kumar Gala ga...@kernel.crashing.org
Cc: linuxppc-...@ozlabs.org
---
 arch/powerpc/kernel/kprobes.c |   10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index e88c643..4901b34 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -104,13 +104,13 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
 
 static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs 
*regs)
 {
-   /* We turn off async exceptions to ensure that the single step will
-* be for the instruction we have the kprobe on, if we dont its
-* possible we'd get the single step reported for an exception handler
-* like Decrementer or External Interrupt */
-   regs-msr = ~MSR_EE;
regs-msr |= MSR_SINGLESTEP;
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
+   /* 
+* We turn off Critical Input Exception(CE) to ensure that the single
+* step will be for the instruction we have the probe on; if we don't,
+* it is possible we'd get the single step reported for CE.
+*/
regs-msr = ~MSR_CE;
mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
 #ifdef CONFIG_PPC_47x

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 2/4] powerpc: Move the single step enable code to a generic path

2012-12-03 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suz...@in.ibm.com

This patch moves the single step enable code used by kprobe to a generic
routine header so that, it can be re-used by other code, in this case,
uprobes. No functional changes.

Signed-off-by: Suzuki K. Poulose suz...@in.ibm.com
Cc: Ananth N Mavinakaynahalli ana...@in.ibm.com
Cc: Kumar Gala ga...@kernel.crashing.org
Cc: linuxppc-...@ozlabs.org
---
 arch/powerpc/include/asm/probes.h |   25 +
 arch/powerpc/kernel/kprobes.c |   21 +
 2 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/include/asm/probes.h 
b/arch/powerpc/include/asm/probes.h
index 5f1e15b..f94a44f 100644
--- a/arch/powerpc/include/asm/probes.h
+++ b/arch/powerpc/include/asm/probes.h
@@ -38,5 +38,30 @@ typedef u32 ppc_opcode_t;
 #define is_trap(instr) (IS_TW(instr) || IS_TWI(instr))
 #endif /* CONFIG_PPC64 */
 
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+#define MSR_SINGLESTEP (MSR_DE)
+#else
+#define MSR_SINGLESTEP (MSR_SE)
+#endif
+
+/* Enable single stepping for the current task */
+static inline void enable_single_step(struct pt_regs *regs)
+{
+   regs-msr |= MSR_SINGLESTEP;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+   /* 
+* We turn off Critical Input Exception(CE) to ensure that the single
+* step will be for the instruction we have the probe on; if we don't,
+* it is possible we'd get the single step reported for CE.
+*/
+   regs-msr = ~MSR_CE;
+   mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
+#ifdef CONFIG_PPC_47x
+   isync();
+#endif
+#endif
+}
+
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_PROBES_H */
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 4901b34..92f1be7 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -36,12 +36,6 @@
 #include asm/sstep.h
 #include asm/uaccess.h
 
-#ifdef CONFIG_PPC_ADV_DEBUG_REGS
-#define MSR_SINGLESTEP (MSR_DE)
-#else
-#define MSR_SINGLESTEP (MSR_SE)
-#endif
-
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
@@ -104,20 +98,7 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
 
 static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs 
*regs)
 {
-   regs-msr |= MSR_SINGLESTEP;
-#ifdef CONFIG_PPC_ADV_DEBUG_REGS
-   /* 
-* We turn off Critical Input Exception(CE) to ensure that the single
-* step will be for the instruction we have the probe on; if we don't,
-* it is possible we'd get the single step reported for CE.
-*/
-   regs-msr = ~MSR_CE;
-   mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
-#ifdef CONFIG_PPC_47x
-   isync();
-#endif
-#endif
-
+   enable_single_step(regs);
/*
 * On powerpc we should single step on the original
 * instruction even if the probed insn is a trap

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 3/4] uprobes/powerpc: Introduce routines for save/restore context

2012-12-03 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suz...@in.ibm.com

Introduce routines for saving and restoring the context
befre/after the single step. No functional changes involved.

These will be extended later to save/restore more info about
the process once we replace the ptrace helpers.

Signed-off-by: Suzuki K. Poulose suz...@in.ibm.com
---
 arch/powerpc/kernel/uprobes.c |   16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
index bc77834..1a62353 100644
--- a/arch/powerpc/kernel/uprobes.c
+++ b/arch/powerpc/kernel/uprobes.c
@@ -52,6 +52,16 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe,
return 0;
 }
 
+static void uprobe_save_context_sstep(struct arch_uprobe_task *autask)
+{
+   autask-saved_trap_nr = current-thread.trap_nr;
+}
+
+static void uprobe_restore_context_sstep(struct arch_uprobe_task *autask)
+{
+   current-thread.trap_nr = autask-saved_trap_nr;
+}
+
 /*
  * arch_uprobe_pre_xol - prepare to execute out of line.
  * @auprobe: the probepoint information.
@@ -61,7 +71,7 @@ int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct 
pt_regs *regs)
 {
struct arch_uprobe_task *autask = current-utask-autask;
 
-   autask-saved_trap_nr = current-thread.trap_nr;
+   uprobe_save_context_sstep(autask);
current-thread.trap_nr = UPROBE_TRAP_NR;
regs-nip = current-utask-xol_vaddr;
 
@@ -111,7 +121,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, 
struct pt_regs *regs)
 
WARN_ON_ONCE(current-thread.trap_nr != UPROBE_TRAP_NR);
 
-   current-thread.trap_nr = utask-autask.saved_trap_nr;
+   uprobe_restore_context_sstep(utask-autask);
 
/*
 * On powerpc, except for loads and stores, most instructions
@@ -164,7 +174,7 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, 
struct pt_regs *regs)
 {
struct uprobe_task *utask = current-utask;
 
-   current-thread.trap_nr = utask-autask.saved_trap_nr;
+   uprobe_restore_context_sstep(utask-autask);
instruction_pointer_set(regs, utask-vaddr);
 
user_disable_single_step(current);

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 4/4] uprobes/powerpc: Make use of generic routines to enable single step

2012-12-03 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suz...@in.ibm.com

Replace the ptrace helpers with the powerpc generic routines to
enable/disable single step. We save/restore the MSR (and DCBR for BookE)
across for the operation. We don't have to disable the single step,
as restoring the MSR/DBCR would restore the previous state.

Signed-off-by: Suzuki K. Poulose suz...@in.ibm.com
---
 arch/powerpc/include/asm/uprobes.h |4 
 arch/powerpc/kernel/uprobes.c  |   26 +-
 2 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/include/asm/uprobes.h 
b/arch/powerpc/include/asm/uprobes.h
index b532060..10a521c 100644
--- a/arch/powerpc/include/asm/uprobes.h
+++ b/arch/powerpc/include/asm/uprobes.h
@@ -43,6 +43,10 @@ struct arch_uprobe {
 
 struct arch_uprobe_task {
unsigned long   saved_trap_nr;
+   unsigned long   saved_msr;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+   unsigned long   saved_dbcr0;
+#endif
 };
 
 extern int  arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct 
*mm, unsigned long addr);
diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
index 1a62353..6af55c4 100644
--- a/arch/powerpc/kernel/uprobes.c
+++ b/arch/powerpc/kernel/uprobes.c
@@ -52,14 +52,25 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe,
return 0;
 }
 
-static void uprobe_save_context_sstep(struct arch_uprobe_task *autask)
+static void uprobe_save_context_sstep(struct arch_uprobe_task *autask,
+   struct pt_regs *regs)
 {
autask-saved_trap_nr = current-thread.trap_nr;
+   autask-saved_msr = regs-msr;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+   autask-saved_dbcr0 = mfspr(SPRN_DBCR0);
+#endif
 }
 
-static void uprobe_restore_context_sstep(struct arch_uprobe_task *autask)
+static void uprobe_restore_context_sstep(struct arch_uprobe_task *autask,
+   struct pt_regs *regs)
 {
current-thread.trap_nr = autask-saved_trap_nr;
+
+   regs-msr = autask-saved_msr;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+   mtspr(SPRN_DBCR0, autask-saved_dbcr0);
+#endif
 }
 
 /*
@@ -71,11 +82,11 @@ int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct 
pt_regs *regs)
 {
struct arch_uprobe_task *autask = current-utask-autask;
 
-   uprobe_save_context_sstep(autask);
+   uprobe_save_context_sstep(autask, regs);
current-thread.trap_nr = UPROBE_TRAP_NR;
regs-nip = current-utask-xol_vaddr;
 
-   user_enable_single_step(current);
+   enable_single_step(regs);
return 0;
 }
 
@@ -121,7 +132,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, 
struct pt_regs *regs)
 
WARN_ON_ONCE(current-thread.trap_nr != UPROBE_TRAP_NR);
 
-   uprobe_restore_context_sstep(utask-autask);
+   uprobe_restore_context_sstep(utask-autask, regs);
 
/*
 * On powerpc, except for loads and stores, most instructions
@@ -132,7 +143,6 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, 
struct pt_regs *regs)
 */
regs-nip = utask-vaddr + MAX_UINSN_BYTES;
 
-   user_disable_single_step(current);
return 0;
 }
 
@@ -174,10 +184,8 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, 
struct pt_regs *regs)
 {
struct uprobe_task *utask = current-utask;
 
-   uprobe_restore_context_sstep(utask-autask);
+   uprobe_restore_context_sstep(utask-autask, regs);
instruction_pointer_set(regs, utask-vaddr);
-
-   user_disable_single_step(current);
 }
 
 /*

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 3/4] uprobes/powerpc: Introduce routines for save/restore context

2012-12-03 Thread Suzuki K. Poulose

On 12/03/2012 08:45 PM, Ananth N Mavinakayanahalli wrote:

On Mon, Dec 03, 2012 at 08:39:35PM +0530, Suzuki K. Poulose wrote:

From: Suzuki K. Poulose suz...@in.ibm.com

Introduce routines for saving and restoring the context
befre/after the single step. No functional changes involved.

These will be extended later to save/restore more info about
the process once we replace the ptrace helpers.

Signed-off-by: Suzuki K. Poulose suz...@in.ibm.com
---
  arch/powerpc/kernel/uprobes.c |   16 +---
  1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
index bc77834..1a62353 100644
--- a/arch/powerpc/kernel/uprobes.c
+++ b/arch/powerpc/kernel/uprobes.c
@@ -52,6 +52,16 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe,
return 0;
  }

+static void uprobe_save_context_sstep(struct arch_uprobe_task *autask)
+{
+   autask-saved_trap_nr = current-thread.trap_nr;
+}
+
+static void uprobe_restore_context_sstep(struct arch_uprobe_task *autask)
+{
+   current-thread.trap_nr = autask-saved_trap_nr;
+}


Can't the two above be inline?

I had this discussion with Srikar and he was of the opinion that, we
should leave it as just static and let the compiler do the optimization.


Thanks
Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 1/2] [powerpc] Change memory_limit from phys_addr_t to unsigned long long

2012-09-07 Thread Suzuki K. Poulose

On 09/07/2012 07:05 AM, Benjamin Herrenschmidt wrote:

On Tue, 2012-08-21 at 17:12 +0530, Suzuki K. Poulose wrote:

There are some device-tree nodes, whose values are of type phys_addr_t.
The phys_addr_t is variable sized based on the CONFIG_PHSY_T_64BIT.

Change these to a fixed unsigned long long for consistency.

This patch does the change only for memory_limit.

The following is a list of such variables which need the change:

  1) kernel_end, crashk_size - in arch/powerpc/kernel/machine_kexec.c

  2) (struct resource *)crashk_res.start - We could export a local static
 variable from machine_kexec.c.

Changing the above values might break the kexec-tools. So, I will
fix kexec-tools first to handle the different sized values and then change
  the above.

Suggested-by: Benjamin Herrenschmidt b...@kernel.crashing.org
Signed-off-by: Suzuki K. Poulose suz...@in.ibm.com
---


Breaks the build on some configs (with 32-bit phys_addr_t):


Sorry for that.


/home/benh/linux-powerpc-test/arch/powerpc/kernel/prom.c: In function
'early_init_devtree':
/home/benh/linux-powerpc-test/arch/powerpc/kernel/prom.c:664:25: error:
comparison of distinct pointer types lacks a cast

I'm fixing that myself this time but please be more careful.

Sure. Thanks Ben for fixing that.

Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] [perf] Remove the node from rblist in strlist__remove

2012-08-29 Thread Suzuki K. Poulose
The following commit:

author  David Ahern dsah...@gmail.com
Tue, 31 Jul 2012 04:31:33 + (22:31 -0600)
committer   Arnaldo Carvalho de Melo a...@redhat.com
Fri, 3 Aug 2012 13:39:51 + (10:39 -0300)
commit  ee8dd3ca43f151d9fbe1edeef68fb8a77eb9f047

causes a double free during a probe deletion as the node is
never removed from the list via strlist__remove(), even though
it gets 'deleted' (read free()'d). This causes a double
free when we do strlist__delete() as the node is already deleted
but present in the rblist.

[suzukikp@suzukikp perf]$ sudo ./perf probe -a do_fork
Added new event:
  probe:do_fork(on do_fork)

You can now use it in all perf tools, such as:

perf record -e probe:do_fork -aR sleep 1

[suzukikp@suzukikp perf]$ sudo ./perf probe -d do_fork
Removed event: probe:do_fork
*** glibc detected *** ./perf: double free or corruption (fasttop): 
0x0133d600 ***
=== Backtrace: =
/lib64/libc.so.6[0x38eec7dda6]
./perf(rblist__delete+0x5c)[0x47d3dc]
./perf(del_perf_probe_events+0xb6)[0x47b826]
./perf(cmd_probe+0x471)[0x42c8d1]
./perf[0x4150b3]
./perf(main+0x501)[0x4148e1]
/lib64/libc.so.6(__libc_start_main+0xed)[0x38eec2169d]
./perf[0x414a61]


Make sure we remove the node from the rblist before we delete the
node. The rblist__remove_node() will invoke rblist-node_delete,
which  will take care of deleting the node with the suitable function
provided by the user.

Reported-by: Ananth N. Mavinakayanahalli ana...@in.ibm.com
Signed-off-by: Suzuki K. Poulose suz...@in.ibm.com
Cc: David Ahern dsah...@gmail.com
Cc: Arnaldo Carvalho de Melo a...@infradead.org
---

 tools/perf/util/strlist.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/tools/perf/util/strlist.c b/tools/perf/util/strlist.c
index 95856ff..155d8b7 100644
--- a/tools/perf/util/strlist.c
+++ b/tools/perf/util/strlist.c
@@ -93,7 +93,7 @@ out:
 
 void strlist__remove(struct strlist *slist, struct str_node *snode)
 {
-   str_node__delete(snode, slist-dupstr);
+   rblist__remove_node(slist-rblist, snode-rb_node);
 }
 
 struct str_node *strlist__find(struct strlist *slist, const char *entry)

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] [perf] Remove the node from rblist in strlist__remove

2012-08-29 Thread Suzuki K. Poulose

On 08/29/2012 11:59 AM, David Ahern wrote:

On 8/29/12 12:00 AM, Suzuki K. Poulose wrote:

The following commit:

authorDavid Ahern dsah...@gmail.com
Tue, 31 Jul 2012 04:31:33 + (22:31 -0600)
committerArnaldo Carvalho de Melo a...@redhat.com
Fri, 3 Aug 2012 13:39:51 + (10:39 -0300)
commitee8dd3ca43f151d9fbe1edeef68fb8a77eb9f047

causes a double free during a probe deletion as the node is
never removed from the list via strlist__remove(), even though
it gets 'deleted' (read free()'d). This causes a double
free when we do strlist__delete() as the node is already deleted
but present in the rblist.

[suzukikp@suzukikp perf]$ sudo ./perf probe -a do_fork
Added new event:
   probe:do_fork(on do_fork)

You can now use it in all perf tools, such as:

perf record -e probe:do_fork -aR sleep 1

[suzukikp@suzukikp perf]$ sudo ./perf probe -d do_fork
Removed event: probe:do_fork
*** glibc detected *** ./perf: double free or corruption (fasttop):
0x0133d600 ***
=== Backtrace: =
/lib64/libc.so.6[0x38eec7dda6]
./perf(rblist__delete+0x5c)[0x47d3dc]
./perf(del_perf_probe_events+0xb6)[0x47b826]
./perf(cmd_probe+0x471)[0x42c8d1]
./perf[0x4150b3]
./perf(main+0x501)[0x4148e1]
/lib64/libc.so.6(__libc_start_main+0xed)[0x38eec2169d]
./perf[0x414a61]


Make sure we remove the node from the rblist before we delete the
node. The rblist__remove_node() will invoke rblist-node_delete,
which  will take care of deleting the node with the suitable function
provided by the user.

Reported-by: Ananth N. Mavinakayanahalli ana...@in.ibm.com
Signed-off-by: Suzuki K. Poulose suz...@in.ibm.com
Cc: David Ahern dsah...@gmail.com
Cc: Arnaldo Carvalho de Melo a...@infradead.org


Acked-by: David Ahern dsah...@gmail.com

Same type of change is needed for util/intlist.c if you want to submit
one, otherwise I will take care of it.


I can send it.

Thanks
Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] [perf] Fix intlist node removal

2012-08-31 Thread Suzuki K. Poulose
Similar to the one in :
https://lkml.org/lkml/2012/8/29/27


Make sure we remove the node from the rblist before we delete the
node. The rblist__remove_node() will invoke rblist-node_delete,
which  will take care of deleting the node with the suitable function
provided by the user.

Signed-off-by: Suzuki K Poulose suz...@in.ibm.com
Cc: David Ahern dsah...@gmail.com
---

 tools/perf/util/intlist.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/intlist.c b/tools/perf/util/intlist.c
index fd530dc..77c504f 100644
--- a/tools/perf/util/intlist.c
+++ b/tools/perf/util/intlist.c
@@ -52,9 +52,9 @@ int intlist__add(struct intlist *ilist, int i)
return rblist__add_node(ilist-rblist, (void *)((long)i));
 }
 
-void intlist__remove(struct intlist *ilist __used, struct int_node *node)
+void intlist__remove(struct intlist *ilist, struct int_node *node)
 {
-   int_node__delete(node);
+   rblist__remove_node(ilist-rblist, node-rb_node);
 }
 
 struct int_node *intlist__find(struct intlist *ilist, int i)

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] [perf] Account the nr_entries in rblist properly

2012-08-31 Thread Suzuki K. Poulose
The nr_entries in rblist is never decremented when an element
is deleted. Also, use rblist__remove_node to delete a node in
rblist__delete(). This would keep the nr_entries sane.

Signed-off-by: Suzuki K. Poulose suz...@in.ibm.com
Cc: David S. Ahern dsah...@gmail.com
---

 tools/perf/util/rblist.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/rblist.c b/tools/perf/util/rblist.c
index 0171fb6..a16cdd2 100644
--- a/tools/perf/util/rblist.c
+++ b/tools/perf/util/rblist.c
@@ -44,6 +44,7 @@ int rblist__add_node(struct rblist *rblist, const void 
*new_entry)
 void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node)
 {
rb_erase(rb_node, rblist-entries);
+   --rblist-nr_entries;
rblist-node_delete(rblist, rb_node);
 }
 
@@ -87,8 +88,7 @@ void rblist__delete(struct rblist *rblist)
while (next) {
pos = next;
next = rb_next(pos);
-   rb_erase(pos, rblist-entries);
-   rblist-node_delete(rblist, pos);
+   rblist__remove_node(rblist, pos);
}
free(rblist);
}

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/5] uprobes: remove check for uprobe variable in handle_swbp()

2012-08-08 Thread Suzuki K. Poulose

On 08/07/2012 09:42 PM, Sebastian Andrzej Siewior wrote:

by the time we get here (after we pass cleanup_ret) uprobe is always is
set. If it is NULL we leave very early in the code.

Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
  kernel/events/uprobes.c |   16 +++-
  1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 41a2555..c8e5204 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1528,17 +1528,15 @@ cleanup_ret:
utask-active_uprobe = NULL;
utask-state = UTASK_RUNNING;
}
-   if (uprobe) {
-   if (!(uprobe-flags  UPROBE_SKIP_SSTEP))
+   if (!(uprobe-flags  UPROBE_SKIP_SSTEP))


Shouldn't we check uprobe != NULL before we check the uprobe-flags ?
i.e, shouldn't the above line be :

   if (uprobe  ! (uprobe-flags  UPROBE_SKIP_SSTEP)) ?

-   /*
-* cannot singlestep; cannot skip instruction;
-* re-execute the instruction.
-*/
-   instruction_pointer_set(regs, bp_vaddr);
+   /*
+* cannot singlestep; cannot skip instruction;
+* re-execute the instruction.
+*/
+   instruction_pointer_set(regs, bp_vaddr);

-   put_uprobe(uprobe);
-   }
+   put_uprobe(uprobe);
  }


Thanks
Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/5] uprobes: remove check for uprobe variable in handle_swbp()

2012-08-09 Thread Suzuki K. Poulose

On 08/08/2012 03:05 PM, Sebastian Andrzej Siewior wrote:

On 08/08/2012 11:10 AM, Suzuki K. Poulose wrote:

--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1528,17 +1528,15 @@ cleanup_ret:
utask-active_uprobe = NULL;
utask-state = UTASK_RUNNING;
}
- if (uprobe) {
- if (!(uprobe-flags  UPROBE_SKIP_SSTEP))
+ if (!(uprobe-flags  UPROBE_SKIP_SSTEP))


Shouldn't we check uprobe != NULL before we check the uprobe-flags ?
i.e, shouldn't the above line be :

if (uprobe  ! (uprobe-flags  UPROBE_SKIP_SSTEP)) ?


The function starts like this:

  if (!uprobe) {
  if (is_swbp  0) {
  send_sig(SIGTRAP, current, 0);
  } else {
  instruction_pointer_set(regs, bp_vaddr);
  }
  return;
  }

Which makes uprobe != NULL by the time we get there, no?


My bad, was looking at an older version of the function. Also,
the removal of the if (uprobe), check triggered the above question.

Thanks
Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 0/2][powerpc] Export memory_limit via device tree

2012-08-21 Thread Suzuki K. Poulose
The following series exports the linux memory_limit set by
the mem= parameter via device-tree, so that kexec-tools
can limit the crash regions to the actual memory used by
the kernel.

Change since V1:

 * Added a patch to change the type of memory_limit to a
   fixed size(unsigned long long) from 'phys_addr_t' (which
   is 32bit on some ppc32 and 64 bit on ppc64 and some ppc32)

 * Rebased the patch to use recently fixed prom_update_property()
   which would add the property if it didn't exist.

---

Suzuki K. Poulose (2):
  [powerpc] Change memory_limit from phys_addr_t to unsigned long long
  [powerpc] Export memory limit via device tree


 arch/powerpc/include/asm/setup.h|2 +-
 arch/powerpc/kernel/fadump.c|3 +--
 arch/powerpc/kernel/machine_kexec.c |   14 +-
 arch/powerpc/kernel/prom.c  |2 +-
 arch/powerpc/mm/mem.c   |2 +-
 5 files changed, 17 insertions(+), 6 deletions(-)

-- 
Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 1/2] [powerpc] Change memory_limit from phys_addr_t to unsigned long long

2012-08-21 Thread Suzuki K. Poulose
There are some device-tree nodes, whose values are of type phys_addr_t.
The phys_addr_t is variable sized based on the CONFIG_PHSY_T_64BIT.

Change these to a fixed unsigned long long for consistency.

This patch does the change only for memory_limit.

The following is a list of such variables which need the change:

 1) kernel_end, crashk_size - in arch/powerpc/kernel/machine_kexec.c

 2) (struct resource *)crashk_res.start - We could export a local static
variable from machine_kexec.c.

Changing the above values might break the kexec-tools. So, I will
fix kexec-tools first to handle the different sized values and then change
 the above.

Suggested-by: Benjamin Herrenschmidt b...@kernel.crashing.org
Signed-off-by: Suzuki K. Poulose suz...@in.ibm.com
---

 arch/powerpc/include/asm/setup.h|2 +-
 arch/powerpc/kernel/fadump.c|3 +--
 arch/powerpc/kernel/machine_kexec.c |2 +-
 arch/powerpc/kernel/prom.c  |2 +-
 arch/powerpc/mm/mem.c   |2 +-
 5 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h
index d084ce1..8b9a306 100644
--- a/arch/powerpc/include/asm/setup.h
+++ b/arch/powerpc/include/asm/setup.h
@@ -9,7 +9,7 @@ extern void ppc_printk_progress(char *s, unsigned short hex);
 extern unsigned int rtas_data;
 extern int mem_init_done;  /* set on boot once kmalloc can be called */
 extern int init_bootmem_done;  /* set once bootmem is available */
-extern phys_addr_t memory_limit;
+extern unsigned long long memory_limit;
 extern unsigned long klimit;
 extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
 
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index 18bdf74..06c8202 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -289,8 +289,7 @@ int __init fadump_reserve_mem(void)
else
memory_limit = memblock_end_of_DRAM();
printk(KERN_INFO Adjusted memory_limit for firmware-assisted
-dump, now %#016llx\n,
-   (unsigned long long)memory_limit);
+dump, now %#016llx\n, memory_limit);
}
if (memory_limit)
memory_boundary = memory_limit;
diff --git a/arch/powerpc/kernel/machine_kexec.c 
b/arch/powerpc/kernel/machine_kexec.c
index 5df..4074eff 100644
--- a/arch/powerpc/kernel/machine_kexec.c
+++ b/arch/powerpc/kernel/machine_kexec.c
@@ -165,7 +165,7 @@ void __init reserve_crashkernel(void)
if (memory_limit  memory_limit = crashk_res.end) {
memory_limit = crashk_res.end + 1;
printk(Adjusted memory limit for crashkernel, now 0x%llx\n,
-  (unsigned long long)memory_limit);
+  memory_limit);
}
 
printk(KERN_INFO Reserving %ldMB of memory at %ldMB 
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index f191bf0..c82c77d 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -78,7 +78,7 @@ static int __init early_parse_mem(char *p)
return 1;
 
memory_limit = PAGE_ALIGN(memparse(p, p));
-   DBG(memory limit = 0x%llx\n, (unsigned long long)memory_limit);
+   DBG(memory limit = 0x%llx\n, memory_limit);
 
return 0;
 }
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index baaafde..0a8f353 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -62,7 +62,7 @@
 
 int init_bootmem_done;
 int mem_init_done;
-phys_addr_t memory_limit;
+unsigned long long memory_limit;
 
 #ifdef CONFIG_HIGHMEM
 pte_t *kmap_pte;

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 2/2] [powerpc] Export memory limit via device tree

2012-08-21 Thread Suzuki K. Poulose
The powerpc kernel doesn't export the memory limit enforced by 'mem='
kernel parameter. This is required for building the ELF header in
kexec-tools to limit the vmcore to capture only the used memory. On
powerpc the kexec-tools depends on the device-tree for memory related
information, unlike /proc/iomem on the x86.

Without this information, the kexec-tools assumes the entire System
RAM and vmcore creates an unnecessarily larger dump.

This patch exports the memory limit, if present, via
chosen/linux,memory-limit
property, so that the vmcore can be limited to the memory limit.

The prom_init seems to export this value in the same node. But doesn't
really
appear there.  Also the memory_limit gets adjusted with the processing of
crashkernel= parameter. This patch makes sure we get the actual limit.

The kexec-tools will use the value to limit the 'end' of the memory
regions.

Tested this patch on ppc64 and ppc32(ppc440) with a kexec-tools
patch by Mahesh.

Signed-off-by: Suzuki K. Poulose suz...@in.ibm.com
Tested-by: Mahesh J. Salgaonkar mah...@linux.vnet.ibm.com
---

 arch/powerpc/kernel/machine_kexec.c |   12 
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/kernel/machine_kexec.c 
b/arch/powerpc/kernel/machine_kexec.c
index 4074eff..fa9f6c7 100644
--- a/arch/powerpc/kernel/machine_kexec.c
+++ b/arch/powerpc/kernel/machine_kexec.c
@@ -204,6 +204,12 @@ static struct property crashk_size_prop = {
.value = crashk_size,
 };
 
+static struct property memory_limit_prop = {
+   .name = linux,memory-limit,
+   .length = sizeof(unsigned long long),
+   .value = memory_limit,
+};
+
 static void __init export_crashk_values(struct device_node *node)
 {
struct property *prop;
@@ -223,6 +229,12 @@ static void __init export_crashk_values(struct device_node 
*node)
crashk_size = resource_size(crashk_res);
prom_add_property(node, crashk_size_prop);
}
+
+   /*
+* memory_limit is required by the kexec-tools to limit the
+* crash regions to the actual memory used.
+*/
+   prom_update_property(node, memory_limit_prop);
 }
 
 static int __init kexec_setup(void)

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 1/4] kprobes/powerpc: Do not disable External interrupts during single step

2012-12-10 Thread Suzuki K. Poulose

On 12/03/2012 08:37 PM, Suzuki K. Poulose wrote:

From: Suzuki K. Poulose suz...@in.ibm.com

External/Decrement exceptions have lower priority than the Debug Exception.
So, we don't have to disable the External interrupts before a single step.
However, on BookE, Critical Input Exception(CE) has higher priority than a
Debug Exception. Hence we mask them.

Signed-off-by:  Suzuki K. Poulose suz...@in.ibm.com
Cc: Sebastian Andrzej Siewior bige...@linutronix.de
Cc: Ananth N Mavinakaynahalli ana...@in.ibm.com
Cc: Kumar Gala ga...@kernel.crashing.org
Cc: linuxppc-...@ozlabs.org
---
  arch/powerpc/kernel/kprobes.c |   10 +-
  1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index e88c643..4901b34 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -104,13 +104,13 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)

  static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs 
*regs)
  {
-   /* We turn off async exceptions to ensure that the single step will
-* be for the instruction we have the kprobe on, if we dont its
-* possible we'd get the single step reported for an exception handler
-* like Decrementer or External Interrupt */
-   regs-msr = ~MSR_EE;
regs-msr |= MSR_SINGLESTEP;
  #ifdef CONFIG_PPC_ADV_DEBUG_REGS
+   /*
+* We turn off Critical Input Exception(CE) to ensure that the single
+* step will be for the instruction we have the probe on; if we don't,
+* it is possible we'd get the single step reported for CE.
+*/
regs-msr = ~MSR_CE;
mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
  #ifdef CONFIG_PPC_47x



Ben, Kumar,

Could you please review this patch ?


Thanks
Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/4] perf/powerpc: Use uapi/unistd.h to fix build error

2012-11-20 Thread Suzuki K. Poulose

On 11/08/2012 12:48 AM, Sukadev Bhattiprolu wrote:


 From b8beef080260c1625c8f801105504a82005295e5 Mon Sep 17 00:00:00 2001
From: Sukadev Bhattiprolu suka...@linux.vnet.ibm.com
Date: Wed, 31 Oct 2012 11:21:28 -0700
Subject: [PATCH 1/4] perf/powerpc: Use uapi/unistd.h to fix build error

Use the 'unistd.h' from arch/powerpc/include/uapi to build the perf tool.

Signed-off-by: Sukadev Bhattiprolu suka...@linux.vnet.ibm.com

Without this patch, I couldn't build perf on powerpc, with 3.7.0-rc2

Tested-by: Suzuki K. Poulose suz...@in.ibm.com

Thanks
Suzuki

---
  tools/perf/perf.h |2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 054182e..f4952da 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -26,7 +26,7 @@ void get_term_dimensions(struct winsize *ws);
  #endif

  #ifdef __powerpc__
-#include ../../arch/powerpc/include/asm/unistd.h
+#include ../../arch/powerpc/include/uapi/asm/unistd.h
  #define rmb() asm volatile (sync ::: memory)
  #define cpu_relax()   asm volatile ( ::: memory);
  #define CPUINFO_PROC  cpu



--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/2] uprobes/powerpc: Replace ptrace single step helpers

2012-11-26 Thread Suzuki K. Poulose
The following series replaces the ptrace helpers used for single step
enable/disable for uprobes on powerpc, with uprobe specific code.

We reuse the kprobe code to enable single stepping by making it generic
and save/restore the MSR (and DBCR for BookE) across the single step.

This series applies on top of the patches posted by Oleg at :
https://lkml.org/lkml/2012/10/28/92 


Patches have been verified on Power6 and PPC440 (BookE).

---

Suzuki K. Poulose (2):
  powerpc: Move the single step enable code to a generic path
  uprobes/powerpc: Make use of generic routines to enable single step


 arch/powerpc/include/asm/probes.h  |   29 +
 arch/powerpc/include/asm/uprobes.h |4 
 arch/powerpc/kernel/kprobes.c  |   21 +
 arch/powerpc/kernel/uprobes.c  |   11 +--
 4 files changed, 43 insertions(+), 22 deletions(-)

-- 
Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/2] powerpc: Move the single step enable code to a generic path

2012-11-26 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suz...@in.ibm.com

This patch moves the single step enable code used by kprobe to a generic
routine so that, it can be re-used by other code, in this case,
uprobes.


Signed-off-by: Suzuki K. Poulose suz...@in.ibm.com
Cc: linuxppc-...@ozlabs.org
---
 arch/powerpc/include/asm/probes.h |   29 +
 arch/powerpc/kernel/kprobes.c |   21 +
 2 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/include/asm/probes.h 
b/arch/powerpc/include/asm/probes.h
index 5f1e15b..836e9b9 100644
--- a/arch/powerpc/include/asm/probes.h
+++ b/arch/powerpc/include/asm/probes.h
@@ -38,5 +38,34 @@ typedef u32 ppc_opcode_t;
 #define is_trap(instr) (IS_TW(instr) || IS_TWI(instr))
 #endif /* CONFIG_PPC64 */
 
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+#define MSR_SINGLESTEP (MSR_DE)
+#else
+#define MSR_SINGLESTEP (MSR_SE)
+#endif
+
+/* Enable single stepping for the current task */
+static inline void enable_single_step(struct pt_regs *regs)
+{
+
+   /* 
+* We turn off async exceptions to ensure that the single step will
+* be for the instruction we have the kprobe on, if we dont its
+* possible we'd get the single step reported for an exception handler
+* like Decrementer or External Interrupt
+*/
+   regs-msr = ~MSR_EE;
+   regs-msr |= MSR_SINGLESTEP;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+   regs-msr = ~MSR_CE;
+   mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
+#ifdef CONFIG_PPC_47x
+   isync();
+#endif
+#endif
+
+}
+
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_PROBES_H */
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index e88c643..92f1be7 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -36,12 +36,6 @@
 #include asm/sstep.h
 #include asm/uaccess.h
 
-#ifdef CONFIG_PPC_ADV_DEBUG_REGS
-#define MSR_SINGLESTEP (MSR_DE)
-#else
-#define MSR_SINGLESTEP (MSR_SE)
-#endif
-
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
@@ -104,20 +98,7 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
 
 static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs 
*regs)
 {
-   /* We turn off async exceptions to ensure that the single step will
-* be for the instruction we have the kprobe on, if we dont its
-* possible we'd get the single step reported for an exception handler
-* like Decrementer or External Interrupt */
-   regs-msr = ~MSR_EE;
-   regs-msr |= MSR_SINGLESTEP;
-#ifdef CONFIG_PPC_ADV_DEBUG_REGS
-   regs-msr = ~MSR_CE;
-   mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
-#ifdef CONFIG_PPC_47x
-   isync();
-#endif
-#endif
-
+   enable_single_step(regs);
/*
 * On powerpc we should single step on the original
 * instruction even if the probed insn is a trap

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/2] uprobes/powerpc: Make use of generic routines to enable single step

2012-11-26 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suz...@in.ibm.com

Replace the ptrace helpers with the powerpc generic routines to
enable/disable single step. We save/restore the MSR (and DCBR for BookE)
across for the operation.


Signed-off-by: Suzuki K. Poulose suz...@in.ibm.com
---
 arch/powerpc/include/asm/uprobes.h |4 
 arch/powerpc/kernel/uprobes.c  |   11 +--
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/uprobes.h 
b/arch/powerpc/include/asm/uprobes.h
index b532060..884be93 100644
--- a/arch/powerpc/include/asm/uprobes.h
+++ b/arch/powerpc/include/asm/uprobes.h
@@ -43,6 +43,10 @@ struct arch_uprobe {
 
 struct arch_uprobe_task {
unsigned long   saved_trap_nr;
+   unsigned long   saved_msr;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+   unsigned long   saved_dbcr;
+#endif
 };
 
 extern int  arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct 
*mm, unsigned long addr);
diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
index bc77834..c407c07 100644
--- a/arch/powerpc/kernel/uprobes.c
+++ b/arch/powerpc/kernel/uprobes.c
@@ -62,10 +62,14 @@ int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct 
pt_regs *regs)
struct arch_uprobe_task *autask = current-utask-autask;
 
autask-saved_trap_nr = current-thread.trap_nr;
+   autask-saved_msr = regs-msr;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+   autask-saved_dbcr = mfspr(SPRN_DBCR0);
+#endif
current-thread.trap_nr = UPROBE_TRAP_NR;
regs-nip = current-utask-xol_vaddr;
 
-   user_enable_single_step(current);
+   enable_single_step(regs);
return 0;
 }
 
@@ -121,8 +125,11 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, 
struct pt_regs *regs)
 * to be executed.
 */
regs-nip = utask-vaddr + MAX_UINSN_BYTES;
+   regs-msr = utask-autask.saved_msr;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+   mtspr(SPRN_DBCR0, utask-autask.saved_dbcr);
+#endif
 
-   user_disable_single_step(current);
return 0;
 }
 

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/2] uprobes/powerpc: Make use of generic routines to enable single step

2012-11-26 Thread Suzuki K. Poulose

On 11/26/2012 10:31 PM, Oleg Nesterov wrote:

On 11/26, Suzuki K. Poulose wrote:


@@ -121,8 +125,11 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, 
struct pt_regs *regs)
 * to be executed.
 */
regs-nip = utask-vaddr + MAX_UINSN_BYTES;
+   regs-msr = utask-autask.saved_msr;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+   mtspr(SPRN_DBCR0, utask-autask.saved_dbcr);
+#endif

-   user_disable_single_step(current);


Don't we need the same change in arch_uprobe_abort_xol() ?

Yes, we do. Thanks for catching that. I will fix it.

Thanks for the review.

Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] powerpc: Move the single step enable code to a generic path

2012-11-27 Thread Suzuki K. Poulose

On 11/26/2012 11:40 PM, Sebastian Andrzej Siewior wrote:

On 11/26/2012 12:05 PM, Suzuki K. Poulose wrote:

diff --git a/arch/powerpc/include/asm/probes.h
b/arch/powerpc/include/asm/probes.h
index 5f1e15b..836e9b9 100644
--- a/arch/powerpc/include/asm/probes.h
+++ b/arch/powerpc/include/asm/probes.h
@@ -38,5 +38,34 @@ typedef u32 ppc_opcode_t;
  #define is_trap(instr)(IS_TW(instr) || IS_TWI(instr))
  #endif /* CONFIG_PPC64 */

+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+#define MSR_SINGLESTEP(MSR_DE)
+#else
+#define MSR_SINGLESTEP(MSR_SE)
+#endif
+
+/* Enable single stepping for the current task */
+static inline void enable_single_step(struct pt_regs *regs)
+{
+
+/*
+ * We turn off async exceptions to ensure that the single step will
+ * be for the instruction we have the kprobe on, if we dont its

it is


+ * possible we'd get the single step reported for an exception
handler
+ * like Decrementer or External Interrupt
+ */


Hmmm. The TRM for E400 says

|5.11.1 e500 Exception Priorities
|The following is a prioritized listing of e500 exceptions:
|   4. Critical input
|   5. Debug interrupt
|   6. External input
|   22. Decrementer

The list has been cut down a little. That means the debug interrupt
comes before external interrupt and before the decrement fires.

And if single step is what wakes you up then DBSR[ICMP] is set. Am I
missing something or is this FSL only not not book-e



You are right. The same priority applies for Book3S as well. The above
code/comment was initially written for kprobe. So I didn't bother to
double check the same, when I moved it to the common place.

I will send a v2 with the required changes.

Thanks for the question !

Cheers
Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 4/4] uprobes/powerpc: Make use of generic routines to enable single step

2012-12-17 Thread Suzuki K. Poulose

On 12/15/2012 01:32 AM, Oleg Nesterov wrote:

On 12/03, Suzuki K. Poulose wrote:


Replace the ptrace helpers with the powerpc generic routines to
enable/disable single step. We save/restore the MSR (and DCBR for BookE)
across for the operation. We don't have to disable the single step,
as restoring the MSR/DBCR would restore the previous state.


Obviously I can't review this series (although it looks fine to me).

Just one note,


@@ -121,7 +132,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, 
struct pt_regs *regs)

WARN_ON_ONCE(current-thread.trap_nr != UPROBE_TRAP_NR);

-   uprobe_restore_context_sstep(utask-autask);
+   uprobe_restore_context_sstep(utask-autask, regs);


I am not sure ppc needs this, but note that x86 does a bit more.

Not only we need to restore the single-step state, we need to
send SIGTRAP if it was not set by us. The same for _skip_sstep.


Ok. I will investigate that part and do the necessary.

Thanks
Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] uprobes/powerpc: Add dependency on single step emulation

2013-01-07 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suz...@in.ibm.com

Uprobes uses emulate_step in sstep.c, but we haven't explicitly specified
the dependency. On pseries HAVE_HW_BREAKPOINT protects us, but 44x has no
such luxury.

Consolidate other users that depend on sstep and create a new config option.

Signed-off-by: Ananth N Mavinakayanahalli ana...@in.ibm.com
Signed-off-by: Suzuki K. Poulose suz...@in.ibm.com
Cc: linuxppc-...@ozlabs.org
Cc: sta...@vger.kernel.org
---
 arch/powerpc/Kconfig  |4 
 arch/powerpc/lib/Makefile |4 +---
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 17903f1..dabe429 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -275,6 +275,10 @@ config PPC_ADV_DEBUG_DAC_RANGE
depends on PPC_ADV_DEBUG_REGS  44x
default y
 
+config PPC_EMULATE_SSTEP
+   bool
+   default y if KPROBES || UPROBES || XMON || HAVE_HW_BREAKPOINT
+
 source init/Kconfig
 
 source kernel/Kconfig.freezer
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 746e0c8..35baad9 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -19,9 +19,7 @@ obj-$(CONFIG_PPC64)   += copypage_64.o copyuser_64.o \
   checksum_wrappers_64.o hweight_64.o \
   copyuser_power7.o string_64.o copypage_power7.o \
   memcpy_power7.o
-obj-$(CONFIG_XMON) += sstep.o ldstfp.o
-obj-$(CONFIG_KPROBES)  += sstep.o ldstfp.o
-obj-$(CONFIG_HAVE_HW_BREAKPOINT)   += sstep.o ldstfp.o
+obj-$(CONFIG_PPC_EMULATE_SSTEP)+= sstep.o ldstfp.o
 
 ifeq ($(CONFIG_PPC64),y)
 obj-$(CONFIG_SMP)  += locks.o

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: RFD: Non-Disruptive Core Dump Infrastructure

2013-09-11 Thread Suzuki K. Poulose
On 09/12/2013 12:57 AM, KOSAKI Motohiro wrote:
 (9/3/13 4:39 AM), Janani Venkataraman wrote:
 Hello,

 We are working on an infrastructure to create a system core file of a
 specific
 process at run-time, non-disruptively. It can also be extended to a
 case where
 a process is able to take a self-core dump.

 gcore, an existing utility creates a core image of the specified
 process. It
 attaches to the process using gdb and runs the gdb gcore command and then
 detaches. In gcore the dump cannot be issued from a signal handler
 context as
 fork() is not signal safe and moreover it is disruptive in nature as
 the gdb
 attaches using ptrace which sends a SIGSTOP signal. Hence the gcore
 method
 cannot be used if the process wants to initiate a self dump.
 
 Maybe I'm missing something. But why gcore uses c-level fork()? gcore
 need to
 call pthread-at-fork handler? No. gcore need to flush stdio buffer? No.
 
Let me clarify. If an application wants to dump itself, it has to do a
fork() and then exec the gcore with the pid of the appication to
generate the dump.

So, if the application wants to initiate the dump from a signal handler
context, it may lead to trouble.

Thanks
Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC] [PATCH 00/19] Non disruptive application core dump infrastructure using task_work_add()

2013-10-07 Thread Suzuki K. Poulose
On 10/04/2013 07:14 PM, Andi Kleen wrote:
 On Fri, Oct 04, 2013 at 04:00:12PM +0530, Janani Venkataraman wrote:
 Hi all,

 The following series implements an infrastructure for capturing the core of 
 an 
 application without disrupting its process.
 
 The problem is that gcore et.al. have to stop the process briefly
 to attach and then use the pid mmap ptrace interfaces, right?
 
Correct.

 Couldn't they just use the new process_vm_readv() syscalls instead?
 AFAIK those do not require ptrace.
 
We need the register set and hence would need a ptrace.

 Then this could be all done in user space.
 
 Or are there some specific races with this approach?
 
Cheers
Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFT PATCH -next v2] [BUGFIX] kprobes: Fix Failed to find blacklist error on ia64 and ppc64

2014-05-29 Thread Suzuki K. Poulose
On 05/27/2014 12:01 PM, Masami Hiramatsu wrote:
 On ia64 and ppc64, the function pointer does not point the
 entry address of the function, but the address of function
 discriptor (which contains the entry address and misc
 data.) Since the kprobes passes the function pointer stored
 by NOKPROBE_SYMBOL() to kallsyms_lookup_size_offset() for
 initalizing its blacklist, it fails and reports many errors
 as below.
 
   Failed to find blacklist 000101316830
   Failed to find blacklist 0001013000f0a000
   Failed to find blacklist 000101315f70a000
   Failed to find blacklist 000101324c80a000
   Failed to find blacklist 0001013063f0a000
   Failed to find blacklist 000101327800a000
   Failed to find blacklist 0001013277f0a000
   Failed to find blacklist 000101315a70a000
   Failed to find blacklist 0001013277e0a000
   Failed to find blacklist 000101305a20a000
   Failed to find blacklist 0001013277d0a000
   Failed to find blacklist 00010130bdc0a000
   Failed to find blacklist 00010130dc20a000
   Failed to find blacklist 000101309a00a000
   Failed to find blacklist 0001013277c0a000
   Failed to find blacklist 0001013277b0a000
   Failed to find blacklist 0001013277a0a000
   Failed to find blacklist 000101327790a000
   Failed to find blacklist 000101303140a000
   Failed to find blacklist 0001013a3280a000
 
 To fix this bug, this introduces function_entry() macro to
 retrieve the entry address from the given function pointer,
 and uses for kallsyms_lookup_size_offset() while initializing
 blacklist.
 
 Changes in V2:
  - Use function_entry() macro when lookin up symbols instead
of storing it.
  - Update for the latest -next.
 
 Signed-off-by: Masami Hiramatsu masami.hiramatsu...@hitachi.com
 Reported-by: Tony Luck tony.l...@gmail.com
 Cc: Suzuki K. Poulose suz...@in.ibm.com
 Cc: Tony Luck tony.l...@intel.com
 Cc: Fenghua Yu fenghua...@intel.com
 Cc: Benjamin Herrenschmidt b...@kernel.crashing.org
 Cc: Paul Mackerras pau...@samba.org
 Cc: Ananth N Mavinakayanahalli ana...@in.ibm.com
 Cc: Kevin Hao haoke...@gmail.com
 Cc: linux-i...@vger.kernel.org
 Cc: linux-kernel@vger.kernel.org
 Cc: linuxppc-...@lists.ozlabs.org
 ---
  arch/ia64/include/asm/types.h|2 ++
  arch/powerpc/include/asm/types.h |   11 +++
  include/linux/types.h|4 
  kernel/kprobes.c |4 +++-
  4 files changed, 20 insertions(+), 1 deletion(-)
 
 diff --git a/arch/ia64/include/asm/types.h b/arch/ia64/include/asm/types.h
 index 4c351b1..95279dd 100644
 --- a/arch/ia64/include/asm/types.h
 +++ b/arch/ia64/include/asm/types.h
 @@ -27,5 +27,7 @@ struct fnptr {
   unsigned long gp;
  };
  
 +#define function_entry(fn) (((struct fnptr *)(fn))-ip)
 +
  #endif /* !__ASSEMBLY__ */
  #endif /* _ASM_IA64_TYPES_H */
 diff --git a/arch/powerpc/include/asm/types.h 
 b/arch/powerpc/include/asm/types.h
 index bfb6ded..8b89d65 100644
 --- a/arch/powerpc/include/asm/types.h
 +++ b/arch/powerpc/include/asm/types.h
 @@ -25,6 +25,17 @@ typedef struct {
   unsigned long env;
  } func_descr_t;
  
 +#if defined(CONFIG_PPC64)  (!defined(_CALL_ELF) || _CALL_ELF == 1)
 +/*
 + * On PPC64 ABIv1 the function pointer actually points to the
 + * function's descriptor. The first entry in the descriptor is the
 + * address of the function text.
 + */
 +#define function_entry(fn)   (((func_descr_t *)(fn))-entry)
 +#else
 +#define function_entry(fn)   ((unsigned long)(fn))
 +#endif
 +
  #endif /* __ASSEMBLY__ */
  
  #endif /* _ASM_POWERPC_TYPES_H */
 diff --git a/include/linux/types.h b/include/linux/types.h
 index a0bb704..3b95369 100644
 --- a/include/linux/types.h
 +++ b/include/linux/types.h
 @@ -213,5 +213,9 @@ struct callback_head {
  };
  #define rcu_head callback_head
  
 +#ifndef function_entry
 +#define function_entry(fn)   ((unsigned long)(fn))
 +#endif
 +
  #endif /*  __ASSEMBLY__ */
  #endif /* _LINUX_TYPES_H */
 diff --git a/kernel/kprobes.c b/kernel/kprobes.c
 index 2ac9f13..3859c88 100644
 --- a/kernel/kprobes.c
 +++ b/kernel/kprobes.c
 @@ -32,6 +32,7 @@
   *   prasa...@in.ibm.com added function-return probes.
   */
  #include linux/kprobes.h
 +#include linux/types.h
  #include linux/hash.h
  #include linux/init.h
  #include linux/slab.h
 @@ -2042,7 +2043,8 @@ static int __init populate_kprobe_blacklist(unsigned 
 long *start,
   unsigned long offset = 0, size = 0;
  
   for (iter = start; iter  end; iter++) {
 - if (!kallsyms_lookup_size_offset(*iter, size, offset)) {
 + if (!kallsyms_lookup_size_offset(function_entry(*iter),
 +  size, offset)) {

On powerpc we will be able to resolve the *iter to func_descr and won't
get the below error with/without this patch. So we have to actually
verify the kprobe_blacklist contents to make sure everything is alright.

   pr_err(Failed to find blacklist %p\n, (void *)*iter);
   continue;
   }
 

There is a bug here.
You need to set

Re: [RFT PATCH -next ] [BUGFIX] kprobes: Fix Failed to find blacklist error on ia64 and ppc64

2014-05-26 Thread Suzuki K. Poulose
On 05/07/2014 05:25 PM, Masami Hiramatsu wrote:
 On ia64 and ppc64, the function pointer does not point the
 entry address of the function, but the address of function
 discriptor (which contains the entry address and misc
 data.) Since the kprobes passes the function pointer stored
 by NOKPROBE_SYMBOL() to kallsyms_lookup_size_offset() for
 initalizing its blacklist, it fails and reports many errors
 as below.
 
   Failed to find blacklist 000101316830
   Failed to find blacklist 0001013000f0a000
   Failed to find blacklist 000101315f70a000
   Failed to find blacklist 000101324c80a000
   Failed to find blacklist 0001013063f0a000
   Failed to find blacklist 000101327800a000
   Failed to find blacklist 0001013277f0a000
   Failed to find blacklist 000101315a70a000
   Failed to find blacklist 0001013277e0a000
   Failed to find blacklist 000101305a20a000
   Failed to find blacklist 0001013277d0a000
   Failed to find blacklist 00010130bdc0a000
   Failed to find blacklist 00010130dc20a000
   Failed to find blacklist 000101309a00a000
   Failed to find blacklist 0001013277c0a000
   Failed to find blacklist 0001013277b0a000
   Failed to find blacklist 0001013277a0a000
   Failed to find blacklist 000101327790a000
   Failed to find blacklist 000101303140a000
   Failed to find blacklist 0001013a3280a000
 
 To fix this bug, this introduces function_entry() macro to
 retrieve the entry address from the given function pointer,
 and uses it in NOKPROBE_SYMBOL().
 
 
 Signed-off-by: Masami Hiramatsu masami.hiramatsu...@hitachi.com
 Reported-by: Tony Luck tony.l...@gmail.com
 Cc: Tony Luck tony.l...@intel.com
 Cc: Fenghua Yu fenghua...@intel.com
 Cc: Benjamin Herrenschmidt b...@kernel.crashing.org
 Cc: Paul Mackerras pau...@samba.org
 Cc: Ananth N Mavinakayanahalli ana...@in.ibm.com
 Cc: Kevin Hao haoke...@gmail.com
 Cc: linux-i...@vger.kernel.org
 Cc: linux-kernel@vger.kernel.org
 Cc: linuxppc-...@lists.ozlabs.org
 ---
  arch/ia64/include/asm/types.h|2 ++
  arch/powerpc/include/asm/types.h |   11 +++
  include/linux/kprobes.h  |3 ++-
  include/linux/types.h|4 
  4 files changed, 19 insertions(+), 1 deletion(-)
 
 diff --git a/arch/ia64/include/asm/types.h b/arch/ia64/include/asm/types.h
 index 4c351b1..6ab7b6c 100644
 --- a/arch/ia64/include/asm/types.h
 +++ b/arch/ia64/include/asm/types.h
 @@ -27,5 +27,7 @@ struct fnptr {
   unsigned long gp;
  };
  
 +#define constant_function_entry(fn) (((struct fnptr *)(fn))-ip)
 +
  #endif /* !__ASSEMBLY__ */
  #endif /* _ASM_IA64_TYPES_H */
 diff --git a/arch/powerpc/include/asm/types.h 
 b/arch/powerpc/include/asm/types.h
 index bfb6ded..fd297b8 100644
 --- a/arch/powerpc/include/asm/types.h
 +++ b/arch/powerpc/include/asm/types.h
 @@ -25,6 +25,17 @@ typedef struct {
   unsigned long env;
  } func_descr_t;
  
 +#if defined(CONFIG_PPC64)  (!defined(_CALL_ELF) || _CALL_ELF == 1)
 +/*
 + * On PPC64 ABIv1 the function pointer actually points to the
 + * function's descriptor. The first entry in the descriptor is the
 + * address of the function text.
 + */
 +#define constant_function_entry(fn)  (((func_descr_t *)(fn))-entry)
 +#else
 +#define constant_function_entry(fn)  ((unsigned long)(fn))
 +#endif
 +
  #endif /* __ASSEMBLY__ */
  
  #endif /* _ASM_POWERPC_TYPES_H */
 diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
 index e059507..637eafe 100644
 --- a/include/linux/kprobes.h
 +++ b/include/linux/kprobes.h
 @@ -40,6 +40,7 @@
  #include linux/rcupdate.h
  #include linux/mutex.h
  #include linux/ftrace.h
 +#include linux/types.h
  
  #ifdef CONFIG_KPROBES
  #include asm/kprobes.h
 @@ -485,7 +486,7 @@ static inline int enable_jprobe(struct jprobe *jp)
  #define __NOKPROBE_SYMBOL(fname) \
  static unsigned long __used  \
   __attribute__((section(_kprobe_blacklist)))   \
 - _kbl_addr_##fname = (unsigned long)fname;
 + _kbl_addr_##fname = constant_function_entry(fname);
  #define NOKPROBE_SYMBOL(fname)   __NOKPROBE_SYMBOL(fname)


Throws up build errors for me :

  CC  kernel/notifier.o
kernel/notifier.c:105:1: error: initializer element is not constant
 NOKPROBE_SYMBOL(notifier_call_chain);
 ^
kernel/notifier.c:188:1: error: initializer element is not constant
 NOKPROBE_SYMBOL(__atomic_notifier_call_chain);
 ^
kernel/notifier.c:196:1: error: initializer element is not constant
 NOKPROBE_SYMBOL(atomic_notifier_call_chain);
 ^
kernel/notifier.c:546:1: error: initializer element is not constant
 NOKPROBE_SYMBOL(notify_die);
 ^
make[1]: *** [kernel/notifier.o] Error 1
make: *** [kernel] Error 2

Thanks
Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFT PATCH -next v3] [BUGFIX] kprobes: Fix Failed to find blacklist error on ia64 and ppc64

2014-06-19 Thread Suzuki K. Poulose
On 06/19/2014 10:22 AM, Masami Hiramatsu wrote:
 (2014/06/19 10:30), Michael Ellerman wrote:
 On Wed, 2014-06-18 at 17:46 +0900, Masami Hiramatsu wrote:
 (2014/06/18 16:56), Michael Ellerman wrote:
 On Fri, 2014-06-06 at 15:38 +0900, Masami Hiramatsu wrote:
 Ping?

 I guess this should go to 3.16 branch, shouldn't it?

 diff --git a/arch/powerpc/include/asm/types.h 
 b/arch/powerpc/include/asm/types.h
 index bfb6ded..8b89d65 100644
 --- a/arch/powerpc/include/asm/types.h
 +++ b/arch/powerpc/include/asm/types.h
 @@ -25,6 +25,17 @@ typedef struct {
  unsigned long env;
  } func_descr_t;
  
 +#if defined(CONFIG_PPC64)  (!defined(_CALL_ELF) || _CALL_ELF == 1)
 +/*
 + * On PPC64 ABIv1 the function pointer actually points to the
 + * function's descriptor. The first entry in the descriptor is the
 + * address of the function text.
 + */
 +#define function_entry(fn)  (((func_descr_t *)(fn))-entry)
 +#else
 +#define function_entry(fn)  ((unsigned long)(fn))
 +#endif

 We already have ppc_function_entry(), can't you use that?

 I'd like to ask you whether the address which ppc_function_entry() returns 
 on
 PPC ABIv2 is really same address in kallsyms or not.
 As you can see, kprobes uses function_entry() to get the actual entry 
 address
 where kallsyms knows. I have not much information about that, but it seems 
 that
 the global entry point is the address which kallsyms knows, isn't it?

 OK. I'm not sure off the top of my head which address kallsyms knows about, 
 but
 yes it's likely that it is the global entry point.

 I recently sent a patch to add ppc_global_function_entry(), because we need 
 it
 in the ftrace code. Once that is merged you could use that.
 
 Yeah, I could use that. But since this is used in arch-independent code (e.g. 
 IA64
 needs similar macro), I think we'd better define function_entry() in 
 asm/types.h for
 general use (for kallsyms), and rename ppc_function_entry to 
 local_function_entry()
 in asm/code-patching.h.
 
 
 How do you hit the original problem, you don't actually specify in your 
 commit
 message? Something with kprobes obviously, but what exactly? I'll try and
 reproduce it here.
 
 Ah, those messages should be shown in dmesg when booting if it doesn't work,
 because the messages are printed by initialization process of kprobe 
 blacklist.
 So, reproducing it is just enabling CONFIG_KPROBES and boot it.
Well,  we don't get those messages on Power, since the kallsyms has the
entries for .function_name. The correct way to verify is, either  :

1) Dump the black_list via xmon ( see :
https://lkml.org/lkml/2014/5/29/893 ) and verify the entries.

or

2) Issue a kprobe on a black listed entry and hit a success,(which we
will, since we don't check the actual function address).

Thanks
Suzuki


 
 Thank you,
 

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFT PATCH -next v3] [BUGFIX] kprobes: Fix Failed to find blacklist error on ia64 and ppc64

2014-06-19 Thread Suzuki K. Poulose
On 06/19/2014 12:56 PM, Masami Hiramatsu wrote:
 (2014/06/19 15:40), Suzuki K. Poulose wrote:
 On 06/19/2014 10:22 AM, Masami Hiramatsu wrote:
 (2014/06/19 10:30), Michael Ellerman wrote:
 On Wed, 2014-06-18 at 17:46 +0900, Masami Hiramatsu wrote:
 (2014/06/18 16:56), Michael Ellerman wrote:
 On Fri, 2014-06-06 at 15:38 +0900, Masami Hiramatsu wrote:
 Ping?

 I guess this should go to 3.16 branch, shouldn't it?

 diff --git a/arch/powerpc/include/asm/types.h 
 b/arch/powerpc/include/asm/types.h
 index bfb6ded..8b89d65 100644
 --- a/arch/powerpc/include/asm/types.h
 +++ b/arch/powerpc/include/asm/types.h
 @@ -25,6 +25,17 @@ typedef struct {
unsigned long env;
  } func_descr_t;
  
 +#if defined(CONFIG_PPC64)  (!defined(_CALL_ELF) || _CALL_ELF == 1)
 +/*
 + * On PPC64 ABIv1 the function pointer actually points to the
 + * function's descriptor. The first entry in the descriptor is the
 + * address of the function text.
 + */
 +#define function_entry(fn)(((func_descr_t *)(fn))-entry)
 +#else
 +#define function_entry(fn)((unsigned long)(fn))
 +#endif

 We already have ppc_function_entry(), can't you use that?

 I'd like to ask you whether the address which ppc_function_entry() 
 returns on
 PPC ABIv2 is really same address in kallsyms or not.
 As you can see, kprobes uses function_entry() to get the actual entry 
 address
 where kallsyms knows. I have not much information about that, but it 
 seems that
 the global entry point is the address which kallsyms knows, isn't it?

 OK. I'm not sure off the top of my head which address kallsyms knows 
 about, but
 yes it's likely that it is the global entry point.

 I recently sent a patch to add ppc_global_function_entry(), because we 
 need it
 in the ftrace code. Once that is merged you could use that.

 Yeah, I could use that. But since this is used in arch-independent code 
 (e.g. IA64
 needs similar macro), I think we'd better define function_entry() in 
 asm/types.h for
 general use (for kallsyms), and rename ppc_function_entry to 
 local_function_entry()
 in asm/code-patching.h.


 How do you hit the original problem, you don't actually specify in your 
 commit
 message? Something with kprobes obviously, but what exactly? I'll try and
 reproduce it here.

 Ah, those messages should be shown in dmesg when booting if it doesn't work,
 because the messages are printed by initialization process of kprobe 
 blacklist.
 So, reproducing it is just enabling CONFIG_KPROBES and boot it.
 Well,  we don't get those messages on Power, since the kallsyms has the
 entries for .function_name. The correct way to verify is, either  :
 
 Hmm, that seems another issue on powerpc. Is that expected(and designed)
 behavior?
AFAIK, yes, it is.
To be more precise :

we have 'foo' and '.foo' for a function foo(), where 'foo' points to the
function_entry and '.foo' points to the actual function.

So, a kallsyms_lookup_size_offset() on both 'foo' and '.foo' will return
a hit. So, if we make sure we use the value of '.foo' (by using the
appropriate macros) we should be fine.

 And if so, how I can verify when initializing blacklist?
 (should I better use kallsyms_lookup() and kallsyms_lookup_name() for
 verification?)
One way to verify would be to make sure the symbol starts with '.' from
the result of the current kallsyms_lookup_size_offset() for PPC.

Thanks
Suzuki

 
 Thank you,
 

 1) Dump the black_list via xmon ( see :
 https://lkml.org/lkml/2014/5/29/893 ) and verify the entries.

 or

 2) Issue a kprobe on a black listed entry and hit a success,(which we
 will, since we don't check the actual function address).

 Thanks
 Suzuki



 Thank you,


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 00/33] [RFC] Non disruptive application core dump infrastructure

2014-07-03 Thread Suzuki K. Poulose
On 03/24/2014 07:24 PM, Phillip Susi wrote:
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1
 
 On 3/24/2014 5:43 AM, Janani Venkataraman wrote:
 Gcore attaches to the process using gdb and runs the gdb gcore
 command and then detaches. In gcore the dump cannot be issued from
 a signal handler context as fork() is not signal safe and moreover
 it is disruptive in
 
 You can fork+exec from a signal handler just fine.
Please go through the bug, and especially the comment below :

https://sourceware.org/bugzilla/show_bug.cgi?id=4737#c12

Cheers
Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] arm64: Fix SCTLR_EL1 initialisation

2014-12-30 Thread Suzuki K. Poulose

On 17/12/14 17:39, Will Deacon wrote:

On Wed, Dec 17, 2014 at 03:50:21PM +, Suzuki K. Poulose wrote:

From: Suzuki K. Poulose suzuki.poul...@arm.com

We initialise the SCTLR_EL1 value by read-modify-writeback
of the desired bits, leaving the other bits (including reserved
bits(RESx)) untouched. However, sometimes the boot monitor could
leave garbage values in the RESx bits which could have different
implications. This patch makes sure that all the bits, including
the RESx bits, are set to the proper state, except for the
'endianness' control bits, EE(25)  E0E(24)- which are set early
in the el2_setup.

Updated the state of the Bit[6] in the comment to RES0 in the
comment.

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
Cc: Will Deacon will.dea...@arm.com
Cc: Catalin Marinas catalin.mari...@arm.com
---


Looks good to me:

   Acked-by: Will Deacon will.dea...@arm.com

Is this 3.19 material, or simply a cleanup/being cautious?

Sorry, for the late response. Yes this is kind of being cautious.

Suzuki


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] arm64: Fix SCTLR_EL1 initialisation

2014-12-17 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

We initialise the SCTLR_EL1 value by read-modify-writeback
of the desired bits, leaving the other bits (including reserved
bits(RESx)) untouched. However, sometimes the boot monitor could
leave garbage values in the RESx bits which could have different
implications. This patch makes sure that all the bits, including
the RESx bits, are set to the proper state, except for the
'endianness' control bits, EE(25)  E0E(24)- which are set early
in the el2_setup.

Updated the state of the Bit[6] in the comment to RES0 in the
comment.

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
Cc: Will Deacon will.dea...@arm.com
Cc: Catalin Marinas catalin.mari...@arm.com
---
 arch/arm64/mm/proc.S |   12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 4e778b1..f1bb1fc 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -244,14 +244,18 @@ ENTRY(__cpu_setup)
 ENDPROC(__cpu_setup)
 
/*
+* We set the desired value explicitly, including those of the 
+* reserved bits. The values of bits EE  E0E were set early in
+* el2_setup, which are left untouched below.
+*
 * n nT
 *   U E  WT T UD US IHBS
 *   CE0  XWHW CZ ME TEEA S
 *  .IEE  NEAI TE.I ..AD DEN0 ACAM
-* 0011 0... 1101 ..0. ..0. 10..    hardware reserved
-*  .1..  01.1 11.1 ..01 0001 1101  software settings
+* 0011 0... 1101 ..0. ..0. 10.. .0..   hardware reserved
+*  .1..  01.1 11.1 ..01 0.01 1101  software settings
 */
.type   crval, #object
 crval:
-   .word   0x000802e2  // clear
-   .word   0x0405d11d  // set
+   .word   0xfcff  // clear
+   .word   0x34d5d91d  // set
-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: How can I parse the command name from /proc/pid/stat?

2014-12-05 Thread Suzuki K. Poulose

On 04/12/14 19:44, Steven Stewart-Gallus wrote:

Hello,

Given an evil hacker trying to confuse process monitors that might use such
strange process names as 'pause) R 0 0 (foo' how can I correctly parse the
command name from /proc/pid/stat? Maybe I should just use /proc/pid/status?
Maybe there should be some documentation written on the issue? I just wanted to
send an email off to check if I was missing anything before writing a few small
additions to the documentation or filing a bug report. procps-ng seems to use an
ugly hack that involves knowing the limits on the size of a possible command
name that I'm not actually sure works totally correctly.


You can do something like :

cmd_start = strchr(stat_buf, '(');
cmd_end = strrchr(stat_buf, ')');

Cheers
Suzuki




Thank you,
Steven Stewart-Gallus
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/





--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [Regression] 3.19-rc3 : memcg: Hang in mount memcg

2015-01-19 Thread Suzuki K. Poulose

On 10/01/15 08:55, Vladimir Davydov wrote:

On Fri, Jan 09, 2015 at 05:43:17PM +, Suzuki K. Poulose wrote:

Hi

We have hit a hang on ARM64 defconfig, while running LTP tests on
3.19-rc3. We are
in the process of a git bisect and will update the results as and
when we find the commit.

During the ksm ltp run, the test hangs trying to mount memcg with
the following strace
output:

mount(memcg, /dev/cgroup, cgroup, 0, memory) = ?
ERESTARTNOINTR (To be restarted)
mount(memcg, /dev/cgroup, cgroup, 0, memory) = ?
ERESTARTNOINTR (To be restarted)
[ ... repeated forever ... ]

At this point, one can try mounting the memcg to verify the problem.
# mount -t cgroup -o memory memcg memcg_dir
--hangs--

Strangely, if we run the mount command from a cold boot (i.e.
without running LTP first),
then it succeeds.

Upon a quick look we are hitting the following code :
kernel/cgroup.c: cgroup_mount() :

1779 for_each_subsys(ss, i) {
1780 if (!(opts.subsys_mask  (1  i)) ||
1781 ss-root == cgrp_dfl_root)
1782 continue;
1783
1784 if
(!percpu_ref_tryget_live(ss-root-cgrp.self.refcnt)) {
1785 mutex_unlock(cgroup_mutex);
1786 msleep(10);
1787 ret = restart_syscall(); =
1788 goto out_free;
1789 }
1790 cgroup_put(ss-root-cgrp);
1791 }

with ss-root-cgrp.self.refct.percpu_count_ptr == __PERCPU_REF_ATOMIC_DEAD

Any ideas?


The problem is that the memory cgroup controller takes a css reference
per each charged page and does not reparent charged pages on css
offline, while cgroup_mount/cgroup_kill_sb expect all css references to
offline cgroups to be gone soon, restarting the syscall if the ref count
!= 0. As a result, if you create a memory cgroup, charge some page cache
to it, and then remove it, unmount/mount will hang forever.

May be, we should kill the ref counter to the memory controller root in
cgroup_kill_sb only if there is no children at all, neither online nor
offline.



Still reproducible on 3.19-rc5 with the same setup. From git bisect, the 
last good commit is :


commit 8df0c2dcf61781d2efa8e6e5b06870f6c6785735
Author: Pranith Kumar bobby.pr...@gmail.com
Date:   Wed Dec 10 15:42:28 2014 -0800

slab: replace smp_read_barrier_depends() with lockless_dereference()



Thanks
Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/3] arm64: Track system support for mixed endian EL0

2015-01-19 Thread Suzuki K. Poulose

On 16/01/15 16:15, Suzuki K. Poulose wrote:

On 16/01/15 15:53, Will Deacon wrote:

On Thu, Jan 15, 2015 at 12:36:04PM +, Suzuki K. Poulose wrote:

From: Suzuki K. Poulose suzuki.poul...@arm.com

This patch keeps track of the mixed endian EL0 support across
the system and provides helper functions to export it. The status
is a boolean indicating whether all the CPUs on the system supports
mixed endian at EL0.

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
   arch/arm64/include/asm/cpufeature.h |   10 ++
   arch/arm64/kernel/cpuinfo.c |   22 ++
   2 files changed, 32 insertions(+)

diff --git a/arch/arm64/include/asm/cpufeature.h 
b/arch/arm64/include/asm/cpufeature.h
index 07547cc..c7f68d1 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -26,6 +26,9 @@

   #define ARM64_NCAPS  2

+#define ID_AA64MMFR0_EL1_BigEndEL0 (0x1UL  16)
+#define ID_AA64MMFR0_EL1_BigEnd(0x1UL  8)


I don't like the CaMeLcAsE. Also, perhaps these definitions should be
somewhere like cputype.h?

Yeah, I tried to keep it aligned withe ARMv8 architecture definition of
those bits. Will change it.
Things are a bit messy w.r.t the definitions. We have cpu.h,
cpufeature.h and cputype.h. I could move it to cputype.h, where we
already have MIDR_ defintions.




+
   #ifndef __ASSEMBLY__

   extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
@@ -51,7 +54,14 @@ static inline void cpus_set_cap(unsigned int num)
__set_bit(num, cpu_hwcaps);
   }

+static inline bool id_aa64mmfr0_mixed_endian_el0(unsigned long mmfr0)
+{
+   return !!(mmfr0  (ID_AA64MMFR0_EL1_BigEndEL0 | 
ID_AA64MMFR0_EL1_BigEnd));
+}


These are 4-bit fields and I think you think you should be treating them
as such.

OK




+
   void check_local_cpu_errata(void);
+bool system_supports_mixed_endian_el0(void);
+bool cpu_supports_mixed_endian_el0(void);

   #endif /* __ASSEMBLY__ */

diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 07d435c..b6d1135 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -35,6 +35,7 @@
*/
   DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
   static struct cpuinfo_arm64 boot_cpu_data;
+static bool mixed_endian_el0 = true;

   static char *icache_policy_str[] = {
[ICACHE_POLICY_RESERVED] = RESERVED/UNKNOWN,
@@ -68,6 +69,26 @@ static void cpuinfo_detect_icache_policy(struct 
cpuinfo_arm64 *info)
pr_info(Detected %s I-cache on CPU%d\n, icache_policy_str[l1ip], cpu);
   }

+bool cpu_supports_mixed_endian_el0(void)
+{
+   return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
+}


Can we not just define a mask/value pair and have code do the MMFR0 access
inline? It also feels a bit over-engineered like this.

Sure, will change this.


On a second thought, we need the id_aa64mmfr0_mixed_endian_el0() for 
another code path. For a new CPU detected at boot time via 
cpuinfo_store_cpu(), where we get the 'filled' cpuinfo_arm64 which 
already has the id_aa64mmfr0. So we do:


+
+static void update_mixed_endian_el0_support(struct cpuinfo_arm64 *info)
+{
+   mixed_endian_el0 = 
id_aa64mmfr0_mixed_endian_el0(info-reg_id_aa64mmfr0);
+}

So, having a helper to extract the support from the id_aa64mmfr0 makes 
it a bit more ordered.


But yes, we could switch to mask/value pair.

Thanks
Suzuki


Thanks
Suzuki


Will




--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/




--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/3] arm64: Consolidate hotplug notifier for instruction emulation

2015-01-16 Thread Suzuki K. Poulose

On 16/01/15 16:07, Will Deacon wrote:

On Thu, Jan 15, 2015 at 12:36:05PM +, Suzuki K. Poulose wrote:

From: Suzuki K. Poulose suzuki.poul...@arm.com

As of now each insn_emulation has a cpu hotplug notifier that
enables/disables the CPU feature bit for the functionality. This
patch re-arranges the code, such that there is only one notifier
that runs through the list of registered emulation hooks and runs
their corresponding set_hw_mode.

We do nothing when a CPU is dying as we will set the appropriate bits
as it comes back online based on the state of the hooks.

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
Signed-off-by: Mark Rutland mark.rutl...@arm.com
---
  Documentation/arm64/legacy_instructions.txt |4 +
  arch/arm64/include/asm/cpufeature.h |2 +
  arch/arm64/kernel/armv8_deprecated.c|  113 +++
  3 files changed, 69 insertions(+), 50 deletions(-)

diff --git a/Documentation/arm64/legacy_instructions.txt 
b/Documentation/arm64/legacy_instructions.txt
index a3b3da2..0a4dc26 100644
--- a/Documentation/arm64/legacy_instructions.txt
+++ b/Documentation/arm64/legacy_instructions.txt
@@ -27,6 +27,10 @@ behaviours and the corresponding values of the sysctl nodes -
instructions. Using hardware execution generally provides better
performance, but at the loss of ability to gather runtime statistics
about the use of the deprecated instructions.
+  Note: Emulation of a deprecated instruction depends on the availability
+  of the feature on all the active CPUs. In case of CPU hotplug, if a new
+  CPU doesn't support a feature, it could result in the abortion of the
+  hotplug operation.


Is this true? We should be able to *emulate* the instruction anywhere,
it's the hardware execution setting that needs CPU support.
Yes. Particularly for SETEND, if the CPU doesn't support mixed endian 
data access at EL0, we shouldn't emulate setend and cause unexpected 
results at EL0. So it is upto the hook to raise a flag if it can emulate 
without the hardware capability.





  The default mode depends on the status of the instruction in the
  architecture. Deprecated instructions should default to emulation
diff --git a/arch/arm64/include/asm/cpufeature.h 
b/arch/arm64/include/asm/cpufeature.h
index c7f68d1..a56b45f 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -29,6 +29,8 @@
  #define ID_AA64MMFR0_EL1_BigEndEL0(0x1UL  16)
  #define ID_AA64MMFR0_EL1_BigEnd   (0x1UL  8)

+#define SCTLR_EL1_CP15BEN  (1  5)
+
  #ifndef __ASSEMBLY__

  extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
diff --git a/arch/arm64/kernel/armv8_deprecated.c 
b/arch/arm64/kernel/armv8_deprecated.c
index c363671..be64218 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -19,6 +19,7 @@
  #include asm/system_misc.h
  #include asm/traps.h
  #include asm/uaccess.h
+#include asm/cpufeature.h

  #define CREATE_TRACE_POINTS
  #include trace-events-emulation.h
@@ -46,7 +47,7 @@ struct insn_emulation_ops {
const char  *name;
enum legacy_insn_status status;
struct undef_hook   *hooks;
-   int (*set_hw_mode)(bool enable);
+   int (*set_hw_mode)(void *enable);


I think it would be cleaner to have a wrapper for the on_each_cpu
variant of this, otherwise we lose the type information altogether.


OK.

  };

  struct insn_emulation {
@@ -85,6 +86,40 @@ static void remove_emulation_hooks(struct insn_emulation_ops 
*ops)
pr_notice(Removed %s emulation handler\n, ops-name);
  }





+static int insn_cpu_hotplug_notify(struct notifier_block *b,
+ unsigned long action, void *hcpu)
+{
+   int rc = 0;
+   if ((action  ~CPU_TASKS_FROZEN) == CPU_STARTING)
+   rc = run_all_insn_set_hw_mode();
+
+   /* Abort the CPU hotplug if there is an incompatibility */
+   return notifier_from_errno(rc);


Could we restrict the emulation options instead and just disable hardware
support for the instruction?


As explained earlier, each hook could decide if missing a feature could 
result in an abort.


Thanks
Suzuki


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/3] arm64: Track system support for mixed endian EL0

2015-01-16 Thread Suzuki K. Poulose

On 16/01/15 15:53, Will Deacon wrote:

On Thu, Jan 15, 2015 at 12:36:04PM +, Suzuki K. Poulose wrote:

From: Suzuki K. Poulose suzuki.poul...@arm.com

This patch keeps track of the mixed endian EL0 support across
the system and provides helper functions to export it. The status
is a boolean indicating whether all the CPUs on the system supports
mixed endian at EL0.

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
  arch/arm64/include/asm/cpufeature.h |   10 ++
  arch/arm64/kernel/cpuinfo.c |   22 ++
  2 files changed, 32 insertions(+)

diff --git a/arch/arm64/include/asm/cpufeature.h 
b/arch/arm64/include/asm/cpufeature.h
index 07547cc..c7f68d1 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -26,6 +26,9 @@

  #define ARM64_NCAPS   2

+#define ID_AA64MMFR0_EL1_BigEndEL0 (0x1UL  16)
+#define ID_AA64MMFR0_EL1_BigEnd(0x1UL  8)


I don't like the CaMeLcAsE. Also, perhaps these definitions should be
somewhere like cputype.h?
Yeah, I tried to keep it aligned withe ARMv8 architecture definition of 
those bits. Will change it.
Things are a bit messy w.r.t the definitions. We have cpu.h, 
cpufeature.h and cputype.h. I could move it to cputype.h, where we 
already have MIDR_ defintions.





+
  #ifndef __ASSEMBLY__

  extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
@@ -51,7 +54,14 @@ static inline void cpus_set_cap(unsigned int num)
__set_bit(num, cpu_hwcaps);
  }

+static inline bool id_aa64mmfr0_mixed_endian_el0(unsigned long mmfr0)
+{
+   return !!(mmfr0  (ID_AA64MMFR0_EL1_BigEndEL0 | 
ID_AA64MMFR0_EL1_BigEnd));
+}


These are 4-bit fields and I think you think you should be treating them
as such.

OK




+
  void check_local_cpu_errata(void);
+bool system_supports_mixed_endian_el0(void);
+bool cpu_supports_mixed_endian_el0(void);

  #endif /* __ASSEMBLY__ */

diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 07d435c..b6d1135 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -35,6 +35,7 @@
   */
  DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
  static struct cpuinfo_arm64 boot_cpu_data;
+static bool mixed_endian_el0 = true;

  static char *icache_policy_str[] = {
[ICACHE_POLICY_RESERVED] = RESERVED/UNKNOWN,
@@ -68,6 +69,26 @@ static void cpuinfo_detect_icache_policy(struct 
cpuinfo_arm64 *info)
pr_info(Detected %s I-cache on CPU%d\n, icache_policy_str[l1ip], cpu);
  }

+bool cpu_supports_mixed_endian_el0(void)
+{
+   return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
+}


Can we not just define a mask/value pair and have code do the MMFR0 access
inline? It also feels a bit over-engineered like this.

Sure, will change this.

Thanks
Suzuki


Will




--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] arm64: Track system support for mixed endian EL0

2015-01-15 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

This patch keeps track of the mixed endian EL0 support across
the system and provides helper functions to export it. The status
is a boolean indicating whether all the CPUs on the system supports
mixed endian at EL0.

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 arch/arm64/include/asm/cpufeature.h |   10 ++
 arch/arm64/kernel/cpuinfo.c |   22 ++
 2 files changed, 32 insertions(+)

diff --git a/arch/arm64/include/asm/cpufeature.h 
b/arch/arm64/include/asm/cpufeature.h
index 07547cc..c7f68d1 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -26,6 +26,9 @@
 
 #define ARM64_NCAPS2
 
+#define ID_AA64MMFR0_EL1_BigEndEL0 (0x1UL  16)
+#define ID_AA64MMFR0_EL1_BigEnd(0x1UL  8)
+
 #ifndef __ASSEMBLY__
 
 extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
@@ -51,7 +54,14 @@ static inline void cpus_set_cap(unsigned int num)
__set_bit(num, cpu_hwcaps);
 }
 
+static inline bool id_aa64mmfr0_mixed_endian_el0(unsigned long mmfr0)
+{
+   return !!(mmfr0  (ID_AA64MMFR0_EL1_BigEndEL0 | 
ID_AA64MMFR0_EL1_BigEnd));
+}
+
 void check_local_cpu_errata(void);
+bool system_supports_mixed_endian_el0(void);
+bool cpu_supports_mixed_endian_el0(void);
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 07d435c..b6d1135 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -35,6 +35,7 @@
  */
 DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
 static struct cpuinfo_arm64 boot_cpu_data;
+static bool mixed_endian_el0 = true;
 
 static char *icache_policy_str[] = {
[ICACHE_POLICY_RESERVED] = RESERVED/UNKNOWN,
@@ -68,6 +69,26 @@ static void cpuinfo_detect_icache_policy(struct 
cpuinfo_arm64 *info)
pr_info(Detected %s I-cache on CPU%d\n, icache_policy_str[l1ip], cpu);
 }
 
+bool cpu_supports_mixed_endian_el0(void)
+{
+   return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
+}
+
+bool system_supports_mixed_endian_el0(void)
+{
+   return mixed_endian_el0;
+}
+
+static void update_mixed_endian_el0_support(struct cpuinfo_arm64 *info)
+{
+   mixed_endian_el0 = 
id_aa64mmfr0_mixed_endian_el0(info-reg_id_aa64mmfr0);
+}
+
+static void update_cpu_features(struct cpuinfo_arm64 *info)
+{
+   update_mixed_endian_el0_support(info);
+}
+
 static int check_reg_mask(char *name, u64 mask, u64 boot, u64 cur, int cpu)
 {
if ((boot  mask) == (cur  mask))
@@ -215,6 +236,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
cpuinfo_detect_icache_policy(info);
 
check_local_cpu_errata();
+   update_cpu_features(info);
 }
 
 void cpuinfo_store_cpu(void)
-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/3] arm64: Consolidate hotplug notifier for instruction emulation

2015-01-15 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

As of now each insn_emulation has a cpu hotplug notifier that
enables/disables the CPU feature bit for the functionality. This
patch re-arranges the code, such that there is only one notifier
that runs through the list of registered emulation hooks and runs
their corresponding set_hw_mode.

We do nothing when a CPU is dying as we will set the appropriate bits
as it comes back online based on the state of the hooks.

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
Signed-off-by: Mark Rutland mark.rutl...@arm.com
---
 Documentation/arm64/legacy_instructions.txt |4 +
 arch/arm64/include/asm/cpufeature.h |2 +
 arch/arm64/kernel/armv8_deprecated.c|  113 +++
 3 files changed, 69 insertions(+), 50 deletions(-)

diff --git a/Documentation/arm64/legacy_instructions.txt 
b/Documentation/arm64/legacy_instructions.txt
index a3b3da2..0a4dc26 100644
--- a/Documentation/arm64/legacy_instructions.txt
+++ b/Documentation/arm64/legacy_instructions.txt
@@ -27,6 +27,10 @@ behaviours and the corresponding values of the sysctl nodes -
   instructions. Using hardware execution generally provides better
   performance, but at the loss of ability to gather runtime statistics
   about the use of the deprecated instructions.
+  Note: Emulation of a deprecated instruction depends on the availability
+  of the feature on all the active CPUs. In case of CPU hotplug, if a new
+  CPU doesn't support a feature, it could result in the abortion of the
+  hotplug operation.
 
 The default mode depends on the status of the instruction in the
 architecture. Deprecated instructions should default to emulation
diff --git a/arch/arm64/include/asm/cpufeature.h 
b/arch/arm64/include/asm/cpufeature.h
index c7f68d1..a56b45f 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -29,6 +29,8 @@
 #define ID_AA64MMFR0_EL1_BigEndEL0 (0x1UL  16)
 #define ID_AA64MMFR0_EL1_BigEnd(0x1UL  8)
 
+#define SCTLR_EL1_CP15BEN  (1  5)
+
 #ifndef __ASSEMBLY__
 
 extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
diff --git a/arch/arm64/kernel/armv8_deprecated.c 
b/arch/arm64/kernel/armv8_deprecated.c
index c363671..be64218 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -19,6 +19,7 @@
 #include asm/system_misc.h
 #include asm/traps.h
 #include asm/uaccess.h
+#include asm/cpufeature.h
 
 #define CREATE_TRACE_POINTS
 #include trace-events-emulation.h
@@ -46,7 +47,7 @@ struct insn_emulation_ops {
const char  *name;
enum legacy_insn_status status;
struct undef_hook   *hooks;
-   int (*set_hw_mode)(bool enable);
+   int (*set_hw_mode)(void *enable);
 };
 
 struct insn_emulation {
@@ -85,6 +86,40 @@ static void remove_emulation_hooks(struct insn_emulation_ops 
*ops)
pr_notice(Removed %s emulation handler\n, ops-name);
 }
 
+/* Run set_hw_mode(mode) on all active CPUs */
+static int run_all_cpu_set_hw_mode(struct insn_emulation *insn, bool enable)
+{
+   void (*set_hw_mode)(void *) = (void (*) (void *))insn-ops-set_hw_mode;
+   if (!set_hw_mode)
+   return -EINVAL;
+   on_each_cpu(set_hw_mode, (void *)enable, true);
+   return 0;
+}
+
+/*
+ * Run set_hw_mode for all insns on a starting CPU.
+ * Returns:
+ *  0  - If all the hooks ran successfully.
+ * -EINVAL - At least one hook is not supported by the CPU.
+ *   abort the hotplug.
+ */
+static int run_all_insn_set_hw_mode(void)
+{
+   int rc = 0;
+   unsigned long flags;
+   struct insn_emulation *insn;
+
+   raw_spin_lock_irqsave(insn_emulation_lock, flags);
+   list_for_each_entry(insn, insn_emulation, node) {
+   bool hw_mode = (insn-current_mode == INSN_HW);
+   if (insn-ops-set_hw_mode 
+   insn-ops-set_hw_mode((void*)hw_mode))
+   rc = -EINVAL;
+   }
+   raw_spin_unlock_irqrestore(insn_emulation_lock, flags);
+   return rc;
+}
+
 static int update_insn_emulation_mode(struct insn_emulation *insn,
   enum insn_emulation_mode prev)
 {
@@ -97,10 +132,8 @@ static int update_insn_emulation_mode(struct insn_emulation 
*insn,
remove_emulation_hooks(insn-ops);
break;
case INSN_HW:
-   if (insn-ops-set_hw_mode) {
-   insn-ops-set_hw_mode(false);
+   if (!run_all_cpu_set_hw_mode(insn, false))
pr_notice(Disabled %s support\n, insn-ops-name);
-   }
break;
}
 
@@ -111,10 +144,9 @@ static int update_insn_emulation_mode(struct 
insn_emulation *insn,
register_emulation_hooks(insn-ops);
break;
case INSN_HW:
-   if (insn-ops-set_hw_mode  insn-ops-set_hw_mode

[PATCHv2 0/3] Handle SETEND for AArch32 tasks

2015-01-15 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

This series add support for controlling the 'setend' instruction,
which is deprecated in ARMv8, using the legacy instruction emulation
framework, introduced by Punit Agrawal.


Changes since V1:
 - Added a patch to keep track of the mixed endian support and register
   the setend emulation only if all the active CPUs supports mixed endian.
 - Fail hotplug operation if the CPU doesn't support a feature
   required by insn_emulation.
 - Signal handler runs in native endian

Testing :

 $ cat setend_sig.c 
 #include stdio.h
 #include signal.h

 #define setend_be(a)   asm __volatile__ ( setend be ::: memory )
 #define setend_le(a)   asm __volatile__ ( setend le ::: memory )

 volatile int flag = 1;

 void sigint(int sig)
 {
printf(in sighandler %d\n, sig);
flag = 0;
return;
 }

 main()
 {
volatile int a = 0x0;

(void)signal(SIGINT, sigint);
printf(Press Ctrl+C to continue\n);
setend_be();
a ++;

while (flag);

setend_le();
a ++;

printf(a: 0x%x\n, a);
return 0;
 }
 $ cat /proc/sys/abi/setend 
 1
 $ echo 1  
/sys/kernel/debug/tracing/events/emulation/instruction_emulation/enable 
 $ echo 1  /sys/kernel/debug/tracing/tracing_on 
 $ ./setend_sig_a32 
 Press Ctrl+C to continue
 ^Cin sighandler 2
 a: 0x101
 $ cat /sys/kernel/debug/tracing/trace
 # tracer: nop
 #
 # entries-in-buffer/entries-written: 2/2   #P:2
 #
 #  _-= irqs-off
 # / _= need-resched
 #| / _---= hardirq/softirq
 #|| / _--= preempt-depth
 #||| / delay
 #   TASK-PID   CPU#  TIMESTAMP  FUNCTION
 #  | |   |      | |
   setend_sig_a32-1373  [000] ...1   491.554499: instruction_emulation: 
instr=setend be addr=0x8460
   setend_sig_a32-1373  [000] ...1   492.833056: instruction_emulation: 
instr=setend le addr=0x8488
 $ dmesg | tail
 [  491.554807] setend_sig_a32 (1373) uses deprecated setend instruction at 
0x8460
 [  492.833285] setend_sig_a32 (1373) uses deprecated setend instruction at 
0x8488
 $ echo 2  /proc/sys/abi/setend
 $ ./setend_sig_t16 
 Press Ctrl+C to continue
 ^Cin sighandler 2
 a: 0x101
 $ dmesg | tail
 [  491.554807] setend_sig_a32 (1373) uses deprecated setend instruction at 
0x8460
 [  492.833285] setend_sig_a32 (1373) uses deprecated setend instruction at 
0x8488
 [  537.426216] Removed setend emulation handler
 [  537.426624] Enabled setend support

Suzuki K. Poulose (3):
  arm64: Track system support for mixed endian EL0
  arm64: Consolidate hotplug notifier for instruction emulation
  arm64:  Emulate SETEND for AArch32 tasks

 Documentation/arm64/legacy_instructions.txt |   13 ++
 arch/arm64/Kconfig  |   10 ++
 arch/arm64/include/asm/cpufeature.h |   13 ++
 arch/arm64/include/asm/ptrace.h |7 +
 arch/arm64/kernel/armv8_deprecated.c|  195 ---
 arch/arm64/kernel/cpuinfo.c |   22 +++
 arch/arm64/kernel/signal32.c|5 +-
 7 files changed, 214 insertions(+), 51 deletions(-)

-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/3] arm64: Emulate SETEND for AArch32 tasks

2015-01-15 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

Emulate deprecated 'setend' instruction for AArch32 bit tasks.

setend [le/be] - Sets the endianness of EL0

On systems with CPUs which support mixed endian at EL0, the hardware
support for the instruction can be enabled by setting the SCTLR_EL1.SED
bit. Like the other emulated instructions it is controlled by an entry in
/proc/sys/abi/. For more information see :
Documentation/arm64/legacy_instructions.txt

The instruction is emulated by setting/clearing the SPSR_EL1.E bit, which
will be reflected in the PSTATE.E in AArch32 context.

This patch also restores the native endianness for the execution of signal
handlers, since the process could have changed the endianness.

Note: All CPUs on the system should support for mixed endian at EL0. Once the
handler is registered a CPU which doesn't support mixed endian, cannot be
hotplugged in.

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 Documentation/arm64/legacy_instructions.txt |9 +++
 arch/arm64/Kconfig  |   10 
 arch/arm64/include/asm/cpufeature.h |1 +
 arch/arm64/include/asm/ptrace.h |7 +++
 arch/arm64/kernel/armv8_deprecated.c|   82 +++
 arch/arm64/kernel/signal32.c|5 +-
 6 files changed, 113 insertions(+), 1 deletion(-)

diff --git a/Documentation/arm64/legacy_instructions.txt 
b/Documentation/arm64/legacy_instructions.txt
index 0a4dc26..92b7945 100644
--- a/Documentation/arm64/legacy_instructions.txt
+++ b/Documentation/arm64/legacy_instructions.txt
@@ -47,3 +47,12 @@ Default: Undef (0)
 Node: /proc/sys/abi/cp15_barrier
 Status: Deprecated
 Default: Emulate (1)
+
+* SETEND
+Node: /proc/sys/abi/setend
+Status: Deprecated
+Default: Emulate (1)*
+Note: All the cpus on the system should support mixed endian at EL0
+(ID_AA64MMFR0_EL1:BigEnd or BigEndEL0), for this feature to be enabled.
+Once this feature is registered, a CPU that doesn't support the feature
+cannot be hotplugged in.
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b1f9a20..c6d1fd9 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -540,6 +540,16 @@ config CP15_BARRIER_EMULATION
 
  If unsure, say Y
 
+config SETEND_EMULATION
+   bool Emulate SETEND instruction
+   help
+ The SETEND instruction alters the data-endianness of the
+ AArch32 EL0, and is deprecated in ARMv8.
+
+ Say Y here to enable software emulation of the instruction
+ for AArch32 userspace code.
+
+ If unsure, say Y
 endif
 
 endmenu
diff --git a/arch/arm64/include/asm/cpufeature.h 
b/arch/arm64/include/asm/cpufeature.h
index a56b45f..760bb20 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -30,6 +30,7 @@
 #define ID_AA64MMFR0_EL1_BigEnd(0x1UL  8)
 
 #define SCTLR_EL1_CP15BEN  (1  5)
+#define SCTLR_EL1_SED  (1  8)
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 41ed9e1..d6dd9fd 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -58,6 +58,13 @@
 #define COMPAT_PSR_Z_BIT   0x4000
 #define COMPAT_PSR_N_BIT   0x8000
 #define COMPAT_PSR_IT_MASK 0x0600fc00  /* If-Then execution state mask 
*/
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define COMPAT_PSR_ENDSTATECOMPAT_PSR_E_BIT
+#else
+#define COMPAT_PSR_ENDSTATE0
+#endif
+
 /*
  * These are 'magic' values for PTRACE_PEEKUSR that return info about where a
  * process is located in memory.
diff --git a/arch/arm64/kernel/armv8_deprecated.c 
b/arch/arm64/kernel/armv8_deprecated.c
index be64218..204c610 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -531,6 +531,84 @@ static struct insn_emulation_ops cp15_barrier_ops = {
.set_hw_mode = cp15_barrier_set_hw_mode,
 };
 
+static int setend_set_hw_mode(void *enable)
+{
+   if (!cpu_supports_mixed_endian_el0()) {
+   pr_warn_ratelimited(Missing mixed endian support at EL0,
+Abort CPU hotplug...\n);
+   return -EINVAL;
+   }
+
+   if (enable)
+   config_sctlr_el1(SCTLR_EL1_SED, 0);
+   else
+   config_sctlr_el1(0, SCTLR_EL1_SED);
+   return 0;
+}
+
+static int compat_setend_handler(struct pt_regs *regs, u32 endian)
+{
+   char insn[16] = setend _e;
+
+   perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs-pc);
+
+   if (endian) {
+   /* Big Endian */
+   insn[7] = 'b';
+   regs-pstate |= COMPAT_PSR_E_BIT;
+   } else {
+   /* Little Endian */
+   insn[7] = 'l';
+   regs-pstate = ~COMPAT_PSR_E_BIT;
+   }
+
+   trace_instruction_emulation(insn, regs-pc);
+   pr_warn_ratelimited(\%s\ (%ld) uses deprecated setend instruction

[PATCH 2/3] arm64: Consolidate hotplug notifier for instruction emulation

2015-01-21 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

As of now each insn_emulation has a cpu hotplug notifier that
enables/disables the CPU feature bit for the functionality. This
patch re-arranges the code, such that there is only one notifier
that runs through the list of registered emulation hooks and runs
their corresponding set_hw_mode.

We do nothing when a CPU is dying as we will set the appropriate bits
as it comes back online based on the state of the hooks.

Signed-off-by: Mark Rutland mark.rutl...@arm.com
Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
Cc: Will Deacon will.dea...@arm.com
Cc: Catalin Marinas catalin.mari...@arm.com
Cc: Punit Agrawal punit.agra...@arm.com
---
 arch/arm64/include/asm/cputype.h |2 +
 arch/arm64/kernel/armv8_deprecated.c |  125 +-
 2 files changed, 79 insertions(+), 48 deletions(-)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 44e578d..2c4c852 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -82,6 +82,8 @@
 #define ID_AA64MMFR0_BIGEND(mmfr0) \
(((mmfr0)  ID_AA64MMFR0_BIGEND_MASK)  ID_AA64MMFR0_BIGEND_SHIFT)
 
+#define SCTLR_EL1_CP15BEN  (0x1  5)
+
 #ifndef __ASSEMBLY__
 
 /*
diff --git a/arch/arm64/kernel/armv8_deprecated.c 
b/arch/arm64/kernel/armv8_deprecated.c
index c363671..2c991f1 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -19,6 +19,7 @@
 #include asm/system_misc.h
 #include asm/traps.h
 #include asm/uaccess.h
+#include asm/cpufeature.h
 
 #define CREATE_TRACE_POINTS
 #include trace-events-emulation.h
@@ -85,6 +86,57 @@ static void remove_emulation_hooks(struct insn_emulation_ops 
*ops)
pr_notice(Removed %s emulation handler\n, ops-name);
 }
 
+static void enable_insn_hw_mode(void *data)
+{
+   struct insn_emulation *insn = (struct insn_emulation *)data;
+   if (insn  insn-ops-set_hw_mode)
+   insn-ops-set_hw_mode(true);
+}
+
+static void disable_insn_hw_mode(void *data)
+{
+   struct insn_emulation *insn = (struct insn_emulation *)data;
+   if (insn  insn-ops-set_hw_mode)
+   insn-ops-set_hw_mode(false);
+}
+
+/* Run set_hw_mode(mode) on all active CPUs */
+static int run_all_cpu_set_hw_mode(struct insn_emulation *insn, bool enable)
+{
+   if (!insn-ops-set_hw_mode)
+   return -EINVAL;
+   if (enable)
+   on_each_cpu(enable_insn_hw_mode, (void *)insn, true);
+   else
+   on_each_cpu(disable_insn_hw_mode, (void *)insn, true);
+   return 0;
+}
+
+/*
+ * Run set_hw_mode for all insns on a starting CPU.
+ * Returns:
+ *  0  - If all the hooks ran successfully.
+ * -EINVAL - At least one hook is not supported by the CPU.
+ */
+static int run_all_insn_set_hw_mode(unsigned long cpu)
+{
+   int rc = 0;
+   unsigned long flags;
+   struct insn_emulation *insn;
+
+   raw_spin_lock_irqsave(insn_emulation_lock, flags);
+   list_for_each_entry(insn, insn_emulation, node) {
+   bool enable = (insn-current_mode == INSN_HW);
+   if (insn-ops-set_hw_mode  insn-ops-set_hw_mode(enable)) {
+   pr_warn(enable, CPU[%ld] cannot support the emulation 
of %s,
+   cpu, insn-ops-name);
+   rc = -EINVAL;
+   }
+   }
+   raw_spin_unlock_irqrestore(insn_emulation_lock, flags);
+   return rc;
+}
+
 static int update_insn_emulation_mode(struct insn_emulation *insn,
   enum insn_emulation_mode prev)
 {
@@ -97,10 +149,8 @@ static int update_insn_emulation_mode(struct insn_emulation 
*insn,
remove_emulation_hooks(insn-ops);
break;
case INSN_HW:
-   if (insn-ops-set_hw_mode) {
-   insn-ops-set_hw_mode(false);
+   if (!run_all_cpu_set_hw_mode(insn, false))
pr_notice(Disabled %s support\n, insn-ops-name);
-   }
break;
}
 
@@ -111,10 +161,9 @@ static int update_insn_emulation_mode(struct 
insn_emulation *insn,
register_emulation_hooks(insn-ops);
break;
case INSN_HW:
-   if (insn-ops-set_hw_mode  insn-ops-set_hw_mode(true))
+   ret = run_all_cpu_set_hw_mode(insn, true);
+   if (!ret)
pr_notice(Enabled %s support\n, insn-ops-name);
-   else
-   ret = -EINVAL;
break;
}
 
@@ -133,6 +182,8 @@ static void register_insn_emulation(struct 
insn_emulation_ops *ops)
switch (ops-status) {
case INSN_DEPRECATED:
insn-current_mode = INSN_EMULATE;
+   /* Disable the HW mode if it was turned on at early boot time */
+   run_all_cpu_set_hw_mode(insn, false

[PATCHv3 0/3] Handle SETEND for AArch32 tasks

2015-01-21 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

This series add support for controlling the 'setend' instruction,
which is deprecated in ARMv8, using the legacy instruction emulation
framework, introduced by Punit Agrawal.

Changes since V2:
 - Move ID_AA64MMFR0_EL1 bit definitions to asm/cputype.h
 - Use mask/value pair for the features in ID_AA64MMFR0_EL1
 - Better documentation about the hardware support limitaion under
   Documentation and the Kconfig help
 - Restore the original 'set_hw_mode' API, with wrappers to invoke
   the set_hw_mode for on_each_cpu() variants.
 - Print a warning when we detect an incompatibility for a registered
   insn_emulation hook on a hotplugged CPU.

Changes since V1:
 - Added a patch to keep track of the mixed endian support and register
   the setend emulation only if all the active CPUs supports mixed endian.
 - Fail hotplug operation if the CPU doesn't support a feature
   required by insn_emulation.
 - Signal handler runs in native endian

Testing :

 $ cat setend_sig.c 
 #include stdio.h
 #include signal.h

 #define setend_be(a)   asm __volatile__ ( setend be ::: memory )
 #define setend_le(a)   asm __volatile__ ( setend le ::: memory )

 volatile int flag = 1;

 void sigint(int sig)
 {
printf(in sighandler %d\n, sig);
flag = 0;
return;
 }

 main()
 {
volatile int a = 0x0;

(void)signal(SIGINT, sigint);
printf(Press Ctrl+C to continue\n);
setend_be();
a ++;

while (flag);

setend_le();
a ++;

printf(a: 0x%x\n, a);
return 0;
 }
 $ cat /proc/sys/abi/setend 
 1
 $ echo 1  
/sys/kernel/debug/tracing/events/emulation/instruction_emulation/enable 
 $ echo 1  /sys/kernel/debug/tracing/tracing_on 
 $ ./setend_sig_a32 
 Press Ctrl+C to continue
 ^Cin sighandler 2
 a: 0x101
 $ cat /sys/kernel/debug/tracing/trace
 # tracer: nop
 #
 # entries-in-buffer/entries-written: 2/2   #P:2
 #
 #  _-= irqs-off
 # / _= need-resched
 #| / _---= hardirq/softirq
 #|| / _--= preempt-depth
 #||| / delay
 #   TASK-PID   CPU#  TIMESTAMP  FUNCTION
 #  | |   |      | |
   setend_sig_a32-1373  [000] ...1   491.554499: instruction_emulation: 
instr=setend be addr=0x8460
   setend_sig_a32-1373  [000] ...1   492.833056: instruction_emulation: 
instr=setend le addr=0x8488
 $ dmesg | tail
 [  491.554807] setend_sig_a32 (1373) uses deprecated setend instruction at 
0x8460
 [  492.833285] setend_sig_a32 (1373) uses deprecated setend instruction at 
0x8488
 $ echo 2  /proc/sys/abi/setend
 $ ./setend_sig_t16 
 Press Ctrl+C to continue
 ^Cin sighandler 2
 a: 0x101
 $ dmesg | tail
 [  491.554807] setend_sig_a32 (1373) uses deprecated setend instruction at 
0x8460
 [  492.833285] setend_sig_a32 (1373) uses deprecated setend instruction at 
0x8488
 [  537.426216] Removed setend emulation handler
 [  537.426624] Enabled setend support


Suzuki K. Poulose (3):
  arm64: Track system support for mixed endian EL0
  arm64: Consolidate hotplug notifier for instruction emulation
  arm64:  Emulate SETEND for AArch32 tasks

 Documentation/arm64/legacy_instructions.txt |   12 ++
 arch/arm64/Kconfig  |   15 ++
 arch/arm64/include/asm/cpufeature.h |2 +
 arch/arm64/include/asm/cputype.h|   17 +++
 arch/arm64/include/asm/ptrace.h |7 +
 arch/arm64/kernel/armv8_deprecated.c|  205 ---
 arch/arm64/kernel/cpuinfo.c |   22 +++
 arch/arm64/kernel/signal32.c|5 +-
 8 files changed, 236 insertions(+), 49 deletions(-)

-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] arm64: Track system support for mixed endian EL0

2015-01-21 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

This patch keeps track of the mixed endian EL0 support across
the system and provides helper functions to export it. The status
is a boolean indicating whether all the CPUs on the system supports
mixed endian at EL0.

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
Cc: Will Deacon will.dea...@arm.com
Cc: Catalin Marinas catalin.mari...@arm.com
---
 arch/arm64/include/asm/cpufeature.h |2 ++
 arch/arm64/include/asm/cputype.h|   14 ++
 arch/arm64/kernel/cpuinfo.c |   22 ++
 3 files changed, 38 insertions(+)

diff --git a/arch/arm64/include/asm/cpufeature.h 
b/arch/arm64/include/asm/cpufeature.h
index 07547cc..b6c16d5 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -52,6 +52,8 @@ static inline void cpus_set_cap(unsigned int num)
 }
 
 void check_local_cpu_errata(void);
+bool cpu_supports_mixed_endian_el0(void);
+bool system_supports_mixed_endian_el0(void);
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 53d59b0..44e578d 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -73,6 +73,15 @@
 
 #define APM_CPU_PART_POTENZA   0x000
 
+#define ID_AA64MMFR0_BIGENDEL0_SHIFT   16
+#define ID_AA64MMFR0_BIGENDEL0_MASK(0xf  ID_AA64MMFR0_BIGENDEL0_SHIFT)
+#define ID_AA64MMFR0_BIGENDEL0(mmfr0)  \
+   (((mmfr0)  ID_AA64MMFR0_BIGENDEL0_MASK)  
ID_AA64MMFR0_BIGENDEL0_SHIFT)
+#define ID_AA64MMFR0_BIGEND_SHIFT  8
+#define ID_AA64MMFR0_BIGEND_MASK   (0xf  ID_AA64MMFR0_BIGEND_SHIFT)
+#define ID_AA64MMFR0_BIGEND(mmfr0) \
+   (((mmfr0)  ID_AA64MMFR0_BIGEND_MASK)  ID_AA64MMFR0_BIGEND_SHIFT)
+
 #ifndef __ASSEMBLY__
 
 /*
@@ -105,6 +114,11 @@ static inline u32 __attribute_const__ 
read_cpuid_cachetype(void)
return read_cpuid(CTR_EL0);
 }
 
+static inline bool id_aa64mmfr0_mixed_endian_el0(u64 mmfr0)
+{
+   return (ID_AA64MMFR0_BIGEND(mmfr0) == 0x1) ||
+   (ID_AA64MMFR0_BIGENDEL0(mmfr0) == 0x1);
+}
 #endif /* __ASSEMBLY__ */
 
 #endif
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 07d435c..b6d1135 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -35,6 +35,7 @@
  */
 DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
 static struct cpuinfo_arm64 boot_cpu_data;
+static bool mixed_endian_el0 = true;
 
 static char *icache_policy_str[] = {
[ICACHE_POLICY_RESERVED] = RESERVED/UNKNOWN,
@@ -68,6 +69,26 @@ static void cpuinfo_detect_icache_policy(struct 
cpuinfo_arm64 *info)
pr_info(Detected %s I-cache on CPU%d\n, icache_policy_str[l1ip], cpu);
 }
 
+bool cpu_supports_mixed_endian_el0(void)
+{
+   return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
+}
+
+bool system_supports_mixed_endian_el0(void)
+{
+   return mixed_endian_el0;
+}
+
+static void update_mixed_endian_el0_support(struct cpuinfo_arm64 *info)
+{
+   mixed_endian_el0 = 
id_aa64mmfr0_mixed_endian_el0(info-reg_id_aa64mmfr0);
+}
+
+static void update_cpu_features(struct cpuinfo_arm64 *info)
+{
+   update_mixed_endian_el0_support(info);
+}
+
 static int check_reg_mask(char *name, u64 mask, u64 boot, u64 cur, int cpu)
 {
if ((boot  mask) == (cur  mask))
@@ -215,6 +236,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
cpuinfo_detect_icache_policy(info);
 
check_local_cpu_errata();
+   update_cpu_features(info);
 }
 
 void cpuinfo_store_cpu(void)
-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/3] arm64: Emulate SETEND for AArch32 tasks

2015-01-21 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

Emulate deprecated 'setend' instruction for AArch32 bit tasks.

setend [le/be] - Sets the endianness of EL0

On systems with CPUs which support mixed endian at EL0, the hardware
support for the instruction can be enabled by setting the SCTLR_EL1.SED
bit. Like the other emulated instructions it is controlled by an entry in
/proc/sys/abi/. For more information see :
Documentation/arm64/legacy_instructions.txt

The instruction is emulated by setting/clearing the SPSR_EL1.E bit, which
will be reflected in the PSTATE.E in AArch32 context.

This patch also restores the native endianness for the execution of signal
handlers, since the process could have changed the endianness.

Note: All CPUs on the system must have mixed endian support at EL0. Once the
handler is registered, hotplugging a CPU which doesn't support mixed endian,
could lead to unexpected results/behavior in applications.

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
Cc: Will Deacon will.dea...@arm.com
Cc: Catalin Marinas catalin.mari...@arm.com
Cc: Punit Agrawal punit.agra...@arm.com
---
 Documentation/arm64/legacy_instructions.txt |   12 
 arch/arm64/Kconfig  |   15 +
 arch/arm64/include/asm/cputype.h|1 +
 arch/arm64/include/asm/ptrace.h |7 +++
 arch/arm64/kernel/armv8_deprecated.c|   80 +++
 arch/arm64/kernel/signal32.c|5 +-
 6 files changed, 119 insertions(+), 1 deletion(-)

diff --git a/Documentation/arm64/legacy_instructions.txt 
b/Documentation/arm64/legacy_instructions.txt
index a3b3da2..01bf3d9 100644
--- a/Documentation/arm64/legacy_instructions.txt
+++ b/Documentation/arm64/legacy_instructions.txt
@@ -32,6 +32,9 @@ The default mode depends on the status of the instruction in 
the
 architecture. Deprecated instructions should default to emulation
 while obsolete instructions must be undefined by default.
 
+Note: Instruction emulation may not be possible in all cases. See
+individual instruction notes for further information.
+
 Supported legacy instructions
 -
 * SWP{B}
@@ -43,3 +46,12 @@ Default: Undef (0)
 Node: /proc/sys/abi/cp15_barrier
 Status: Deprecated
 Default: Emulate (1)
+
+* SETEND
+Node: /proc/sys/abi/setend
+Status: Deprecated
+Default: Emulate (1)*
+Note: All the cpus on the system must have mixed endian support at EL0
+for this feature to be enabled. If a new CPU - which doesn't support mixed
+endian - is hotplugged in after this feature has been enabled, there could
+be unexpected results in the application.
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b1f9a20..21a59bf 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -540,6 +540,21 @@ config CP15_BARRIER_EMULATION
 
  If unsure, say Y
 
+config SETEND_EMULATION
+   bool Emulate SETEND instruction
+   help
+ The SETEND instruction alters the data-endianness of the
+ AArch32 EL0, and is deprecated in ARMv8.
+
+ Say Y here to enable software emulation of the instruction
+ for AArch32 userspace code.
+
+ Note: All the cpus on the system must have mixed endian support at EL0
+ for this feature to be enabled. If a new CPU - which doesn't support 
mixed
+ endian - is hotplugged in after this feature has been enabled, there 
could
+ be unexpected results in the applications.
+
+ If unsure, say Y
 endif
 
 endmenu
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 2c4c852..241dd2f 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -83,6 +83,7 @@
(((mmfr0)  ID_AA64MMFR0_BIGEND_MASK)  ID_AA64MMFR0_BIGEND_SHIFT)
 
 #define SCTLR_EL1_CP15BEN  (0x1  5)
+#define SCTLR_EL1_SED  (0x1  8)
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 41ed9e1..d6dd9fd 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -58,6 +58,13 @@
 #define COMPAT_PSR_Z_BIT   0x4000
 #define COMPAT_PSR_N_BIT   0x8000
 #define COMPAT_PSR_IT_MASK 0x0600fc00  /* If-Then execution state mask 
*/
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define COMPAT_PSR_ENDSTATECOMPAT_PSR_E_BIT
+#else
+#define COMPAT_PSR_ENDSTATE0
+#endif
+
 /*
  * These are 'magic' values for PTRACE_PEEKUSR that return info about where a
  * process is located in memory.
diff --git a/arch/arm64/kernel/armv8_deprecated.c 
b/arch/arm64/kernel/armv8_deprecated.c
index 2c991f1..dea6f59 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -548,6 +548,79 @@ static struct insn_emulation_ops cp15_barrier_ops = {
.set_hw_mode = cp15_barrier_set_hw_mode,
 };
 
+static int setend_set_hw_mode(bool enable)
+{
+   if (!cpu_supports_mixed_endian_el0())
+   return

Re: [PATCHv2] perf/stat: Report unsupported events properly

2015-02-17 Thread Suzuki K. Poulose

On 13/02/15 20:50, Arnaldo Carvalho de Melo wrote:

Em Fri, Feb 13, 2015 at 12:39:24PM -0700, David Ahern escreveu:



On 02/13/2015 11:40 AM, Suzuki K. Poulose wrote:

From: Suzuki K. Poulose suzuki.poul...@arm.com

Commit 1971f59 (perf stat: Use read_counter in read_counter_aggr )
broke the perf stat output for unsupported counters.

  $ perf stat -v -a -C 0 -e CCI_400/config=24/ sleep 1
  Warning:
  CCI_400/config=24/ event is not supported by the kernel.

   Performance counter stats for 'system wide':

   0  CCI_400/config=24/

 1.080265400 seconds time elapsed

Where it used to be :

$ perf stat -v -a -C 0 -e CCI_400/config=24/ sleep 1
  Warning:
  CCI_400/config=24/ event is not supported by the kernel.

   Performance counter stats for 'system wide':

 not supported  CCI_400/config=24/

 1.083840675 seconds time elapsed

This patch fixes the issues by checking if the counter is supported,
before reading and logging the counter value.

Cc: Jiri Olsa jo...@kernel.org
Cc: Arnaldo Carvalho de Melo a...@redhat.com
Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
  tools/perf/builtin-stat.c |5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index e598e4e..d28949d 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -510,6 +510,9 @@ static int read_counter(struct perf_evsel *counter)
int ncpus = perf_evsel__nr_cpus(counter);
int cpu, thread;

+   if (!counter-supported)
+   return -ENOENT;
+
if (counter-system_wide)
nthreads = 1;

@@ -1285,7 +1288,7 @@ static void print_counter_aggr(struct perf_evsel 
*counter, char *prefix)
if (prefix)
fprintf(output, %s, prefix);

-   if (scaled == -1) {
+   if (scaled == -1 || !counter-supported) {
fprintf(output, %*s%s,
csv_output ? 0 : 18,
counter-supported ? CNTR_NOT_COUNTED : 
CNTR_NOT_SUPPORTED,



Just hit this as well.

Acked-and-Tested-by: David Ahern dsah...@gmail.com


Gack, 10ms after I sent my pre-California pull req :-\

Will go in the next one :-)
I think this may need to goto 3.19 stable series as well. Missed that. 
Do you want me to send it there ?


Cheers
Suzuki


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[Regression] 3.19-rc3 : memcg: Hang in mount memcg

2015-01-09 Thread Suzuki K. Poulose

Hi

We have hit a hang on ARM64 defconfig, while running LTP tests on 
3.19-rc3. We are

in the process of a git bisect and will update the results as and
when we find the commit.

During the ksm ltp run, the test hangs trying to mount memcg with the 
following strace

output:

mount(memcg, /dev/cgroup, cgroup, 0, memory) = ? ERESTARTNOINTR 
(To be restarted)
mount(memcg, /dev/cgroup, cgroup, 0, memory) = ? ERESTARTNOINTR 
(To be restarted)

[ ... repeated forever ... ]

At this point, one can try mounting the memcg to verify the problem.
# mount -t cgroup -o memory memcg memcg_dir
--hangs--

Strangely, if we run the mount command from a cold boot (i.e. without 
running LTP first),

then it succeeds.

Upon a quick look we are hitting the following code :
kernel/cgroup.c: cgroup_mount() :

1779 for_each_subsys(ss, i) {
1780 if (!(opts.subsys_mask  (1  i)) ||
1781 ss-root == cgrp_dfl_root)
1782 continue;
1783
1784 if 
(!percpu_ref_tryget_live(ss-root-cgrp.self.refcnt)) {

1785 mutex_unlock(cgroup_mutex);
1786 msleep(10);
1787 ret = restart_syscall(); =
1788 goto out_free;
1789 }
1790 cgroup_put(ss-root-cgrp);
1791 }

with ss-root-cgrp.self.refct.percpu_count_ptr == __PERCPU_REF_ATOMIC_DEAD

Any ideas?

Thanks
Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] arm64: mm: support instruction SETEND

2015-01-07 Thread Suzuki K. Poulose

On 07/01/15 05:52, Leo Yan wrote:

Currently kernel has set the bit SCTLR_EL1.SED, so the SETEND
instruction will be treated as UNALLOCATED; this error can be
reproduced when ARMv8 cpu runs with EL1/aarch64 and EL0/aarch32
mode, finally kernel will trap the exception if the userspace
libs use SETEND instruction.

So this patch clears bit SCTLR_EL1.SED to support SETEND instruction.

The best way to do this, is via the instruction emulation framework 
added by Punit, which handles the armv8 deprecated/obsoleted 
instructions. This is now queued for 3.19.
I have a patchset which adds the 'SETEND' emulation support to the 
framework. This will enable better handling of the feature, including 
finding out the users of the deprecated instruction (when we switch to 
the emulation mode).


Btw, there is one open question that I am seeking answer for.

What should be the endianness of the signal handlers ? Should we leave 
it to the application ? Or restore the 'default' endianness for the 
signal handler ?



Thanks
Suzuki



Signed-off-by: Leo Yan leo@linaro.org
Signed-off-by: Xiaolong Ye y...@marvell.com
---
  arch/arm64/mm/proc.S | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 4e778b1..66a7363 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -249,9 +249,9 @@ ENDPROC(__cpu_setup)
 *   CE0  XWHW CZ ME TEEA S
 *  .IEE  NEAI TE.I ..AD DEN0 ACAM
 * 0011 0... 1101 ..0. ..0. 10..    hardware reserved
-*  .1..  01.1 11.1 ..01 0001 1101  software settings
+*  .1..  01.1 11.1 ..00 0001 1101  software settings
 */
.type   crval, #object
  crval:
-   .word   0x000802e2  // clear
-   .word   0x0405d11d  // set
+   .word   0x000803e2  // clear
+   .word   0x0405d01d  // set




--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/2] arm64: Emulate SETEND for AArch32 tasks

2015-01-09 Thread Suzuki K. Poulose

On 08/01/15 18:43, Mark Rutland wrote:

Hi Suzuki,

On Wed, Jan 07, 2015 at 04:16:45PM +, Suzuki K. Poulose wrote:

From: Suzuki K. Poulose suzuki.poul...@arm.com

Emulate deprecated 'setend' instruction for AArch32 bit tasks.

setend [le/be] - Sets the endianness of EL0

The hardware support for the instruction can be enabled by setting the
SCTLR_EL1.SED bit. Like the other emulated instructions it is controlled by
an entry in /proc/sys/abi/. For more information see :
Documentation/arm64/legacy_instructions.txt

The instruction is emulated by setting/clearing the SPSR_EL1.E bit, which
will be reflected in the PSTATE.E in AArch32 context.


A fun problem with emulating setend is that it will not always work
unless we emulate the entire instruction set when userspace wants to be
in an unsupported endianness.

For implementations which are not bi-endian at EL0 (i.e. where
ID_AA64MMFR0_EL1.BigEndEL0 == 0), SCTLR_EL1.E0E has a fixed value which
we cannot change. The field names are misleading: in a BE-only system
ID_AA64MMFR0_EL1.{BigEnd,BigEndEL0} == {0,0} and SCTLR_EL1.{EE,E0E} are
fixed to {1,1}.

I think we need to detect when EL0 has a fixed endianness such that we
can treat the setend instruction as undefined. Otherwise we will
silently fail to change EL0 endianness, advance the PC, and return to
userspace in the wrong endianness, which will be very painful to debug.
Userspace has the option of handling the resulting SIGILL in such cases.


You are right. I missed this scenario. To add to that things get 
complicated when there are heterogeneous CPUs on the system that might 
have differing bits for BigEndEL0. I will take a look at this one. 
Thanks for pointing this out.


That means we need to be able to fail to transition into INSN_EMULATE
mode as we currently can when transitioning to INSN_HW.


This patch also restores the native endianness for the execution of signal
handlers, since the process could have changed the endianness.

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
  Documentation/arm64/legacy_instructions.txt |5 ++
  arch/arm64/Kconfig  |   10 
  arch/arm64/include/asm/ptrace.h |7 +++
  arch/arm64/kernel/armv8_deprecated.c|   75 +++
  arch/arm64/kernel/signal32.c|5 +-
  5 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/Documentation/arm64/legacy_instructions.txt 
b/Documentation/arm64/legacy_instructions.txt
index a3b3da2..20e5621 100644
--- a/Documentation/arm64/legacy_instructions.txt
+++ b/Documentation/arm64/legacy_instructions.txt
@@ -43,3 +43,8 @@ Default: Undef (0)
  Node: /proc/sys/abi/cp15_barrier
  Status: Deprecated
  Default: Emulate (1)
+
+* SETEND
+Node: /proc/sys/abi/setend
+Status: Deprecated
+Default: Emulate (1)


Given we can't always emulate SETEND, should we document Emulate where
possible or something to that effect?


Will fix it in the next revision.


diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b1f9a20..c6d1fd9 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -540,6 +540,16 @@ config CP15_BARRIER_EMULATION

  If unsure, say Y

+config SETEND_EMULATION
+   bool Emulate SETEND instruction
+   help
+ The SETEND instruction alters the data-endianness of the
+ AArch32 EL0, and is deprecated in ARMv8.
+
+ Say Y here to enable software emulation of the instruction
+ for AArch32 userspace code.
+
+ If unsure, say Y
  endif

  endmenu
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 41ed9e1..d6dd9fd 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -58,6 +58,13 @@
  #define COMPAT_PSR_Z_BIT  0x4000
  #define COMPAT_PSR_N_BIT  0x8000
  #define COMPAT_PSR_IT_MASK0x0600fc00  /* If-Then execution state mask 
*/
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define COMPAT_PSR_ENDSTATECOMPAT_PSR_E_BIT
+#else
+#define COMPAT_PSR_ENDSTATE0
+#endif
+
  /*
   * These are 'magic' values for PTRACE_PEEKUSR that return info about where a
   * process is located in memory.
diff --git a/arch/arm64/kernel/armv8_deprecated.c 
b/arch/arm64/kernel/armv8_deprecated.c
index 9054447..dc91bac 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -477,6 +477,7 @@ ret:
  }

  #define SCTLR_EL1_CP15BEN (1  5)
+#define SCTLR_EL1_SED  (1  8)

  static inline void config_sctlr_el1(u32 clear, u32 set)
  {
@@ -521,6 +522,77 @@ static struct insn_emulation_ops cp15_barrier_ops = {
.set_hw_mode = cp15_barrier_set_hw_mode,
  };

+static void setend_set_hw_mode(void *enable)
+{
+   if (enable)
+   config_sctlr_el1(SCTLR_EL1_SED, 0);
+   else
+   config_sctlr_el1(0, SCTLR_EL1_SED);
+}
+
+static int compat_setend_handler(struct pt_regs *regs, u32 endian)


If we s/endian/big_endian/ here we can

Re: [PATCH cgroup/for-3.19-fixes] cgroup: implement cgroup_subsys-unbind() callback

2015-01-14 Thread Suzuki K. Poulose

On 11/01/15 20:55, Johannes Weiner wrote:

On Sat, Jan 10, 2015 at 04:43:16PM -0500, Tejun Heo wrote:

Currently, if a hierarchy doesn't have any live children when it's
unmounted, the hierarchy starts dying by killing its refcnt.  The
expectation is that even if there are lingering dead children which
are lingering due to remaining references, they'll be put in a finite
amount of time.  When the children are finally released, the hierarchy
is destroyed and all controllers bound to it also are released.

However, for memcg, the premise that the lingering refs will be put in
a finite amount time is not true.  In the absense of memory pressure,
dead memcg's may hang around indefinitely pinned by its pages.  This
unfortunately may lead to indefinite hang on the next mount attempt
involving memcg as the mount logic waits for it to get released.

While we can change hierarchy destruction logic such that a hierarchy
is only destroyed when it's not mounted anywhere and all its children,
live or dead, are gone, this makes whether the hierarchy gets
destroyed or not to be determined by factors opaque to userland.
Userland may or may not get a new hierarchy on the next mount attempt.
Worse, if it explicitly wants to create a new hierarchy with different
options or controller compositions involving memcg, it will fail in an
essentially arbitrary manner.

We want to guarantee that a hierarchy is destroyed once the
conditions, unmounted and no visible children, are met.  To aid it,
this patch introduces a new callback cgroup_subsys-unbind() which is
invoked right before the hierarchy a subsystem is bound to starts
dying.  memcg can implement this callback and initiate draining of
remaining refs so that the hierarchy can eventually be released in a
finite amount of time.

Signed-off-by: Tejun Heo t...@kernel.org
Cc: Li Zefan lize...@huawei.com
Cc: Johannes Weiner han...@cmpxchg.org
Cc: Michal Hocko mho...@suse.cz
Cc: Vladimir Davydov vdavy...@parallels.com
---
Hello,


May be, we should kill the ref counter to the memory controller root in
cgroup_kill_sb only if there is no children at all, neither online nor
offline.


Ah, thanks for the analysis, but I really wanna avoid making hierarchy
destruction conditions opaque to userland.  This is userland visible
behavior.  It shouldn't be determined by kernel internals invisible
outside.  This patch adds ss-unbind() which memcg can hook into to
kick off draining of residual refs.  If this would work, I'll add this
patch to cgroup/for-3.19-fixes, possibly with stable cc'd.


How about this -unbind() for memcg?

 From d527ba1dbfdb58e1f7c7c4ee12b32ef2e5461990 Mon Sep 17 00:00:00 2001
From: Johannes Weiner han...@cmpxchg.org
Date: Sun, 11 Jan 2015 10:29:05 -0500
Subject: [patch] mm: memcontrol: zap outstanding cache/swap references during
  unbind

This patch doesn't cleanly apply on 3.19-rc4 for me (hunks in 
mm/memcontrol.c). I have manually applied it.


With these two patches in, I am still getting the failure. Also, the 
kworker thread is taking up 100% time (unbind_work) and continues to do 
so even after 6minutes.


Is there something I missed ?

Thanks
Suzuki





Cgroup core assumes that any outstanding css references after
offlining are temporary in nature, and e.g. mount waits for them to
disappear and release the root cgroup.  But leftover page cache and
swapout records in an offlined memcg are only dropped when the pages
get reclaimed under pressure or the swapped out pages get faulted in
from other cgroups, and so those cgroup operations can hang forever.

Implement the -unbind() callback to actively get rid of outstanding
references when cgroup core wants them gone.  Swap out records are
deleted, such that the swap-in path will charge those pages to the
faulting task.  Page cache pages are moved to the root memory cgroup.

Signed-off-by: Johannes Weiner han...@cmpxchg.org
---
  include/linux/swap_cgroup.h |   6 +++
  mm/memcontrol.c | 126 
  mm/swap_cgroup.c|  38 +
  3 files changed, 170 insertions(+)

diff --git a/include/linux/swap_cgroup.h b/include/linux/swap_cgroup.h
index 145306bdc92f..ffe0866d2997 100644
--- a/include/linux/swap_cgroup.h
+++ b/include/linux/swap_cgroup.h
@@ -9,6 +9,7 @@ extern unsigned short swap_cgroup_cmpxchg(swp_entry_t ent,
unsigned short old, unsigned short new);
  extern unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id);
  extern unsigned short lookup_swap_cgroup_id(swp_entry_t ent);
+extern unsigned long swap_cgroup_zap_records(unsigned short id);
  extern int swap_cgroup_swapon(int type, unsigned long max_pages);
  extern void swap_cgroup_swapoff(int type);

@@ -26,6 +27,11 @@ unsigned short lookup_swap_cgroup_id(swp_entry_t ent)
return 0;
  }

+static inline unsigned long swap_cgroup_zap_records(unsigned short id)
+{
+   return 0;
+}
+
  static inline int
  swap_cgroup_swapon(int 

Re: [Regression] 3.19-rc3 : memcg: Hang in mount memcg

2015-01-12 Thread Suzuki K. Poulose
On Fri, Jan 09, 2015 at 09:46:49PM +, Tejun Heo wrote:
 On Fri, Jan 09, 2015 at 05:43:17PM +, Suzuki K. Poulose wrote:
  We have hit a hang on ARM64 defconfig, while running LTP tests on 3.19-rc3.
  We are
  in the process of a git bisect and will update the results as and
  when we find the commit.
 
  During the ksm ltp run, the test hangs trying to mount memcg with the
  following strace
  output:
 
  mount(memcg, /dev/cgroup, cgroup, 0, memory) = ? ERESTARTNOINTR (To
  be restarted)
  mount(memcg, /dev/cgroup, cgroup, 0, memory) = ? ERESTARTNOINTR (To
  be restarted)
  [ ... repeated forever ... ]
 
  At this point, one can try mounting the memcg to verify the problem.
  # mount -t cgroup -o memory memcg memcg_dir
  --hangs--
 
  Strangely, if we run the mount command from a cold boot (i.e. without
  running LTP first),
  then it succeeds.

 I don't know what LTP is doing and this could actually be hitting on
 an actual bug but if it's trying to move memcg back from unified
 hierarchy to an old one, that might hang - it should prolly made to
 just fail at that point.  Anyways, any chance you can find out what
 happened, in terms of cgroup mounting, to memcg upto that point?


This is what the test(ksm03) does, roughly from strace :

faccessat(AT_FDCWD, /sys/kernel/mm/ksm/, F_OK) = 0
faccessat(AT_FDCWD, /sys/kernel/mm/ksm/merge_across_nodes, F_OK) = -1 ENOENT 
(No such file or directory)
mkdirat(AT_FDCWD, /dev/cgroup, 0777)  = 0
mount(memcg, /dev/cgroup, cgroup, 0, memory) = 0

--- set memory limit. Create a new set /dev/cgroups/1 and moves test to that 
group ---
mkdirat(AT_FDCWD, /dev/cgroup/1, 0777) = 0
openat(AT_FDCWD, /dev/cgroup/1/memory.limit_in_bytes, 
O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fstat(3, {st_dev=makedev(0, 24), st_ino=41, st_mode=S_IFREG|0644, st_nlink=1, 
st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=0, 
st_atime=2015/01/12-15:10:13, st_mtime=2015/01/12-15:10:13, 
st_ctime=2015/01/12-15:10:13}) = 0
mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 
0x7fb2903000
write(3, 1073741824, 10)  = 10
close(3)= 0
munmap(0x7fb2903000, 65536) = 0
getpid()= 1324
openat(AT_FDCWD, /dev/cgroup/1/tasks, O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fstat(3, {st_dev=makedev(0, 24), st_ino=37, st_mode=S_IFREG|0644, st_nlink=1, 
st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=0, 
st_atime=2015/01/12-15:10:13, st_mtime=2015/01/12-15:10:13, 
st_ctime=2015/01/12-15:10:13}) = 0
mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 
0x7fb2903000
write(3, 1324, 4) = 4
close(3)= 0
munmap(0x7fb2903000, 65536) = 0

clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, 
child_tidptr=0x7fb2a7f0d0) = 1325
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, 
child_tidptr=0x7fb2a7f0d0) = 1326
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, 
child_tidptr=0x7fb2a7f0d0) = 1327

--- Creates 3 children, perform a lot of memory operations with shared pages
verify the ksm for activity and wait for children to exit ---

wait4(-1, [{WIFEXITED(s)  WEXITSTATUS(s) == 0}], WSTOPPED|WCONTINUED, NULL) = 
1325
wait4(-1, [{WIFEXITED(s)  WEXITSTATUS(s) == 0}], WSTOPPED|WCONTINUED, NULL) = 
1326
wait4(-1, [{WIFEXITED(s)  WEXITSTATUS(s) == 0}], WSTOPPED|WCONTINUED, NULL) = 
1327
wait4(-1, 0x7fe5625f3c, WSTOPPED|WCONTINUED, NULL) = -1 ECHILD (No child 
processes)

--- cleanup: Move tasks under /dev/cgroups/1/ to /dev/cgroups/ and delete 
subdir, umount cgroup ---

faccessat(AT_FDCWD, /sys/kernel/mm/ksm/merge_across_nodes, F_OK) = -1 ENOENT 
(No such file or directory)
openat(AT_FDCWD, /dev/cgroup/tasks, O_WRONLY) = 205
openat(AT_FDCWD, /dev/cgroup/1/tasks, O_RDONLY) = 206
fstat(206, {st_dev=makedev(0, 24), st_ino=37, st_mode=S_IFREG|0644, st_nlink=1, 
st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=0, 
st_atime=2015/01/12-15:10:13, st_mtime=2015/01/12-15:10:13, 
st_ctime=2015/01/12-15:10:13}) = 0
mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 
0x7fb1c53000
read(206, 1324\n, 4096)   = 5
write(205, 1324, 4)   = 4
read(206, , 4096) = 0
close(205)  = 0
close(206)  = 0
munmap(0x7fb1c53000, 65536) = 0
unlinkat(AT_FDCWD, /dev/cgroup/1, AT_REMOVEDIR) = 0
umount2(/dev/cgroup, 0)   = 0
unlinkat(AT_FDCWD, /dev/cgroup, AT_REMOVEDIR) = 0
exit_group(0)   = ?


The next invocation of the same test fails to mount the cgroup memory.

Thanks
Suzuki

 Thanks.

 --
 tejun


-- IMPORTANT NOTICE: The contents of this email and any attachments are 
confidential and may also be privileged. If you are not the intended recipient, 
please notify the sender immediately and do

[PATCHv2] perf/stat: Report unsupported events properly

2015-02-13 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

Commit 1971f59 (perf stat: Use read_counter in read_counter_aggr )
broke the perf stat output for unsupported counters.

 $ perf stat -v -a -C 0 -e CCI_400/config=24/ sleep 1
 Warning:
 CCI_400/config=24/ event is not supported by the kernel.

  Performance counter stats for 'system wide':

  0  CCI_400/config=24/

1.080265400 seconds time elapsed

Where it used to be :

$ perf stat -v -a -C 0 -e CCI_400/config=24/ sleep 1
 Warning:
 CCI_400/config=24/ event is not supported by the kernel.

  Performance counter stats for 'system wide':

not supported  CCI_400/config=24/

1.083840675 seconds time elapsed

This patch fixes the issues by checking if the counter is supported,
before reading and logging the counter value.

Cc: Jiri Olsa jo...@kernel.org
Cc: Arnaldo Carvalho de Melo a...@redhat.com
Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 tools/perf/builtin-stat.c |5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index e598e4e..d28949d 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -510,6 +510,9 @@ static int read_counter(struct perf_evsel *counter)
int ncpus = perf_evsel__nr_cpus(counter);
int cpu, thread;
 
+   if (!counter-supported)
+   return -ENOENT;
+
if (counter-system_wide)
nthreads = 1;
 
@@ -1285,7 +1288,7 @@ static void print_counter_aggr(struct perf_evsel 
*counter, char *prefix)
if (prefix)
fprintf(output, %s, prefix);
 
-   if (scaled == -1) {
+   if (scaled == -1 || !counter-supported) {
fprintf(output, %*s%s,
csv_output ? 0 : 18,
counter-supported ? CNTR_NOT_COUNTED : 
CNTR_NOT_SUPPORTED,
-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/2] arm64: Emulate SETEND for AArch32 tasks

2015-01-07 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

Emulate deprecated 'setend' instruction for AArch32 bit tasks.

setend [le/be] - Sets the endianness of EL0

The hardware support for the instruction can be enabled by setting the
SCTLR_EL1.SED bit. Like the other emulated instructions it is controlled by
an entry in /proc/sys/abi/. For more information see :
Documentation/arm64/legacy_instructions.txt

The instruction is emulated by setting/clearing the SPSR_EL1.E bit, which
will be reflected in the PSTATE.E in AArch32 context.

This patch also restores the native endianness for the execution of signal
handlers, since the process could have changed the endianness.

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 Documentation/arm64/legacy_instructions.txt |5 ++
 arch/arm64/Kconfig  |   10 
 arch/arm64/include/asm/ptrace.h |7 +++
 arch/arm64/kernel/armv8_deprecated.c|   75 +++
 arch/arm64/kernel/signal32.c|5 +-
 5 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/Documentation/arm64/legacy_instructions.txt 
b/Documentation/arm64/legacy_instructions.txt
index a3b3da2..20e5621 100644
--- a/Documentation/arm64/legacy_instructions.txt
+++ b/Documentation/arm64/legacy_instructions.txt
@@ -43,3 +43,8 @@ Default: Undef (0)
 Node: /proc/sys/abi/cp15_barrier
 Status: Deprecated
 Default: Emulate (1)
+
+* SETEND
+Node: /proc/sys/abi/setend
+Status: Deprecated
+Default: Emulate (1)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b1f9a20..c6d1fd9 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -540,6 +540,16 @@ config CP15_BARRIER_EMULATION
 
  If unsure, say Y
 
+config SETEND_EMULATION
+   bool Emulate SETEND instruction
+   help
+ The SETEND instruction alters the data-endianness of the
+ AArch32 EL0, and is deprecated in ARMv8.
+
+ Say Y here to enable software emulation of the instruction
+ for AArch32 userspace code.
+
+ If unsure, say Y
 endif
 
 endmenu
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 41ed9e1..d6dd9fd 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -58,6 +58,13 @@
 #define COMPAT_PSR_Z_BIT   0x4000
 #define COMPAT_PSR_N_BIT   0x8000
 #define COMPAT_PSR_IT_MASK 0x0600fc00  /* If-Then execution state mask 
*/
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define COMPAT_PSR_ENDSTATECOMPAT_PSR_E_BIT
+#else
+#define COMPAT_PSR_ENDSTATE0
+#endif
+
 /*
  * These are 'magic' values for PTRACE_PEEKUSR that return info about where a
  * process is located in memory.
diff --git a/arch/arm64/kernel/armv8_deprecated.c 
b/arch/arm64/kernel/armv8_deprecated.c
index 9054447..dc91bac 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -477,6 +477,7 @@ ret:
 }
 
 #define SCTLR_EL1_CP15BEN  (1  5)
+#define SCTLR_EL1_SED  (1  8)
 
 static inline void config_sctlr_el1(u32 clear, u32 set)
 {
@@ -521,6 +522,77 @@ static struct insn_emulation_ops cp15_barrier_ops = {
.set_hw_mode = cp15_barrier_set_hw_mode,
 };
 
+static void setend_set_hw_mode(void *enable)
+{
+   if (enable)
+   config_sctlr_el1(SCTLR_EL1_SED, 0);
+   else
+   config_sctlr_el1(0, SCTLR_EL1_SED);
+}
+
+static int compat_setend_handler(struct pt_regs *regs, u32 endian)
+{
+   char insn[16] = setend _e;
+
+   perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs-pc);
+
+   if (endian) {
+   /* Big Endian */
+   insn[7] = 'b';
+   regs-pstate |= COMPAT_PSR_E_BIT;
+   } else {
+   /* Little Endian */
+   insn[7] = 'l';
+   regs-pstate = ~COMPAT_PSR_E_BIT;
+   }
+
+   trace_instruction_emulation(insn, regs-pc);
+   pr_warn_ratelimited(\%s\ (%ld) uses deprecated setend instruction at 
0x%llx\n,
+   current-comm, (unsigned long)current-pid, regs-pc);
+
+   return 0;
+}
+
+static int a32_setend_handler(struct pt_regs *regs, u32 instr)
+{
+   int rc = compat_setend_handler(regs, (instr  9)  1);
+   regs-pc += 4;
+   return rc;
+}
+
+static int t16_setend_handler(struct pt_regs *regs, u32 instr)
+{
+   int rc = compat_setend_handler(regs, (instr  3)  1);
+   regs-pc += 2;
+   return rc;
+}
+
+static struct undef_hook setend_hooks[] = {
+   {
+   .instr_mask = 0xfdff,
+   .instr_val  = 0xf101,
+   .pstate_mask= COMPAT_PSR_MODE_MASK,
+   .pstate_val = COMPAT_PSR_MODE_USR,
+   .fn = a32_setend_handler,
+   },
+   {
+   /* Thumb mode */
+   .instr_mask = 0xfff7,
+   .instr_val  = 0xb650,
+   .pstate_mask= (COMPAT_PSR_T_BIT

[PATCH 0/2] Support deprecated SETEND instruction for AArch32

2015-01-07 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

This series add support for controlling the 'setend' instruction,
which is deprecated in ARMv8, using the legacy instruction emulation
framework, introduced by Punit Agrawal.

Patch 1 re-organises the infrastructure a little bit to avoid multiple
CPU hotplug notifiers.

Patch 2 adds the support for SETEND.

Testing :

 $ cat setend_sig.c 
 #include stdio.h
 #include signal.h

 #define setend_be(a)   asm __volatile__ ( setend be ::: memory )
 #define setend_le(a)   asm __volatile__ ( setend le ::: memory )

 volatile int flag = 1;

 void sigint(int sig)
 {
printf(in sighandler %d\n, sig);
flag = 0;
return;
 }

 main()
 {
volatile int a = 0x0;

(void)signal(SIGINT, sigint);
printf(Press Ctrl+C to continue\n);
setend_be();
a ++;

while (flag);

setend_le();
a ++;

printf(a: 0x%x\n, a);
return 0;
 }
 $ cat /proc/sys/abi/setend 
 1
 $ echo 1  
/sys/kernel/debug/tracing/events/emulation/instruction_emulation/enable 
 $ echo 1  /sys/kernel/debug/tracing/tracing_on 
 $ ./setend_sig_a32 
 Press Ctrl+C to continue
 ^Cin sighandler 2
 a: 0x101
 $ cat /sys/kernel/debug/tracing/trace
 # tracer: nop
 #
 # entries-in-buffer/entries-written: 2/2   #P:2
 #
 #  _-= irqs-off
 # / _= need-resched
 #| / _---= hardirq/softirq
 #|| / _--= preempt-depth
 #||| / delay
 #   TASK-PID   CPU#  TIMESTAMP  FUNCTION
 #  | |   |      | |
   setend_sig_a32-1373  [000] ...1   491.554499: instruction_emulation: 
instr=setend be addr=0x8460
   setend_sig_a32-1373  [000] ...1   492.833056: instruction_emulation: 
instr=setend le addr=0x8488
 $ dmesg | tail
 [  491.554807] setend_sig_a32 (1373) uses deprecated setend instruction at 
0x8460
 [  492.833285] setend_sig_a32 (1373) uses deprecated setend instruction at 
0x8488
 $ echo 2  /proc/sys/abi/setend
 $ ./setend_sig_t16 
 Press Ctrl+C to continue
 ^Cin sighandler 2
 a: 0x101
 $ dmesg | tail
 [  491.554807] setend_sig_a32 (1373) uses deprecated setend instruction at 
0x8460
 [  492.833285] setend_sig_a32 (1373) uses deprecated setend instruction at 
0x8488
 [  537.426216] Removed setend emulation handler
 [  537.426624] Enabled setend support
 ---

Suzuki K. Poulose (2):
  arm64: Consolidate hotplug notifier for instruction emulation
  arm64: Emulate SETEND for AArch32 tasks

 Documentation/arm64/legacy_instructions.txt |5 +
 arch/arm64/Kconfig  |   10 ++
 arch/arm64/include/asm/ptrace.h |7 ++
 arch/arm64/kernel/armv8_deprecated.c|  174 +++
 arch/arm64/kernel/signal32.c|5 +-
 5 files changed, 151 insertions(+), 50 deletions(-)

-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/2] arm64: Consolidate hotplug notifier for instruction emulation

2015-01-07 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

As of now each insn_emulation has a cpu hotplug notifier that
enables/disables the CPU feature bit for the functionality. This
patch re-arranges the code, such that there is only one notifier
that runs through the list of registered emulation hooks and runs
their corresponding set_hw_mode.

We do nothing when a CPU is dying as we will set the appropriate bits
when it comes back online based on the state of the hooks.

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
Signed-off-by: Mark Rutland mark.rutl...@arm.com
---
 arch/arm64/kernel/armv8_deprecated.c |   99 +-
 1 file changed, 50 insertions(+), 49 deletions(-)

diff --git a/arch/arm64/kernel/armv8_deprecated.c 
b/arch/arm64/kernel/armv8_deprecated.c
index c363671..9054447 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -46,7 +46,7 @@ struct insn_emulation_ops {
const char  *name;
enum legacy_insn_status status;
struct undef_hook   *hooks;
-   int (*set_hw_mode)(bool enable);
+   void(*set_hw_mode)(void *enable);
 };
 
 struct insn_emulation {
@@ -85,6 +85,30 @@ static void remove_emulation_hooks(struct insn_emulation_ops 
*ops)
pr_notice(Removed %s emulation handler\n, ops-name);
 }
 
+/* Run set_hw_mode(action) on all active CPUs */
+static int run_all_cpu_set_hw_mode(struct insn_emulation *insn, bool action)
+{
+   if (!insn-ops-set_hw_mode)
+   return -EINVAL;
+   on_each_cpu(insn-ops-set_hw_mode, (void *)action, true);
+   return 0;
+}
+
+/* Run set_hw_mode for all insns on a starting CPU */
+static void run_all_insn_set_hw_mode(void)
+{
+   unsigned long flags;
+   struct insn_emulation *insn;
+
+   raw_spin_lock_irqsave(insn_emulation_lock, flags);
+   list_for_each_entry(insn, insn_emulation, node) {
+   bool hw_mode = (insn-current_mode == INSN_HW);
+   if (insn-ops-set_hw_mode)
+   insn-ops-set_hw_mode((void *)hw_mode);
+   }
+   raw_spin_unlock_irqrestore(insn_emulation_lock, flags);
+}
+
 static int update_insn_emulation_mode(struct insn_emulation *insn,
   enum insn_emulation_mode prev)
 {
@@ -97,10 +121,8 @@ static int update_insn_emulation_mode(struct insn_emulation 
*insn,
remove_emulation_hooks(insn-ops);
break;
case INSN_HW:
-   if (insn-ops-set_hw_mode) {
-   insn-ops-set_hw_mode(false);
+   if (!run_all_cpu_set_hw_mode(insn, false))
pr_notice(Disabled %s support\n, insn-ops-name);
-   }
break;
}
 
@@ -111,10 +133,9 @@ static int update_insn_emulation_mode(struct 
insn_emulation *insn,
register_emulation_hooks(insn-ops);
break;
case INSN_HW:
-   if (insn-ops-set_hw_mode  insn-ops-set_hw_mode(true))
+   ret = run_all_cpu_set_hw_mode(insn, true);
+   if (!ret)
pr_notice(Enabled %s support\n, insn-ops-name);
-   else
-   ret = -EINVAL;
break;
}
 
@@ -133,6 +154,8 @@ static void register_insn_emulation(struct 
insn_emulation_ops *ops)
switch (ops-status) {
case INSN_DEPRECATED:
insn-current_mode = INSN_EMULATE;
+   /* Disable the HW mode if it was turned on at early boot time */
+   run_all_cpu_set_hw_mode(insn, false);
insn-max = INSN_HW;
break;
case INSN_OBSOLETE:
@@ -453,7 +476,7 @@ ret:
return 0;
 }
 
-#define SCTLR_EL1_CP15BEN (1  5)
+#define SCTLR_EL1_CP15BEN  (1  5)
 
 static inline void config_sctlr_el1(u32 clear, u32 set)
 {
@@ -465,48 +488,12 @@ static inline void config_sctlr_el1(u32 clear, u32 set)
asm volatile(msr sctlr_el1, %0 : : r (val));
 }
 
-static void enable_cp15_ben(void *info)
+static void cp15_barrier_set_hw_mode(void *enable)
 {
-   config_sctlr_el1(0, SCTLR_EL1_CP15BEN);
-}
-
-static void disable_cp15_ben(void *info)
-{
-   config_sctlr_el1(SCTLR_EL1_CP15BEN, 0);
-}
-
-static int cpu_hotplug_notify(struct notifier_block *b,
- unsigned long action, void *hcpu)
-{
-   switch (action) {
-   case CPU_STARTING:
-   case CPU_STARTING_FROZEN:
-   enable_cp15_ben(NULL);
-   return NOTIFY_DONE;
-   case CPU_DYING:
-   case CPU_DYING_FROZEN:
-   disable_cp15_ben(NULL);
-   return NOTIFY_DONE;
-   }
-
-   return NOTIFY_OK;
-}
-
-static struct notifier_block cpu_hotplug_notifier = {
-   .notifier_call = cpu_hotplug_notify,
-};
-
-static int cp15_barrier_set_hw_mode(bool enable)
-{
-   if (enable) {
-   register_cpu_notifier

Re: [PATCHv3 0/5] arm-cci400: PMU monitoring support on ARM64

2015-03-18 Thread Suzuki K. Poulose

On 17/03/15 18:54, Will Deacon wrote:

On Tue, Mar 10, 2015 at 03:18:50PM +, Suzuki K. Poulose wrote:

From: Suzuki K. Poulose suzuki.poul...@arm.com

This series enables the PMU monitoring support for CCI400 on ARM64.
The existing CCI400 driver code is a mix of PMU driver and the MCPM
driver code. The MCPM driver is only used on ARM(32) and contains
arm32 assembly and hence can't be built on ARM64. This patch splits
the code to

  - ARM_CCI400_PORT_CTRL driver - depends on ARM  V7
  - ARM_CCI400_PMU driver


If you repost this with acks added and my feedback addressed, then I'm
happy to put together a branch for arm-soc along with your other CCI PMU
fix for event validation.


Sure, I will do that.

Thanks
Suzuki



Will




--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/5] arm-cci: Abstract the CCI400 PMU speicific definitions

2015-03-18 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

CCI400 has different event specifications for PMU, for revsion
0 and revision 1. As of now, we check the revision every single
time before using the parameters for the PMU. This patch abstracts
the details of the pmu models in a struct (cci_pmu_model) and
stores the information in cci_pmu at initialisation time, avoiding
multiple probe operations.

Changes since V2:
 - Cleanup event validation(pmu_validate_hw_event). Get rid of
   helper functions:
pmu_is_valid_slave_event
pmu_is_valid_master_event

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
Tested-by: Sudeep Holla sudeep.ho...@arm.com
Acked-by: Punit Agrawal punit.agra...@arm.com
Reviewed-by: Will Deacon will.dea...@arm.com
---
 drivers/bus/arm-cci.c |  141 -
 1 file changed, 81 insertions(+), 60 deletions(-)

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 5d29ec3..ae3864d 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -79,19 +79,38 @@ static const struct of_device_id arm_cci_matches[] = {
 
 #define CCI_PMU_MAX_HW_EVENTS 5   /* CCI PMU has 4 counters + 1 cycle counter 
*/
 
+/* Types of interfaces that can generate events */
+enum {
+   CCI_IF_SLAVE,
+   CCI_IF_MASTER,
+   CCI_IF_MAX,
+};
+
+struct event_range {
+   u32 min;
+   u32 max;
+};
+
 struct cci_pmu_hw_events {
struct perf_event *events[CCI_PMU_MAX_HW_EVENTS];
unsigned long used_mask[BITS_TO_LONGS(CCI_PMU_MAX_HW_EVENTS)];
raw_spinlock_t pmu_lock;
 };
 
+struct cci_pmu_model {
+   char *name;
+   struct event_range event_ranges[CCI_IF_MAX];
+};
+
+static struct cci_pmu_model cci_pmu_models[];
+
 struct cci_pmu {
void __iomem *base;
struct pmu pmu;
int nr_irqs;
int irqs[CCI_PMU_MAX_HW_EVENTS];
unsigned long active_irqs;
-   struct pmu_port_event_ranges *port_ranges;
+   const struct cci_pmu_model *model;
struct cci_pmu_hw_events hw_events;
struct platform_device *plat_device;
int num_events;
@@ -152,53 +171,11 @@ enum cci400_perf_events {
 #define CCI_REV_R1_MASTER_PORT_MIN_EV  0x00
 #define CCI_REV_R1_MASTER_PORT_MAX_EV  0x11
 
-struct pmu_port_event_ranges {
-   u8 slave_min;
-   u8 slave_max;
-   u8 master_min;
-   u8 master_max;
-};
-
-static struct pmu_port_event_ranges port_event_range[] = {
-   [CCI_REV_R0] = {
-   .slave_min = CCI_REV_R0_SLAVE_PORT_MIN_EV,
-   .slave_max = CCI_REV_R0_SLAVE_PORT_MAX_EV,
-   .master_min = CCI_REV_R0_MASTER_PORT_MIN_EV,
-   .master_max = CCI_REV_R0_MASTER_PORT_MAX_EV,
-   },
-   [CCI_REV_R1] = {
-   .slave_min = CCI_REV_R1_SLAVE_PORT_MIN_EV,
-   .slave_max = CCI_REV_R1_SLAVE_PORT_MAX_EV,
-   .master_min = CCI_REV_R1_MASTER_PORT_MIN_EV,
-   .master_max = CCI_REV_R1_MASTER_PORT_MAX_EV,
-   },
-};
-
-/*
- * Export different PMU names for the different revisions so userspace knows
- * because the event ids are different
- */
-static char *const pmu_names[] = {
-   [CCI_REV_R0] = CCI_400,
-   [CCI_REV_R1] = CCI_400_r1,
-};
-
-static int pmu_is_valid_slave_event(u8 ev_code)
-{
-   return pmu-port_ranges-slave_min = ev_code 
-   ev_code = pmu-port_ranges-slave_max;
-}
-
-static int pmu_is_valid_master_event(u8 ev_code)
-{
-   return pmu-port_ranges-master_min = ev_code 
-   ev_code = pmu-port_ranges-master_max;
-}
-
 static int pmu_validate_hw_event(u8 hw_event)
 {
u8 ev_source = CCI_PMU_EVENT_SOURCE(hw_event);
u8 ev_code = CCI_PMU_EVENT_CODE(hw_event);
+   int if_type;
 
switch (ev_source) {
case CCI_PORT_S0:
@@ -207,18 +184,22 @@ static int pmu_validate_hw_event(u8 hw_event)
case CCI_PORT_S3:
case CCI_PORT_S4:
/* Slave Interface */
-   if (pmu_is_valid_slave_event(ev_code))
-   return hw_event;
+   if_type = CCI_IF_SLAVE;
break;
case CCI_PORT_M0:
case CCI_PORT_M1:
case CCI_PORT_M2:
/* Master Interface */
-   if (pmu_is_valid_master_event(ev_code))
-   return hw_event;
+   if_type = CCI_IF_MASTER;
break;
+   default:
+   return -ENOENT;
}
 
+   if (ev_code = pmu-model-event_ranges[if_type].min 
+   ev_code = pmu-model-event_ranges[if_type].max)
+   return hw_event;
+
return -ENOENT;
 }
 
@@ -234,11 +215,9 @@ static int probe_cci_revision(void)
return CCI_REV_R1;
 }
 
-static struct pmu_port_event_ranges *port_range_by_rev(void)
+static const struct cci_pmu_model *probe_cci_model(struct platform_device 
*pdev)
 {
-   int rev = probe_cci_revision();
-
-   return port_event_range[rev];
+   return cci_pmu_models

[PATCH 1/5] arm-cci: Rearrange code for splitting PMU vs driver code

2015-03-18 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

No functional changes, only code re-arrangements for easier split of the
PMU code vs low level driver code. Extracts the port handling code
to cci_probe_ports().

Change since V2:
 - Removed unnecessary goto. (Suggested-by: Sudeep Holla)

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
Tested-by: Sudeep Holla sudeep.ho...@arm.com
Acked-by: Nicolas Pitre nicolas.pi...@linaro.org
Acked-by: Punit Agrawal punit.agra...@arm.com
---
 drivers/bus/arm-cci.c |  326 -
 1 file changed, 163 insertions(+), 163 deletions(-)

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 68ef6f2..5d29ec3 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -29,42 +29,29 @@
 #include asm/cacheflush.h
 #include asm/smp_plat.h
 
-#define DRIVER_NAMECCI-400
-#define DRIVER_NAME_PMUDRIVER_NAME  PMU
-
-#define CCI_PORT_CTRL  0x0
-#define CCI_CTRL_STATUS0xc
-
-#define CCI_ENABLE_SNOOP_REQ   0x1
-#define CCI_ENABLE_DVM_REQ 0x2
-#define CCI_ENABLE_REQ (CCI_ENABLE_SNOOP_REQ | CCI_ENABLE_DVM_REQ)
+static void __iomem *cci_ctrl_base;
+static unsigned long cci_ctrl_phys;
 
 struct cci_nb_ports {
unsigned int nb_ace;
unsigned int nb_ace_lite;
 };
 
-enum cci_ace_port_type {
-   ACE_INVALID_PORT = 0x0,
-   ACE_PORT,
-   ACE_LITE_PORT,
+static const struct cci_nb_ports cci400_ports = {
+   .nb_ace = 2,
+   .nb_ace_lite = 3
 };
 
-struct cci_ace_port {
-   void __iomem *base;
-   unsigned long phys;
-   enum cci_ace_port_type type;
-   struct device_node *dn;
+static const struct of_device_id arm_cci_matches[] = {
+   {.compatible = arm,cci-400, .data = cci400_ports },
+   {},
 };
 
-static struct cci_ace_port *ports;
-static unsigned int nb_cci_ports;
-
-static void __iomem *cci_ctrl_base;
-static unsigned long cci_ctrl_phys;
-
 #ifdef CONFIG_HW_PERF_EVENTS
 
+#define DRIVER_NAMECCI-400
+#define DRIVER_NAME_PMUDRIVER_NAME  PMU
+
 #define CCI_PMCR   0x0100
 #define CCI_PID2   0x0fe8
 
@@ -75,6 +62,47 @@ static unsigned long cci_ctrl_phys;
 #define CCI_PID2_REV_MASK  0xf0
 #define CCI_PID2_REV_SHIFT 4
 
+#define CCI_PMU_EVT_SEL0x000
+#define CCI_PMU_CNTR   0x004
+#define CCI_PMU_CNTR_CTRL  0x008
+#define CCI_PMU_OVRFLW 0x00c
+
+#define CCI_PMU_OVRFLW_FLAG1
+
+#define CCI_PMU_CNTR_BASE(idx) ((idx) * SZ_4K)
+
+#define CCI_PMU_CNTR_MASK  ((1ULL  32) -1)
+
+#define CCI_PMU_EVENT_MASK 0xff
+#define CCI_PMU_EVENT_SOURCE(event)((event  5)  0x7)
+#define CCI_PMU_EVENT_CODE(event)  (event  0x1f)
+
+#define CCI_PMU_MAX_HW_EVENTS 5   /* CCI PMU has 4 counters + 1 cycle counter 
*/
+
+struct cci_pmu_hw_events {
+   struct perf_event *events[CCI_PMU_MAX_HW_EVENTS];
+   unsigned long used_mask[BITS_TO_LONGS(CCI_PMU_MAX_HW_EVENTS)];
+   raw_spinlock_t pmu_lock;
+};
+
+struct cci_pmu {
+   void __iomem *base;
+   struct pmu pmu;
+   int nr_irqs;
+   int irqs[CCI_PMU_MAX_HW_EVENTS];
+   unsigned long active_irqs;
+   struct pmu_port_event_ranges *port_ranges;
+   struct cci_pmu_hw_events hw_events;
+   struct platform_device *plat_device;
+   int num_events;
+   atomic_t active_events;
+   struct mutex reserve_mutex;
+   cpumask_t cpus;
+};
+static struct cci_pmu *pmu;
+
+#define to_cci_pmu(c)  (container_of(c, struct cci_pmu, pmu))
+
 /* Port ids */
 #define CCI_PORT_S00
 #define CCI_PORT_S11
@@ -89,17 +117,6 @@ static unsigned long cci_ctrl_phys;
 #define CCI_REV_R1 1
 #define CCI_REV_R1_PX  5
 
-#define CCI_PMU_EVT_SEL0x000
-#define CCI_PMU_CNTR   0x004
-#define CCI_PMU_CNTR_CTRL  0x008
-#define CCI_PMU_OVRFLW 0x00c
-
-#define CCI_PMU_OVRFLW_FLAG1
-
-#define CCI_PMU_CNTR_BASE(idx) ((idx) * SZ_4K)
-
-#define CCI_PMU_CNTR_MASK  ((1ULL  32) -1)
-
 /*
  * Instead of an event id to monitor CCI cycles, a dedicated counter is
  * provided. Use 0xff to represent CCI cycles and hope that no future revisions
@@ -109,12 +126,6 @@ enum cci400_perf_events {
CCI_PMU_CYCLES = 0xff
 };
 
-#define CCI_PMU_EVENT_MASK 0xff
-#define CCI_PMU_EVENT_SOURCE(event)((event  5)  0x7)
-#define CCI_PMU_EVENT_CODE(event)  (event  0x1f)
-
-#define CCI_PMU_MAX_HW_EVENTS 5   /* CCI PMU has 4 counters + 1 cycle counter 
*/
-
 #define CCI_PMU_CYCLE_CNTR_IDX 0
 #define CCI_PMU_CNTR0_IDX  1
 #define CCI_PMU_CNTR_LAST(cci_pmu) (CCI_PMU_CYCLE_CNTR_IDX + 
cci_pmu-num_events - 1)
@@ -172,60 +183,6 @@ static char *const pmu_names[] = {
[CCI_REV_R1] = CCI_400_r1,
 };
 
-struct cci_pmu_hw_events {
-   struct perf_event *events[CCI_PMU_MAX_HW_EVENTS];
-   unsigned long used_mask[BITS_TO_LONGS(CCI_PMU_MAX_HW_EVENTS)];
-   raw_spinlock_t

[PATCH 5/5] arm-cci: Fix CCI PMU event validation

2015-03-18 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

We mask the event with the CCI_PMU_EVENT_MASK, before passing
the config to pmu_validate_hw_event(), which causes extra bits
to be ignored and qualifies an invalid event code as valid.

e.g,
 $ perf stat -a -C 0 -e CCI_400/config=0x1ff,name=cycles/ sleep 1
   Performance counter stats for 'system wide':

 506951142  cycles

   1.013879626 seconds time elapsed

where, cycles has an event coding of 0xff. This patch also removes
the unnecessary 'event' mask in pmu_write_register, since the config_base
is set by the pmu code after the event is validated.

Changes since V3:
 - Fix type for CCI_PMU_EVENT_MASK - Suggested-by: Will Deacon.

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
Acked-by: Punit Agrawal punit.agra...@arm.com
Reviewed-by: Will Deacon will.dea...@arm.com
---
 drivers/bus/arm-cci.c |   12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 054df84..b854125 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -81,7 +81,7 @@ static const struct of_device_id arm_cci_matches[] = {
 
 #define CCI_PMU_CNTR_MASK  ((1ULL  32) -1)
 
-#define CCI_PMU_EVENT_MASK 0xff
+#define CCI_PMU_EVENT_MASK 0xffUL
 #define CCI_PMU_EVENT_SOURCE(event)((event  5)  0x7)
 #define CCI_PMU_EVENT_CODE(event)  (event  0x1f)
 
@@ -179,12 +179,15 @@ enum cci400_perf_events {
 #define CCI_REV_R1_MASTER_PORT_MIN_EV  0x00
 #define CCI_REV_R1_MASTER_PORT_MAX_EV  0x11
 
-static int pmu_validate_hw_event(u8 hw_event)
+static int pmu_validate_hw_event(unsigned long hw_event)
 {
u8 ev_source = CCI_PMU_EVENT_SOURCE(hw_event);
u8 ev_code = CCI_PMU_EVENT_CODE(hw_event);
int if_type;
 
+   if (hw_event  ~CCI_PMU_EVENT_MASK)
+   return -ENOENT;
+
switch (ev_source) {
case CCI_PORT_S0:
case CCI_PORT_S1:
@@ -258,7 +261,6 @@ static void pmu_enable_counter(int idx)
 
 static void pmu_set_event(int idx, unsigned long event)
 {
-   event = CCI_PMU_EVENT_MASK;
pmu_write_register(event, idx, CCI_PMU_EVT_SEL);
 }
 
@@ -275,7 +277,7 @@ static int pmu_get_event_idx(struct cci_pmu_hw_events *hw, 
struct perf_event *ev
 {
struct cci_pmu *cci_pmu = to_cci_pmu(event-pmu);
struct hw_perf_event *hw_event = event-hw;
-   unsigned long cci_event = hw_event-config_base  CCI_PMU_EVENT_MASK;
+   unsigned long cci_event = hw_event-config_base;
int idx;
 
if (cci_event == CCI_PMU_CYCLES) {
@@ -296,7 +298,7 @@ static int pmu_get_event_idx(struct cci_pmu_hw_events *hw, 
struct perf_event *ev
 static int pmu_map_event(struct perf_event *event)
 {
int mapping;
-   u8 config = event-attr.config  CCI_PMU_EVENT_MASK;
+   unsigned long config = event-attr.config;
 
if (event-attr.type  PERF_TYPE_MAX)
return -ENOENT;
-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/5] arm-cci: Get rid of secure transactions for PMU driver

2015-03-18 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

Avoid secure transactions while probing the CCI PMU. The
existing code makes use of the Peripheral ID2 (PID2) register
to determine the revision of the CCI400, which requires a
secure transaction. This puts a limitation on the usage of the
driver on systems running non-secure Linux(e.g, ARM64).

Updated the device-tree binding for cci pmu node to add the explicit
revision number for the compatible field.

The supported strings are :
arm,cci-400-pmu,r0
arm,cci-400-pmu,r1
arm,cci-400-pmu - DEPRECATED. See NOTE below

NOTE: If the revision is not mentioned, we need to probe the cci revision,
which could be fatal on a platform running non-secure. We need a reliable way
to know if we can poke the CCI registers at runtime on ARM32. We depend on
'mcpm_is_available()' when it is available. mcpm_is_available() returns true
only when there is a registered driver for mcpm. Otherwise, we assume that we
don't have secure access, and skips probing the revision number(ARM64 case).

The MCPM should figure out if it is safe to access the CCI. Unfortunately
there isn't a reliable way to indicate the same via dtb. This patch doesn't
address/change the current situation. It only deals with the CCI-PMU, leaving
the assumptions about the secure access as it has been, prior to this patch.

Changes since V2:
 - Use 'bool' instead of 'int' for platform_has_secure_cci_access().
   (Suggested-by: Sudeep Holla)

Cc: devicet...@vger.kernel.org
Cc: Punit Agrawal punit.agra...@arm.com
Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
Tested-by: Sudeep Holla sudeep.ho...@arm.com
Acked-by: Nicolas Pitre nicolas.pi...@linaro.org
---
 Documentation/devicetree/bindings/arm/cci.txt |7 +++--
 arch/arm/include/asm/arm-cci.h|   42 +
 arch/arm64/include/asm/arm-cci.h  |   27 
 drivers/bus/arm-cci.c |   17 +-
 include/linux/arm-cci.h   |2 ++
 5 files changed, 92 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/include/asm/arm-cci.h
 create mode 100644 arch/arm64/include/asm/arm-cci.h

diff --git a/Documentation/devicetree/bindings/arm/cci.txt 
b/Documentation/devicetree/bindings/arm/cci.txt
index f28d82b..0e4b6a7 100644
--- a/Documentation/devicetree/bindings/arm/cci.txt
+++ b/Documentation/devicetree/bindings/arm/cci.txt
@@ -94,8 +94,11 @@ specific to ARM.
- compatible
Usage: required
Value type: string
-   Definition: must be arm,cci-400-pmu
-
+   Definition: Supported strings are :
+arm,cci-400-pmu,r0
+arm,cci-400-pmu,r1
+arm,cci-400-pmu  - DEPRECATED, permitted 
only where OS has
+ secure acces to CCI 
registers
- reg:
Usage: required
Value type: Integer cells. A register entry, expressed
diff --git a/arch/arm/include/asm/arm-cci.h b/arch/arm/include/asm/arm-cci.h
new file mode 100644
index 000..fe77f7a
--- /dev/null
+++ b/arch/arm/include/asm/arm-cci.h
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/include/asm/arm-cci.h
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see http://www.gnu.org/licenses/.
+ */
+
+#ifndef __ASM_ARM_CCI_H
+#define __ASM_ARM_CCI_H
+
+#ifdef CONFIG_MCPM
+#include asm/mcpm.h
+
+/*
+ * We don't have a reliable way of detecting whether,
+ * if we have access to secure-only registers, unless
+ * mcpm is registered.
+ */
+static inline bool platform_has_secure_cci_access(void)
+{
+   return mcpm_is_available();
+}
+
+#else
+static inline bool platform_has_secure_cci_access(void)
+{
+   return false;
+}
+#endif
+
+#endif
diff --git a/arch/arm64/include/asm/arm-cci.h b/arch/arm64/include/asm/arm-cci.h
new file mode 100644
index 000..f0b6371
--- /dev/null
+++ b/arch/arm64/include/asm/arm-cci.h
@@ -0,0 +1,27 @@
+/*
+ * arch/arm64/include/asm/arm-cci.h
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT

[PATCHv4 0/5] arm-cci400: PMU monitoring support on ARM64

2015-03-18 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

This series enables the PMU monitoring support for CCI400 on ARM64.
The existing CCI400 driver code is a mix of PMU driver and the MCPM
driver code. The MCPM driver is only used on ARM(32) and contains
arm32 assembly and hence can't be built on ARM64. This patch splits
the code to

 - ARM_CCI400_PORT_CTRL driver - depends on ARM  V7
 - ARM_CCI400_PMU driver

Accessing the Peripheral ID2 register(PID2) on CCI-400, to detect
the revision of the chipset, is a secure operation. Hence, it prevents
us from running this on non-secure platforms. The issue is overcome by
explicitly mentioning the revision number of the CCI PMU in the device tree
binding. The device-tree binding has been updated with the new bindings.

i.e,arm-cci-400-pmu,r0 = revision 0
arm-cci-400-pmu,r1 = revision 1
arm-cci-400-pmu = (old) DEPRECATED

The old binding has been DEPRECATED and must be used only on ARM32
system with secure access. We don't have a reliable dynamic way to detect
if the system is running secure. This series tries to use the best safe
method by relying on the availability of MCPM(as it was prior to the series).
It is upto the MCPM platform driver to decide, if the system is secure before
it goes ahead and registers its drivers and pokes the CCI. This series doesn't
address/solve the problem of MCPM. I will be happy to use a better approach,
if there is any.

Tested on (non-secure)TC2 and A53x2.

Changes since V3
 - Patch 5 : Use unsigned long for CCI_PMU_EVENT_MASK (Suggested-by: Will 
Deacon)
 - Patch 3 : Fix misspelled 'DEPRECATED' in dev_warn().
 - Added the ACKs and Reviews.

Changes since V2

 - Include suggestions from Sudeep Holla.
 - Cleanup event validation checks.

Changes since V1 (Suggestions from Nicolas Pitre):

 - Split Patch 2 to separate the 'PMU' abstraction(now Patch 2/5)
   from the introduction of a new device-tree binding(now Patch 3/5)
 - Rename
ARM_CCI400_MCPM = ARM_CCI400_PORT_CTRL
CCI400_MCPM_PORTS_DATA = CCI400_PORTS_DATA
 - Select ARM_CCI400_COMMON for ARM_CCI400_PORT_CTRL
 - Better documentation in the git commit log about the ARM_CCI config.
 - Move the 'pr_info' to its apporpriate patch.


Suzuki K. Poulose (5):
  arm-cci: Rearrange code for splitting PMU vs driver code
  arm-cci: Abstract the CCI400 PMU speicific definitions
  arm-cci: Get rid of secure transactions for PMU driver
  arm-cci: Split the code for PMU vs driver support
  arm-cci: Fix CCI PMU event validation

 Documentation/devicetree/bindings/arm/cci.txt |7 +-
 arch/arm/include/asm/arm-cci.h|   42 +++
 arch/arm/mach-exynos/Kconfig  |2 +-
 arch/arm/mach-vexpress/Kconfig|4 +-
 arch/arm64/include/asm/arm-cci.h  |   27 ++
 drivers/bus/Kconfig   |   28 +-
 drivers/bus/arm-cci.c |  498 ++---
 include/linux/arm-cci.h   |9 +-
 8 files changed, 385 insertions(+), 232 deletions(-)
 create mode 100644 arch/arm/include/asm/arm-cci.h
 create mode 100644 arch/arm64/include/asm/arm-cci.h

-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 4/5] arm-cci: Split the code for PMU vs driver support

2015-03-18 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

This patch separates the PMU driver code from the low level
CCI driver code and enables the PMU driver for ARM64.

Introduces config options for both.

 ARM_CCI400_PORT_CTRL   - controls the low level driver code for
  CCI400 ports.
 ARM_CCI400_PMU - controls the PMU driver code
 ARM_CCI400_COMMON  - Common defintions for CCI400

This patch also changes:
 ARM_CCI - common code for probing the CCI devices. This can be
   used for adding support for newer CCI versions(e.g, CCI-500).

Changes since V2:
  - Make ARM_CCI400_PMU default y (Suggested-by: Sudeep Holla)
Changes since V1 (Suggestions-by: Nicolas Pitre):
  - Renames
CONFIG_ARM_CCI400_MCPM = CONFIG_ARM_CCI400_PORT_CTRL
CCI400_MCPM_PORTS_DATA = CCI400_PORTS_DATA
  - Select ARM_CCI400_COMMON for ARM_CCI400_PORT_CTRL
  - Better documentation in the git commit log about the ARM_CCI config.

Cc: Bartlomiej Zolnierkiewicz b.zolnier...@samsung.com
Cc: Kukjin Kim kg...@kernel.org
Cc: Abhilash Kesavan a.kesa...@samsung.com
Cc: Liviu Dudau liviu.du...@arm.com
Cc: Lorenzo Pieralisi lorenzo.pieral...@arm.com
Cc: Sudeep Holla sudeep.ho...@arm.com
Cc: Nicolas Pitre nicolas.pi...@linaro.org
Cc: Punit Agrawal punit.agra...@arm.com
Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
Acked-by: Sudeep Holla sudeep.ho...@arm.com
Acked-by: Nicolas Pitre nicolas.pi...@linaro.org
Acked-by: Punit Agrawal punit.agra...@arm.com
---
 arch/arm/mach-exynos/Kconfig   |2 +-
 arch/arm/mach-vexpress/Kconfig |4 ++--
 drivers/bus/Kconfig|   28 
 drivers/bus/arm-cci.c  |   24 
 include/linux/arm-cci.h|7 ++-
 5 files changed, 53 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 603820e..81064cd 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -123,7 +123,7 @@ config SOC_EXYNOS5800
 config EXYNOS5420_MCPM
bool Exynos5420 Multi-Cluster PM support
depends on MCPM  SOC_EXYNOS5420
-   select ARM_CCI
+   select ARM_CCI400_PORT_CTRL
select ARM_CPU_SUSPEND
help
  This is needed to provide CPU and cluster power management
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index 3c2509b..daa7ab6 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -53,7 +53,7 @@ config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
 config ARCH_VEXPRESS_DCSCB
bool Dual Cluster System Control Block (DCSCB) support
depends on MCPM
-   select ARM_CCI
+   select ARM_CCI400_PORT_CTRL
help
  Support for the Dual Cluster System Configuration Block (DCSCB).
  This is needed to provide CPU and cluster power management
@@ -71,7 +71,7 @@ config ARCH_VEXPRESS_SPC
 config ARCH_VEXPRESS_TC2_PM
bool Versatile Express TC2 power management
depends on MCPM
-   select ARM_CCI
+   select ARM_CCI400_PORT_CTRL
select ARCH_VEXPRESS_SPC
select ARM_CPU_SUSPEND
help
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index b99729e..79e297b 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -43,12 +43,32 @@ config OMAP_INTERCONNECT
help
  Driver to enable OMAP interconnect error handling driver.
 
-config ARM_CCI
-   bool ARM CCI driver support
+config ARM_CCI400_PORT_CTRL
+   bool
depends on ARM  OF  CPU_V7
+   select ARM_CCI400_COMMON
+   help
+ Low level power management driver for CCI400 cache coherent
+ interconnect for ARM platforms.
+
+config ARM_CCI400_PMU
+   bool ARM CCI400 PMU support
+   default y
+   depends on ARM || ARM64
+   depends on HW_PERF_EVENTS
+   select ARM_CCI400_COMMON
help
- Driver supporting the CCI cache coherent interconnect for ARM
- platforms.
+ Support for PMU events monitoring on the ARM CCI cache coherent
+ interconnect.
+
+ If unsure, say Y
+
+config ARM_CCI400_COMMON
+   bool
+   select ARM_CCI
+
+config ARM_CCI
+   bool
 
 config ARM_CCN
bool ARM CCN driver support
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index a23663c..054df84 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -32,6 +32,7 @@
 static void __iomem *cci_ctrl_base;
 static unsigned long cci_ctrl_phys;
 
+#ifdef CONFIG_ARM_CCI400_PORT_CTRL
 struct cci_nb_ports {
unsigned int nb_ace;
unsigned int nb_ace_lite;
@@ -42,12 +43,19 @@ static const struct cci_nb_ports cci400_ports = {
.nb_ace_lite = 3
 };
 
+#define CCI400_PORTS_DATA  (cci400_ports)
+#else
+#define CCI400_PORTS_DATA  (NULL)
+#endif
+
 static const struct of_device_id arm_cci_matches[] = {
-   {.compatible = arm,cci-400, .data = cci400_ports },
+#ifdef CONFIG_ARM_CCI400_COMMON

[UPDATED] [PATCH 3/5] arm-cci: Get rid of secure transactions for PMU driver

2015-03-17 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

A minor change, fixed missplled 'DEPRECATED' in the dev_warn().

Thanks
Suzuki

8
Avoid secure transactions while probing the CCI PMU. The
existing code makes use of the Peripheral ID2 (PID2) register
to determine the revision of the CCI400, which requires a
secure transaction. This puts a limitation on the usage of the
driver on systems running non-secure Linux(e.g, ARM64).

Updated the device-tree binding for cci pmu node to add the explicit
revision number for the compatible field.

The supported strings are :
arm,cci-400-pmu,r0
arm,cci-400-pmu,r1
arm,cci-400-pmu - DEPRECATED. See NOTE below

NOTE: If the revision is not mentioned, we need to probe the cci revision,
which could be fatal on a platform running non-secure. We need a reliable way
to know if we can poke the CCI registers at runtime on ARM32. We depend on
'mcpm_is_available()' when it is available. mcpm_is_available() returns true
only when there is a registered driver for mcpm. Otherwise, we assume that we
don't have secure access, and skips probing the revision number(ARM64 case).

The MCPM should figure out if it is safe to access the CCI. Unfortunately
there isn't a reliable way to indicate the same via dtb. This patch doesn't
address/change the current situation. It only deals with the CCI-PMU, leaving
the assumptions about the secure access as it has been, prior to this patch.

Changes since V2:
 - Use 'bool' instead of 'int' for platform_has_secure_cci_access().
   (Suggested-by: Sudeep Holla)

Cc: devicet...@vger.kernel.org
Cc: Punit Agrawal punit.agra...@arm.com
Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
Tested-by: Sudeep Holla sudeep.ho...@arm.com
Acked-by: Nicolas Pitre nicolas.pi...@linaro.org
---
 Documentation/devicetree/bindings/arm/cci.txt |7 +++--
 arch/arm/include/asm/arm-cci.h|   42 +
 arch/arm64/include/asm/arm-cci.h  |   27 
 drivers/bus/arm-cci.c |   17 +-
 include/linux/arm-cci.h   |2 ++
 5 files changed, 92 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/include/asm/arm-cci.h
 create mode 100644 arch/arm64/include/asm/arm-cci.h

diff --git a/Documentation/devicetree/bindings/arm/cci.txt 
b/Documentation/devicetree/bindings/arm/cci.txt
index f28d82b..0e4b6a7 100644
--- a/Documentation/devicetree/bindings/arm/cci.txt
+++ b/Documentation/devicetree/bindings/arm/cci.txt
@@ -94,8 +94,11 @@ specific to ARM.
- compatible
Usage: required
Value type: string
-   Definition: must be arm,cci-400-pmu
-
+   Definition: Supported strings are :
+arm,cci-400-pmu,r0
+arm,cci-400-pmu,r1
+arm,cci-400-pmu  - DEPRECATED, permitted 
only where OS has
+ secure acces to CCI 
registers
- reg:
Usage: required
Value type: Integer cells. A register entry, expressed
diff --git a/arch/arm/include/asm/arm-cci.h b/arch/arm/include/asm/arm-cci.h
new file mode 100644
index 000..fe77f7a
--- /dev/null
+++ b/arch/arm/include/asm/arm-cci.h
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/include/asm/arm-cci.h
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see http://www.gnu.org/licenses/.
+ */
+
+#ifndef __ASM_ARM_CCI_H
+#define __ASM_ARM_CCI_H
+
+#ifdef CONFIG_MCPM
+#include asm/mcpm.h
+
+/*
+ * We don't have a reliable way of detecting whether,
+ * if we have access to secure-only registers, unless
+ * mcpm is registered.
+ */
+static inline bool platform_has_secure_cci_access(void)
+{
+   return mcpm_is_available();
+}
+
+#else
+static inline bool platform_has_secure_cci_access(void)
+{
+   return false;
+}
+#endif
+
+#endif
diff --git a/arch/arm64/include/asm/arm-cci.h b/arch/arm64/include/asm/arm-cci.h
new file mode 100644
index 000..f0b6371
--- /dev/null
+++ b/arch/arm64/include/asm/arm-cci.h
@@ -0,0 +1,27 @@
+/*
+ * arch/arm64/include/asm/arm-cci.h
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation

Re: [UPDATED] [PATCH 3/5] arm-cci: Get rid of secure transactions for PMU driver

2015-03-19 Thread Suzuki K. Poulose

On 19/03/15 17:38, Sudeep Holla wrote:



On 19/03/15 17:32, Mark Rutland wrote:

One more thing:


@@ -883,7 +894,11 @@ static inline const struct cci_pmu_model 
*get_cci_model(struct platform_device *
pdev-dev.of_node);
if (!match)
return NULL;
+   if (match-data)
+   return match-data;

+   dev_warn(pdev-dev, DEPRECATED compatible property,
+requires secure access to CCI registers);
return probe_cci_model(pdev);
   }


Before the probe, could we please have:

if (!IS_ENABLED(CONFIG_ARM))
return -EINVAL;

On arm64 we require a model-specific string, and we shouldn't go
touching secure-only registers.



IIUC platform_has_secure_cci_access always return false for ARM64
preventing any secure access. No ?

Yes, you are right. The check has been abstracted away with the 
platform_has_secure_cci_access().


Cheers
Suzuki


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/3] [4.0] arm/arm64: Do not group hardware events from different PMUs

2015-03-09 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

This is a collection of fixes which denies grouping hardware events
from different PMUs. They also fix crashes triggered by perf_fuzzer
on Linux-4.0-rc2.

Pawel,

Similar fix is required in ARM CCN PMU driver. I didn't find it
straight forward to fix it there. Could you please take a look
into it ?


Suzuki K. Poulose (3):
  arm/pmu: Reject groups spanning multiple hardware PMUs
  arm64/pmu: Reject groups spanning multiple HW PMUs
  arm-cci: Reject groups spanning multiple HW PMUs

 arch/arm/kernel/perf_event.c   |   21 +++--
 arch/arm64/kernel/perf_event.c |   21 +++--
 drivers/bus/arm-cci.c  |   19 ++-
 3 files changed, 44 insertions(+), 17 deletions(-)

-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/3] arm64/pmu: Reject groups spanning multiple HW PMUs

2015-03-09 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

Don't allow grouping hardware events from different PMUs
 (eg. CCI + CPU).

Fixes a crash triggered by perf_fuzzer on Linux-4.0-rc2,
with CCI PMU turned on. The validate_event(), after certain checks,
assumes that the given hardware pmu event belongs to armpmu,
which may not be true always, with other hardware PMUs
around (CCI, CCN).

Bad mode in Synchronous Abort handler detected, code 0x8606 -- IABT 
(current EL)
CPU: 0 PID: 1371 Comm: perf_fuzzer Not tainted 3.19.0+ #249
Hardware name: V2F-1XV7 Cortex-A53x2 SMM (DT)
task: ffc07c73a280 ti: ffc07b0a task.ti: ffc07b0a
PC is at 0x0
LR is at validate_event+0x90/0xa8
pc : [] lr : [ffc90228] pstate: 0145
sp : ffc07b0a3ba0

[  (null)]   (null)
[ffc907d8] armpmu_event_init+0x174/0x3cc
[ffc00015d870] perf_try_init_event+0x34/0x70
[ffc000164094] perf_init_event+0xe0/0x10c
[ffc000164348] perf_event_alloc+0x288/0x358
[ffc000164c5c] SyS_perf_event_open+0x464/0x98c
Code: bad PC value

Also cleans up the code to use the arm_pmu only when we know
that we are dealing with an arm pmu event.

Cc: Will Deacon will.dea...@arm.com
Cc: Mark Rutland mark.rutl...@arm.com
Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 arch/arm64/kernel/perf_event.c |   21 +++--
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 25a5308..68a7415 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -322,22 +322,31 @@ out:
 }
 
 static int
-validate_event(struct pmu_hw_events *hw_events,
-  struct perf_event *event)
+validate_event(struct pmu *pmu, struct pmu_hw_events *hw_events,
+   struct perf_event *event)
 {
-   struct arm_pmu *armpmu = to_arm_pmu(event-pmu);
+   struct arm_pmu *armpmu;
struct hw_perf_event fake_event = event-hw;
struct pmu *leader_pmu = event-group_leader-pmu;
 
if (is_software_event(event))
return 1;
 
+   /*
+* Reject groups spanning multiple HW PMUs (e.g. CPU + CCI). The
+* core perf code won't check that the pmu-ctx == leader-ctx
+* until after pmu-event_init(event).
+*/
+   if (event-pmu != pmu)
+   return 0;
+
if (event-pmu != leader_pmu || event-state  PERF_EVENT_STATE_OFF)
return 1;
 
if (event-state == PERF_EVENT_STATE_OFF  !event-attr.enable_on_exec)
return 1;
 
+   armpmu = to_arm_pmu(event-pmu);
return armpmu-get_event_idx(hw_events, fake_event) = 0;
 }
 
@@ -355,15 +364,15 @@ validate_group(struct perf_event *event)
memset(fake_used_mask, 0, sizeof(fake_used_mask));
fake_pmu.used_mask = fake_used_mask;
 
-   if (!validate_event(fake_pmu, leader))
+   if (!validate_event(event-pmu, fake_pmu, leader))
return -EINVAL;
 
list_for_each_entry(sibling, leader-sibling_list, group_entry) {
-   if (!validate_event(fake_pmu, sibling))
+   if (!validate_event(event-pmu, fake_pmu, sibling))
return -EINVAL;
}
 
-   if (!validate_event(fake_pmu, event))
+   if (!validate_event(event-pmu, fake_pmu, event))
return -EINVAL;
 
return 0;
-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] arm/pmu: Reject groups spanning multiple hardware PMUs

2015-03-09 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

Don't allow grouping hardware events from different PMUs
 (eg. CCI + CPU).

Fixes a crash triggered by perf_fuzzer on Linux-4.0-rc2,
with CCI PMU turned on. The validate_event(), after certain checks,
assumes that the given hardware pmu event belongs to armpmu,
which may not be true always, with other hardware PMUs
around (CCI, CCN).

 ---
CPU: 0 PID: 1527 Comm: perf_fuzzer Not tainted 4.0.0-rc2 #57
Hardware name: ARM-Versatile Express
task: bd8484c0 ti: be676000 task.ti: be676000
PC is at 0xbf1bbc90
LR is at validate_event+0x34/0x5c
pc : [bf1bbc90]lr : [80016060]psr: 0013
...
[80016060] (validate_event) from [80016198] (validate_group+0x28/0x90)
[80016198] (validate_group) from [80016398] (armpmu_event_init+0x150/0x218)
[80016398] (armpmu_event_init) from [800882e4] 
(perf_try_init_event+0x30/0x48)
[800882e4] (perf_try_init_event) from [8008f544] (perf_init_event+0x5c/0xf4)
[8008f544] (perf_init_event) from [8008f8a8] (perf_event_alloc+0x2cc/0x35c)
[8008f8a8] (perf_event_alloc) from [8009015c] 
(SyS_perf_event_open+0x498/0xa70)
[8009015c] (SyS_perf_event_open) from [8000e420] (ret_fast_syscall+0x0/0x34)
Code: bf1be000 bf1bb380 802a2664  (0002)
---[ end trace 01aff0ff00926a0a ]---

Also cleans up the code to use the arm_pmu only when we know that
we are dealing with an arm pmu event.

Cc: Will Deacon will.dea...@arm.com
Cc: Mark Rutland mark.rutl...@arm.com
Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 arch/arm/kernel/perf_event.c |   21 +++--
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 557e128..4a86a01 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -259,20 +259,29 @@ out:
 }
 
 static int
-validate_event(struct pmu_hw_events *hw_events,
-  struct perf_event *event)
+validate_event(struct pmu *pmu, struct pmu_hw_events *hw_events,
+  struct perf_event *event)
 {
-   struct arm_pmu *armpmu = to_arm_pmu(event-pmu);
+   struct arm_pmu *armpmu;
 
if (is_software_event(event))
return 1;
 
+   /*
+* Reject groups spanning multiple HW PMUs (e.g. CPU + CCI). The
+* core perf code won't check that the pmu-ctx == leader-ctx
+* until after pmu-event_init(event).
+*/
+   if (event-pmu != pmu)
+   return 0;
+
if (event-state  PERF_EVENT_STATE_OFF)
return 1;
 
if (event-state == PERF_EVENT_STATE_OFF  !event-attr.enable_on_exec)
return 1;
 
+   armpmu = to_arm_pmu(event-pmu);
return armpmu-get_event_idx(hw_events, event) = 0;
 }
 
@@ -288,15 +297,15 @@ validate_group(struct perf_event *event)
 */
memset(fake_pmu.used_mask, 0, sizeof(fake_pmu.used_mask));
 
-   if (!validate_event(fake_pmu, leader))
+   if (!validate_event(event-pmu, fake_pmu, leader))
return -EINVAL;
 
list_for_each_entry(sibling, leader-sibling_list, group_entry) {
-   if (!validate_event(fake_pmu, sibling))
+   if (!validate_event(event-pmu, fake_pmu, sibling))
return -EINVAL;
}
 
-   if (!validate_event(fake_pmu, event))
+   if (!validate_event(event-pmu, fake_pmu, event))
return -EINVAL;
 
return 0;
-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/3] arm-cci: Reject groups spanning multiple HW PMUs

2015-03-09 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

Invalidate an event if the group has a hardware event from
a different PMU as we cannot schedule all of them in the same
context. The perf core code won't check the group consistency
until after pmu_event_init().

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 drivers/bus/arm-cci.c |   19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 84fd660..68ef6f2 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -660,12 +660,21 @@ static void cci_pmu_del(struct perf_event *event, int 
flags)
 }
 
 static int
-validate_event(struct cci_pmu_hw_events *hw_events,
-  struct perf_event *event)
+validate_event(struct pmu *cci_pmu,
+   struct cci_pmu_hw_events *hw_events,
+   struct perf_event *event)
 {
if (is_software_event(event))
return 1;
 
+   /*
+* Reject groups spanning multiple HW PMUs (e.g. CPU + CCI). The
+* core perf code won't check that the pmu-ctx == leader-ctx
+* until after pmu-event_init(event).
+*/
+   if (event-pmu != cci_pmu)
+   return 0;
+
if (event-state  PERF_EVENT_STATE_OFF)
return 1;
 
@@ -687,15 +696,15 @@ validate_group(struct perf_event *event)
.used_mask = CPU_BITS_NONE,
};
 
-   if (!validate_event(fake_pmu, leader))
+   if (!validate_event(event-pmu, fake_pmu, leader))
return -EINVAL;
 
list_for_each_entry(sibling, leader-sibling_list, group_entry) {
-   if (!validate_event(fake_pmu, sibling))
+   if (!validate_event(event-pmu, fake_pmu, sibling))
return -EINVAL;
}
 
-   if (!validate_event(fake_pmu, event))
+   if (!validate_event(event-pmu, fake_pmu, event))
return -EINVAL;
 
return 0;
-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 0/3] [4.0] arm/arm64: Do not group hardware events from different PMUs

2015-03-09 Thread Suzuki K. Poulose

On 09/03/15 12:43, a wrote:

From: Suzuki K. Poulose suzuki.poul...@arm.com

This is a collection of fixes which denies grouping hardware events
from different PMUs. They also fix crashes triggered by perf_fuzzer
on Linux-4.0-rc2.

Pawel,

Similar fix is required in ARM CCN PMU driver. I didn't find it
straight forward to fix it there. Could you please take a look
into it ?



Sorry, I messed up the git send-email inputs. This indeed was sent by
me. :(

Cheers
Suzuki



--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/3] arm/pmu: Reject groups spanning multiple hardware PMUs

2015-03-10 Thread Suzuki K. Poulose

On 10/03/15 11:27, Peter Zijlstra wrote:

On Mon, Mar 09, 2015 at 12:46:30PM +, Suzuki K. Poulose wrote:

From: Suzuki K. Poulose suzuki.poul...@arm.com

Don't allow grouping hardware events from different PMUs
  (eg. CCI + CPU).


Uhm, how does this work? If we have multiple hardware PMUs we'll stop
scheduling events after the first failed event schedule. This can leave
one of the PMUs severely under utilized.

This is done from pmu-event_init(), where we haven't scheduled an
event yet. Do you think we need to solve it using a different approach
? What is the best way to handle this situation ? Is it OK
to allow different PMUs in the group ?

Suzuki





--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/3] arm/pmu: Reject groups spanning multiple hardware PMUs

2015-03-10 Thread Suzuki K. Poulose

On 10/03/15 13:00, Peter Zijlstra wrote:

On Tue, Mar 10, 2015 at 01:53:51PM +0100, Peter Zijlstra wrote:

It would be nicer if we could prevent this in the core so we're not
reliant on every PMU driver doing the same verification. My initial
thought was that seemed like unnecessary duplication of the ctx checking
above, but if we're going to end up shoving it into several drivers
anyway perhaps it's the lesser evil.


Again, agreed, that would be better and less error prone. But I'm not
entirely sure how to go about doing it :/ I'll have to go think about
that; and conferences are not the best place for that.

Suggestions on that are welcome of course ;)


So the problem is that event_init() is what will return the pmu, so we
cannot make decisions on it until after that returns.

Maybe we can pull out the validate step into its own funciton;
pmu-validate() or whatnot, to be called slightly later.


I think we could still solve this problem by deferring the 'context'
validation to the core. The PMUs could validate the group, within its
context. i.e, if it can accommodate its events as a group, during 
event_init.  The problem we face now, is encountering an event from a 
different PMU, which we could leave it to the core as we do already.


i.e the fix could look like (and similarly for other cases):

diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 557e128..b3af19b 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -259,20 +259,28 @@ out:
 }

 static int
-validate_event(struct pmu_hw_events *hw_events,
-  struct perf_event *event)
+validate_event(struct pmu *pmu, struct pmu_hw_events *hw_events,
+  struct perf_event *event)
 {
-   struct arm_pmu *armpmu = to_arm_pmu(event-pmu);
+   struct arm_pmu *armpmu;

if (is_software_event(event))
return 1;

+   /*
+* We are only worried if we can accommodate the events
+* from this pmu in this group.
+*/
+   if (event-pmu != pmu)
+   return 1;
+
if (event-state  PERF_EVENT_STATE_OFF)
return 1;

if (event-state == PERF_EVENT_STATE_OFF  !event-attr.enable_on_exec)
return 1;

+   armpmu = to_arm_pmu(event-pmu);
return armpmu-get_event_idx(hw_events, event) = 0;
 }

@@ -288,15 +296,15 @@ validate_group(struct perf_event *event)
 */
memset(fake_pmu.used_mask, 0, sizeof(fake_pmu.used_mask));

-   if (!validate_event(fake_pmu, leader))
+   if (!validate_event(event-pmu, fake_pmu, leader))
return -EINVAL;

list_for_each_entry(sibling, leader-sibling_list, group_entry) {
-   if (!validate_event(fake_pmu, sibling))
+   if (!validate_event(event-pmu, fake_pmu, sibling))
return -EINVAL;
}

-   if (!validate_event(fake_pmu, event))
+   if (!validate_event(event-pmu, fake_pmu, event))
return -EINVAL;

return 0;

Thoughts ?

Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/5] arm-cci: Rearrange code for splitting PMU vs driver code

2015-03-10 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

No functional changes, only code re-arrangements for easier split of the
PMU code vs low level driver code. Extracts the port handling code
to cci_probe_ports().

Change since V2:
 - Removed unnecessary goto. (Suggested-by: Sudeep Holla)

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 drivers/bus/arm-cci.c |  326 -
 1 file changed, 163 insertions(+), 163 deletions(-)

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 84fd660..ea39fc2 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -29,42 +29,29 @@
 #include asm/cacheflush.h
 #include asm/smp_plat.h
 
-#define DRIVER_NAMECCI-400
-#define DRIVER_NAME_PMUDRIVER_NAME  PMU
-
-#define CCI_PORT_CTRL  0x0
-#define CCI_CTRL_STATUS0xc
-
-#define CCI_ENABLE_SNOOP_REQ   0x1
-#define CCI_ENABLE_DVM_REQ 0x2
-#define CCI_ENABLE_REQ (CCI_ENABLE_SNOOP_REQ | CCI_ENABLE_DVM_REQ)
+static void __iomem *cci_ctrl_base;
+static unsigned long cci_ctrl_phys;
 
 struct cci_nb_ports {
unsigned int nb_ace;
unsigned int nb_ace_lite;
 };
 
-enum cci_ace_port_type {
-   ACE_INVALID_PORT = 0x0,
-   ACE_PORT,
-   ACE_LITE_PORT,
+static const struct cci_nb_ports cci400_ports = {
+   .nb_ace = 2,
+   .nb_ace_lite = 3
 };
 
-struct cci_ace_port {
-   void __iomem *base;
-   unsigned long phys;
-   enum cci_ace_port_type type;
-   struct device_node *dn;
+static const struct of_device_id arm_cci_matches[] = {
+   {.compatible = arm,cci-400, .data = cci400_ports },
+   {},
 };
 
-static struct cci_ace_port *ports;
-static unsigned int nb_cci_ports;
-
-static void __iomem *cci_ctrl_base;
-static unsigned long cci_ctrl_phys;
-
 #ifdef CONFIG_HW_PERF_EVENTS
 
+#define DRIVER_NAMECCI-400
+#define DRIVER_NAME_PMUDRIVER_NAME  PMU
+
 #define CCI_PMCR   0x0100
 #define CCI_PID2   0x0fe8
 
@@ -75,6 +62,47 @@ static unsigned long cci_ctrl_phys;
 #define CCI_PID2_REV_MASK  0xf0
 #define CCI_PID2_REV_SHIFT 4
 
+#define CCI_PMU_EVT_SEL0x000
+#define CCI_PMU_CNTR   0x004
+#define CCI_PMU_CNTR_CTRL  0x008
+#define CCI_PMU_OVRFLW 0x00c
+
+#define CCI_PMU_OVRFLW_FLAG1
+
+#define CCI_PMU_CNTR_BASE(idx) ((idx) * SZ_4K)
+
+#define CCI_PMU_CNTR_MASK  ((1ULL  32) -1)
+
+#define CCI_PMU_EVENT_MASK 0xff
+#define CCI_PMU_EVENT_SOURCE(event)((event  5)  0x7)
+#define CCI_PMU_EVENT_CODE(event)  (event  0x1f)
+
+#define CCI_PMU_MAX_HW_EVENTS 5   /* CCI PMU has 4 counters + 1 cycle counter 
*/
+
+struct cci_pmu_hw_events {
+   struct perf_event *events[CCI_PMU_MAX_HW_EVENTS];
+   unsigned long used_mask[BITS_TO_LONGS(CCI_PMU_MAX_HW_EVENTS)];
+   raw_spinlock_t pmu_lock;
+};
+
+struct cci_pmu {
+   void __iomem *base;
+   struct pmu pmu;
+   int nr_irqs;
+   int irqs[CCI_PMU_MAX_HW_EVENTS];
+   unsigned long active_irqs;
+   struct pmu_port_event_ranges *port_ranges;
+   struct cci_pmu_hw_events hw_events;
+   struct platform_device *plat_device;
+   int num_events;
+   atomic_t active_events;
+   struct mutex reserve_mutex;
+   cpumask_t cpus;
+};
+static struct cci_pmu *pmu;
+
+#define to_cci_pmu(c)  (container_of(c, struct cci_pmu, pmu))
+
 /* Port ids */
 #define CCI_PORT_S00
 #define CCI_PORT_S11
@@ -89,17 +117,6 @@ static unsigned long cci_ctrl_phys;
 #define CCI_REV_R1 1
 #define CCI_REV_R1_PX  5
 
-#define CCI_PMU_EVT_SEL0x000
-#define CCI_PMU_CNTR   0x004
-#define CCI_PMU_CNTR_CTRL  0x008
-#define CCI_PMU_OVRFLW 0x00c
-
-#define CCI_PMU_OVRFLW_FLAG1
-
-#define CCI_PMU_CNTR_BASE(idx) ((idx) * SZ_4K)
-
-#define CCI_PMU_CNTR_MASK  ((1ULL  32) -1)
-
 /*
  * Instead of an event id to monitor CCI cycles, a dedicated counter is
  * provided. Use 0xff to represent CCI cycles and hope that no future revisions
@@ -109,12 +126,6 @@ enum cci400_perf_events {
CCI_PMU_CYCLES = 0xff
 };
 
-#define CCI_PMU_EVENT_MASK 0xff
-#define CCI_PMU_EVENT_SOURCE(event)((event  5)  0x7)
-#define CCI_PMU_EVENT_CODE(event)  (event  0x1f)
-
-#define CCI_PMU_MAX_HW_EVENTS 5   /* CCI PMU has 4 counters + 1 cycle counter 
*/
-
 #define CCI_PMU_CYCLE_CNTR_IDX 0
 #define CCI_PMU_CNTR0_IDX  1
 #define CCI_PMU_CNTR_LAST(cci_pmu) (CCI_PMU_CYCLE_CNTR_IDX + 
cci_pmu-num_events - 1)
@@ -172,60 +183,6 @@ static char *const pmu_names[] = {
[CCI_REV_R1] = CCI_400_r1,
 };
 
-struct cci_pmu_hw_events {
-   struct perf_event *events[CCI_PMU_MAX_HW_EVENTS];
-   unsigned long used_mask[BITS_TO_LONGS(CCI_PMU_MAX_HW_EVENTS)];
-   raw_spinlock_t pmu_lock;
-};
-
-struct cci_pmu {
-   void __iomem *base;
-   struct pmu pmu;
-   int nr_irqs;
-   int irqs

[PATCH 2/5] arm-cci: Abstract the CCI400 PMU speicific definitions

2015-03-10 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

CCI400 has different event specifications for PMU, for revsion
0 and revision 1. As of now, we check the revision every single
time before using the parameters for the PMU. This patch abstracts
the details of the pmu models in a struct (cci_pmu_model) and
stores the information in cci_pmu at initialisation time, avoiding
multiple probe operations.

Changes since V2:
 - Cleanup event validation(pmu_validate_hw_event). Get rid of
   helper functions:
pmu_is_valid_slave_event
pmu_is_valid_master_event

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 drivers/bus/arm-cci.c |  141 -
 1 file changed, 81 insertions(+), 60 deletions(-)

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index ea39fc2..f88383e 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -79,19 +79,38 @@ static const struct of_device_id arm_cci_matches[] = {
 
 #define CCI_PMU_MAX_HW_EVENTS 5   /* CCI PMU has 4 counters + 1 cycle counter 
*/
 
+/* Types of interfaces that can generate events */
+enum {
+   CCI_IF_SLAVE,
+   CCI_IF_MASTER,
+   CCI_IF_MAX,
+};
+
+struct event_range {
+   u32 min;
+   u32 max;
+};
+
 struct cci_pmu_hw_events {
struct perf_event *events[CCI_PMU_MAX_HW_EVENTS];
unsigned long used_mask[BITS_TO_LONGS(CCI_PMU_MAX_HW_EVENTS)];
raw_spinlock_t pmu_lock;
 };
 
+struct cci_pmu_model {
+   char *name;
+   struct event_range event_ranges[CCI_IF_MAX];
+};
+
+static struct cci_pmu_model cci_pmu_models[];
+
 struct cci_pmu {
void __iomem *base;
struct pmu pmu;
int nr_irqs;
int irqs[CCI_PMU_MAX_HW_EVENTS];
unsigned long active_irqs;
-   struct pmu_port_event_ranges *port_ranges;
+   const struct cci_pmu_model *model;
struct cci_pmu_hw_events hw_events;
struct platform_device *plat_device;
int num_events;
@@ -152,53 +171,11 @@ enum cci400_perf_events {
 #define CCI_REV_R1_MASTER_PORT_MIN_EV  0x00
 #define CCI_REV_R1_MASTER_PORT_MAX_EV  0x11
 
-struct pmu_port_event_ranges {
-   u8 slave_min;
-   u8 slave_max;
-   u8 master_min;
-   u8 master_max;
-};
-
-static struct pmu_port_event_ranges port_event_range[] = {
-   [CCI_REV_R0] = {
-   .slave_min = CCI_REV_R0_SLAVE_PORT_MIN_EV,
-   .slave_max = CCI_REV_R0_SLAVE_PORT_MAX_EV,
-   .master_min = CCI_REV_R0_MASTER_PORT_MIN_EV,
-   .master_max = CCI_REV_R0_MASTER_PORT_MAX_EV,
-   },
-   [CCI_REV_R1] = {
-   .slave_min = CCI_REV_R1_SLAVE_PORT_MIN_EV,
-   .slave_max = CCI_REV_R1_SLAVE_PORT_MAX_EV,
-   .master_min = CCI_REV_R1_MASTER_PORT_MIN_EV,
-   .master_max = CCI_REV_R1_MASTER_PORT_MAX_EV,
-   },
-};
-
-/*
- * Export different PMU names for the different revisions so userspace knows
- * because the event ids are different
- */
-static char *const pmu_names[] = {
-   [CCI_REV_R0] = CCI_400,
-   [CCI_REV_R1] = CCI_400_r1,
-};
-
-static int pmu_is_valid_slave_event(u8 ev_code)
-{
-   return pmu-port_ranges-slave_min = ev_code 
-   ev_code = pmu-port_ranges-slave_max;
-}
-
-static int pmu_is_valid_master_event(u8 ev_code)
-{
-   return pmu-port_ranges-master_min = ev_code 
-   ev_code = pmu-port_ranges-master_max;
-}
-
 static int pmu_validate_hw_event(u8 hw_event)
 {
u8 ev_source = CCI_PMU_EVENT_SOURCE(hw_event);
u8 ev_code = CCI_PMU_EVENT_CODE(hw_event);
+   int if_type;
 
switch (ev_source) {
case CCI_PORT_S0:
@@ -207,18 +184,22 @@ static int pmu_validate_hw_event(u8 hw_event)
case CCI_PORT_S3:
case CCI_PORT_S4:
/* Slave Interface */
-   if (pmu_is_valid_slave_event(ev_code))
-   return hw_event;
+   if_type = CCI_IF_SLAVE;
break;
case CCI_PORT_M0:
case CCI_PORT_M1:
case CCI_PORT_M2:
/* Master Interface */
-   if (pmu_is_valid_master_event(ev_code))
-   return hw_event;
+   if_type = CCI_IF_MASTER;
break;
+   default:
+   return -ENOENT;
}
 
+   if (ev_code = pmu-model-event_ranges[if_type].min 
+   ev_code = pmu-model-event_ranges[if_type].max)
+   return hw_event;
+
return -ENOENT;
 }
 
@@ -234,11 +215,9 @@ static int probe_cci_revision(void)
return CCI_REV_R1;
 }
 
-static struct pmu_port_event_ranges *port_range_by_rev(void)
+static const struct cci_pmu_model *probe_cci_model(struct platform_device 
*pdev)
 {
-   int rev = probe_cci_revision();
-
-   return port_event_range[rev];
+   return cci_pmu_models[probe_cci_revision()];
 }
 
 static int pmu_is_valid_counter(struct cci_pmu *cci_pmu, int idx)
@@ -807,9 +786,9 @@ static const struct

Re: [PATCHv3 0/5] arm-cci400: PMU monitoring support on ARM64

2015-03-10 Thread Suzuki K. Poulose

On 10/03/15 16:09, Nicolas Pitre wrote:

On Tue, 10 Mar 2015, Suzuki K. Poulose wrote:


From: Suzuki K. Poulose suzuki.poul...@arm.com

This series enables the PMU monitoring support for CCI400 on ARM64.
The existing CCI400 driver code is a mix of PMU driver and the MCPM
driver code. The MCPM driver is only used on ARM(32) and contains
arm32 assembly and hence can't be built on ARM64. This patch splits
the code to

  - ARM_CCI400_PORT_CTRL driver - depends on ARM  V7
  - ARM_CCI400_PMU driver

Accessing the Peripheral ID2 register(PID2) on CCI-400, to detect
the revision of the chipset, is a secure operation. Hence, it prevents
us from running this on non-secure platforms. The issue is overcome by
explicitly mentioning the revision number of the CCI PMU in the device tree
binding. The device-tree binding has been updated with the new bindings.

i.e,arm-cci-400-pmu,r0 = revision 0
arm-cci-400-pmu,r1 = revision 1
arm-cci-400-pmu = (old) DEPRECATED

The old binding has been DEPRECATED and must be used only on ARM32
system with secure access. We don't have a reliable dynamic way to detect
if the system is running secure. This series tries to use the best safe
method by relying on the availability of MCPM(as it was prior to the series).
It is upto the MCPM platform driver to decide, if the system is secure before
it goes ahead and registers its drivers and pokes the CCI. This series doesn't
address/solve the problem of MCPM. I will be happy to use a better approach,
if there is any.

Tested on (non-secure)TC2 and A53x2.


Would be nice if you could also test it on secure TC2 making sure MCPM
is still functional.


Sudeep is testing those bits.


For patches 1, 3 and 4, you may add:

Acked-by: Nicolas Pitre n...@linaro.org

Patches 2 and 5 are purely PMU stuff and out of my area of expertise.



Thanks
Suzuki


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/5] arm-cci: Get rid of secure transactions for PMU driver

2015-03-10 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

Avoid secure transactions while probing the CCI PMU. The
existing code makes use of the Peripheral ID2 (PID2) register
to determine the revision of the CCI400, which requires a
secure transaction. This puts a limitation on the usage of the
driver on systems running non-secure Linux(e.g, ARM64).

Updated the device-tree binding for cci pmu node to add the explicit
revision number for the compatible field.

The supported strings are :
arm,cci-400-pmu,r0
arm,cci-400-pmu,r1
arm,cci-400-pmu - DEPRECATED. See NOTE below

NOTE: If the revision is not mentioned, we need to probe the cci revision,
which could be fatal on a platform running non-secure. We need a reliable way
to know if we can poke the CCI registers at runtime on ARM32. We depend on
'mcpm_is_available()' when it is available. mcpm_is_available() returns true
only when there is a registered driver for mcpm. Otherwise, we assume that we
don't have secure access, and skips probing the revision number(ARM64 case).

The MCPM should figure out if it is safe to access the CCI. Unfortunately
there isn't a reliable way to indicate the same via dtb. This patch doesn't
address/change the current situation. It only deals with the CCI-PMU, leaving
the assumptions about the secure access as it has been, prior to this patch.

Changes since V2:
 - Use 'bool' instead of 'int' for platform_has_secure_cci_access().
   (Suggested-by: Sudeep Holla)

Cc: devicet...@vger.kernel.org
Cc: Punit Agrawal punit.agra...@arm.com
Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 Documentation/devicetree/bindings/arm/cci.txt |7 +++--
 arch/arm/include/asm/arm-cci.h|   42 +
 arch/arm64/include/asm/arm-cci.h  |   27 
 drivers/bus/arm-cci.c |   17 +-
 include/linux/arm-cci.h   |2 ++
 5 files changed, 92 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/include/asm/arm-cci.h
 create mode 100644 arch/arm64/include/asm/arm-cci.h

diff --git a/Documentation/devicetree/bindings/arm/cci.txt 
b/Documentation/devicetree/bindings/arm/cci.txt
index f28d82b..0e4b6a7 100644
--- a/Documentation/devicetree/bindings/arm/cci.txt
+++ b/Documentation/devicetree/bindings/arm/cci.txt
@@ -94,8 +94,11 @@ specific to ARM.
- compatible
Usage: required
Value type: string
-   Definition: must be arm,cci-400-pmu
-
+   Definition: Supported strings are :
+arm,cci-400-pmu,r0
+arm,cci-400-pmu,r1
+arm,cci-400-pmu  - DEPRECATED, permitted 
only where OS has
+ secure acces to CCI 
registers
- reg:
Usage: required
Value type: Integer cells. A register entry, expressed
diff --git a/arch/arm/include/asm/arm-cci.h b/arch/arm/include/asm/arm-cci.h
new file mode 100644
index 000..fe77f7a
--- /dev/null
+++ b/arch/arm/include/asm/arm-cci.h
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/include/asm/arm-cci.h
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see http://www.gnu.org/licenses/.
+ */
+
+#ifndef __ASM_ARM_CCI_H
+#define __ASM_ARM_CCI_H
+
+#ifdef CONFIG_MCPM
+#include asm/mcpm.h
+
+/*
+ * We don't have a reliable way of detecting whether,
+ * if we have access to secure-only registers, unless
+ * mcpm is registered.
+ */
+static inline bool platform_has_secure_cci_access(void)
+{
+   return mcpm_is_available();
+}
+
+#else
+static inline bool platform_has_secure_cci_access(void)
+{
+   return false;
+}
+#endif
+
+#endif
diff --git a/arch/arm64/include/asm/arm-cci.h b/arch/arm64/include/asm/arm-cci.h
new file mode 100644
index 000..f0b6371
--- /dev/null
+++ b/arch/arm64/include/asm/arm-cci.h
@@ -0,0 +1,27 @@
+/*
+ * arch/arm64/include/asm/arm-cci.h
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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

[PATCH 4/5] arm-cci: Split the code for PMU vs driver support

2015-03-10 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

This patch separates the PMU driver code from the low level
CCI driver code and enables the PMU driver for ARM64.

Introduces config options for both.

 ARM_CCI400_PORT_CTRL   - controls the low level driver code for
  CCI400 ports.
 ARM_CCI400_PMU - controls the PMU driver code
 ARM_CCI400_COMMON  - Common defintions for CCI400

This patch also changes:
 ARM_CCI - common code for probing the CCI devices. This can be
   used for adding support for newer CCI versions(e.g, CCI-500).

Changes since V2:
  - Make ARM_CCI400_PMU default y (Suggested-by: Sudeep Holla)
Changes since V1 (Suggestions-by: Nicolas Pitre):
  - Renames
CONFIG_ARM_CCI400_MCPM = CONFIG_ARM_CCI400_PORT_CTRL
CCI400_MCPM_PORTS_DATA = CCI400_PORTS_DATA
  - Select ARM_CCI400_COMMON for ARM_CCI400_PORT_CTRL
  - Better documentation in the git commit log about the ARM_CCI config.

Cc: Bartlomiej Zolnierkiewicz b.zolnier...@samsung.com
Cc: Kukjin Kim kg...@kernel.org
Cc: Abhilash Kesavan a.kesa...@samsung.com
Cc: Liviu Dudau liviu.du...@arm.com
Cc: Lorenzo Pieralisi lorenzo.pieral...@arm.com
Cc: Sudeep Holla sudeep.ho...@arm.com
Cc: Nicolas Pitre nicolas.pi...@linaro.org
Cc: Punit Agrawal punit.agra...@arm.com
Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 arch/arm/mach-exynos/Kconfig   |2 +-
 arch/arm/mach-vexpress/Kconfig |4 ++--
 drivers/bus/Kconfig|   28 
 drivers/bus/arm-cci.c  |   24 
 include/linux/arm-cci.h|7 ++-
 5 files changed, 53 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 603820e..81064cd 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -123,7 +123,7 @@ config SOC_EXYNOS5800
 config EXYNOS5420_MCPM
bool Exynos5420 Multi-Cluster PM support
depends on MCPM  SOC_EXYNOS5420
-   select ARM_CCI
+   select ARM_CCI400_PORT_CTRL
select ARM_CPU_SUSPEND
help
  This is needed to provide CPU and cluster power management
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index 3c2509b..daa7ab6 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -53,7 +53,7 @@ config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
 config ARCH_VEXPRESS_DCSCB
bool Dual Cluster System Control Block (DCSCB) support
depends on MCPM
-   select ARM_CCI
+   select ARM_CCI400_PORT_CTRL
help
  Support for the Dual Cluster System Configuration Block (DCSCB).
  This is needed to provide CPU and cluster power management
@@ -71,7 +71,7 @@ config ARCH_VEXPRESS_SPC
 config ARCH_VEXPRESS_TC2_PM
bool Versatile Express TC2 power management
depends on MCPM
-   select ARM_CCI
+   select ARM_CCI400_PORT_CTRL
select ARCH_VEXPRESS_SPC
select ARM_CPU_SUSPEND
help
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index b99729e..79e297b 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -43,12 +43,32 @@ config OMAP_INTERCONNECT
help
  Driver to enable OMAP interconnect error handling driver.
 
-config ARM_CCI
-   bool ARM CCI driver support
+config ARM_CCI400_PORT_CTRL
+   bool
depends on ARM  OF  CPU_V7
+   select ARM_CCI400_COMMON
+   help
+ Low level power management driver for CCI400 cache coherent
+ interconnect for ARM platforms.
+
+config ARM_CCI400_PMU
+   bool ARM CCI400 PMU support
+   default y
+   depends on ARM || ARM64
+   depends on HW_PERF_EVENTS
+   select ARM_CCI400_COMMON
help
- Driver supporting the CCI cache coherent interconnect for ARM
- platforms.
+ Support for PMU events monitoring on the ARM CCI cache coherent
+ interconnect.
+
+ If unsure, say Y
+
+config ARM_CCI400_COMMON
+   bool
+   select ARM_CCI
+
+config ARM_CCI
+   bool
 
 config ARM_CCN
bool ARM CCN driver support
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 70dff09..581190d 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -32,6 +32,7 @@
 static void __iomem *cci_ctrl_base;
 static unsigned long cci_ctrl_phys;
 
+#ifdef CONFIG_ARM_CCI400_PORT_CTRL
 struct cci_nb_ports {
unsigned int nb_ace;
unsigned int nb_ace_lite;
@@ -42,12 +43,19 @@ static const struct cci_nb_ports cci400_ports = {
.nb_ace_lite = 3
 };
 
+#define CCI400_PORTS_DATA  (cci400_ports)
+#else
+#define CCI400_PORTS_DATA  (NULL)
+#endif
+
 static const struct of_device_id arm_cci_matches[] = {
-   {.compatible = arm,cci-400, .data = cci400_ports },
+#ifdef CONFIG_ARM_CCI400_COMMON
+   {.compatible = arm,cci-400, .data = CCI400_PORTS_DATA },
+#endif
{},
 };
 
-#ifdef CONFIG_HW_PERF_EVENTS
+#ifdef CONFIG_ARM_CCI400_PMU

[PATCHv3 0/5] arm-cci400: PMU monitoring support on ARM64

2015-03-10 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

This series enables the PMU monitoring support for CCI400 on ARM64.
The existing CCI400 driver code is a mix of PMU driver and the MCPM
driver code. The MCPM driver is only used on ARM(32) and contains
arm32 assembly and hence can't be built on ARM64. This patch splits
the code to

 - ARM_CCI400_PORT_CTRL driver - depends on ARM  V7
 - ARM_CCI400_PMU driver

Accessing the Peripheral ID2 register(PID2) on CCI-400, to detect
the revision of the chipset, is a secure operation. Hence, it prevents
us from running this on non-secure platforms. The issue is overcome by
explicitly mentioning the revision number of the CCI PMU in the device tree
binding. The device-tree binding has been updated with the new bindings.

i.e,arm-cci-400-pmu,r0 = revision 0
arm-cci-400-pmu,r1 = revision 1
arm-cci-400-pmu = (old) DEPRECATED

The old binding has been DEPRECATED and must be used only on ARM32
system with secure access. We don't have a reliable dynamic way to detect
if the system is running secure. This series tries to use the best safe
method by relying on the availability of MCPM(as it was prior to the series).
It is upto the MCPM platform driver to decide, if the system is secure before
it goes ahead and registers its drivers and pokes the CCI. This series doesn't
address/solve the problem of MCPM. I will be happy to use a better approach,
if there is any.

Tested on (non-secure)TC2 and A53x2.

Changes sinve V2

 - Include suggestions from Sudeep Holla.
 - Cleanup event validation checks.

Changes since V1 (Suggestions from Nicolas Pitre):

 - Split Patch 2 to separate the 'PMU' abstraction(now Patch 2/5)
   from the introduction of a new device-tree binding(now Patch 3/5)
 - Rename
ARM_CCI400_MCPM = ARM_CCI400_PORT_CTRL
CCI400_MCPM_PORTS_DATA = CCI400_PORTS_DATA
 - Select ARM_CCI400_COMMON for ARM_CCI400_PORT_CTRL
 - Better documentation in the git commit log about the ARM_CCI config.
 - Move the 'pr_info' to its apporpriate patch.


Suzuki K. Poulose (5):
  arm-cci: Rearrange code for splitting PMU vs driver code
  arm-cci: Abstract the CCI400 PMU speicific definitions
  arm-cci: Get rid of secure transactions for PMU driver
  arm-cci: Split the code for PMU vs driver support
  arm-cci: Fix CCI PMU event validation

 Documentation/devicetree/bindings/arm/cci.txt |7 +-
 arch/arm/include/asm/arm-cci.h|   42 +++
 arch/arm/mach-exynos/Kconfig  |2 +-
 arch/arm/mach-vexpress/Kconfig|4 +-
 arch/arm64/include/asm/arm-cci.h  |   27 ++
 drivers/bus/Kconfig   |   28 +-
 drivers/bus/arm-cci.c |  496 ++---
 include/linux/arm-cci.h   |9 +-
 8 files changed, 384 insertions(+), 231 deletions(-)
 create mode 100644 arch/arm/include/asm/arm-cci.h
 create mode 100644 arch/arm64/include/asm/arm-cci.h

-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv3 0/5] arm-cci400: PMU monitoring support on ARM64

2015-03-10 Thread Suzuki K. Poulose

On 10/03/15 16:21, Sudeep Holla wrote:



On 10/03/15 15:18, Suzuki K. Poulose wrote:

From: Suzuki K. Poulose suzuki.poul...@arm.com

This series enables the PMU monitoring support for CCI400 on ARM64.
The existing CCI400 driver code is a mix of PMU driver and the MCPM
driver code. The MCPM driver is only used on ARM(32) and contains
arm32 assembly and hence can't be built on ARM64. This patch splits
the code to

   - ARM_CCI400_PORT_CTRL driver - depends on ARM  V7
   - ARM_CCI400_PMU driver

Accessing the Peripheral ID2 register(PID2) on CCI-400, to detect
the revision of the chipset, is a secure operation. Hence, it prevents
us from running this on non-secure platforms. The issue is overcome by
explicitly mentioning the revision number of the CCI PMU in the device tree
binding. The device-tree binding has been updated with the new bindings.

i.e,arm-cci-400-pmu,r0 = revision 0
arm-cci-400-pmu,r1 = revision 1
arm-cci-400-pmu = (old) DEPRECATED

The old binding has been DEPRECATED and must be used only on ARM32
system with secure access. We don't have a reliable dynamic way to detect
if the system is running secure. This series tries to use the best safe
method by relying on the availability of MCPM(as it was prior to the series).
It is upto the MCPM platform driver to decide, if the system is secure before
it goes ahead and registers its drivers and pokes the CCI. This series doesn't
address/solve the problem of MCPM. I will be happy to use a better approach,
if there is any.

Tested on (non-secure)TC2 and A53x2.



For the series,
Tested-by: Sudeep Holla sudeep.ho...@arm.com
(Tested on secure TC2 using MCPM)


Thank you very much for the testing

Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 5/5] arm-cci: Fix CCI PMU event validation

2015-03-10 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

We mask the event with the CCI_PMU_EVENT_MASK, before passing
the config to pmu_validate_hw_event(), which causes extra bits
to be ignored and qualifies an invalid event code as valid.

e.g,
 $ perf stat -a -C 0 -e CCI_400/config=0x1ff,name=cycles/ sleep 1
   Performance counter stats for 'system wide':

 506951142  cycles

   1.013879626 seconds time elapsed

where, cycles has an event coding of 0xff. This patch also removes
the unnecessary 'event' mask in pmu_write_register, since the config_base
is set by the pmu code after the event is validated.

Changes since V2:
 - Switch to input unsigned long for pmu_validate_hw_event()

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 drivers/bus/arm-cci.c |   10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 581190d..89c86e9 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -179,12 +179,15 @@ enum cci400_perf_events {
 #define CCI_REV_R1_MASTER_PORT_MIN_EV  0x00
 #define CCI_REV_R1_MASTER_PORT_MAX_EV  0x11
 
-static int pmu_validate_hw_event(u8 hw_event)
+static int pmu_validate_hw_event(unsigned long hw_event)
 {
u8 ev_source = CCI_PMU_EVENT_SOURCE(hw_event);
u8 ev_code = CCI_PMU_EVENT_CODE(hw_event);
int if_type;
 
+   if (hw_event  ~CCI_PMU_EVENT_MASK)
+   return -ENOENT;
+
switch (ev_source) {
case CCI_PORT_S0:
case CCI_PORT_S1:
@@ -258,7 +261,6 @@ static void pmu_enable_counter(int idx)
 
 static void pmu_set_event(int idx, unsigned long event)
 {
-   event = CCI_PMU_EVENT_MASK;
pmu_write_register(event, idx, CCI_PMU_EVT_SEL);
 }
 
@@ -275,7 +277,7 @@ static int pmu_get_event_idx(struct cci_pmu_hw_events *hw, 
struct perf_event *ev
 {
struct cci_pmu *cci_pmu = to_cci_pmu(event-pmu);
struct hw_perf_event *hw_event = event-hw;
-   unsigned long cci_event = hw_event-config_base  CCI_PMU_EVENT_MASK;
+   unsigned long cci_event = hw_event-config_base;
int idx;
 
if (cci_event == CCI_PMU_CYCLES) {
@@ -296,7 +298,7 @@ static int pmu_get_event_idx(struct cci_pmu_hw_events *hw, 
struct perf_event *ev
 static int pmu_map_event(struct perf_event *event)
 {
int mapping;
-   u8 config = event-attr.config  CCI_PMU_EVENT_MASK;
+   unsigned long config = event-attr.config;
 
if (event-attr.type  PERF_TYPE_MAX)
return -ENOENT;
-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: linux-next: manual merge of the arm-soc tree with the arm-perf tree

2015-03-24 Thread Suzuki K. Poulose

On 23/03/15 21:16, Stephen Rothwell wrote:

Hi all,

On Mon, 23 Mar 2015 15:13:51 + Suzuki K. Poulose suzuki.poul...@arm.com 
wrote:


On 23/03/15 14:41, Abhilash Kesavan wrote:


On Mon, Mar 23, 2015 at 6:03 AM, Stephen Rothwell s...@canb.auug.org.au wrote:


Today's linux-next merge of the arm-soc tree got a conflict in
drivers/bus/Kconfig between commit c9966c98697a (arm-cci: Split the
code for PMU vs driver support) from the arm-perf tree and commit
13fbf3c8d0f7 (drivers: bus: Sort Kconfig entries alphabetically) from
the arm-soc tree.

I fixed it up (see below) and can carry the fix as necessary (no action
is required).


Not sure if this has been reported elsewhere, but I am seeing core
boot-up failures on the exynos5420 with next-20150323 due to this.
Your conflict fix is missing the ARM_CCI symbol because of which the
CCI does not get enabled.

Suzuki, can you confirm ?


Yes, you are right. We need the config ARM_CCI even now, which enables
the building of the arm-cci.c.

Stephen,

We need the following fix on the linux-next.


Oops, sorry about that.  I have fixed up the merge resolution for today
so that file starts like this:

#
# Bus Devices
#

menu Bus devices

config ARM_CCI
bool

config ARM_CCI400_COMMON
bool
select ARM_CCI

config ARM_CCI400_PMU
bool ARM CCI400 PMU support
default y
depends on ARM || ARM64
depends on HW_PERF_EVENTS
select ARM_CCI400_COMMON
help
  Support for PMU events monitoring on the ARM CCI cache coherent
  interconnect.

  If unsure, say Y

config ARM_CCI400_PORT_CTRL
bool
depends on ARM  OF  CPU_V7
select ARM_CCI400_COMMON
help
  Low level power management driver for CCI400 cache coherent
  interconnect for ARM platforms.


Looks good.

Thanks

Suzuki


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: linux-next: manual merge of the arm-soc tree with the arm-perf tree

2015-03-23 Thread Suzuki K. Poulose

On 23/03/15 14:41, Abhilash Kesavan wrote:

Hi Stephen,

On Mon, Mar 23, 2015 at 6:03 AM, Stephen Rothwell s...@canb.auug.org.au wrote:

Hi all,

Today's linux-next merge of the arm-soc tree got a conflict in
drivers/bus/Kconfig between commit c9966c98697a (arm-cci: Split the
code for PMU vs driver support) from the arm-perf tree and commit
13fbf3c8d0f7 (drivers: bus: Sort Kconfig entries alphabetically) from
the arm-soc tree.

I fixed it up (see below) and can carry the fix as necessary (no action
is required).


Not sure if this has been reported elsewhere, but I am seeing core
boot-up failures on the exynos5420 with next-20150323 due to this.
Your conflict fix is missing the ARM_CCI symbol because of which the
CCI does not get enabled.

Suzuki, can you confirm ?



Yes, you are right. We need the config ARM_CCI even now, which enables 
the building of the arm-cci.c.


Stephen,

We need the following fix on the linux-next.

Suzuki


diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index f4213b1..e0eac5a 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -4,6 +4,9 @@

 menu Bus devices

+config ARM_CCI
+   bool
+
 config ARM_CCI400_PORT_CTRL
bool
depends on ARM  OF  CPU_V7



Regards,
Abhilash


--
Cheers,
Stephen Rothwells...@canb.auug.org.au

diff --cc drivers/bus/Kconfig
index 79e297b1f221,7e9c2674af81..
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@@ -4,6 -4,21 +4,38 @@@

   menu Bus devices

  -config ARM_CCI
  -  bool ARM CCI driver support
++config ARM_CCI400_PORT_CTRL
++  bool
+   depends on ARM  OF  CPU_V7
++  select ARM_CCI400_COMMON
+   help
  -Driver supporting the CCI cache coherent interconnect for ARM
  -platforms.
++Low level power management driver for CCI400 cache coherent
++interconnect for ARM platforms.
++
++config ARM_CCI400_PMU
++  bool ARM CCI400 PMU support
++  default y
++  depends on ARM || ARM64
++  depends on HW_PERF_EVENTS
++  select ARM_CCI400_COMMON
++  help
++Support for PMU events monitoring on the ARM CCI cache coherent
++interconnect.
++
++If unsure, say Y
++
++config ARM_CCI400_COMMON
++  bool
++  select ARM_CCI
+
+ config ARM_CCN
+   bool ARM CCN driver support
+   depends on ARM || ARM64
+   depends on PERF_EVENTS
+   help
+ PMU (perf) driver supporting the ARM CCN (Cache Coherent Network)
+ interconnect.
+
   config BRCMSTB_GISB_ARB
 bool Broadcom STB GISB bus arbiter
 depends on ARM || MIPS

___
linux-arm-kernel mailing list
linux-arm-ker...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel






--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Renaming ARM_CCI

2015-03-23 Thread Suzuki K. Poulose

On 23/03/15 15:10, Valentin Rothberg wrote:

Hi Suzuki,

your commit c9966c98697a (arm-cci: Split the code for PMU vs driver
support) renames the Kconfig option ARM_CCI to ARM_CCI400_PORT_CTRL.
However, the commit does not rename all references on ARM_CCI:

It renames, but still, leaves the ARM_CCI to build the arm-cci.o, which 
is in the original commit.



drivers/bus/Kconfig:29: select ARM_CCI
drivers/bus/Makefile:6:obj-$(CONFIG_ARM_CCI)+= arm-cci.o
include/linux/arm-cci.h:31:#ifdef CONFIG_ARM_CCI

Is this intentional or is there a patch scheduled somewhere to fix this issue?

Yes, it is. This problem was introduced due to a conflict in the linux-next.

See :
 https://lkml.org/lkml/2015/3/22/240

Cheers
Suzuki


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Renaming ARM_CCI

2015-03-23 Thread Suzuki K. Poulose

On 23/03/15 15:17, Suzuki K. Poulose wrote:

On 23/03/15 15:10, Valentin Rothberg wrote:

Hi Suzuki,

your commit c9966c98697a (arm-cci: Split the code for PMU vs driver
support) renames the Kconfig option ARM_CCI to ARM_CCI400_PORT_CTRL.
However, the commit does not rename all references on ARM_CCI:


It renames, but still, leaves the ARM_CCI to build the arm-cci.o, which
is in the original commit.


drivers/bus/Kconfig:29: select ARM_CCI
drivers/bus/Makefile:6:obj-$(CONFIG_ARM_CCI)+= arm-cci.o
include/linux/arm-cci.h:31:#ifdef CONFIG_ARM_CCI

Is this intentional or is there a patch scheduled somewhere to fix this issue?

Yes, it is. This problem was introduced due to a conflict in the linux-next.

See :
   https://lkml.org/lkml/2015/3/22/240

Somehow, the link above doesn't link my response to the thread.
Please find it below.

https://lkml.org/lkml/2015/3/23/484

Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 0/5] arm-cci400: PMU monitoring support on ARM64

2015-03-02 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

This series enables the PMU monitoring support for CCI400 on ARM64.
The existing CCI400 driver code is a mix of PMU driver and the MCPM
driver code. The MCPM driver is only used on ARM(32) and contains
arm32 assembly and hence can't be built on ARM64. This patch splits
the code to

 - ARM_CCI400_PORT_CTRL driver - depends on ARM  V7
 - ARM_CCI400_PMU driver

Accessing the Peripheral ID2 register(PID2) on CCI-400, to detect
the revision of the chipset, is a secure operation. Hence, it prevents
us from running this on non-secure platforms. The issue is overcome by
explicitly mentioning the revision number of the CCI PMU in the device tree
binding. The device-tree binding has been updated with the new bindings.

i.e,arm-cci-400-pmu,r0 = revision 0
arm-cci-400-pmu,r1 = revision 1
arm-cci-400-pmu = (old) DEPRECATED

The old binding has been DEPRECATED and must be used only on ARM32
system with secure access. We don't have a reliable dynamic way to detect
if the system is running secure. This series tries to use the best safe
method by relying on the availability of MCPM(as it was prior to the series).
It is upto the MCPM platform driver to decide, if the system is secure before
it goes ahead and registers its drivers and pokes the CCI. This series doesn't
address/solve the problem of MCPM. I will be happy to use a better approach,
if there is any.

Tested on (non-secure)TC2 and Juno.

Change since V1 (Suggestions from Nicolas Pitre):

 - Split Patch 2 to separate the 'PMU' abstraction(now Patch 2/5)
   from the introduction of a new device-tree binding(now Patch 3/5)
 - Rename
ARM_CCI400_MCPM = ARM_CCI400_PORT_CTRL
CCI400_MCPM_PORTS_DATA = CCI400_PORTS_DATA
 - Select ARM_CCI400_COMMON for ARM_CCI400_PORT_CTRL
 - Better documentation in the git commit log about the ARM_CCI config.
 - Move the 'pr_info' to its apporpriate patch.

Suzuki K. Poulose (5):
  arm-cci: Rearrange code for splitting PMU vs driver code
  arm-cci: Abstract the CCI400 PMU speicific definitions
  arm-cci: Get rid of secure transactions for PMU driver
  arm-cci: Split the code for PMU vs driver support
  arm-cci: Fix CCI PMU event validation

 Documentation/devicetree/bindings/arm/cci.txt |7 +-
 arch/arm/include/asm/arm-cci.h|   42 +++
 arch/arm/mach-exynos/Kconfig  |2 +-
 arch/arm/mach-vexpress/Kconfig|4 +-
 arch/arm64/include/asm/arm-cci.h  |   27 ++
 drivers/bus/Kconfig   |   27 +-
 drivers/bus/arm-cci.c |  483 ++---
 include/linux/arm-cci.h   |9 +-
 8 files changed, 383 insertions(+), 218 deletions(-)
 create mode 100644 arch/arm/include/asm/arm-cci.h
 create mode 100644 arch/arm64/include/asm/arm-cci.h

-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 5/5] arm-cci: Fix CCI PMU event validation

2015-03-02 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

We mask the event with the CCI_PMU_EVENT_MASK, before passing
the config to pmu_validate_hw_event(), which causes extra bits
to be ignored and qualifies an invalid event code as valid.

e.g,
 $ perf stat -a -C 0 -e CCI_400/config=0x1ff,name=cycles/ sleep 1
   Performance counter stats for 'system wide':

 506951142  cycles

   1.013879626 seconds time elapsed

where, cycles has an event coding of 0xff. This patch also removes
the unnecessary 'event' mask in pmu_write_register, since the config_base
is set by the pmu code after the event is validated.

Helps in killing CCI_PMU_EVENT_MASK from common code.

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 drivers/bus/arm-cci.c |   10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index f86f096..438a121 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -191,11 +191,14 @@ static int pmu_is_valid_master_event(u8 ev_code)
ev_code = pmu-model-event_ranges[CCI_IF_MASTER].max;
 }
 
-static int pmu_validate_hw_event(u8 hw_event)
+static int pmu_validate_hw_event(u32 hw_event)
 {
u8 ev_source = CCI_PMU_EVENT_SOURCE(hw_event);
u8 ev_code = CCI_PMU_EVENT_CODE(hw_event);
 
+   if (hw_event  ~CCI_PMU_EVENT_MASK)
+   return -ENOENT;
+
switch (ev_source) {
case CCI_PORT_S0:
case CCI_PORT_S1:
@@ -265,7 +268,6 @@ static void pmu_enable_counter(int idx)
 
 static void pmu_set_event(int idx, unsigned long event)
 {
-   event = CCI_PMU_EVENT_MASK;
pmu_write_register(event, idx, CCI_PMU_EVT_SEL);
 }
 
@@ -282,7 +284,7 @@ static int pmu_get_event_idx(struct cci_pmu_hw_events *hw, 
struct perf_event *ev
 {
struct cci_pmu *cci_pmu = to_cci_pmu(event-pmu);
struct hw_perf_event *hw_event = event-hw;
-   unsigned long cci_event = hw_event-config_base  CCI_PMU_EVENT_MASK;
+   unsigned long cci_event = hw_event-config_base;
int idx;
 
if (cci_event == CCI_PMU_CYCLES) {
@@ -303,7 +305,7 @@ static int pmu_get_event_idx(struct cci_pmu_hw_events *hw, 
struct perf_event *ev
 static int pmu_map_event(struct perf_event *event)
 {
int mapping;
-   u8 config = event-attr.config  CCI_PMU_EVENT_MASK;
+   u32 config = event-attr.config;
 
if (event-attr.type  PERF_TYPE_MAX)
return -ENOENT;
-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/5] arm-cci: Abstract the CCI400 PMU speicific definitions

2015-03-02 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

CCI400 has different event specifications for PMU, for revsion0 and
revision 1. As of now, we check the revision twice, for using the
parameters for the PMU. This patch abstracts the details of the pmu
models in a struct (cci_pmu_model) and stores the information in cci_pmu
at initialisation time, avoiding multiple probe operations.

This will also help us to add new PMU versions.

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 drivers/bus/arm-cci.c |  124 ++---
 1 file changed, 76 insertions(+), 48 deletions(-)

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index f27cf56..bec014b 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -79,19 +79,38 @@ static const struct of_device_id arm_cci_matches[] = {
 
 #define CCI_PMU_MAX_HW_EVENTS 5   /* CCI PMU has 4 counters + 1 cycle counter 
*/
 
+/* Types of interfaces that can generate events */
+enum {
+   CCI_IF_SLAVE,
+   CCI_IF_MASTER,
+   CCI_IF_MAX,
+};
+
+struct event_range {
+   u32 min;
+   u32 max;
+};
+
 struct cci_pmu_hw_events {
struct perf_event *events[CCI_PMU_MAX_HW_EVENTS];
unsigned long used_mask[BITS_TO_LONGS(CCI_PMU_MAX_HW_EVENTS)];
raw_spinlock_t pmu_lock;
 };
 
+struct cci_pmu_model {
+   char *name;
+   struct event_range event_ranges[CCI_IF_MAX];
+};
+
+static struct cci_pmu_model cci_pmu_models[];
+
 struct cci_pmu {
void __iomem *base;
struct pmu pmu;
int nr_irqs;
int irqs[CCI_PMU_MAX_HW_EVENTS];
unsigned long active_irqs;
-   struct pmu_port_event_ranges *port_ranges;
+   const struct cci_pmu_model *model;
struct cci_pmu_hw_events hw_events;
struct platform_device *plat_device;
int num_events;
@@ -152,47 +171,16 @@ enum cci400_perf_events {
 #define CCI_REV_R1_MASTER_PORT_MIN_EV  0x00
 #define CCI_REV_R1_MASTER_PORT_MAX_EV  0x11
 
-struct pmu_port_event_ranges {
-   u8 slave_min;
-   u8 slave_max;
-   u8 master_min;
-   u8 master_max;
-};
-
-static struct pmu_port_event_ranges port_event_range[] = {
-   [CCI_REV_R0] = {
-   .slave_min = CCI_REV_R0_SLAVE_PORT_MIN_EV,
-   .slave_max = CCI_REV_R0_SLAVE_PORT_MAX_EV,
-   .master_min = CCI_REV_R0_MASTER_PORT_MIN_EV,
-   .master_max = CCI_REV_R0_MASTER_PORT_MAX_EV,
-   },
-   [CCI_REV_R1] = {
-   .slave_min = CCI_REV_R1_SLAVE_PORT_MIN_EV,
-   .slave_max = CCI_REV_R1_SLAVE_PORT_MAX_EV,
-   .master_min = CCI_REV_R1_MASTER_PORT_MIN_EV,
-   .master_max = CCI_REV_R1_MASTER_PORT_MAX_EV,
-   },
-};
-
-/*
- * Export different PMU names for the different revisions so userspace knows
- * because the event ids are different
- */
-static char *const pmu_names[] = {
-   [CCI_REV_R0] = CCI_400,
-   [CCI_REV_R1] = CCI_400_r1,
-};
-
 static int pmu_is_valid_slave_event(u8 ev_code)
 {
-   return pmu-port_ranges-slave_min = ev_code 
-   ev_code = pmu-port_ranges-slave_max;
+   return pmu-model-event_ranges[CCI_IF_SLAVE].min = ev_code 
+   ev_code = pmu-model-event_ranges[CCI_IF_SLAVE].max;
 }
 
 static int pmu_is_valid_master_event(u8 ev_code)
 {
-   return pmu-port_ranges-master_min = ev_code 
-   ev_code = pmu-port_ranges-master_max;
+   return pmu-model-event_ranges[CCI_IF_MASTER].min = ev_code 
+   ev_code = pmu-model-event_ranges[CCI_IF_MASTER].max;
 }
 
 static int pmu_validate_hw_event(u8 hw_event)
@@ -234,11 +222,9 @@ static int probe_cci_revision(void)
return CCI_REV_R1;
 }
 
-static struct pmu_port_event_ranges *port_range_by_rev(void)
+static const struct cci_pmu_model *probe_cci_model(struct platform_device 
*pdev)
 {
-   int rev = probe_cci_revision();
-
-   return port_event_range[rev];
+   return cci_pmu_models[probe_cci_revision()];
 }
 
 static int pmu_is_valid_counter(struct cci_pmu *cci_pmu, int idx)
@@ -807,9 +793,9 @@ static const struct attribute_group *pmu_attr_groups[] = {
 
 static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *pdev)
 {
-   char *name = pmu_names[probe_cci_revision()];
+   char *name = cci_pmu-model-name;
cci_pmu-pmu = (struct pmu) {
-   .name   = pmu_names[probe_cci_revision()],
+   .name   = cci_pmu-model-name,
.task_ctx_nr= perf_invalid_context,
.pmu_enable = cci_pmu_enable,
.pmu_disable= cci_pmu_disable,
@@ -862,6 +848,35 @@ static struct notifier_block cci_pmu_cpu_nb = {
.priority   = CPU_PRI_PERF + 1,
 };
 
+static struct cci_pmu_model cci_pmu_models[] = {
+   [CCI_REV_R0] = {
+   .name = CCI_400,
+   .event_ranges = {
+   [CCI_IF_SLAVE

[PATCH 3/5] arm-cci: Get rid of secure transactions for PMU driver

2015-03-02 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

Avoid secure transactions while probing the CCI PMU. The
existing code makes use of the Peripheral ID2 (PID2) register
to determine the revision of the CCI400, which requires a
secure transaction. This puts a limitation on the usage of the
driver on systems running non-secure Linux(e.g, ARM64).

Updated the device-tree binding for cci pmu node to add the explicit
revision number for the compatible field.

The supported strings are :
arm,cci-400-pmu,r0
arm,cci-400-pmu,r1
arm,cci-400-pmu - DEPRECATED. See NOTE below

NOTE: If the revision is not mentioned, we need to probe the cci revision,
which could be fatal on a platform running non-secure. We need a reliable way
to know if we can poke the CCI registers at runtime on ARM32. We depend on
'mcpm_is_available()' when it is available. mcpm_is_available() returns true
only when there is a registered driver for mcpm. Otherwise, we assume that we
don't have secure access, and skips probing the revision number(ARM64 case).

The MCPM should figure out if it is safe to access the CCI. Unfortunately
there isn't a reliable way to indicate the same via dtb. This patch doesn't
address/change the current situation. It only deals with the CCI-PMU, leaving
the assumptions about the secure access as it has been, prior to this patch.

Cc: devicet...@vger.kernel.org
Cc: Punit Agrawal punit.agra...@arm.com
Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 Documentation/devicetree/bindings/arm/cci.txt |7 +++--
 arch/arm/include/asm/arm-cci.h|   42 +
 arch/arm64/include/asm/arm-cci.h  |   27 
 drivers/bus/arm-cci.c |   17 +-
 include/linux/arm-cci.h   |2 ++
 5 files changed, 92 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/include/asm/arm-cci.h
 create mode 100644 arch/arm64/include/asm/arm-cci.h

diff --git a/Documentation/devicetree/bindings/arm/cci.txt 
b/Documentation/devicetree/bindings/arm/cci.txt
index f28d82b..0e4b6a7 100644
--- a/Documentation/devicetree/bindings/arm/cci.txt
+++ b/Documentation/devicetree/bindings/arm/cci.txt
@@ -94,8 +94,11 @@ specific to ARM.
- compatible
Usage: required
Value type: string
-   Definition: must be arm,cci-400-pmu
-
+   Definition: Supported strings are :
+arm,cci-400-pmu,r0
+arm,cci-400-pmu,r1
+arm,cci-400-pmu  - DEPRECATED, permitted 
only where OS has
+ secure acces to CCI 
registers
- reg:
Usage: required
Value type: Integer cells. A register entry, expressed
diff --git a/arch/arm/include/asm/arm-cci.h b/arch/arm/include/asm/arm-cci.h
new file mode 100644
index 000..936e74a
--- /dev/null
+++ b/arch/arm/include/asm/arm-cci.h
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/include/asm/arm-cci.h
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see http://www.gnu.org/licenses/.
+ */
+
+#ifndef __ASM_ARM_CCI_H
+#define __ASM_ARM_CCI_H
+
+#ifdef CONFIG_MCPM
+#include asm/mcpm.h
+
+/*
+ * We don't have a reliable way of detecting whether,
+ * if we have access to secure-only registers, unless
+ * mcpm is registered.
+ */
+static inline int platform_has_secure_cci_access(void)
+{
+   return mcpm_is_available();
+}
+
+#else
+static inline int platform_has_secure_cci_access(void)
+{
+   return 0;
+}
+#endif
+
+#endif
diff --git a/arch/arm64/include/asm/arm-cci.h b/arch/arm64/include/asm/arm-cci.h
new file mode 100644
index 000..37bbe37
--- /dev/null
+++ b/arch/arm64/include/asm/arm-cci.h
@@ -0,0 +1,27 @@
+/*
+ * arch/arm64/include/asm/arm-cci.h
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU

[PATCH 1/5] arm-cci: Rearrange code for splitting PMU vs driver code

2015-03-02 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

No functional changes, only code re-arrangements for easier split of the
PMU code vs low level driver code. Extracts the port handling code
to cci_probe_ports().

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 drivers/bus/arm-cci.c |  330 +
 1 file changed, 168 insertions(+), 162 deletions(-)

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 84fd660..f27cf56 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -29,42 +29,29 @@
 #include asm/cacheflush.h
 #include asm/smp_plat.h
 
-#define DRIVER_NAMECCI-400
-#define DRIVER_NAME_PMUDRIVER_NAME  PMU
-
-#define CCI_PORT_CTRL  0x0
-#define CCI_CTRL_STATUS0xc
-
-#define CCI_ENABLE_SNOOP_REQ   0x1
-#define CCI_ENABLE_DVM_REQ 0x2
-#define CCI_ENABLE_REQ (CCI_ENABLE_SNOOP_REQ | CCI_ENABLE_DVM_REQ)
+static void __iomem *cci_ctrl_base;
+static unsigned long cci_ctrl_phys;
 
 struct cci_nb_ports {
unsigned int nb_ace;
unsigned int nb_ace_lite;
 };
 
-enum cci_ace_port_type {
-   ACE_INVALID_PORT = 0x0,
-   ACE_PORT,
-   ACE_LITE_PORT,
+static const struct cci_nb_ports cci400_ports = {
+   .nb_ace = 2,
+   .nb_ace_lite = 3
 };
 
-struct cci_ace_port {
-   void __iomem *base;
-   unsigned long phys;
-   enum cci_ace_port_type type;
-   struct device_node *dn;
+static const struct of_device_id arm_cci_matches[] = {
+   {.compatible = arm,cci-400, .data = cci400_ports },
+   {},
 };
 
-static struct cci_ace_port *ports;
-static unsigned int nb_cci_ports;
-
-static void __iomem *cci_ctrl_base;
-static unsigned long cci_ctrl_phys;
-
 #ifdef CONFIG_HW_PERF_EVENTS
 
+#define DRIVER_NAMECCI-400
+#define DRIVER_NAME_PMUDRIVER_NAME  PMU
+
 #define CCI_PMCR   0x0100
 #define CCI_PID2   0x0fe8
 
@@ -75,6 +62,47 @@ static unsigned long cci_ctrl_phys;
 #define CCI_PID2_REV_MASK  0xf0
 #define CCI_PID2_REV_SHIFT 4
 
+#define CCI_PMU_EVT_SEL0x000
+#define CCI_PMU_CNTR   0x004
+#define CCI_PMU_CNTR_CTRL  0x008
+#define CCI_PMU_OVRFLW 0x00c
+
+#define CCI_PMU_OVRFLW_FLAG1
+
+#define CCI_PMU_CNTR_BASE(idx) ((idx) * SZ_4K)
+
+#define CCI_PMU_CNTR_MASK  ((1ULL  32) -1)
+
+#define CCI_PMU_EVENT_MASK 0xff
+#define CCI_PMU_EVENT_SOURCE(event)((event  5)  0x7)
+#define CCI_PMU_EVENT_CODE(event)  (event  0x1f)
+
+#define CCI_PMU_MAX_HW_EVENTS 5   /* CCI PMU has 4 counters + 1 cycle counter 
*/
+
+struct cci_pmu_hw_events {
+   struct perf_event *events[CCI_PMU_MAX_HW_EVENTS];
+   unsigned long used_mask[BITS_TO_LONGS(CCI_PMU_MAX_HW_EVENTS)];
+   raw_spinlock_t pmu_lock;
+};
+
+struct cci_pmu {
+   void __iomem *base;
+   struct pmu pmu;
+   int nr_irqs;
+   int irqs[CCI_PMU_MAX_HW_EVENTS];
+   unsigned long active_irqs;
+   struct pmu_port_event_ranges *port_ranges;
+   struct cci_pmu_hw_events hw_events;
+   struct platform_device *plat_device;
+   int num_events;
+   atomic_t active_events;
+   struct mutex reserve_mutex;
+   cpumask_t cpus;
+};
+static struct cci_pmu *pmu;
+
+#define to_cci_pmu(c)  (container_of(c, struct cci_pmu, pmu))
+
 /* Port ids */
 #define CCI_PORT_S00
 #define CCI_PORT_S11
@@ -89,17 +117,6 @@ static unsigned long cci_ctrl_phys;
 #define CCI_REV_R1 1
 #define CCI_REV_R1_PX  5
 
-#define CCI_PMU_EVT_SEL0x000
-#define CCI_PMU_CNTR   0x004
-#define CCI_PMU_CNTR_CTRL  0x008
-#define CCI_PMU_OVRFLW 0x00c
-
-#define CCI_PMU_OVRFLW_FLAG1
-
-#define CCI_PMU_CNTR_BASE(idx) ((idx) * SZ_4K)
-
-#define CCI_PMU_CNTR_MASK  ((1ULL  32) -1)
-
 /*
  * Instead of an event id to monitor CCI cycles, a dedicated counter is
  * provided. Use 0xff to represent CCI cycles and hope that no future revisions
@@ -109,12 +126,6 @@ enum cci400_perf_events {
CCI_PMU_CYCLES = 0xff
 };
 
-#define CCI_PMU_EVENT_MASK 0xff
-#define CCI_PMU_EVENT_SOURCE(event)((event  5)  0x7)
-#define CCI_PMU_EVENT_CODE(event)  (event  0x1f)
-
-#define CCI_PMU_MAX_HW_EVENTS 5   /* CCI PMU has 4 counters + 1 cycle counter 
*/
-
 #define CCI_PMU_CYCLE_CNTR_IDX 0
 #define CCI_PMU_CNTR0_IDX  1
 #define CCI_PMU_CNTR_LAST(cci_pmu) (CCI_PMU_CYCLE_CNTR_IDX + 
cci_pmu-num_events - 1)
@@ -172,60 +183,6 @@ static char *const pmu_names[] = {
[CCI_REV_R1] = CCI_400_r1,
 };
 
-struct cci_pmu_hw_events {
-   struct perf_event *events[CCI_PMU_MAX_HW_EVENTS];
-   unsigned long used_mask[BITS_TO_LONGS(CCI_PMU_MAX_HW_EVENTS)];
-   raw_spinlock_t pmu_lock;
-};
-
-struct cci_pmu {
-   void __iomem *base;
-   struct pmu pmu;
-   int nr_irqs;
-   int irqs[CCI_PMU_MAX_HW_EVENTS];
-   unsigned long active_irqs;
-   struct

[PATCH 4/5] arm-cci: Split the code for PMU vs driver support

2015-03-02 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

This patch separates the PMU driver code from the low level
CCI driver code.

Introduces config options for both.

 ARM_CCI400_PORT_CTRL   - controls the low level driver code for
  CCI400 ports.
 ARM_CCI400_PMU - controls the PMU driver code
 ARM_CCI400_COMMON  - Common defintions for CCI400

Also the ARM_CCI400_PORT_CTRL cannot be enabled by user. This
should be selected by platforms which need it.

This patch also changes:
 ARM_CCI - common code for probing the CCI devices. This can be
   used for adding support for newer CCI versions(e.g, CCI-500).

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 arch/arm/mach-exynos/Kconfig   |2 +-
 arch/arm/mach-vexpress/Kconfig |4 ++--
 drivers/bus/Kconfig|   27 +++
 drivers/bus/arm-cci.c  |   24 
 include/linux/arm-cci.h|7 ++-
 5 files changed, 52 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 603820e..81064cd 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -123,7 +123,7 @@ config SOC_EXYNOS5800
 config EXYNOS5420_MCPM
bool Exynos5420 Multi-Cluster PM support
depends on MCPM  SOC_EXYNOS5420
-   select ARM_CCI
+   select ARM_CCI400_PORT_CTRL
select ARM_CPU_SUSPEND
help
  This is needed to provide CPU and cluster power management
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index d6b16d9..dd127f1 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -53,7 +53,7 @@ config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
 config ARCH_VEXPRESS_DCSCB
bool Dual Cluster System Control Block (DCSCB) support
depends on MCPM
-   select ARM_CCI
+   select ARM_CCI400_PORT_CTRL
help
  Support for the Dual Cluster System Configuration Block (DCSCB).
  This is needed to provide CPU and cluster power management
@@ -71,7 +71,7 @@ config ARCH_VEXPRESS_SPC
 config ARCH_VEXPRESS_TC2_PM
bool Versatile Express TC2 power management
depends on MCPM
-   select ARM_CCI
+   select ARM_CCI400_PORT_CTRL
select ARCH_VEXPRESS_SPC
help
  Support for CPU and cluster power management on Versatile Express
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index b99729e..bdc189f 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -43,12 +43,31 @@ config OMAP_INTERCONNECT
help
  Driver to enable OMAP interconnect error handling driver.
 
-config ARM_CCI
-   bool ARM CCI driver support
+config ARM_CCI400_PORT_CTRL
+   bool
depends on ARM  OF  CPU_V7
+   select ARM_CCI400_COMMON
+   help
+ Low level power management driver for CCI400 cache coherent
+ interconnect for ARM platforms.
+
+config ARM_CCI400_PMU
+   bool ARM CCI400 PMU support
+   depends on ARM || ARM64
+   depends on HW_PERF_EVENTS
+   select ARM_CCI400_COMMON
help
- Driver supporting the CCI cache coherent interconnect for ARM
- platforms.
+ Support for PMU events monitoring on the ARM CCI cache coherent
+ interconnect.
+
+ If unsure, say N
+
+config ARM_CCI400_COMMON
+   bool
+   select ARM_CCI
+
+config ARM_CCI
+   bool
 
 config ARM_CCN
bool ARM CCN driver support
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 56ad928..f86f096 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -32,6 +32,7 @@
 static void __iomem *cci_ctrl_base;
 static unsigned long cci_ctrl_phys;
 
+#ifdef CONFIG_ARM_CCI400_PORT_CTRL
 struct cci_nb_ports {
unsigned int nb_ace;
unsigned int nb_ace_lite;
@@ -42,12 +43,19 @@ static const struct cci_nb_ports cci400_ports = {
.nb_ace_lite = 3
 };
 
+#define CCI400_PORTS_DATA  (cci400_ports)
+#else
+#define CCI400_PORTS_DATA  (NULL)
+#endif
+
 static const struct of_device_id arm_cci_matches[] = {
-   {.compatible = arm,cci-400, .data = cci400_ports },
+#ifdef CONFIG_ARM_CCI400_COMMON
+   {.compatible = arm,cci-400, .data = CCI400_PORTS_DATA },
+#endif
{},
 };
 
-#ifdef CONFIG_HW_PERF_EVENTS
+#ifdef CONFIG_ARM_CCI400_PMU
 
 #define DRIVER_NAMECCI-400
 #define DRIVER_NAME_PMUDRIVER_NAME  PMU
@@ -1020,14 +1028,16 @@ static int __init cci_platform_init(void)
return platform_driver_register(cci_platform_driver);
 }
 
-#else /* !CONFIG_HW_PERF_EVENTS */
+#else /* !CONFIG_ARM_CCI400_PMU */
 
 static int __init cci_platform_init(void)
 {
return 0;
 }
 
-#endif /* CONFIG_HW_PERF_EVENTS */
+#endif /* CONFIG_ARM_CCI400_PMU */
+
+#ifdef CONFIG_ARM_CCI400_PORT_CTRL
 
 #define CCI_PORT_CTRL  0x0
 #define CCI_CTRL_STATUS0xc
@@ -1458,6 +1468,12 @@ static int cci_probe_ports

Re: [PATCH 3/5] arm-cci: Get rid of secure transactions for PMU driver

2015-03-04 Thread Suzuki K. Poulose

On 03/03/15 15:44, Sudeep Holla wrote:



On 02/03/15 11:29, Suzuki K. Poulose wrote:

From: Suzuki K. Poulose suzuki.poul...@arm.com

Avoid secure transactions while probing the CCI PMU. The
existing code makes use of the Peripheral ID2 (PID2) register
to determine the revision of the CCI400, which requires a
secure transaction. This puts a limitation on the usage of the
driver on systems running non-secure Linux(e.g, ARM64).

Updated the device-tree binding for cci pmu node to add the explicit
revision number for the compatible field.

The supported strings are :
arm,cci-400-pmu,r0
arm,cci-400-pmu,r1
arm,cci-400-pmu - DEPRECATED. See NOTE below

NOTE: If the revision is not mentioned, we need to probe the cci revision,
which could be fatal on a platform running non-secure. We need a reliable way
to know if we can poke the CCI registers at runtime on ARM32. We depend on
'mcpm_is_available()' when it is available. mcpm_is_available() returns true
only when there is a registered driver for mcpm. Otherwise, we assume that we
don't have secure access, and skips probing the revision number(ARM64 case).

The MCPM should figure out if it is safe to access the CCI. Unfortunately
there isn't a reliable way to indicate the same via dtb. This patch doesn't
address/change the current situation. It only deals with the CCI-PMU, leaving
the assumptions about the secure access as it has been, prior to this patch.

Cc: devicet...@vger.kernel.org
Cc: Punit Agrawal punit.agra...@arm.com
Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
   Documentation/devicetree/bindings/arm/cci.txt |7 +++--
   arch/arm/include/asm/arm-cci.h|   42 
+
   arch/arm64/include/asm/arm-cci.h  |   27 
   drivers/bus/arm-cci.c |   17 +-
   include/linux/arm-cci.h   |2 ++
   5 files changed, 92 insertions(+), 3 deletions(-)
   create mode 100644 arch/arm/include/asm/arm-cci.h
   create mode 100644 arch/arm64/include/asm/arm-cci.h



[...]


diff --git a/arch/arm/include/asm/arm-cci.h b/arch/arm/include/asm/arm-cci.h
new file mode 100644
index 000..936e74a
--- /dev/null
+++ b/arch/arm/include/asm/arm-cci.h
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/include/asm/arm-cci.h
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see http://www.gnu.org/licenses/.
+ */
+
+#ifndef __ASM_ARM_CCI_H
+#define __ASM_ARM_CCI_H
+
+#ifdef CONFIG_MCPM
+#include asm/mcpm.h
+
+/*
+ * We don't have a reliable way of detecting whether,
+ * if we have access to secure-only registers, unless
+ * mcpm is registered.
+ */
+static inline int platform_has_secure_cci_access(void)


bool instead of int might be more apt here ?


Yes, I will do that in the next revision.

Thanks
Suzuki


Regards,
Sudeep




--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 4/5] arm-cci: Split the code for PMU vs driver support

2015-03-04 Thread Suzuki K. Poulose

On 03/03/15 15:53, Sudeep Holla wrote:



On 02/03/15 11:29, Suzuki K. Poulose wrote:

From: Suzuki K. Poulose suzuki.poul...@arm.com

This patch separates the PMU driver code from the low level
CCI driver code.

Introduces config options for both.

   ARM_CCI400_PORT_CTRL - controls the low level driver code for
  CCI400 ports.
   ARM_CCI400_PMU   - controls the PMU driver code
   ARM_CCI400_COMMON- Common defintions for CCI400

Also the ARM_CCI400_PORT_CTRL cannot be enabled by user. This
should be selected by platforms which need it.

This patch also changes:
   ARM_CCI - common code for probing the CCI devices. This can be
 used for adding support for newer CCI versions(e.g, CCI-500).

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
   arch/arm/mach-exynos/Kconfig   |2 +-
   arch/arm/mach-vexpress/Kconfig |4 ++--
   drivers/bus/Kconfig|   27 +++
   drivers/bus/arm-cci.c  |   24 
   include/linux/arm-cci.h|7 ++-
   5 files changed, 52 insertions(+), 12 deletions(-)



[...]


diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index b99729e..bdc189f 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -43,12 +43,31 @@ config OMAP_INTERCONNECT
help
  Driver to enable OMAP interconnect error handling driver.

-config ARM_CCI
-   bool ARM CCI driver support
+config ARM_CCI400_PORT_CTRL
+   bool
depends on ARM  OF  CPU_V7
+   select ARM_CCI400_COMMON
+   help
+ Low level power management driver for CCI400 cache coherent
+ interconnect for ARM platforms.
+
+config ARM_CCI400_PMU
+   bool ARM CCI400 PMU support
+   depends on ARM || ARM64
+   depends on HW_PERF_EVENTS
+   select ARM_CCI400_COMMON
help
- Driver supporting the CCI cache coherent interconnect for ARM
- platforms.
+ Support for PMU events monitoring on the ARM CCI cache coherent
+ interconnect.
+
+ If unsure, say N


Just a query rather than comment. Before this change all platforms
having ARM_CCI and HW_PERF_EVENTS had CCI PMU enabled by default.
With this change, one has to select this option explicitly. I assume
that's fine, else this needs to be default 'y'


Yes, that makes sense. Now that we decide if we can access the CCI 
safely at runtime, it is safe to make this default.


Regards
Suzuki


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 0/5] arm-cci400: PMU monitoring support on ARM64

2015-03-04 Thread Suzuki K. Poulose

On 03/03/15 16:00, Sudeep Holla wrote:



On 02/03/15 11:29, Suzuki K. Poulose wrote:

From: Suzuki K. Poulose suzuki.poul...@arm.com

This series enables the PMU monitoring support for CCI400 on ARM64.
The existing CCI400 driver code is a mix of PMU driver and the MCPM
driver code. The MCPM driver is only used on ARM(32) and contains
arm32 assembly and hence can't be built on ARM64. This patch splits
the code to

   - ARM_CCI400_PORT_CTRL driver - depends on ARM  V7
   - ARM_CCI400_PMU driver

Accessing the Peripheral ID2 register(PID2) on CCI-400, to detect
the revision of the chipset, is a secure operation. Hence, it prevents
us from running this on non-secure platforms. The issue is overcome by
explicitly mentioning the revision number of the CCI PMU in the device tree
binding. The device-tree binding has been updated with the new bindings.

i.e,arm-cci-400-pmu,r0 = revision 0
arm-cci-400-pmu,r1 = revision 1
arm-cci-400-pmu = (old) DEPRECATED

The old binding has been DEPRECATED and must be used only on ARM32
system with secure access. We don't have a reliable dynamic way to detect
if the system is running secure. This series tries to use the best safe
method by relying on the availability of MCPM(as it was prior to the series).
It is upto the MCPM platform driver to decide, if the system is secure before
it goes ahead and registers its drivers and pokes the CCI. This series doesn't
address/solve the problem of MCPM. I will be happy to use a better approach,
if there is any.

Tested on (non-secure)TC2 and Juno.



For the series:
Tested-by: Sudeep Holla sudeep.ho...@arm.com (on secure/MCPM TC2)



Thanks a lot for the testing

Suzuki

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/5] arm-cci: Rearrange code for splitting PMU vs driver code

2015-03-04 Thread Suzuki K. Poulose

On 03/03/15 15:35, Sudeep Holla wrote:



On 02/03/15 11:29, Suzuki K. Poulose wrote:

From: Suzuki K. Poulose suzuki.poul...@arm.com

No functional changes, only code re-arrangements for easier split of the
PMU code vs low level driver code. Extracts the port handling code
to cci_probe_ports().

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
   drivers/bus/arm-cci.c |  330 
+
   1 file changed, 168 insertions(+), 162 deletions(-)

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 84fd660..f27cf56 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c


[...]


@@ -1395,11 +1412,36 @@ static int cci_probe(void)
sync_cache_w(cpu_port);
__sync_cache_range_w(ports, sizeof(*ports) * nb_cci_ports);
pr_info(ARM CCI driver probed\n);
+
return 0;
+}
+
+static int cci_probe(void)
+{
+   int ret;
+   struct device_node *np;
+   struct resource res;
+
+   np = of_find_matching_node(NULL, arm_cci_matches);
+   if (!np)
+   return -ENODEV;

-memalloc_err:
+   if (!of_device_is_available(np))
+   return -ENODEV;
+
+   ret = of_address_to_resource(np, 0, res);
+   if (!ret) {
+   cci_ctrl_base = ioremap(res.start, resource_size(res));
+   cci_ctrl_phys = res.start;
+   }
+   if (ret || !cci_ctrl_base) {
+   WARN(1, unable to ioremap CCI ctrl\n);
+   ret = -ENXIO;
+   goto out;


IMO you can return directly here and get rid of this goto as nothing is
done there.


Yes, you are right. I will fix that in the next revision.

Regards
Suzuki


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] fanotify: Fix event filtering with FAN_ONDIR set

2015-02-27 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

With FAN_ONDIR set, the user can end up getting events, which
it hasn't marked. This was revealed with fanotify04 testcase
failure on Linux-4.0-rc1, and is a regression from 3.19, revealed
with commit (66ba93c0d7fe6: fanotify: don't set FAN_ONDIR implicitly
on a marks ignored mask).

 # /opt/ltp/testcases/bin/fanotify04
 [ ... ]
fanotify047  TPASS  :  event generated properly for type 10
fanotify048  TFAIL  :  fanotify04.c:147: got unexpected event 30
fanotify049  TPASS  :  No event as expected

The testcase sets the adds the following marks :
FAN_OPEN | FAN_ONDIR for a fanotify on a dir.
Then does an open(), followed by close() of the directory and
expects to see an event FAN_OPEN(0x20). However, the fanotify
returns (FAN_OPEN|FAN_CLOSE_NOWRITE(0x10)). This happens due
to the flaw in the check for event_mask in fanotify_should_send_event()
which does:

if (event_mask  marks_mask  ~marks_ignored_mask)
return true;

where, event_mask = (FAN_ONDIR | FAN_CLOSE_NOWRITE),
   marks_mask = (FAN_ONDIR | FAN_OPEN),
   marks_ignored_mask = 0

Fix this by masking the outgoing events to the user, as we
already take care of FAN_ONDIR and FAN_EVENT_ON_CHILD.

Cc: Lino Sanfilippo linosanfili...@gmx.de
Cc: Jan Kara j...@suse.cz
Cc: Eric Paris epa...@redhat.com
Cc: Andrew Morton a...@linux-foundation.org
Cc: Will Deacon will.dea...@arm.com
Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 fs/notify/fanotify/fanotify.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index 9a66ff7..d2f97ec 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -143,7 +143,8 @@ static bool fanotify_should_send_event(struct fsnotify_mark 
*inode_mark,
!(marks_mask  FS_ISDIR  ~marks_ignored_mask))
return false;
 
-   if (event_mask  marks_mask  ~marks_ignored_mask)
+   if (event_mask  FAN_ALL_OUTGOING_EVENTS  marks_mask 
+~marks_ignored_mask)
return true;
 
return false;
-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/4] arm-cci: Rearrange code for splitting PMU vs driver code

2015-02-24 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

No functional changes, only code re-arrangements for easier split of the
PMU code vs low level driver code. Extracts the port handling code
to cci_probe_ports().

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 drivers/bus/arm-cci.c |  330 +
 1 file changed, 168 insertions(+), 162 deletions(-)

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 84fd660..f27cf56 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -29,42 +29,29 @@
 #include asm/cacheflush.h
 #include asm/smp_plat.h
 
-#define DRIVER_NAMECCI-400
-#define DRIVER_NAME_PMUDRIVER_NAME  PMU
-
-#define CCI_PORT_CTRL  0x0
-#define CCI_CTRL_STATUS0xc
-
-#define CCI_ENABLE_SNOOP_REQ   0x1
-#define CCI_ENABLE_DVM_REQ 0x2
-#define CCI_ENABLE_REQ (CCI_ENABLE_SNOOP_REQ | CCI_ENABLE_DVM_REQ)
+static void __iomem *cci_ctrl_base;
+static unsigned long cci_ctrl_phys;
 
 struct cci_nb_ports {
unsigned int nb_ace;
unsigned int nb_ace_lite;
 };
 
-enum cci_ace_port_type {
-   ACE_INVALID_PORT = 0x0,
-   ACE_PORT,
-   ACE_LITE_PORT,
+static const struct cci_nb_ports cci400_ports = {
+   .nb_ace = 2,
+   .nb_ace_lite = 3
 };
 
-struct cci_ace_port {
-   void __iomem *base;
-   unsigned long phys;
-   enum cci_ace_port_type type;
-   struct device_node *dn;
+static const struct of_device_id arm_cci_matches[] = {
+   {.compatible = arm,cci-400, .data = cci400_ports },
+   {},
 };
 
-static struct cci_ace_port *ports;
-static unsigned int nb_cci_ports;
-
-static void __iomem *cci_ctrl_base;
-static unsigned long cci_ctrl_phys;
-
 #ifdef CONFIG_HW_PERF_EVENTS
 
+#define DRIVER_NAMECCI-400
+#define DRIVER_NAME_PMUDRIVER_NAME  PMU
+
 #define CCI_PMCR   0x0100
 #define CCI_PID2   0x0fe8
 
@@ -75,6 +62,47 @@ static unsigned long cci_ctrl_phys;
 #define CCI_PID2_REV_MASK  0xf0
 #define CCI_PID2_REV_SHIFT 4
 
+#define CCI_PMU_EVT_SEL0x000
+#define CCI_PMU_CNTR   0x004
+#define CCI_PMU_CNTR_CTRL  0x008
+#define CCI_PMU_OVRFLW 0x00c
+
+#define CCI_PMU_OVRFLW_FLAG1
+
+#define CCI_PMU_CNTR_BASE(idx) ((idx) * SZ_4K)
+
+#define CCI_PMU_CNTR_MASK  ((1ULL  32) -1)
+
+#define CCI_PMU_EVENT_MASK 0xff
+#define CCI_PMU_EVENT_SOURCE(event)((event  5)  0x7)
+#define CCI_PMU_EVENT_CODE(event)  (event  0x1f)
+
+#define CCI_PMU_MAX_HW_EVENTS 5   /* CCI PMU has 4 counters + 1 cycle counter 
*/
+
+struct cci_pmu_hw_events {
+   struct perf_event *events[CCI_PMU_MAX_HW_EVENTS];
+   unsigned long used_mask[BITS_TO_LONGS(CCI_PMU_MAX_HW_EVENTS)];
+   raw_spinlock_t pmu_lock;
+};
+
+struct cci_pmu {
+   void __iomem *base;
+   struct pmu pmu;
+   int nr_irqs;
+   int irqs[CCI_PMU_MAX_HW_EVENTS];
+   unsigned long active_irqs;
+   struct pmu_port_event_ranges *port_ranges;
+   struct cci_pmu_hw_events hw_events;
+   struct platform_device *plat_device;
+   int num_events;
+   atomic_t active_events;
+   struct mutex reserve_mutex;
+   cpumask_t cpus;
+};
+static struct cci_pmu *pmu;
+
+#define to_cci_pmu(c)  (container_of(c, struct cci_pmu, pmu))
+
 /* Port ids */
 #define CCI_PORT_S00
 #define CCI_PORT_S11
@@ -89,17 +117,6 @@ static unsigned long cci_ctrl_phys;
 #define CCI_REV_R1 1
 #define CCI_REV_R1_PX  5
 
-#define CCI_PMU_EVT_SEL0x000
-#define CCI_PMU_CNTR   0x004
-#define CCI_PMU_CNTR_CTRL  0x008
-#define CCI_PMU_OVRFLW 0x00c
-
-#define CCI_PMU_OVRFLW_FLAG1
-
-#define CCI_PMU_CNTR_BASE(idx) ((idx) * SZ_4K)
-
-#define CCI_PMU_CNTR_MASK  ((1ULL  32) -1)
-
 /*
  * Instead of an event id to monitor CCI cycles, a dedicated counter is
  * provided. Use 0xff to represent CCI cycles and hope that no future revisions
@@ -109,12 +126,6 @@ enum cci400_perf_events {
CCI_PMU_CYCLES = 0xff
 };
 
-#define CCI_PMU_EVENT_MASK 0xff
-#define CCI_PMU_EVENT_SOURCE(event)((event  5)  0x7)
-#define CCI_PMU_EVENT_CODE(event)  (event  0x1f)
-
-#define CCI_PMU_MAX_HW_EVENTS 5   /* CCI PMU has 4 counters + 1 cycle counter 
*/
-
 #define CCI_PMU_CYCLE_CNTR_IDX 0
 #define CCI_PMU_CNTR0_IDX  1
 #define CCI_PMU_CNTR_LAST(cci_pmu) (CCI_PMU_CYCLE_CNTR_IDX + 
cci_pmu-num_events - 1)
@@ -172,60 +183,6 @@ static char *const pmu_names[] = {
[CCI_REV_R1] = CCI_400_r1,
 };
 
-struct cci_pmu_hw_events {
-   struct perf_event *events[CCI_PMU_MAX_HW_EVENTS];
-   unsigned long used_mask[BITS_TO_LONGS(CCI_PMU_MAX_HW_EVENTS)];
-   raw_spinlock_t pmu_lock;
-};
-
-struct cci_pmu {
-   void __iomem *base;
-   struct pmu pmu;
-   int nr_irqs;
-   int irqs[CCI_PMU_MAX_HW_EVENTS];
-   unsigned long active_irqs;
-   struct

[PATCH 3/4] arm-cci: Split the code for PMU vs driver support

2015-02-24 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

This patch separates the PMU driver code from the low level
CCI driver code, and enables the CCI400-PMU for ARM64.

Introduces config options for both.

 - ARM_CCI400_MCPM  - controls the low level MCPM driver code for CCI
 - ARM_CCI400_PMU   - controls the PMU driver code
 - ARM_CCI400_COMMON- CCI400 specific details shared by MCPM
  and PMU
Changes:
 - ARM_CCI  - common code for probing the CCI devices

Cc: Bartlomiej Zolnierkiewicz b.zolnier...@samsung.com
Cc: Kukjin Kim kg...@kernel.org
Cc: Abhilash Kesavan a.kesa...@samsung.com
Cc: Liviu Dudau liviu.du...@arm.com
Cc: Lorenzo Pieralisi lorenzo.pieral...@arm.com
Cc: Sudeep Holla sudeep.ho...@arm.com
Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 arch/arm/mach-exynos/Kconfig   |2 +-
 arch/arm/mach-vexpress/Kconfig |4 ++--
 drivers/bus/Kconfig|   28 +++-
 drivers/bus/arm-cci.c  |   25 +
 include/linux/arm-cci.h|7 ++-
 5 files changed, 53 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 603820e..9bc8b4d 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -123,7 +123,7 @@ config SOC_EXYNOS5800
 config EXYNOS5420_MCPM
bool Exynos5420 Multi-Cluster PM support
depends on MCPM  SOC_EXYNOS5420
-   select ARM_CCI
+   select ARM_CCI400_MCPM
select ARM_CPU_SUSPEND
help
  This is needed to provide CPU and cluster power management
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index d6b16d9..097912f 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -53,7 +53,7 @@ config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
 config ARCH_VEXPRESS_DCSCB
bool Dual Cluster System Control Block (DCSCB) support
depends on MCPM
-   select ARM_CCI
+   select ARM_CCI400_MCPM
help
  Support for the Dual Cluster System Configuration Block (DCSCB).
  This is needed to provide CPU and cluster power management
@@ -71,7 +71,7 @@ config ARCH_VEXPRESS_SPC
 config ARCH_VEXPRESS_TC2_PM
bool Versatile Express TC2 power management
depends on MCPM
-   select ARM_CCI
+   select ARM_CCI400_MCPM
select ARCH_VEXPRESS_SPC
help
  Support for CPU and cluster power management on Versatile Express
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index b99729e..91dd013 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -43,12 +43,30 @@ config OMAP_INTERCONNECT
help
  Driver to enable OMAP interconnect error handling driver.
 
-config ARM_CCI
-   bool ARM CCI driver support
-   depends on ARM  OF  CPU_V7
+config ARM_CCI400_MCPM
+   bool
+   depends on ARM  OF  CPU_V7  MCPM
+   help
+ Low level power management driver for CCI400 cache coherent
+ interconnect for ARM platforms.
+
+config ARM_CCI400_PMU
+   bool ARM CCI400 PMU support
+   depends on ARM || ARM64
+   depends on HW_PERF_EVENTS
+   select ARM_CCI400_COMMON
help
- Driver supporting the CCI cache coherent interconnect for ARM
- platforms.
+ Support for PMU events monitoring on the ARM CCI cache coherent
+ interconnect.
+
+ If unsure, say N
+
+config ARM_CCI400_COMMON
+   bool
+   select ARM_CCI
+
+config ARM_CCI
+   bool
 
 config ARM_CCN
bool ARM CCN driver support
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index fe9fa46..7e330fe 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -32,6 +32,7 @@
 static void __iomem *cci_ctrl_base;
 static unsigned long cci_ctrl_phys;
 
+#ifdef CONFIG_ARM_CCI400_MCPM
 struct cci_nb_ports {
unsigned int nb_ace;
unsigned int nb_ace_lite;
@@ -42,12 +43,19 @@ static const struct cci_nb_ports cci400_ports = {
.nb_ace_lite = 3
 };
 
+#define CCI400_MCPM_PORTS_DATA (cci400_ports)
+#else
+#define CCI400_MCPM_PORTS_DATA (NULL)
+#endif
+
 static const struct of_device_id arm_cci_matches[] = {
-   {.compatible = arm,cci-400, .data = cci400_ports },
+#ifdef CONFIG_ARM_CCI400_COMMON
+   {.compatible = arm,cci-400, .data = CCI400_MCPM_PORTS_DATA },
+#endif
{},
 };
 
-#ifdef CONFIG_HW_PERF_EVENTS
+#ifdef CONFIG_ARM_CCI400_PMU
 
 #define DRIVER_NAMECCI-400
 #define DRIVER_NAME_PMUDRIVER_NAME  PMU
@@ -981,6 +989,7 @@ static int cci_pmu_probe(struct platform_device *pdev)
if (ret)
return ret;
 
+   pr_info(ARM %s PMU driver probed, pmu-model-name);
return 0;
 }
 
@@ -1019,14 +1028,16 @@ static int __init cci_platform_init(void)
return platform_driver_register(cci_platform_driver);
 }
 
-#else /* !CONFIG_HW_PERF_EVENTS */
+#else /* !CONFIG_ARM_CCI400_PMU

[PATCH 4/4] arm-cci: Fix CCI PMU event validation

2015-02-24 Thread Suzuki K. Poulose
From: Suzuki K. Poulose suzuki.poul...@arm.com

We mask the event with the CCI_PMU_EVENT_MASK, before passing
the config to pmu_validate_hw_event(), which causes extra bits
to be ignored and qualifies an invalid event code as valid.

e.g,
 $ perf stat -a -C 0 -e CCI_400/config=0x1ff,name=cycles/ sleep 1
   Performance counter stats for 'system wide':

 506951142  cycles

   1.013879626 seconds time elapsed

where, cycles has an event coding of 0xff. This patch also removes
the unnecessary 'event' mask in pmu_write_register, since the config_base
is set by the pmu code after the event is validated.

Signed-off-by: Suzuki K. Poulose suzuki.poul...@arm.com
---
 drivers/bus/arm-cci.c |   10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 7e330fe..b0ee582 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -191,11 +191,14 @@ static int pmu_is_valid_master_event(u8 ev_code)
ev_code = pmu-model-event_ranges[CCI_IF_MASTER].max;
 }
 
-static int pmu_validate_hw_event(u8 hw_event)
+static int pmu_validate_hw_event(u32 hw_event)
 {
u8 ev_source = CCI_PMU_EVENT_SOURCE(hw_event);
u8 ev_code = CCI_PMU_EVENT_CODE(hw_event);
 
+   if (hw_event  ~CCI_PMU_EVENT_MASK)
+   return -ENOENT;
+
switch (ev_source) {
case CCI_PORT_S0:
case CCI_PORT_S1:
@@ -265,7 +268,6 @@ static void pmu_enable_counter(int idx)
 
 static void pmu_set_event(int idx, unsigned long event)
 {
-   event = CCI_PMU_EVENT_MASK;
pmu_write_register(event, idx, CCI_PMU_EVT_SEL);
 }
 
@@ -282,7 +284,7 @@ static int pmu_get_event_idx(struct cci_pmu_hw_events *hw, 
struct perf_event *ev
 {
struct cci_pmu *cci_pmu = to_cci_pmu(event-pmu);
struct hw_perf_event *hw_event = event-hw;
-   unsigned long cci_event = hw_event-config_base  CCI_PMU_EVENT_MASK;
+   unsigned long cci_event = hw_event-config_base;
int idx;
 
if (cci_event == CCI_PMU_CYCLES) {
@@ -303,7 +305,7 @@ static int pmu_get_event_idx(struct cci_pmu_hw_events *hw, 
struct perf_event *ev
 static int pmu_map_event(struct perf_event *event)
 {
int mapping;
-   u8 config = event-attr.config  CCI_PMU_EVENT_MASK;
+   u32 config = event-attr.config;
 
if (event-attr.type  PERF_TYPE_MAX)
return -ENOENT;
-- 
1.7.9.5


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


  1   2   3   4   5   6   7   8   9   10   >