[PATCHv2 1/8] kprobes: Fix kallsyms lookup across powerpc ABIv1 and ABIv2
Currently, all non-dot symbols are being treated as function descriptors in ABIv1. This is incorrect and is resulting in perf probe not working: # perf probe do_fork Added new event: Failed to write event: Invalid argument Error: Failed to add events. # dmesg | tail -1 [192268.073063] Could not insert probe at _text+768432: -22 perf probe bases all kernel probes on _text and writes, for example, p:probe/do_fork _text+768432 to /sys/kernel/debug/tracing/kprobe_events. In-kernel, _text is being considered to be a function descriptor and is resulting in the above error. Fix this by changing how we lookup symbol addresses on ppc64. We first check for the dot variant of a symbol and look at the non-dot variant only if that fails. In this manner, we avoid having to look at the function descriptor. While at it, also separate out how this works on ABIv2 where we don't have dot symbols, but need to use the local entry point. Signed-off-by: Naveen N. Rao naveen.n@linux.vnet.ibm.com --- Mike, I have restricted all changes to just the kprobe_lookup_name() macro. It has now been split into different implementations for ABIv1 and ABIv2, hopefully addressing the concerns you raised previously. - Naveen arch/powerpc/include/asm/kprobes.h | 63 ++ 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/arch/powerpc/include/asm/kprobes.h b/arch/powerpc/include/asm/kprobes.h index af15d4d..039b583 100644 --- a/arch/powerpc/include/asm/kprobes.h +++ b/arch/powerpc/include/asm/kprobes.h @@ -41,34 +41,59 @@ typedef ppc_opcode_t kprobe_opcode_t; #define MAX_INSN_SIZE 1 #ifdef CONFIG_PPC64 +#if defined(_CALL_ELF) _CALL_ELF == 2 +/* PPC64 ABIv2 needs local entry point */ +#define kprobe_lookup_name(name, addr) \ +{ \ + addr = (kprobe_opcode_t *)kallsyms_lookup_name(name); \ + if (addr) \ + addr = (kprobe_opcode_t *)ppc_function_entry(addr); \ +} +#else /* - * 64bit powerpc uses function descriptors. - * Handle cases where: - * - User passes a .symbol or module:.symbol - * - User passes a symbol or module:symbol - * - User passes a non-existent symbol, kallsyms_lookup_name - * returns 0. Don't deref the NULL pointer in that case + * 64bit powerpc ABIv1 uses function descriptors: + * - Check for the dot variant of the symbol first. + * - If that fails, try looking up the symbol provided. + * + * This ensures we always get to the actual symbol and not the descriptor. + * Also handle module:symbol format. */ #define kprobe_lookup_name(name, addr) \ { \ - addr = (kprobe_opcode_t *)kallsyms_lookup_name(name); \ - if (addr) { \ - char *colon;\ - if ((colon = strchr(name, ':')) != NULL) { \ - colon++;\ - if (*colon != '\0' *colon != '.')\ - addr = (kprobe_opcode_t *)ppc_function_entry(addr); \ - } else if (name[0] != '.') \ - addr = (kprobe_opcode_t *)ppc_function_entry(addr); \ - } else {\ - char dot_name[KSYM_NAME_LEN]; \ + char dot_name[MODULE_NAME_LEN + 1 + KSYM_NAME_LEN]; \ + char *modsym; \ + bool dot_appended = false; \ + if ((modsym = strchr(name, ':')) != NULL) { \ + modsym++; \ + if (*modsym != '\0' *modsym != '.') {\ + /* Convert to module:.symbol */ \ + strncpy(dot_name, name, modsym - name); \ + dot_name[modsym - name] = '.'; \ + dot_name[modsym - name + 1] = '\0'; \ + strncat(dot_name, modsym, \ + sizeof(dot_name) - (modsym - name) - 2);\ + dot_appended = true;\ + } else {\ + dot_name[0] = '\0'; \ + strncat(dot_name, name, sizeof(dot_name) - 1); \ + } \ + } else if
[PATCHv2 0/8] Fix perf probe issues on powerpc
This patchset fixes various issues with perf probe on powerpc across ABIv1 and ABIv2: - in the presence of DWARF debug-info, - in the absence of DWARF, but with the symbol table, and - in the absence of debug-info, but with kallsyms. Applies cleanly on -tip. Tested on ppc64 BE and LE. Changes from previous version: Addressed various review comments from Mike Ellerman largely to generalize changes. Some of the simpler patches have been retained in their previous form to limit code churn, while others have been generalized by introducing arch helpers. Individual patches have more details. - Naveen Naveen N. Rao (8): kprobes: Fix kallsyms lookup across powerpc ABIv1 and ABIv2 perf probe: Improve detection of file/function name in the probe pattern perf probe powerpc: Fix symbol fixup issues due to ELF type perf probe powerpc: Handle powerpc dot symbols perf probe powerpc: Allow matching against dot symbols perf tools powerpc: Fix PPC64 ELF ABIv2 symbol decoding perf probe powerpc: Use DWARF info only if necessary perf probe powerpc: Fixup function entry if using kallsyms lookup arch/powerpc/include/asm/kprobes.h | 63 +++- tools/perf/arch/powerpc/Makefile| 1 + tools/perf/arch/powerpc/util/sym-handling.c | 64 + tools/perf/config/Makefile | 2 + tools/perf/util/probe-event.c | 48 ++ tools/perf/util/probe-event.h | 21 ++ tools/perf/util/symbol-elf.c| 5 ++- tools/perf/util/symbol.c| 6 +++ tools/perf/util/symbol.h| 6 +++ 9 files changed, 188 insertions(+), 28 deletions(-) create mode 100644 tools/perf/arch/powerpc/util/sym-handling.c -- 2.1.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCHv2 2/8] perf probe: Improve detection of file/function name in the probe pattern
Currently, perf probe considers patterns including a '.' to be a file. However, this causes problems on powerpc ABIv1 where all functions have a leading '.': $ perf probe -F | grep schedule_timeout_interruptible .schedule_timeout_interruptible $ perf probe .schedule_timeout_interruptible Semantic error :File always requires line number or lazy pattern. Error: Command Parse Error. Fix this by checking the probe pattern in more detail. Signed-off-by: Naveen N. Rao naveen.n@linux.vnet.ibm.com --- tools/perf/util/probe-event.c | 23 --- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 28eb141..9943ff3 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -999,6 +999,24 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) arg = tmp; } + /* +* Check arg is function or file name and copy it. +* +* We consider arg to be a file spec if and only if it satisfies +* all of the below criteria:: +* - it does not include any of +@%, +* - it includes one of :;, and +* - it has a period '.' in the name. +* +* Otherwise, we consider arg to be a function specification. +*/ + c = 0; + if (!strpbrk(arg, +@%) (ptr = strpbrk(arg, ;:)) != NULL) { + /* This is a file spec if it includes a '.' before ; or : */ + if (memchr(arg, '.', ptr-arg)) + c = 1; + } + ptr = strpbrk(arg, ;:+@%); if (ptr) { nc = *ptr; @@ -1009,10 +1027,9 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) if (tmp == NULL) return -ENOMEM; - /* Check arg is function or file and copy it */ - if (strchr(tmp, '.')) /* File */ + if (c == 1) pp-file = tmp; - else/* Function */ + else pp-function = tmp; /* Parse other options */ -- 2.1.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCHv2 3/8] perf probe powerpc: Fix symbol fixup issues due to ELF type
If using the symbol table, symbol addresses are not being fixed up properly, resulting in probes being placed at wrong addresses: # perf probe 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 # cat /sys/kernel/debug/tracing/kprobe_events p:probe/do_fork _text+635952 # printf %x 635952 9b430 # grep do_fork /boot/System.map c00ab430 T .do_fork Fix by checking for ELF type ET_DYN used by ppc64 kernels. Signed-off-by: Naveen N. Rao naveen.n@linux.vnet.ibm.com --- tools/perf/util/symbol-elf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 06fcd1b..7ac4e4c 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -683,7 +683,8 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name, NULL) != NULL); } else { ss-adjust_symbols = ehdr.e_type == ET_EXEC || -ehdr.e_type == ET_REL; +ehdr.e_type == ET_REL || +ehdr.e_type == ET_DYN; } ss-name = strdup(name); -- 2.1.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCHv2 4/8] perf probe powerpc: Handle powerpc dot symbols
Fix up various perf aspects related to ppc64's usage of dot functions: - ignore leading '.' when generating event names and when looking for existing events. - use the proper prefix when ignoring SyS symbol lookups. Signed-off-by: Naveen N. Rao naveen.n@linux.vnet.ibm.com --- tools/perf/util/probe-event.c | 8 tools/perf/util/symbol.c | 6 ++ 2 files changed, 14 insertions(+) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 9943ff3..74b7fef 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2080,6 +2080,10 @@ static int get_new_event_name(char *buf, size_t len, const char *base, { int i, ret; + /* Skip the leading dot on powerpc */ + if (*base == '.') + base++; + /* Try no suffix */ ret = e_snprintf(buf, len, %s, base); if (ret 0) { @@ -2538,6 +2542,10 @@ int del_perf_probe_events(struct strlist *dellist) event = str; } + /* Skip the leading dot on powerpc */ + if (event *event == '.') + event++; + ret = e_snprintf(buf, 128, %s:%s, group, event); if (ret 0) { pr_err(Failed to copy event.); diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index c24c5b8..e7b9bae 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -139,6 +139,12 @@ static int choose_best_symbol(struct symbol *syma, struct symbol *symb) if (na = 10 !strncmp(syma-name, compat_SyS, 10)) return SYMBOL_B; + /* On powerpc, ignore the dot variants */ + if (na = 4 !strncmp(syma-name, .SyS, 4)) + return SYMBOL_B; + if (na = 11 !strncmp(syma-name, .compat_SyS, 11)) + return SYMBOL_B; + return SYMBOL_A; } -- 2.1.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCHv2 5/8] perf probe powerpc: Allow matching against dot symbols
Allow perf probe to work on powerpc ABIv1 without the need to specify the leading dot '.' for functions. 'perf probe do_fork' works with this patch. Introduce HAVE_ARCH_SYMBOL_HANDLING to indicate need for special handling of symbols. In this patch, we override probe_function_filter() on powerpc to account for dot symbols. Signed-off-by: Naveen N. Rao naveen.n@linux.vnet.ibm.com --- Changes from the previous patchset: Introduced arch helper to override the way probe function filter works. tools/perf/arch/powerpc/Makefile| 1 + tools/perf/arch/powerpc/util/sym-handling.c | 28 tools/perf/config/Makefile | 1 + tools/perf/util/probe-event.c | 10 +- tools/perf/util/probe-event.h | 5 + 5 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 tools/perf/arch/powerpc/util/sym-handling.c diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile index 6f7782b..1c3d435 100644 --- a/tools/perf/arch/powerpc/Makefile +++ b/tools/perf/arch/powerpc/Makefile @@ -3,4 +3,5 @@ PERF_HAVE_DWARF_REGS := 1 LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/skip-callchain-idx.o endif +LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/sym-handling.o LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c new file mode 100644 index 000..0a77825 --- /dev/null +++ b/tools/perf/arch/powerpc/util/sym-handling.c @@ -0,0 +1,28 @@ +/* + * Special symbol handling for PowerPC: + * - Handle dot symbols on ABIv1 + * + * Copyright (C) 2014 Naveen N Rao, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include map.h +#include symbol.h +#include probe-event.h + +int probe_function_filter(struct map *map __maybe_unused, struct symbol *sym) +{ + if (sym-binding == STB_GLOBAL || sym-binding == STB_LOCAL) { + if ((strcmp(looking_function_name, sym-name) == 0) || + (sym-name[0] == '.' looking_function_name[0] != '.' +strcmp(looking_function_name, sym-name+1) == 0)) { + num_matched_functions++; + return 0; + } + } + return 1; +} diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 5d4b039..35cf934 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -383,6 +383,7 @@ ifeq ($(ARCH),powerpc) ifndef NO_DWARF CFLAGS += -DHAVE_SKIP_CALLCHAIN_IDX endif + CFLAGS += -DHAVE_ARCH_SYMBOL_HANDLING endif ifndef NO_LIBUNWIND diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 74b7fef..7eb9b27 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -50,6 +50,8 @@ #define PERFPROBE_GROUP probe bool probe_event_dry_run; /* Dry run flag */ +char *looking_function_name; +int num_matched_functions; #define semantic_error(msg ...) pr_err(Semantic error : msg) @@ -2210,11 +2212,8 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, return ret; } -static char *looking_function_name; -static int num_matched_functions; - -static int probe_function_filter(struct map *map __maybe_unused, - struct symbol *sym) +#ifndef HAVE_ARCH_SYMBOL_HANDLING +int probe_function_filter(struct map *map __maybe_unused, struct symbol *sym) { if ((sym-binding == STB_GLOBAL || sym-binding == STB_LOCAL) strcmp(looking_function_name, sym-name) == 0) { @@ -2223,6 +,7 @@ static int probe_function_filter(struct map *map __maybe_unused, } return 1; } +#endif /* HAVE_ARCH_SYMBOL_HANDLING */ #define strdup_or_goto(str, label) \ ({ char *__p = strdup(str); if (!__p) goto label; __p; }) diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index e01e994..8564451 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h @@ -7,6 +7,8 @@ #include strfilter.h extern bool probe_event_dry_run; +extern char *looking_function_name; +extern int num_matched_functions; /* kprobe-tracer and uprobe-tracer tracing point */ struct probe_trace_point { @@ -136,6 +138,9 @@ extern int show_available_vars(struct perf_probe_event *pevs, int npevs, extern int show_available_funcs(const char *module, struct strfilter *filter, bool user); +extern int probe_function_filter(struct map *map __maybe_unused, + struct symbol *sym); + /* Maximum index number of event-name postfix */ #define MAX_EVENT_INDEX1024 -- 2.1.3
[PATCHv2 6/8] perf tools powerpc: Fix PPC64 ELF ABIv2 symbol decoding
PPC64 ELF ABIv2 has a Global Entry Point (GEP) and a Local Entry Point (LEP). For purposes of probing, we need the LEP. Offset to the LEP is encoded in st_other. Signed-off-by: Ananth N Mavinakayanahalli ana...@in.ibm.com Signed-off-by: Naveen N. Rao naveen.n@linux.vnet.ibm.com --- Changes from previous patchset: Simplified logic by adding dependancy on HAVE_ARCH_SYMBOL_HANDLING. Also generalized arch_elf_sym_decode() to be suitable for other architectures in future. tools/perf/arch/powerpc/util/sym-handling.c | 10 ++ tools/perf/util/symbol-elf.c| 2 ++ tools/perf/util/symbol.h| 6 ++ 3 files changed, 18 insertions(+) diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c index 0a77825..a27bfaf 100644 --- a/tools/perf/arch/powerpc/util/sym-handling.c +++ b/tools/perf/arch/powerpc/util/sym-handling.c @@ -1,8 +1,10 @@ /* * Special symbol handling for PowerPC: * - Handle dot symbols on ABIv1 + * - Decode offset from Global entry point to Local entry point on ABIv2 * * Copyright (C) 2014 Naveen N Rao, IBM Corporation. + * Copyright (C) 2014 Ananth N Mavinakayanahalli, IBM Corporation. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -26,3 +28,11 @@ int probe_function_filter(struct map *map __maybe_unused, struct symbol *sym) } return 1; } + +inline void arch_elf_sym_decode(GElf_Sym *sym __maybe_unused) +{ +#if defined(_CALL_ELF) _CALL_ELF == 2 + if (sym sym-st_other) + sym-st_value += PPC64_LOCAL_ENTRY_OFFSET(sym-st_other); +#endif +} diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 7ac4e4c..557b63b 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -902,6 +902,8 @@ int dso__load_sym(struct dso *dso, struct map *map, (sym.st_value 1)) --sym.st_value; + arch_elf_sym_decode(sym); + if (dso-kernel || kmodule) { char dso_name[PATH_MAX]; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 9d602e9..9e03cdf 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -294,4 +294,10 @@ int compare_proc_modules(const char *from, const char *to); int setup_list(struct strlist **list, const char *list_str, const char *list_name); +#ifdef HAVE_ARCH_SYMBOL_HANDLING +extern void arch_elf_sym_decode(GElf_Sym *sym __maybe_unused); +#else +static inline void arch_elf_sym_decode(GElf_Sym *sym __maybe_unused) { } +#endif + #endif /* __PERF_SYMBOL */ -- 2.1.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCHv2 7/8] perf probe powerpc: Use DWARF info only if necessary
Use symbol table lookups by default if DWARF is not necessary, since powerpc ABIv2 encodes local entry points in the symbol table and the function entry address in DWARF may not be appropriate for kprobes, as described here: https://sourceware.org/bugzilla/show_bug.cgi?id=17638 The DWARF address ranges deliberately include the *whole* function, both global and local entry points. ... If you want to set probes on a local entry point, you should look up the symbol in the main symbol table (not DWARF), and check the st_other bits; they will indicate whether the function has a local entry point, and what its offset from the global entry point is. Note that GDB does the same when setting a breakpoint on a function entry. Signed-off-by: Naveen N. Rao naveen.n@linux.vnet.ibm.com --- Changes from previous patchset: Generalize and introduce helper to prefer symbol table over DWARF. tools/perf/arch/powerpc/util/sym-handling.c | 9 + tools/perf/config/Makefile | 1 + tools/perf/util/probe-event.c | 6 ++ tools/perf/util/probe-event.h | 6 ++ 4 files changed, 22 insertions(+) diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c index a27bfaf..22fc2e6 100644 --- a/tools/perf/arch/powerpc/util/sym-handling.c +++ b/tools/perf/arch/powerpc/util/sym-handling.c @@ -36,3 +36,12 @@ inline void arch_elf_sym_decode(GElf_Sym *sym __maybe_unused) sym-st_value += PPC64_LOCAL_ENTRY_OFFSET(sym-st_other); #endif } + +inline bool prefer_symtab(void) +{ +#if defined(_CALL_ELF) _CALL_ELF == 2 + return true; +#else + return false; +#endif +} diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 35cf934..849f686 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -384,6 +384,7 @@ ifeq ($(ARCH),powerpc) CFLAGS += -DHAVE_SKIP_CALLCHAIN_IDX endif CFLAGS += -DHAVE_ARCH_SYMBOL_HANDLING + CFLAGS += -DARCH_PREFER_SYMTAB endif ifndef NO_LIBUNWIND diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 7eb9b27..dfc3151 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2373,6 +2373,12 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev, } } + if (prefer_symtab() !perf_probe_event_need_dwarf(pev)) { + ret = find_probe_trace_events_from_map(pev, tevs, max_tevs, target); + if (ret 0) + return ret; /* Found in symbol table */ + } + /* Convert perf_probe_event with debuginfo */ ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, target); if (ret != 0) diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index 8564451..5f92906 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h @@ -141,6 +141,12 @@ extern int show_available_funcs(const char *module, struct strfilter *filter, extern int probe_function_filter(struct map *map __maybe_unused, struct symbol *sym); +#ifdef ARCH_PREFER_SYMTAB +extern bool prefer_symtab(void); +#else +static inline bool prefer_symtab(void) { return false; }; +#endif + /* Maximum index number of event-name postfix */ #define MAX_EVENT_INDEX1024 -- 2.1.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCHv2 8/8] perf probe powerpc: Fixup function entry if using kallsyms lookup
On powerpc ABIv2, if no debug-info is found and we use kallsyms, we need to fixup the function entry to point to the local entry point. Use offset of 8 since current toolchains always generate 2 instructions (8 bytes). Signed-off-by: Naveen N. Rao naveen.n@linux.vnet.ibm.com --- Changes: Generalize and introduce helper to post-process trace point. tools/perf/arch/powerpc/util/sym-handling.c | 17 + tools/perf/util/probe-event.c | 1 + tools/perf/util/probe-event.h | 10 ++ 3 files changed, 28 insertions(+) diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c index 22fc2e6..30c8797 100644 --- a/tools/perf/arch/powerpc/util/sym-handling.c +++ b/tools/perf/arch/powerpc/util/sym-handling.c @@ -45,3 +45,20 @@ inline bool prefer_symtab(void) return false; #endif } + +void arch_fix_tev_from_maps(struct perf_probe_event *pev __maybe_unused, + struct probe_trace_event *tev __maybe_unused, + struct map *map __maybe_unused) +{ +#if defined(_CALL_ELF) _CALL_ELF == 2 + /* +* If we used kallsyms, we should fixup the function entry address here. +* ppc64 ABIv2 local entry point is currently always 2 instructions (8 bytes) +* after the global entry point. Fix this if it ever changes. +*/ + if (!pev-uprobes map-dso-symtab_type == DSO_BINARY_TYPE__KALLSYMS) { + tev-point.address += 8; + tev-point.offset += 8; + } +#endif +} diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index dfc3151..85f37a4 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2340,6 +2340,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, strdup_or_goto(pev-args[i].type, nomem_out); } + arch_fix_tev_from_maps(pev, tev, map); } out: diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index 5f92906..335a6a4 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h @@ -147,6 +147,16 @@ extern bool prefer_symtab(void); static inline bool prefer_symtab(void) { return false; }; #endif +#ifdef HAVE_ARCH_SYMBOL_HANDLING +extern void arch_fix_tev_from_maps(struct perf_probe_event *pev __maybe_unused, + struct probe_trace_event *tev __maybe_unused, + struct map *map __maybe_unused); +#else +static inline void arch_fix_tev_from_maps(struct perf_probe_event *pev __maybe_unused, + struct probe_trace_event *tev __maybe_unused, + struct map *map __maybe_unused) { } +#endif + /* Maximum index number of event-name postfix */ #define MAX_EVENT_INDEX1024 -- 2.1.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 0/2] Add SDHCI support for APM X-Gene SoC using ARASAN SDHCI controller.
Due to the fact that the existing of-arasan driver works with 32-bit platforms. This patch tweaks existing of-arasan driver to work with 64-bit X-Gene platform using IOMMU translation. Signed-off-by: Suman Tripathi stripa...@apm.com --- Suman Tripathi (2): mmc: host: arasan: Add addition of-arasan quirks and add IOMMU support. arm64: dts: Add APM X-Gene SDHCI DTS node. arch/arm64/boot/dts/apm-storm.dtsi | 43 ++ drivers/mmc/host/Kconfig | 1 + drivers/mmc/host/sdhci-of-arasan.c | 54 ++ drivers/mmc/host/sdhci-pltfm.c | 12 + 4 files changed, 110 insertions(+) -- 1.8.2.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/2] arm64: dts: Add APM X-Gene SDHCI DTS node.
This patch adds the ahbclk and sdhciclk clock nodes and the sdhci device tree nodes of APM X-Gene SDHCI controller. Signed-off-by: Suman Tripathi stripa...@apm.com --- arch/arm64/boot/dts/apm-storm.dtsi | 43 ++ 1 file changed, 43 insertions(+) diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi index c0aceef..18e291b 100644 --- a/arch/arm64/boot/dts/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm-storm.dtsi @@ -144,6 +144,40 @@ clock-output-names = socplldiv2; }; + ahbclk: ahbclk@1f2ac000 { + compatible = apm,xgene-device-clock; + #clock-cells = 1; + clocks = socplldiv2 0; + reg = 0x0 0x1f2ac000 0x0 0x1000 + 0x0 0x1700 0x0 0x2000; + reg-names = csr-reg, div-reg; + csr-offset = 0x0; + csr-mask = 0x1; + enable-offset = 0x8; + enable-mask = 0x1; + divider-offset = 0x164; + divider-width = 0x5; + divider-shift = 0x0; + clock-output-names = ahbclk; + }; + + sdioclk: sdioclk@1f2ac000 { + compatible = apm,xgene-device-clock; + #clock-cells = 1; + clocks = socplldiv2 0; + reg = 0x0 0x1f2ac000 0x0 0x1000 + 0x0 0x1700 0x0 0x2000; + reg-names = csr-reg, div-reg; + csr-offset = 0x0; + csr-mask = 0x2; + enable-offset = 0x8; + enable-mask = 0x2; + divider-offset = 0x178; + divider-width = 0x8; + divider-shift = 0x0; + clock-output-names = sdioclk; + }; + qmlclk: qmlclk { compatible = apm,xgene-device-clock; #clock-cells = 1; @@ -397,6 +431,15 @@ clocks = rtcclk 0; }; + sdhc0: sdhc@1c00 { + device_type = sdhc; + compatible = arasan,sdhci-8.9a; + reg = 0x0 0x1c00 0x0 0x100; + interrupts = 0x0 0x49 0x4; + clock-names = clk_xin, clk_ahb; + clocks = sdioclk 0, ahbclk 0; + }; + menet: ethernet@1702 { compatible = apm,xgene-enet; status = disabled; -- 1.8.2.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/2] mmc: host: arasan: Add addition of-arasan quirks and add IOMMU support.
Due to the fact that the existing of-arasan driver works with 32-bit platforms. This patch tweaks existing of-arasan driver to work with 64-bit platform using IOMMU translation. In addition it adds support for more quirks and quirks2 obtained from device tree inside the generic sdhci-platform(sdhci-pltfm.c) driver. Signed-off-by: Suman Tripathi stripa...@apm.com --- drivers/mmc/host/Kconfig | 1 + drivers/mmc/host/sdhci-of-arasan.c | 54 ++ drivers/mmc/host/sdhci-pltfm.c | 12 + 3 files changed, 67 insertions(+) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 4511358..0c6dc47 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -108,6 +108,7 @@ config MMC_SDHCI_OF_ARASAN tristate SDHCI OF support for the Arasan SDHCI controllers depends on MMC_SDHCI_PLTFM depends on OF + select MMC_SDHCI_IO_ACCESSORS help This selects the Arasan Secure Digital Host Controller Interface (SDHCI). This hardware is found e.g. in Xilinx' Zynq SoC. diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 5bd1092..c0e0c9b 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -20,6 +20,10 @@ */ #include linux/module.h +#if defined(CONFIG_IOMMU_SUPPORT) +#include linux/amba/bus.h +#include linux/iommu.h +#endif #include sdhci-pltfm.h #define SDHCI_ARASAN_CLK_CTRL_OFFSET 0x2c @@ -34,8 +38,46 @@ */ struct sdhci_arasan_data { struct clk *clk_ahb; +#if defined(CONFIG_IOMMU_SUPPORT) + struct iommu_domain *domain; +#endif }; +static void sdhci_arasan_write_l(struct sdhci_host *host, u32 val, int reg) +{ +#if defined(CONFIG_IOMMU_SUPPORT) + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_arasan_data *sdhci_arasan = pltfm_host-priv; + /* +* This allows the arasan IP to integrate with 64-bit platform. +* As the AHB dma masters generates 32-bit address so it needs +* IO translation of 32-bit to 42-bit AXI address with help of IOMMU. +*/ + if (reg == SDHCI_DMA_ADDRESS) { + phys_addr_t dma_addr = sg_dma_address(host-data-sg); + sdhci_arasan-domain-ops-map(sdhci_arasan-domain, 0, + dma_addr, 0, 0); + } +#endif + writel(val, host-ioaddr + reg); +} + +static u32 xgene_sdhci_readl(struct sdhci_host *host, int reg) +{ +#if defined(CONFIG_IOMMU_SUPPORT) + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_arasan_data *sdhci_arasan = pltfm_host-priv; + + if (reg == SDHCI_INT_STATUS ) { + if ((readl(host-ioaddr + reg) SDHCI_INT_DATA_MASK) == +SDHCI_INT_DMA_END) + sdhci_arasan-domain-ops-unmap(sdhci_arasan-domain, +0, 0); + } +#endif + return readl(host-ioaddr + reg); +} + static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host) { u32 div; @@ -58,6 +100,8 @@ static struct sdhci_ops sdhci_arasan_ops = { .set_bus_width = sdhci_set_bus_width, .reset = sdhci_reset, .set_uhs_signaling = sdhci_set_uhs_signaling, + .write_l = sdhci_arasan_write_l, + .read_l = xgene_sdhci_readl, }; static struct sdhci_pltfm_data sdhci_arasan_pdata = { @@ -162,6 +206,16 @@ static int sdhci_arasan_probe(struct platform_device *pdev) goto clk_dis_ahb; } +#if defined(CONFIG_IOMMU_SUPPORT) + sdhci_arasan-domain = iommu_domain_alloc(amba_bustype); + if (!sdhci_arasan-domain) { + dev_err(pdev-dev, Unable to allocate iommu domain\n); + return PTR_ERR(sdhci_arasan-domain); + } + + iommu_attach_device(sdhci_arasan-domain, pdev-dev); +#endif + host = sdhci_pltfm_init(pdev, sdhci_arasan_pdata, 0); if (IS_ERR(host)) { ret = PTR_ERR(host); diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index 7e834fb..08a97dc 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c @@ -90,6 +90,18 @@ void sdhci_get_of_property(struct platform_device *pdev) if (of_get_property(np, broken-cd, NULL)) host-quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; + if (of_get_property(np, delay-after-power, NULL)) + host-quirks |= SDHCI_QUIRK_DELAY_AFTER_POWER; + + if (of_get_property(np, no-hispd, NULL)) + host-quirks |= SDHCI_QUIRK_NO_HISPD_BIT; + + if (of_get_property(np, broken-adma, NULL)) + host-quirks |= SDHCI_QUIRK_BROKEN_ADMA; + + if (of_get_property(np, no-cmd23, NULL)) + host-quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; +
PROBLEM: USB isochronous urb leak on EHCI driver
Hi, I am dealing with a USB EHCI driver bug. Here is the info: My configuration: - Host: Freescale i.MX512 with ARM Cortex A8 (USB 2.0 host controller) Linux kernel: 2.6.31, using EHCI USB driver Hub: 4-PORT USB 1.1 HUB (Texas Instruments PN: tusb2046b) Devices: 4 USB 1.1 audio codecs (Texas Instruments PN: pcm2901) Note: each codec is being used in R/W access, so with 4 codecs, I have 4 playback and 4 capture streams. My problem: --- I have usb urb leaks when connecting more than 1 codec to the USB 1.1 Hub. (the result is that some of the audio data is not transferred, part of the sound is simply missing) No problem when using only 1 of the 4 codecs connected to the hub; When I connect a second codec, the sound quality starts to degrade. With 3 codecs, we just cannot recognize a speach. Tests and observations: --- Since I have 3 usb ports available on the i.MX512, I tried to connect 3 codecs directly on USB ports: the sound is perfect on each of the three ports. I bought a consumer USB 2.0 Hub: no problem when using 3 codecs connected to that Hub, however, the audio will completly stop on all channels when connecting the 4th codec. I checked the communication between the Hub (USB 1.1) and the Host controller (USB 2.0) with a scope and concluded that the communication speed is 1.5 MBytes/s has expected (so the communication is downgraded to USB 1.1, since codecs and hub are USB 1.1 devices). Also, I know that there is physically enough bandwidth to transfer the data for two reasons: 1) I have an older CPU with a USB 1.1 host controller (using the OHCI driver), using the same hub and the same codecs: works like a champ, using less than 50% of the available bandwidth (observed with a scope) 2) 1 audio stream is 32khz-mono, 16 bits = 64 kB/s, 4 codecs = 8 streams(R/W) x 64 kB/s = 512 kB/s (out of 1.5MB/s) I noticed that my sound problem starts happening with only 2 codecs (4 streams, 256 kB/s). I first thought that it was a bandwidth limitation, so I decided to connect only 1 codec using more bandwidth. I configured it to 48khz-stereo (16-bits), using 384 kB/s for both read and write streams: no problem. With that configuration, the scope shows about 30% of total bandwidth usage (300us used out of 1ms periods). Then, I added a second codec (48khz-stereo-16bits): very strange, now the total bandwidth usage felt down to about 200us, which seems to keep the same, whatever the number of codec I add (I also tried 3 and 4...). So it looks like the scheduler is not able to properly allocate Isochronous time slots when more than one device is connected to the hub. However, without the hub, it works perfectly. Another interresting fact is that at application level, the Read and Write operations are returning the good amount of bytes read/written. This is not the case at kernel level: I noticed that function usb_submit_urb (from /drivers/usb/core/urb.c) will only tranfer part of the urbs when the sound is degraded. I tried to figure out where the leak comes from without success. Also, there are no error messages from kernel so everything appears to work well, excepted that part of the sound is missing! I can't change my hardware (this is in the hand of customers), so the only possible solution for me is to correct the software. I tried to change my ehci driver with the one from kernel 2.6.39.4 but did not work, same problem. Question: - Before attempting to upgrade to an earlier kernel driver (this is a fairly big amount of work), I would really like to know if this problem would still be in the 3.x kernels. Has anyone seen that issue in 3.x kernels? I am pretty new to USB driver debugging, so any ideas of where/how to find solutions will be appreciated. Thank you very much in advance for the support. Also don't hesitate to redirect me if I'm not at the right place to ask these questions. I can also provide some code if someone need it to help. Attached is a dump of my dmesg after startup. Michael Tessier 5Linux version 2.6.31-770-g0e46b52-0897 (michael.tess...@vsvr-compile-01.pocatec.com) (gcc version 4.1.2) #12 PREEMPT Mon Nov 24 18:34:19 EST 2014 4CPU: ARMv7 Processor [412fc085] revision 5 (ARMv7), cr=10c53c7f 4CPU: VIPT nonaliasing data cache, VIPT nonaliasing instruction cache 4Machine: MX51 Xanthus Board 4Memory policy: ECC disabled, Data cache writeback 7On node 0 totalpages: 65536 7free_area_init_node: node 0, pgdat c02f137c, node_mem_map c0307000 7 DMA zone: 128 pages used for memmap 7 DMA zone: 0 pages reserved 7 DMA zone: 16256 pages, LIFO batch:3 7 Normal zone: 384 pages used for memmap 7 Normal zone: 48768 pages, LIFO batch:15 4Built 1 zonelists in Zone order, mobility grouping on. Total pages: 65024 5Kernel command line: console=ttymxc2,115200 CNFGmagic=XATS CNFGversion=1.0.0.0 vendorID=EXPT platformID=LINX productID=XATS mac1=00:1D:9E:00:17:2e mac2=00:1D:9E:00:17:2f XanthusPart=8100050 XanthusSerial=51
Re: [PATCH 1/2] mmc: host: arasan: Add addition of-arasan quirks and add IOMMU support.
On Monday 15 December 2014 22:31:06 Suman Tripathi wrote: @@ -162,6 +206,16 @@ static int sdhci_arasan_probe(struct platform_device *pdev) goto clk_dis_ahb; } +#if defined(CONFIG_IOMMU_SUPPORT) + sdhci_arasan-domain = iommu_domain_alloc(amba_bustype); + if (!sdhci_arasan-domain) { + dev_err(pdev-dev, Unable to allocate iommu domain\n); + return PTR_ERR(sdhci_arasan-domain); + } + + iommu_attach_device(sdhci_arasan-domain, pdev-dev); +#endif + Device drivers should never care about the implementation details of the iommu. Please change the code to use the regular dma_map_* interfaces that will work both with and without IOMMU. Arnd ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: PROBLEM: USB isochronous urb leak on EHCI driver
On Mon, Dec 15, 2014 at 08:53:20PM +, Michael Tessier wrote: 5Linux version 2.6.31-770-g0e46b52-0897 (michael.tess...@vsvr-compile-01.pocatec.com) (gcc version 4.1.2) #12 PREEMPT Mon Nov 24 18:34:19 EST 2014 That is a _very_ old and obsolete kernel version, you need to get support from the company that is forcing you to stay on that version, as you are paying them for this. There is nothing the community can do with a kernel version like this, sorry. best of luck, greg k-h ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: PROBLEM: USB isochronous urb leak on EHCI driver
On Mon, Dec 15, 2014 at 6:53 PM, Michael Tessier michael.tess...@axiontech.ca wrote: Before attempting to upgrade to an earlier kernel driver (this is a fairly big amount of work), I would really like to know if this problem would still be in the 3.x kernels. Has anyone seen that issue in 3.x kernels? In fact it is very simple to test USB on a 3.18 kernel with your hardware. You only need a minimal dts file with the usb/serial nodes enabled. Take a loot at arch/arm/boot/dts/imx51-babbage.dts for a reference. I tested USB earlier today on this board with 3.18 and it worked fine. You need this patch: http://www.spinics.net/lists/arm-kernel/msg385739.html Regards, Fabio Estevam ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 7/7] CXL: Unmap MMIO regions when detaching a context
On Mon, 2014-12-15 at 14:32 +1100, Ian Munsie wrote: Excerpts from Ian Munsie's message of 2014-12-08 19:18:01 +1100: From: Ian Munsie imun...@au1.ibm.com If we need to force detach a context (e.g. due to EEH or simply force unbinding the driver) we should prevent the userspace contexts from being able to access the Problem State Area MMIO region further, which they may have mapped with mmap(). This patch unmaps any mapped MMIO regions when detaching a userspace context. Might want to drop this one for now - Philippe found that it sometimes causes an issue when multiple contexts are using the afu. Seems that unmap_mapping_range() unmapped a bit more than I expected. Sorry, it's already in next. https://git.kernel.org/cgit/linux/kernel/git/mpe/linux.git/commit/?h=nextid=b123429e6a9e8d03aacf888d23262835f0081448 Send me a revert or a fixup. cheers ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev