Re: [PATCH 0/5] [RFC] printk/ia64/ppc64/parisc64: let's deprecate %pF/%pf printk specifiers
On (09/20/17 12:20), Helge Deller wrote: [..] > > I've not looked at the specifics case... > > > > Another option is using a struct with a single member and > > passing it by value. > > Actually, we do already have correct structs which could be referenced: > parisc: struct Elf64_Fdesc > ia64: struct fdesc > ppc64:struct ppc64_opd_entry > > One could "#define platform_opd_entry" to each of those depending on the > platform and use it. > It might be misleading though, because the pointer which is handed over to > dereference_function_descriptor() can be such a pointer but isn't necessary. > I'll leave it up to Sergey to decide. Hello, I think I'll keep 'unsigned long' for now. -ss
Re: [PATCH 0/5] [RFC] printk/ia64/ppc64/parisc64: let's deprecate %pF/%pf printk specifiers
On 20.09.2017 10:41, David Laight wrote: From: Helge Deller Sent: 19 September 2017 21:08 ... Using 'unsigned long' for any kind of pointer is an accident waiting do happen. It also makes it difficult to typecheck the function calls. Using 'void *' isn't any better. Either a pointer to an undefined struct, or a struct containing a single 'char' member, is likely to be safest. David, you might be right in most cases, but in this case I'd prefer unsigned long too. I think this will create the least amount of typecasts here. I've not looked at the specifics case... Another option is using a struct with a single member and passing it by value. Actually, we do already have correct structs which could be referenced: parisc: struct Elf64_Fdesc ia64: struct fdesc ppc64: struct ppc64_opd_entry One could "#define platform_opd_entry" to each of those depending on the platform and use it. It might be misleading though, because the pointer which is handed over to dereference_function_descriptor() can be such a pointer but isn't necessary. I'll leave it up to Sergey to decide. Helge
RE: [PATCH 0/5] [RFC] printk/ia64/ppc64/parisc64: let's deprecate %pF/%pf printk specifiers
From: Helge Deller > Sent: 19 September 2017 21:08 ... > > Using 'unsigned long' for any kind of pointer is an accident > > waiting do happen. > > It also makes it difficult to typecheck the function calls. > > Using 'void *' isn't any better. > > Either a pointer to an undefined struct, or a struct containing > > a single 'char' member, is likely to be safest. > > David, you might be right in most cases, but in this case I'd prefer > unsigned long too. I think this will create the least amount of > typecasts here. I've not looked at the specifics case... Another option is using a struct with a single member and passing it by value. This could be used for things like user-space pointers or even errno values. The only problem is old ABI where even small structures are always passed by reference. David
Re: [PATCH 0/5] [RFC] printk/ia64/ppc64/parisc64: let's deprecate %pF/%pf printk specifiers
On (09/19/17 22:03), Helge Deller wrote: [..] > Your implementation of dereference_module_function_descriptor() in > arch/parisc/kernel/module.c is faulty. > mod->arch.fdesc_offset is relative to the base address of the module, > so you need to add to mod->core_layout.base. aha, got it. I should have figured that out. many thanks! > Here is the relevant patch to fix this issue (against mainline). > Additionally I compare against mod->arch.fdesc_count instead of > mod->arch.fdesc_max. hmm, .fdesc_max looked relevant to me. it's count_fdescs() - the number of R_PARISC_FPTR64 relocation entries. but ok, will use .fdesc_count. > Can you please fold it into your patch > [PATCH 4/5] parisc64: Add .opd based function descriptor dereference > for the next round? sure, will fold. + SoB. I think I'll try to re-spin the series today (or tomorrow, I'm slightly overloaded with another stuff right now). I've received enough bug reports no need to wait for another week ;) -ss
Re: [PATCH 0/5] [RFC] printk/ia64/ppc64/parisc64: let's deprecate %pF/%pf printk specifiers
On 19.09.2017 15:38, David Laight wrote: From: Sergey Senozhatsky Sent: 19 September 2017 03:06 ... I'll simply convert everything to `unsigned long'. including the dereference_function_descriptor() function [I believe there are still some casts happening when we pass addr from kernel/module dereference functions to dereference_function_descriptor(), or when we return `void *' back to symbol resolution code, etc.) besides, it seems that everything that uses dereference_function_descriptor() wants `unsigned long' anyway: Using 'unsigned long' for any kind of pointer is an accident waiting do happen. It also makes it difficult to typecheck the function calls. Using 'void *' isn't any better. Either a pointer to an undefined struct, or a struct containing a single 'char' member, is likely to be safest. David, you might be right in most cases, but in this case I'd prefer unsigned long too. I think this will create the least amount of typecasts here. Helge
Re: [PATCH 0/5] [RFC] printk/ia64/ppc64/parisc64: let's deprecate %pF/%pf printk specifiers
* Helge Deller: > On 19.09.2017 04:05, Sergey Senozhatsky wrote: > >On (09/18/17 20:39), Helge Deller wrote: > >>I did tried your testcases [on parisc] too. > ... > >>and here is "modprobe zram": > >> printk#7 __UNIQUE_ID_vermagic8+0xb9a4/0xbd04 [zram] > >> printk#8 __UNIQUE_ID_vermagic8+0xb9a4/0xbd04 [zram] > >> printk#9 do_one_initcall+0x194/0x290 > >> printk#10 do_one_initcall+0x194/0x290 > >> printk#11 do_one_initcall+0x194/0x290 > >> printk#12 do_one_initcall+0x194/0x290 > >> printk#13 zram_init+0x22c/0x2a0 [zram] > >> printk#14 zram_init+0x22c/0x2a0 [zram] > >> printk#15 zram_init+0x22c/0x2a0 [zram] > >> printk#16 zram_init+0x22c/0x2a0 [zram] > >> > >>I wonder why printk#7 and printk#8 don't show "zram_init"... > > > >interesting... what does the unpatched kernel show? > > Really strange. > The unpatched kernel shows __UNIQUE_ID_vermagic8+0xb9a4/0xbd04 too. > The symbol should be known, because later on in printk13 it shows correctly > zram_init. > I'll need to dig deeper into it, but at least the regression is not due > to your patch. Sergey, I was wrong with this assumption. Your implementation of dereference_module_function_descriptor() in arch/parisc/kernel/module.c is faulty. mod->arch.fdesc_offset is relative to the base address of the module, so you need to add to mod->core_layout.base. Here is the relevant patch to fix this issue (against mainline). Additionally I compare against mod->arch.fdesc_count instead of mod->arch.fdesc_max. Can you please fold it into your patch [PATCH 4/5] parisc64: Add .opd based function descriptor dereference for the next round? Thanks, Helge Signed-off-by: Helge Deller diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index f1a7693..ae3e6c5 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -66,6 +66,7 @@ #include #include +#include #if 0 #define DEBUGP printk @@ -954,3 +955,19 @@ void module_arch_cleanup(struct module *mod) { deregister_unwind_table(mod); } + +#ifdef CONFIG_64BIT +unsigned long dereference_module_function_descriptor(struct module *mod, +unsigned long addr) +{ + unsigned long opd_start = (Elf64_Addr) mod->core_layout.base + + mod->arch.fdesc_offset; + unsigned long opd_end = opd_start + + mod->arch.fdesc_count * sizeof(Elf64_Fdesc); + + if (addr < opd_start || addr >= opd_end) + return addr; + + return (unsigned long) dereference_function_descriptor((void *) addr); +} +#endif
Re: [PATCH 0/5] [RFC] printk/ia64/ppc64/parisc64: let's deprecate %pF/%pf printk specifiers
On 19.09.2017 04:05, Sergey Senozhatsky wrote: On (09/18/17 20:39), Helge Deller wrote: I did tried your testcases [on parisc] too. ... and here is "modprobe zram": printk#7 __UNIQUE_ID_vermagic8+0xb9a4/0xbd04 [zram] printk#8 __UNIQUE_ID_vermagic8+0xb9a4/0xbd04 [zram] printk#9 do_one_initcall+0x194/0x290 printk#10 do_one_initcall+0x194/0x290 printk#11 do_one_initcall+0x194/0x290 printk#12 do_one_initcall+0x194/0x290 printk#13 zram_init+0x22c/0x2a0 [zram] printk#14 zram_init+0x22c/0x2a0 [zram] printk#15 zram_init+0x22c/0x2a0 [zram] printk#16 zram_init+0x22c/0x2a0 [zram] I wonder why printk#7 and printk#8 don't show "zram_init"... interesting... what does the unpatched kernel show? Really strange. The unpatched kernel shows __UNIQUE_ID_vermagic8+0xb9a4/0xbd04 too. The symbol should be known, because later on in printk13 it shows correctly zram_init. I'll need to dig deeper into it, but at least the regression is not due to your patch. Helge
RE: [PATCH 0/5] [RFC] printk/ia64/ppc64/parisc64: let's deprecate %pF/%pf printk specifiers
From: Sergey Senozhatsky > Sent: 19 September 2017 03:06 ... > I'll simply convert everything to `unsigned long'. including the > dereference_function_descriptor() function [I believe there are > still some casts happening when we pass addr from kernel/module > dereference functions to dereference_function_descriptor(), or > when we return `void *' back to symbol resolution code, etc.) > besides, it seems that everything that uses > dereference_function_descriptor() wants `unsigned long' anyway: Using 'unsigned long' for any kind of pointer is an accident waiting do happen. It also makes it difficult to typecheck the function calls. Using 'void *' isn't any better. Either a pointer to an undefined struct, or a struct containing a single 'char' member, is likely to be safest. David
Re: [PATCH 0/5] [RFC] printk/ia64/ppc64/parisc64: let's deprecate %pF/%pf printk specifiers
On (09/18/17 10:44), Luck, Tony wrote: [..] > > A few new warnings when building on ia64: > > arch/ia64/kernel/module.c:931: warning: passing argument 1 of > 'dereference_function_descriptor' makes pointer from integer without a cast > arch/ia64/kernel/module.c:931: warning: return makes integer from pointer > without a cast > kernel/kallsyms.c:325: warning: assignment makes integer from pointer without > a cast > kernel/kallsyms.c:325: warning: passing argument 1 of > 'dereference_kernel_function_descriptor' makes pointer from integer without a > cast got it, will address in v2. [..] > Which looks like what you wanted. People unaware of the vagaries > of ppc64/ia64/parisc64 can use the wrong %p[SF] variant, but still > get the right output. thanks! -ss
Re: [PATCH 0/5] [RFC] printk/ia64/ppc64/parisc64: let's deprecate %pF/%pf printk specifiers
On (09/18/17 20:39), Helge Deller wrote: [..] > > A few new warnings when building on ia64: > > > > arch/ia64/kernel/module.c:931: warning: passing argument 1 of > > 'dereference_function_descriptor' makes pointer from integer without a cast > > arch/ia64/kernel/module.c:931: warning: return makes integer from pointer > > without a cast > > kernel/kallsyms.c:325: warning: assignment makes integer from pointer > > without a cast > > kernel/kallsyms.c:325: warning: passing argument 1 of > > 'dereference_kernel_function_descriptor' makes pointer from integer without > > a cast > > > I got similiar warnings on parisc. > This patch on top of yours fixed those: > Tony, Helge, thanks for the reports! I'll simply convert everything to `unsigned long'. including the dereference_function_descriptor() function [I believe there are still some casts happening when we pass addr from kernel/module dereference functions to dereference_function_descriptor(), or when we return `void *' back to symbol resolution code, etc.) besides, it seems that everything that uses dereference_function_descriptor() wants `unsigned long' anyway: drivers/misc/kgdbts.c: addr = (unsigned long) dereference_function_descriptor((void *)addr); init/main.c:addr = (unsigned long) dereference_function_descriptor(fn); kernel/extable.c: addr = (unsigned long) dereference_function_descriptor(ptr); kernel/module.c:unsigned long a = (unsigned long)dereference_function_descriptor(addr); so I'll just switch it to ulong. > I did tried your testcases too. > > "echo 1 > /proc/sys/vm/drop_caches" gave correct output: > printk#1 schedule_timeout+0x0/0x4a8 > printk#2 schedule_timeout+0x0/0x4a8 > printk#3 proc_sys_call_handler+0x120/0x180 > printk#4 proc_sys_call_handler+0x120/0x180 > printk#5 proc_sys_call_handler+0x120/0x180 > printk#6 proc_sys_call_handler+0x120/0x180 > > and here is "modprobe zram": > printk#7 __UNIQUE_ID_vermagic8+0xb9a4/0xbd04 [zram] > printk#8 __UNIQUE_ID_vermagic8+0xb9a4/0xbd04 [zram] > printk#9 do_one_initcall+0x194/0x290 > printk#10 do_one_initcall+0x194/0x290 > printk#11 do_one_initcall+0x194/0x290 > printk#12 do_one_initcall+0x194/0x290 > printk#13 zram_init+0x22c/0x2a0 [zram] > printk#14 zram_init+0x22c/0x2a0 [zram] > printk#15 zram_init+0x22c/0x2a0 [zram] > printk#16 zram_init+0x22c/0x2a0 [zram] > > I wonder why printk#7 and printk#8 don't show "zram_init"... interesting... what does the unpatched kernel show? > Regarding your patches: > > In arch/parisc/kernel/process.c: > +void *dereference_kernel_function_descriptor(void *ptr) > +{ > + if (ptr < (void *)__start_opd || (void *)__end_opd < ptr) > > This needs to be (__end_opd is outside): > + if (ptr < (void *)__start_opd || (void *)__end_opd <= ptr) > > The same is true for the checks in the other arches. um... yeah. __end_opd is definitely not a valid place for a descriptor! I think I had `if (!(ptr >= __start_opd && ptr < __end_opd))' which I wrongly converted. "shame, shame, shame". thanks! > I'd suggest to move the various > extern char __start_opd[], __end_opd[]; > out of arch//include/asm/sections.h and into ok, will take a look. -ss
Re: [PATCH 0/5] [RFC] printk/ia64/ppc64/parisc64: let's deprecate %pF/%pf printk specifiers
* Luck, Tony: > On Sat, Sep 16, 2017 at 12:53:42PM +0900, Sergey Senozhatsky wrote: > > Hello > > > > RFC > > > > On some arches C function pointers are indirect and point to > > a function descriptor, which contains the actual pointer to the code. > > This mostly doesn't matter, except for cases when people want to print > > out function pointers in symbolic format, because the usual '%pS/%ps' > > does not work on those arches as expected. That's the reason why we > > have '%pF/%pf', but since it's here because of a subtle ABI detail > > specific to some arches (ppc64/ia64/parisc64) it's easy to misuse > > '%pF/%pf' and '%pS/%ps' (see [1], for example). > > A few new warnings when building on ia64: > > arch/ia64/kernel/module.c:931: warning: passing argument 1 of > 'dereference_function_descriptor' makes pointer from integer without a cast > arch/ia64/kernel/module.c:931: warning: return makes integer from pointer > without a cast > kernel/kallsyms.c:325: warning: assignment makes integer from pointer without > a cast > kernel/kallsyms.c:325: warning: passing argument 1 of > 'dereference_kernel_function_descriptor' makes pointer from integer without a > cast I got similiar warnings on parisc. This patch on top of yours fixed those: diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index bc2eae8..4f34b46 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -66,6 +66,7 @@ #include #include +#include #if 0 #define DEBUGP printk @@ -959,12 +960,12 @@ void module_arch_cleanup(struct module *mod) unsigned long dereference_module_function_descriptor(struct module *mod, unsigned long addr) { - void *opd_sz = mod->arch.fdesc_offset + + unsigned long opd_sz = mod->arch.fdesc_offset + mod->arch.fdesc_max * sizeof(Elf64_Fdesc); if (addr < mod->arch.fdesc_offset || opd_sz < addr) return addr; - return dereference_function_descriptor(addr); + return (unsigned long) dereference_function_descriptor((void *) addr); } #endif diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index e2fc09e..76f4de6 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -322,7 +322,7 @@ const char *kallsyms_lookup(unsigned long addr, if (is_ksym_addr(addr)) { unsigned long pos; - addr = dereference_kernel_function_descriptor(addr); + addr = dereference_kernel_function_descriptor((void *) addr); pos = get_symbol_pos(addr, symbolsize, offset); /* Grab name */ kallsyms_expand_symbol(get_symbol_offset(pos), I did tried your testcases too. "echo 1 > /proc/sys/vm/drop_caches" gave correct output: printk#1 schedule_timeout+0x0/0x4a8 printk#2 schedule_timeout+0x0/0x4a8 printk#3 proc_sys_call_handler+0x120/0x180 printk#4 proc_sys_call_handler+0x120/0x180 printk#5 proc_sys_call_handler+0x120/0x180 printk#6 proc_sys_call_handler+0x120/0x180 and here is "modprobe zram": printk#7 __UNIQUE_ID_vermagic8+0xb9a4/0xbd04 [zram] printk#8 __UNIQUE_ID_vermagic8+0xb9a4/0xbd04 [zram] printk#9 do_one_initcall+0x194/0x290 printk#10 do_one_initcall+0x194/0x290 printk#11 do_one_initcall+0x194/0x290 printk#12 do_one_initcall+0x194/0x290 printk#13 zram_init+0x22c/0x2a0 [zram] printk#14 zram_init+0x22c/0x2a0 [zram] printk#15 zram_init+0x22c/0x2a0 [zram] printk#16 zram_init+0x22c/0x2a0 [zram] I wonder why printk#7 and printk#8 don't show "zram_init"... Regarding your patches: In arch/parisc/kernel/process.c: +void *dereference_kernel_function_descriptor(void *ptr) +{ + if (ptr < (void *)__start_opd || (void *)__end_opd < ptr) This needs to be (__end_opd is outside): + if (ptr < (void *)__start_opd || (void *)__end_opd <= ptr) The same is true for the checks in the other arches. I'd suggest to move the various extern char __start_opd[], __end_opd[]; out of arch//include/asm/sections.h and into I'll continue to test. Helge
Re: [PATCH 0/5] [RFC] printk/ia64/ppc64/parisc64: let's deprecate %pF/%pf printk specifiers
On Sat, Sep 16, 2017 at 12:53:42PM +0900, Sergey Senozhatsky wrote: > Hello > > RFC > > On some arches C function pointers are indirect and point to > a function descriptor, which contains the actual pointer to the code. > This mostly doesn't matter, except for cases when people want to print > out function pointers in symbolic format, because the usual '%pS/%ps' > does not work on those arches as expected. That's the reason why we > have '%pF/%pf', but since it's here because of a subtle ABI detail > specific to some arches (ppc64/ia64/parisc64) it's easy to misuse > '%pF/%pf' and '%pS/%ps' (see [1], for example). A few new warnings when building on ia64: arch/ia64/kernel/module.c:931: warning: passing argument 1 of 'dereference_function_descriptor' makes pointer from integer without a cast arch/ia64/kernel/module.c:931: warning: return makes integer from pointer without a cast kernel/kallsyms.c:325: warning: assignment makes integer from pointer without a cast kernel/kallsyms.c:325: warning: passing argument 1 of 'dereference_kernel_function_descriptor' makes pointer from integer without a cast Tried out the module case with a simple Hello-world test case. This code: char buf[1]; int init_module(void) { printk(KERN_INFO "Hello world 1.\n"); printk("using %%p my init_module is at %p\n", init_module); printk("using %%pF my init_module is at %pF\n", init_module); printk("using %%pS my init_module is at %pS\n", init_module); printk("using %%p my buf is at %p\n", buf); printk("using %%pF my buf is at %pF\n", buf); printk("using %%pS my buf is at %pS\n", buf); return 0; } Gave this console output: Hello world 1. using %p my init_module is at a00203bf0328 using %pF my init_module is at init_module+0x0/0x140 [hello_1] using %pS my init_module is at init_module+0x0/0x140 [hello_1] using %p my buf is at a00203bf0648 using %pF my buf is at buf+0x0/0xfb58 [hello_1] using %pS my buf is at buf+0x0/0xfb58 [hello_1] Which looks like what you wanted. People unaware of the vagaries of ppc64/ia64/parisc64 can use the wrong %p[SF] variant, but still get the right output. -Tony
[PATCH 0/5] [RFC] printk/ia64/ppc64/parisc64: let's deprecate %pF/%pf printk specifiers
Hello RFC On some arches C function pointers are indirect and point to a function descriptor, which contains the actual pointer to the code. This mostly doesn't matter, except for cases when people want to print out function pointers in symbolic format, because the usual '%pS/%ps' does not work on those arches as expected. That's the reason why we have '%pF/%pf', but since it's here because of a subtle ABI detail specific to some arches (ppc64/ia64/parisc64) it's easy to misuse '%pF/%pf' and '%pS/%ps' (see [1], for example). This patch set attempts to move ia64/ppc64/parisc64 C function pointer ABI details out of printk() to arch code. Function dereference code now checks if a pointer belongs to a .opd ELF section and dereferences that pointer only if it does. The kernel and modules have their own .opd sections that's why I use two different ARCH functions: for kernel and for module pointer dereference. I planned to remove dereference_function_descriptor() entirely, but then I discovered a bunch other uses cases (kgdbts, init/main.c, extable, etc.), so I decided to keep dereference_function_descriptor() around because the main point of this patch set is to deprecate %pF/%pf. But at the same time, I think I can go further and handle both kernel and module descriptor dereference in dereference_function_descriptor(). We need a module pointer for module .opd check, so that will come at an extra cost of module lookup (may be there will some other issues along the way, haven't checked it). Right now we've got: - dereference_function_descriptor(addr) a generic (old) function. it simply attempts to dereference whatever pointer we give it. - dereference_kernel_function_descriptor(addr) dereferences a kernel pointer if it's within the kernel's .opd section. - dereference_module_function_descriptor(module, addr) dereference a module pointer if it's within the module's .opd section. *** A BIG NOTE *** I don't own ia64/ppc64/parisc64 hardware, so the patches are not tested. Sorry about that! Another note: I need to check what is BPF symbol lookup and do we need to do any dereference there. [1] https://marc.info/?l=linux-kernel=150472969730573 Sergey Senozhatsky (5): sections: split dereference_function_descriptor() ia64: Add .opd based function descriptor dereference powerpc64: Add .opd based function descriptor dereference parisc64: Add .opd based function descriptor dereference symbol lookup: use new kernel and module dereference functions Documentation/printk-formats.txt | 15 +-- arch/ia64/include/asm/sections.h | 14 +- arch/ia64/kernel/module.c | 13 + arch/ia64/kernel/vmlinux.lds.S| 2 ++ arch/parisc/boot/compressed/vmlinux.lds.S | 2 ++ arch/parisc/include/asm/sections.h| 3 +++ arch/parisc/kernel/module.c | 14 ++ arch/parisc/kernel/process.c | 10 ++ arch/parisc/kernel/vmlinux.lds.S | 2 ++ arch/powerpc/include/asm/module.h | 3 +++ arch/powerpc/include/asm/sections.h | 13 + arch/powerpc/kernel/module_64.c | 16 arch/powerpc/kernel/vmlinux.lds.S | 2 ++ include/asm-generic/sections.h| 4 ++-- include/linux/moduleloader.h | 4 kernel/kallsyms.c | 1 + kernel/module.c | 7 +++ lib/vsprintf.c| 5 + 18 files changed, 113 insertions(+), 17 deletions(-) -- 2.14.1