From: Masami Hiramatsu <mhiramat@kernel.org>
To: linux-kernel@vger.kernel.org, Peter Zijlstra <peterz@infradead.org>
Cc: Eddy Wu <Eddy_Wu@trendmicro.com>,
x86@kernel.org, "David S . Miller" <davem@davemloft.net>,
Steven Rostedt <rostedt@goodmis.org>,
Ingo Molnar <mingo@redhat.com>,
"Naveen N . Rao" <naveen.n.rao@linux.ibm.com>,
Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>,
linux-arch@vger.kernel.org, guoren@kernel.org
Subject: [PATCH v3 15/16] kprobes: Free kretprobe_instance with rcu callback
Date: Fri, 28 Aug 2020 01:40:46 +0900 [thread overview]
Message-ID: <159854644641.736475.2495205002588583050.stgit@devnote2> (raw)
In-Reply-To: <159854631442.736475.5062989489155389472.stgit@devnote2>
Free kretprobe_instance with rcu callback instead of directly
freeing the object in the kretprobe handler context.
This will make kretprobe run safer in NMI context.
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
Changes in v3:
- Stick the rcu_head with hlist_node in kretprobe_instance
- Make recycle_rp_inst() static
---
include/linux/kprobes.h | 6 ++++--
kernel/kprobes.c | 25 ++++++-------------------
2 files changed, 10 insertions(+), 21 deletions(-)
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 46a7afcf5ec0..b4388abedecf 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -156,7 +156,10 @@ struct kretprobe {
};
struct kretprobe_instance {
- struct hlist_node hlist;
+ union {
+ struct hlist_node hlist;
+ struct rcu_head rcu;
+ };
struct kretprobe *rp;
kprobe_opcode_t *ret_addr;
struct task_struct *task;
@@ -395,7 +398,6 @@ int register_kretprobes(struct kretprobe **rps, int num);
void unregister_kretprobes(struct kretprobe **rps, int num);
void kprobe_flush_task(struct task_struct *tk);
-void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);
int disable_kprobe(struct kprobe *kp);
int enable_kprobe(struct kprobe *kp);
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 311033e4b8e4..ce788574883b 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1223,8 +1223,7 @@ void kprobes_inc_nmissed_count(struct kprobe *p)
}
NOKPROBE_SYMBOL(kprobes_inc_nmissed_count);
-void recycle_rp_inst(struct kretprobe_instance *ri,
- struct hlist_head *head)
+static void recycle_rp_inst(struct kretprobe_instance *ri)
{
struct kretprobe *rp = ri->rp;
@@ -1236,8 +1235,7 @@ void recycle_rp_inst(struct kretprobe_instance *ri,
hlist_add_head(&ri->hlist, &rp->free_instances);
raw_spin_unlock(&rp->lock);
} else
- /* Unregistering */
- hlist_add_head(&ri->hlist, head);
+ kfree_rcu(ri, rcu);
}
NOKPROBE_SYMBOL(recycle_rp_inst);
@@ -1313,7 +1311,7 @@ void kprobe_busy_end(void)
void kprobe_flush_task(struct task_struct *tk)
{
struct kretprobe_instance *ri;
- struct hlist_head *head, empty_rp;
+ struct hlist_head *head;
struct hlist_node *tmp;
unsigned long hash, flags = 0;
@@ -1323,19 +1321,14 @@ void kprobe_flush_task(struct task_struct *tk)
kprobe_busy_begin();
- INIT_HLIST_HEAD(&empty_rp);
hash = hash_ptr(tk, KPROBE_HASH_BITS);
head = &kretprobe_inst_table[hash];
kretprobe_table_lock(hash, &flags);
hlist_for_each_entry_safe(ri, tmp, head, hlist) {
if (ri->task == tk)
- recycle_rp_inst(ri, &empty_rp);
+ recycle_rp_inst(ri);
}
kretprobe_table_unlock(hash, &flags);
- hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
- hlist_del(&ri->hlist);
- kfree(ri);
- }
kprobe_busy_end();
}
@@ -1936,13 +1929,12 @@ unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs,
void *frame_pointer)
{
struct kretprobe_instance *ri = NULL;
- struct hlist_head *head, empty_rp;
+ struct hlist_head *head;
struct hlist_node *tmp;
unsigned long flags, orig_ret_address = 0;
kprobe_opcode_t *correct_ret_addr = NULL;
bool skipped = false;
- INIT_HLIST_HEAD(&empty_rp);
kretprobe_hash_lock(current, &head, &flags);
/*
@@ -2009,7 +2001,7 @@ unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs,
__this_cpu_write(current_kprobe, &kprobe_busy);
}
- recycle_rp_inst(ri, &empty_rp);
+ recycle_rp_inst(ri);
if (orig_ret_address != trampoline_address)
/*
@@ -2022,11 +2014,6 @@ unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs,
kretprobe_hash_unlock(current, &flags);
- hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
- hlist_del(&ri->hlist);
- kfree(ri);
- }
-
return orig_ret_address;
}
NOKPROBE_SYMBOL(__kretprobe_trampoline_handler)
next prev parent reply other threads:[~2020-08-27 16:40 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-27 16:38 [PATCH v3 00/16] kprobes: Unify kretprobe trampoline handlers Masami Hiramatsu
2020-08-27 16:38 ` [PATCH v3 01/16] kprobes: Add generic kretprobe trampoline handler Masami Hiramatsu
2020-08-28 1:57 ` Masami Hiramatsu
2020-08-27 16:38 ` [PATCH v3 02/16] x86/kprobes: Use " Masami Hiramatsu
2020-08-27 16:39 ` [PATCH v3 03/16] arm: kprobes: " Masami Hiramatsu
2020-08-27 16:39 ` [PATCH v3 04/16] arm64: " Masami Hiramatsu
2020-08-27 16:39 ` [PATCH v3 05/16] arc: " Masami Hiramatsu
2020-08-27 16:39 ` [PATCH v3 06/16] csky: " Masami Hiramatsu
2020-08-28 12:34 ` Guo Ren
2020-08-29 9:31 ` Masami Hiramatsu
2020-08-27 16:39 ` [PATCH v3 07/16] ia64: " Masami Hiramatsu
2020-08-27 16:39 ` [PATCH v3 08/16] mips: " Masami Hiramatsu
2020-08-27 16:39 ` [PATCH v3 09/16] parisc: " Masami Hiramatsu
2020-08-27 16:40 ` [PATCH v3 10/16] powerpc: " Masami Hiramatsu
2020-08-27 16:40 ` [PATCH v3 11/16] s390: " Masami Hiramatsu
2020-08-27 16:40 ` [PATCH v3 12/16] sh: " Masami Hiramatsu
2020-08-27 16:40 ` [PATCH v3 13/16] sparc: " Masami Hiramatsu
2020-08-27 16:40 ` [PATCH v3 14/16] kprobes: Remove NMI context check Masami Hiramatsu
2020-08-27 16:40 ` Masami Hiramatsu [this message]
2020-08-27 16:40 ` [PATCH v3 16/16] kprobes: Make local used functions static Masami Hiramatsu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=159854644641.736475.2495205002588583050.stgit@devnote2 \
--to=mhiramat@kernel.org \
--cc=Eddy_Wu@trendmicro.com \
--cc=anil.s.keshavamurthy@intel.com \
--cc=davem@davemloft.net \
--cc=guoren@kernel.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=naveen.n.rao@linux.ibm.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.