powerpc/kprobes: Replace ppc_optinsn by common optinsn

Commit 51c9c08439 ("powerpc/kprobes: Implement Optprobes")
implemented a powerpc specific version of optinsn in order
to workaround the 32Mb limitation for direct branches.

Instead of implementing a dedicated powerpc version, use the
common optinsn and override the allocation and freeing functions.

This also indirectly remove the CLANG warning about
is_kprobe_ppc_optinsn_slot() not being use, and the powerpc will
now benefit from commit 5b485629ba ("kprobes, extable: Identify
kprobes trampolines as kernel text area")

Suggested-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/ec5e85f9f9abcfecc959a03495f4a7858eb4d203.1620896780.git.christophe.leroy@csgroup.eu
This commit is contained in:
Christophe Leroy 2021-05-13 09:07:53 +00:00 committed by Michael Ellerman
parent 7ee3e97e00
commit b73c8cccd7
1 changed files with 5 additions and 18 deletions

View File

@ -31,11 +31,9 @@
#define TMPL_END_IDX \
(optprobe_template_end - optprobe_template_entry)
DEFINE_INSN_CACHE_OPS(ppc_optinsn);
static bool insn_page_in_use;
static void *__ppc_alloc_insn_page(void)
void *alloc_optinsn_page(void)
{
if (insn_page_in_use)
return NULL;
@ -43,20 +41,11 @@ static void *__ppc_alloc_insn_page(void)
return &optinsn_slot;
}
static void __ppc_free_insn_page(void *page __maybe_unused)
void free_optinsn_page(void *page)
{
insn_page_in_use = false;
}
struct kprobe_insn_cache kprobe_ppc_optinsn_slots = {
.mutex = __MUTEX_INITIALIZER(kprobe_ppc_optinsn_slots.mutex),
.pages = LIST_HEAD_INIT(kprobe_ppc_optinsn_slots.pages),
/* insn_size initialized later */
.alloc = __ppc_alloc_insn_page,
.free = __ppc_free_insn_page,
.nr_garbage = 0,
};
/*
* Check if we can optimize this probe. Returns NIP post-emulation if this can
* be optimized and 0 otherwise.
@ -136,7 +125,7 @@ NOKPROBE_SYMBOL(optimized_callback);
void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
{
if (op->optinsn.insn) {
free_ppc_optinsn_slot(op->optinsn.insn, 1);
free_optinsn_slot(op->optinsn.insn, 1);
op->optinsn.insn = NULL;
}
}
@ -203,14 +192,12 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
unsigned long nip, size;
int rc, i;
kprobe_ppc_optinsn_slots.insn_size = MAX_OPTINSN_SIZE;
nip = can_optimize(p);
if (!nip)
return -EILSEQ;
/* Allocate instruction slot for detour buffer */
buff = get_ppc_optinsn_slot();
buff = get_optinsn_slot();
if (!buff)
return -ENOMEM;
@ -297,7 +284,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
return 0;
error:
free_ppc_optinsn_slot(buff, 0);
free_optinsn_slot(buff, 0);
return -ERANGE;
}