Re: [PATCH v4 2/2] arm64: kprobe: Enable OPTPROBE for arm64

From: liuqi (BA)
Date: Tue Nov 30 2021 - 21:55:30 EST




On 2021/12/1 9:50, Masami Hiramatsu wrote:
On Tue, 30 Nov 2021 14:48:06 +0800
"liuqi (BA)" <liuqi115@xxxxxxxxxx> wrote:



On 2021/11/29 22:35, Masami Hiramatsu wrote:
Hi all,

I meet a problem when I use SYM_CODE_START(optprobe_template) to replace
optprobe_template_entry.

If SYM_CODE_START is used, all optprobe will share one trampoline space.
Under this circumstances, if user register two optprobes, trampoline
will be overwritten by the newer one, and this will cause kernel panic
when the old optprobe is trigger.
Hm, this is curious, because the template should be copied to the
trampoline buffer for each optprobe and be modified.

Using optprobe_template_entry will not have this problem, as each
optprobe has its own trampoline space (alloced in get_opinsn_slot()).
Yes, it is designed to do so.

Thank you,

Hi Masami,

Thanks for your reply. But I also met a problem when using
get_opinsn_slot() to alloc trampoline buffer.

As module_alloc(like x86) is used to alloc buffer, trampoline is in
module space, so if origin insn is in kernel space, the range between
origin insn and trampoline is out of 128M.

As module PLT cannot used here, I have no idea to achieve long jump in
this situation. Do you have any good idea?
Hi Masami,

Thanks so much for your reply.

One possible solution is to use pre-allocated trampoline space in
the text area, as same as ppc64 does.
(See arch/powerpc/kernel/optprobes_head.S, it embeds a space at "optinsn_slot")

I find something interesting in arch/powerpc/kernel/optprobes.c, it use
"optinsn_slot" as a public buffer, and use a static "insn_page_in_use"
to make sure there is only one optprobe in kernel.

If we use this solution , users could only register one optprobe each
time. This will also be a limitation for users, what's your opinion
about this?
No, that is just a memory area for pooling trampoline buffer. So optprobe
can allocate the buffer from that area. Please see kernel/kprobes.c:344.
optprobe allocates "insn_slot" from kprobe_optinsn_slots, which uses
alloc_optinsn_page() to allocate the pool of slots.

Thank you,


Hi,

Thanks for your reply, I test alloc_optinsn_page() and it does work well
to alloc the pool of slots.

But when I tried to use module PLT, something seems wrong here.
Arm64 Module PLT in mod->arch.ftrace_trampolines is set in
module_finalize, after that, mod->arch.ftrace_trampolines seems to be a
read-only memory. But in arch_optimize_kprobes() we need to modify the
destination of PLT (as each optprobe has its own trampoline buffer), if
so, we cannot get rid of the 128M branch limit :(

Hi Masami,

Hmm, OK, we need to introduce trampoline buffer allocation pool for modules
for such arch.

Yes, but will this expand the size of Image?

But that should be another story. I think you should start
from the core-kernel. At this moment, if the probe address is in the module,
please return -ERANGE from arch_prepare_optimized_kprobe().
Module support must be done in the next step (series), since that will involve
the kprobes generic code change.


got it, I'll send a new patchset which support core-kernel optprobe soon. thanks a lot for your reply.

Qi
Thank you,


Thanks,
Qi