[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20170601110539.helelmmngwaba7fa@hirez.programming.kicks-ass.net>
Date: Thu, 1 Jun 2017 13:05:39 +0200
From: Peter Zijlstra <peterz@...radead.org>
To: Josh Poimboeuf <jpoimboe@...hat.com>
Cc: x86@...nel.org, linux-kernel@...r.kernel.org,
live-patching@...r.kernel.org,
Linus Torvalds <torvalds@...ux-foundation.org>,
Andy Lutomirski <luto@...nel.org>, Jiri Slaby <jslaby@...e.cz>,
Ingo Molnar <mingo@...nel.org>,
"H. Peter Anvin" <hpa@...or.com>
Subject: Re: [RFC PATCH 10/10] x86/unwind: add undwarf unwinder
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;
> +}
Powered by blists - more mailing lists