Re: [PATCH] [powerpc] Export memory limit via device tree
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
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
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
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
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
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
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
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
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
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
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
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()
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()
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
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
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
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
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
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
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
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
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
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
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
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
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
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()
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
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
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
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
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
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
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
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?
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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/