rfc: remove print_vma_addr ? (was Re: [PATCH 00/16] remove eight obsolete architectures)
From: Joe Perches <joe@perches.com>
Date: 2018-03-15 16:56:46
Also in:
dri-devel, linux-arch, linux-block, linux-doc, linux-fbdev, linux-fsdevel, linux-ide, linux-mm, linux-pwm, linux-rtc, linux-spi, linux-usb, linux-watchdog, linux-wireless, lkml, netdev
Subsystem:
arm64 port (aarch64 architecture), documentation, library code, memory management, memory management - core, mips, parisc architecture, risc-v architecture, s390 architecture, sparc + ultrasparc (sparc/sparc64), the rest, user-mode linux (uml), vsprintf, x86 architecture (32-bit and 64-bit), x86 mm · Maintainers:
Catalin Marinas, Will Deacon, Jonathan Corbet, Andrew Morton, David Hildenbrand, Thomas Bogendoerfer, "James E.J. Bottomley", Helge Deller, Paul Walmsley, Palmer Dabbelt, Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev, "David S. Miller", Andreas Larsson, Linus Torvalds, Richard Weinberger, Anton Ivanov, Johannes Berg, Petr Mladek, Steven Rostedt, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, Andy Lutomirski, Peter Zijlstra
On Thu, 2018-03-15 at 10:48 +0100, Geert Uytterhoeven wrote:
Hi David, On Thu, Mar 15, 2018 at 10:42 AM, David Howells [off-list ref] wrote:quoted
Do we have anything left that still implements NOMMU?Sure: arm, c6x, m68k, microblaze, and sh.
I have a patchset that creates a vsprintf extension for print_vma_addr and removes all the uses similar to the print_symbol() removal. This now avoids any possible printk interleaving. Unfortunately, without some #ifdef in vsprintf, which I would like to avoid, it increases the nommu kernel size by ~500 bytes. Anyone think this is acceptable? Here's the overall patch, but I have it as a series --- Documentation/core-api/printk-formats.rst | 9 +++++ arch/arm64/kernel/traps.c | 13 +++---- arch/mips/mm/fault.c | 16 ++++----- arch/parisc/mm/fault.c | 15 ++++---- arch/riscv/kernel/traps.c | 11 +++--- arch/s390/mm/fault.c | 7 ++-- arch/sparc/mm/fault_32.c | 8 ++--- arch/sparc/mm/fault_64.c | 8 ++--- arch/tile/kernel/signal.c | 9 ++--- arch/um/kernel/trap.c | 13 +++---- arch/x86/kernel/signal.c | 10 ++---- arch/x86/kernel/traps.c | 18 ++++------ arch/x86/mm/fault.c | 12 +++---- include/linux/mm.h | 1 - lib/vsprintf.c | 58 ++++++++++++++++++++++++++----- mm/memory.c | 33 ------------------ 16 files changed, 112 insertions(+), 129 deletions(-)
diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst
index 934559b3c130..10a91da1bc83 100644
--- a/Documentation/core-api/printk-formats.rst
+++ b/Documentation/core-api/printk-formats.rst@@ -157,6 +157,15 @@ DMA address types dma_addr_t For printing a dma_addr_t type which can vary based on build options, regardless of the width of the CPU data path. +VMA name and address +---------------------------- + +:: + + %pav <name>[hexstart+hexsize] or ?[0+0] if unavailable + +For any address, print the vma's name and its starting address and size + Passed by reference. Raw buffer as an escaped string
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 2b478565d774..48edf812ce8b 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c@@ -242,13 +242,14 @@ void arm64_force_sig_info(struct siginfo *info, const char *str, if (!show_unhandled_signals_ratelimited()) goto send_sig; - pr_info("%s[%d]: unhandled exception: ", tsk->comm, task_pid_nr(tsk)); if (esr) - pr_cont("%s, ESR 0x%08x, ", esr_get_class_string(esr), esr); - - pr_cont("%s", str); - print_vma_addr(KERN_CONT " in ", regs->pc); - pr_cont("\n"); + pr_info("%s[%d]: unhandled exception: %s, ESR 0x%08x, %s in %pav\n", + tsk->comm, task_pid_nr(tsk), + esr_get_class_string(esr), esr, + str, ®s->pc); + else + pr_info("%s[%d]: unhandled exception: %s in %pav\n", + tsk->comm, task_pid_nr(tsk), str, ®s->pc); __show_regs(regs); send_sig:
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 4f8f5bf46977..ce7bf077a0f5 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c@@ -213,14 +213,14 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write, tsk->comm, write ? "write access to" : "read access from", field, address); - pr_info("epc = %0*lx in", field, - (unsigned long) regs->cp0_epc); - print_vma_addr(KERN_CONT " ", regs->cp0_epc); - pr_cont("\n"); - pr_info("ra = %0*lx in", field, - (unsigned long) regs->regs[31]); - print_vma_addr(KERN_CONT " ", regs->regs[31]); - pr_cont("\n"); + pr_info("epc = %0*lx in %pav\n", + field, + (unsigned long)regs->cp0_epc, + ®s->cp0_epc); + pr_info("ra = %0*lx in %pav\n", + field, + (unsigned long)regs->regs[31], + ®s->regs[31]); } current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f; info.si_signo = SIGSEGV;
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index e247edbca68e..877cea702714 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c@@ -240,17 +240,14 @@ show_signal_msg(struct pt_regs *regs, unsigned long code, if (!printk_ratelimit()) return; - pr_warn("\n"); - pr_warn("do_page_fault() command='%s' type=%lu address=0x%08lx", - tsk->comm, code, address); - print_vma_addr(KERN_CONT " in ", regs->iaoq[0]); - - pr_cont("\ntrap #%lu: %s%c", code, trap_name(code), - vma ? ',':'\n'); + pr_warn("do_page_fault() command='%s' type=%lu address=0x%08lx in %pav\n", + tsk->comm, code, address, ®s->iaoq[0]); if (vma) - pr_cont(" vm_start = 0x%08lx, vm_end = 0x%08lx\n", - vma->vm_start, vma->vm_end); + pr_warn("trap #%lu: %s%c, vm_start = 0x%08lx, vm_end = 0x%08lx\n", + code, trap_name(code), vma->vm_start, vma->vm_end); + else + pr_warn("trap #%lu: %s%c\n", code, trap_name(code)); show_regs(regs); }
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 93132cb59184..16609dcb2546 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c@@ -78,12 +78,11 @@ static inline void do_trap_siginfo(int signo, int code, void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr, struct task_struct *tsk) { - if (show_unhandled_signals && unhandled_signal(tsk, signo) - && printk_ratelimit()) { - pr_info("%s[%d]: unhandled signal %d code 0x%x at 0x" REG_FMT, - tsk->comm, task_pid_nr(tsk), signo, code, addr); - print_vma_addr(KERN_CONT " in ", GET_IP(regs)); - pr_cont("\n"); + if (show_unhandled_signals && unhandled_signal(tsk, signo) && + printk_ratelimit()) { + pr_info("%s[%d]: unhandled signal %d code 0x%x at 0x" REG_FMT " in %pav\n", + tsk->comm, task_pid_nr(tsk), signo, code, addr, + &GET_IP(regs)); show_regs(regs); }
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 93faeca52284..3b1d6d618af2 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c@@ -250,10 +250,9 @@ void report_user_fault(struct pt_regs *regs, long signr, int is_mm_fault) return; if (!printk_ratelimit()) return; - printk(KERN_ALERT "User process fault: interruption code %04x ilc:%d ", - regs->int_code & 0xffff, regs->int_code >> 17); - print_vma_addr(KERN_CONT "in ", regs->psw.addr); - printk(KERN_CONT "\n"); + printk(KERN_ALERT "User process fault: interruption code %04x ilc:%d in %pav\n", + regs->int_code & 0xffff, regs->int_code >> 17, + ®s->psw.addr); if (is_mm_fault) dump_fault_info(regs); show_regs(regs);
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
index a8103a84b4ac..206ec5a1c915 100644
--- a/arch/sparc/mm/fault_32.c
+++ b/arch/sparc/mm/fault_32.c@@ -113,15 +113,11 @@ show_signal_msg(struct pt_regs *regs, int sig, int code, if (!printk_ratelimit()) return; - printk("%s%s[%d]: segfault at %lx ip %px (rpc %px) sp %px error %x", + printk("%s%s[%d]: segfault at %lx ip %px (rpc %px) sp %px error %x in %pav\n", task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, tsk->comm, task_pid_nr(tsk), address, (void *)regs->pc, (void *)regs->u_regs[UREG_I7], - (void *)regs->u_regs[UREG_FP], code); - - print_vma_addr(KERN_CONT " in ", regs->pc); - - printk(KERN_CONT "\n"); + (void *)regs->u_regs[UREG_FP], code, ®s->pc); } static void __do_fault_siginfo(int code, int sig, struct pt_regs *regs,
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
index 41363f46797b..a21199329ebe 100644
--- a/arch/sparc/mm/fault_64.c
+++ b/arch/sparc/mm/fault_64.c@@ -154,15 +154,11 @@ show_signal_msg(struct pt_regs *regs, int sig, int code, if (!printk_ratelimit()) return; - printk("%s%s[%d]: segfault at %lx ip %px (rpc %px) sp %px error %x", + printk("%s%s[%d]: segfault at %lx ip %px (rpc %px) sp %px error %x in %pav\b", task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, tsk->comm, task_pid_nr(tsk), address, (void *)regs->tpc, (void *)regs->u_regs[UREG_I7], - (void *)regs->u_regs[UREG_FP], code); - - print_vma_addr(KERN_CONT " in ", regs->tpc); - - printk(KERN_CONT "\n"); + (void *)regs->u_regs[UREG_FP], code, ®s->tpc); } static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c
index f2bf557bb005..0556106dfe8a 100644
--- a/arch/tile/kernel/signal.c
+++ b/arch/tile/kernel/signal.c@@ -383,13 +383,10 @@ void trace_unhandled_signal(const char *type, struct pt_regs *regs, if (show_unhandled_signals <= 1 && !printk_ratelimit()) return; - printk("%s%s[%d]: %s at %lx pc "REGFMT" signal %d", + printk("%s%s[%d]: %s at %lx pc " REGFMT " signal %d in %pav\n", task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, - tsk->comm, task_pid_nr(tsk), type, address, regs->pc, sig); - - print_vma_addr(KERN_CONT " in ", regs->pc); - - printk(KERN_CONT "\n"); + tsk->comm, task_pid_nr(tsk), type, address, regs->pc, sig, + ®s->pc); if (show_unhandled_signals > 1) { switch (sig) {
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index b2b02df9896e..9281248972c0 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c@@ -150,14 +150,11 @@ static void show_segv_info(struct uml_pt_regs *regs) if (!printk_ratelimit()) return; - printk("%s%s[%d]: segfault at %lx ip %px sp %px error %x", - task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, - tsk->comm, task_pid_nr(tsk), FAULT_ADDRESS(*fi), - (void *)UPT_IP(regs), (void *)UPT_SP(regs), - fi->error_code); - - print_vma_addr(KERN_CONT " in ", UPT_IP(regs)); - printk(KERN_CONT "\n"); + printk("%s%s[%d]: segfault at %lx ip %px sp %px error %x in %pav\n", + task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, + tsk->comm, task_pid_nr(tsk), FAULT_ADDRESS(*fi), + (void *)UPT_IP(regs), (void *)UPT_SP(regs), + fi->error_code, &UPT_IP(regs)); } static void bad_segv(struct faultinfo fi, unsigned long ip)
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 4cdc0b27ec82..9ab0c5c50b29 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c@@ -841,15 +841,11 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where) { struct task_struct *me = current; - if (show_unhandled_signals && printk_ratelimit()) { - printk("%s" - "%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx", + if (show_unhandled_signals && printk_ratelimit()) + printk("%s%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx in %pav\n", task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG, me->comm, me->pid, where, frame, - regs->ip, regs->sp, regs->orig_ax); - print_vma_addr(KERN_CONT " in ", regs->ip); - pr_cont("\n"); - } + regs->ip, regs->sp, regs->orig_ax, ®s->ip); force_sig(SIGSEGV, me); }
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 3d9b2308e7fa..c6e3d02759e5 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c@@ -270,13 +270,10 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, tsk->thread.trap_nr = trapnr; if (show_unhandled_signals && unhandled_signal(tsk, signr) && - printk_ratelimit()) { - pr_info("%s[%d] trap %s ip:%lx sp:%lx error:%lx", + printk_ratelimit()) + pr_info("%s[%d] trap %s ip:%lx sp:%lx error:%lx in %pav\n", tsk->comm, tsk->pid, str, - regs->ip, regs->sp, error_code); - print_vma_addr(KERN_CONT " in ", regs->ip); - pr_cont("\n"); - } + regs->ip, regs->sp, error_code, ®s->ip); force_sig_info(signr, info ?: SEND_SIG_PRIV, tsk); }
@@ -565,13 +562,10 @@ do_general_protection(struct pt_regs *regs, long error_code) tsk->thread.trap_nr = X86_TRAP_GP; if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && - printk_ratelimit()) { - pr_info("%s[%d] general protection ip:%lx sp:%lx error:%lx", + printk_ratelimit()) + pr_info("%s[%d] general protection ip:%lx sp:%lx error:%lx in %pav\n", tsk->comm, task_pid_nr(tsk), - regs->ip, regs->sp, error_code); - print_vma_addr(KERN_CONT " in ", regs->ip); - pr_cont("\n"); - } + regs->ip, regs->sp, error_code, ®s->ip); force_sig_info(SIGSEGV, SEND_SIG_PRIV, tsk); }
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index e6af2b464c3d..b629319e621a 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c@@ -857,14 +857,10 @@ show_signal_msg(struct pt_regs *regs, unsigned long error_code, if (!printk_ratelimit()) return; - printk("%s%s[%d]: segfault at %lx ip %px sp %px error %lx", - task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, - tsk->comm, task_pid_nr(tsk), address, - (void *)regs->ip, (void *)regs->sp, error_code); - - print_vma_addr(KERN_CONT " in ", regs->ip); - - printk(KERN_CONT "\n"); + printk("%s%s[%d]: segfault at %lx ip %px sp %px error %lx in %pav\n", + task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, + tsk->comm, task_pid_nr(tsk), address, + (void *)regs->ip, (void *)regs->sp, error_code, ®s->ip); } static void
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 9f1270360983..9584bd3e8c25 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h@@ -2537,7 +2537,6 @@ extern int randomize_va_space; #endif const char * arch_vma_name(struct vm_area_struct *vma); -void print_vma_addr(char *prefix, unsigned long rip); void sparse_mem_maps_populate_node(struct page **map_map, unsigned long pnum_begin,
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 942b5234a59b..9081476ea4ea 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c@@ -35,6 +35,8 @@ #include <net/addrconf.h> #include <linux/siphash.h> #include <linux/compiler.h> +#include <linux/mm_types.h> + #ifdef CONFIG_BLOCK #include <linux/blkdev.h> #endif
@@ -407,6 +409,11 @@ struct printf_spec { #define FIELD_WIDTH_MAX ((1 << 23) - 1) #define PRECISION_MAX ((1 << 15) - 1) +static const struct printf_spec strspec = { + .field_width = -1, + .precision = -1, +}; + static noinline_for_stack char *number(char *buf, char *end, unsigned long long num, struct printf_spec spec)
@@ -1427,6 +1434,45 @@ char *netdev_bits(char *buf, char *end, const void *addr, const char *fmt) return special_hex_number(buf, end, num, size); } +static noinline_for_stack +char *vma_addr(char *buf, char *end, const void *addr) +{ + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + char *page; + char tbuf[2 * sizeof(unsigned long) * 2 + 4]; + const char *output = "?[0+0]"; + + /* + * we might be running from an atomic context so we cannot sleep + */ + if (!down_read_trylock(&mm->mmap_sem)) + goto output; + + vma = find_vma(mm, *(unsigned long *)addr); + if (!vma || !vma->vm_file) + goto up_read; + + page = (char *)__get_free_page(GFP_ATOMIC | __GFP_NOWARN); + if (page) { + char *fp; + + fp = file_path(vma->vm_file, page, PAGE_SIZE); + if (IS_ERR(fp)) + fp = "?"; + buf = string(buf, end, kbasename(fp), strspec); + sprintf(tbuf, "[%lx+%lx]", + vma->vm_start, vma->vm_end - vma->vm_start); + output = tbuf; + free_page((unsigned long)page); + } + +up_read: + up_read(&mm->mmap_sem); +output: + return string(buf, end, output, strspec); +} + static noinline_for_stack char *address_val(char *buf, char *end, const void *addr, const char *fmt) {
@@ -1434,6 +1480,8 @@ char *address_val(char *buf, char *end, const void *addr, const char *fmt) int size; switch (fmt[1]) { + case 'v': + return vma_addr(buf, end, addr); case 'd': num = *(const dma_addr_t *)addr; size = sizeof(dma_addr_t);
@@ -1474,11 +1522,7 @@ char *format_flags(char *buf, char *end, unsigned long flags, const struct trace_print_flags *names) { unsigned long mask; - const struct printf_spec strspec = { - .field_width = -1, - .precision = -1, - }; - const struct printf_spec numspec = { + static const struct printf_spec numspec = { .flags = SPECIAL|SMALL, .field_width = -1, .precision = -1,
@@ -1548,10 +1592,6 @@ char *device_node_gen_full_name(const struct device_node *np, char *buf, char *e { int depth; const struct device_node *parent = np->parent; - static const struct printf_spec strspec = { - .field_width = -1, - .precision = -1, - }; /* special case for root node */ if (!parent)
diff --git a/mm/memory.c b/mm/memory.c
index bc760df8a7f4..f1f922421bde 100644
--- a/mm/memory.c
+++ b/mm/memory.c@@ -4502,39 +4502,6 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, } EXPORT_SYMBOL_GPL(access_process_vm); -/* - * Print the name of a VMA. - */ -void print_vma_addr(char *prefix, unsigned long ip) -{ - struct mm_struct *mm = current->mm; - struct vm_area_struct *vma; - - /* - * we might be running from an atomic context so we cannot sleep - */ - if (!down_read_trylock(&mm->mmap_sem)) - return; - - vma = find_vma(mm, ip); - if (vma && vma->vm_file) { - struct file *f = vma->vm_file; - char *buf = (char *)__get_free_page(GFP_NOWAIT); - if (buf) { - char *p; - - p = file_path(f, buf, PAGE_SIZE); - if (IS_ERR(p)) - p = "?"; - printk("%s%s[%lx+%lx]", prefix, kbasename(p), - vma->vm_start, - vma->vm_end - vma->vm_start); - free_page((unsigned long)buf); - } - } - up_read(&mm->mmap_sem); -} - #if defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_DEBUG_ATOMIC_SLEEP) void __might_fault(const char *file, int line) {
_______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel