Uprobe handler will be called from context specified by atomic_ctx.
Change-Id: I325e6f1c96c8e009c39bfe9ba926683db7cb0ffa
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
preload_module_write_msg_init(ip);
}
+static int write_msg_reg(struct us_ip *ip)
+{
+ ip->uprobe.atomic_ctx = false;
+
+ return get_caller_register_probe(ip);
+}
+
static void write_msg_uninit(struct us_ip *ip)
{
preload_module_write_msg_exit(ip);
static struct probe_iface write_msg_iface = {
.init = write_msg_init,
.uninit = write_msg_uninit,
- .reg = get_caller_register_probe,
+ .reg = write_msg_reg,
.unreg = get_caller_unregister_probe,
.get_uprobe = get_caller_get_uprobe,
.copy = get_caller_info_copy,
p = get_ukprobe((kprobe_opcode_t *)vaddr, tgid);
if (p) {
- if (!p->pre_handler || !p->pre_handler(p, regs))
+ struct uprobe *up = kp2up(p);
+ bool prepare = false;
+
+ if (up->atomic_ctx) {
+ if (!p->pre_handler || !p->pre_handler(p, regs))
+ prepare = true;
+ } else {
+ swap_preempt_enable_no_resched();
+ local_irq_restore(flags);
+
+ if (!p->pre_handler || !p->pre_handler(p, regs))
+ prepare = true;
+
+ local_irq_save(flags);
+ preempt_disable();
+ }
+
+ if (prepare)
prepare_singlestep(p, regs);
} else {
ret = urp_handler(regs, tgid);
struct task_struct *task; /**< Pointer to the task struct */
struct slot_manager *sm; /**< Pointer to slot manager */
struct arch_specific_tramp atramp; /**< Stores trampoline */
+ bool atomic_ctx; /**< Handler context */
};
struct uinst_info {
up->kp.addr = (kprobe_opcode_t *)ip->orig_addr;
up->task = ip->page->file->proc->task;
up->sm = ip->page->file->proc->sm;
+ up->atomic_ctx = true;
ret = probe_info_register(ip->info, ip);
if (ret) {