From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752118AbdFALFy (ORCPT ); Thu, 1 Jun 2017 07:05:54 -0400 Received: from bombadil.infradead.org ([65.50.211.133]:56553 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751839AbdFALFv (ORCPT ); Thu, 1 Jun 2017 07:05:51 -0400 Date: Thu, 1 Jun 2017 13:05:39 +0200 From: Peter Zijlstra To: Josh Poimboeuf Cc: x86@kernel.org, linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Linus Torvalds , Andy Lutomirski , Jiri Slaby , Ingo Molnar , "H. Peter Anvin" Subject: Re: [RFC PATCH 10/10] x86/unwind: add undwarf unwinder Message-ID: <20170601110539.helelmmngwaba7fa@hirez.programming.kicks-ass.net> References: <89552d4047e5aed843f7b6a54277f9af62da6a82.1496293620.git.jpoimboe@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <89552d4047e5aed843f7b6a54277f9af62da6a82.1496293620.git.jpoimboe@redhat.com> User-Agent: NeoMutt/20170113 (1.7.2) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Jun 01, 2017 at 12:44:16AM -0500, Josh Poimboeuf wrote: > +static struct undwarf *__undwarf_lookup(struct undwarf *undwarf, > + unsigned int num, unsigned long ip) > +{ > + struct undwarf *first = undwarf; > + struct undwarf *last = undwarf + num - 1; > + struct undwarf *mid; > + unsigned long u_ip; > + > + while (first <= last) { > + mid = first + ((last - first) / 2); > + u_ip = undwarf_ip(mid); > + > + if (ip >= u_ip) { > + if (ip < u_ip + mid->len) > + return mid; > + first = mid + 1; > + } else > + last = mid - 1; > + } > + > + return NULL; > +} That's a bog standard binary search thing, don't we have a helper for that someplace? > +static struct undwarf *undwarf_lookup(unsigned long ip) > +{ > + struct undwarf *undwarf; > + struct module *mod; > + > + /* Look in vmlinux undwarf section: */ > + undwarf = __undwarf_lookup(__undwarf_start, __undwarf_end - __undwarf_start, ip); > + if (undwarf) > + return undwarf; > + > + /* Look in module undwarf sections: */ > + preempt_disable(); > + mod = __module_address(ip); > + if (!mod || !mod->arch.undwarf) > + goto module_out; > + undwarf = __undwarf_lookup(mod->arch.undwarf, mod->arch.num_undwarves, ip); > + > +module_out: > + preempt_enable(); > + return undwarf; > +} A few points here: - that first lookup is entirely pointless if !core_kernel_text(ip) - that preempt_{dis,en}able() muck is 'pointless', for while it shuts up the warnings from __modules_address(), nothing preserves the struct undwarf you get a pointer to after the preempt_enable(). - what about 'interesting' things like, ftrace_trampoline, kprobe insn slots and bpf text? > +static bool stack_access_ok(struct unwind_state *state, unsigned long addr, > + size_t len) > +{ > + struct stack_info *info = &state->stack_info; > + > + /* > + * If the next bp isn't on the current stack, switch to the next one. > + * > + * We may have to traverse multiple stacks to deal with the possibility > + * that info->next_sp could point to an empty stack and the next bp > + * could be on a subsequent stack. > + */ > + while (!on_stack(info, (void *)addr, len)) { > + if (get_stack_info(info->next_sp, state->task, info, > + &state->stack_mask)) > + return false; } > + > + return true; > +}