未验证 提交 a5a6aebf 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!250 add UPROBE_ALTER_PC flag for uprobe mechanism

Merge Pull Request from: @anatas 
 
[Description]
We try to implement a live-patch mechanism in the userspace based on the UPROBE.
In the handler, we may change the PC register.
In this case, UPROBE must skip the handle of the next instruction.

[Testing]
kernel options:
UPROBES_SUPPORT_PC_ALTER=y

 
 
Link:https://gitee.com/openeuler/kernel/pulls/250 
Reviewed-by: Xu Kuohai <xukuohai@huawei.com> 
Reviewed-by: Liu Chao <liuchao173@huawei.com> 
Reviewed-by: Zheng Zengkai <zhengzengkai@huawei.com> 
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com> 
......@@ -156,6 +156,15 @@ config UPROBES
managed by the kernel and kept transparent to the probed
application. )
config UPROBES_SUPPORT_PC_ALTER
def_bool n
depends on UPROBES
help
Add UPROBE_ALTER_PC flag for uprobe handlers. When handlers
change the pc register, set this flag to let the uprobe
mechanism skip the execuation of the next insturction.
config HAVE_64BIT_ALIGNED_ACCESS
def_bool 64BIT && !HAVE_EFFICIENT_UNALIGNED_ACCESS
help
......
......@@ -758,6 +758,7 @@ CONFIG_JUMP_LABEL=y
CONFIG_OPTPROBES=y
CONFIG_KPROBES_ON_FTRACE=y
CONFIG_UPROBES=y
CONFIG_UPROBES_SUPPORT_PC_ALTER=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_KRETPROBES=y
......
......@@ -22,8 +22,14 @@ struct inode;
struct notifier_block;
struct page;
#define UPROBE_HANDLER_REMOVE 1
#define UPROBE_HANDLER_MASK 1
#define UPROBE_HANDLER_REMOVE 1
#ifndef CONFIG_UPROBES_SUPPORT_PC_ALTER
#define UPROBE_HANDLER_MASK 1
#else
#define UPROBE_ALTER_PC 0x2
#define UPROBE_HANDLER_MASK 0x3
#endif
#define MAX_URETPROBE_DEPTH 64
......
......@@ -2070,10 +2070,17 @@ static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp)
return uprobe;
}
#ifdef CONFIG_UPROBES_SUPPORT_PC_ALTER
static bool handler_chain(struct uprobe *uprobe, struct pt_regs *regs)
#else
static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs)
#endif
{
struct uprobe_consumer *uc;
int remove = UPROBE_HANDLER_REMOVE;
#ifdef CONFIG_UPROBES_SUPPORT_PC_ALTER
bool need_skip = false;
#endif
bool need_prep = false; /* prepare return uprobe, when needed */
down_read(&uprobe->register_rwsem);
......@@ -2090,6 +2097,10 @@ static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs)
need_prep = true;
remove &= rc;
#ifdef CONFIG_UPROBES_SUPPORT_PC_ALTER
if (rc & UPROBE_ALTER_PC)
need_skip = true;
#endif
}
if (need_prep && !remove)
......@@ -2100,6 +2111,9 @@ static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs)
unapply_uprobe(uprobe, current->mm);
}
up_read(&uprobe->register_rwsem);
#ifdef CONFIG_UPROBES_SUPPORT_PC_ALTER
return need_skip;
#endif
}
static void
......@@ -2241,7 +2255,12 @@ static void handle_swbp(struct pt_regs *regs)
if (arch_uprobe_ignore(&uprobe->arch, regs))
goto out;
#ifdef CONFIG_UPROBES_SUPPORT_PC_ALTER
if (handler_chain(uprobe, regs))
goto out;
#else
handler_chain(uprobe, regs);
#endif
if (arch_uprobe_skip_sstep(&uprobe->arch, regs))
goto out;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册