[PATCH 1/8] riscv/kprobe: Prepare the skeleton to implement RISCV OPTPROBES feature

liaochang (A) liaochang1 at huawei.com
Tue Nov 1 04:07:44 PDT 2022


Hi,Conor,

在 2022/11/1 3:42, Conor Dooley 写道:
> Hey Chen Guokai,
> 
> On Sun, Oct 30, 2022 at 05:01:34PM +0800, Chen Guokai wrote:
>> From: Liao Chang <liaochang1 at huawei.com>
>>
>> Prepare skeleton to implement optimized kprobe on RISCV, it consists
>> of Makfile, Kconfig and some architecture specific files: kprobe.h and
>> opt.c opt.c includes some macro, type definition and functions required
>> by kprobe framework, opt_trampoline.S provides a piece of assembly code
>> template used to construct the detour buffer as the target of long jump
>> instruction(s) for each optimzed kprobe.
>>
>> Since the jump range of PC-relative instruction JAL is +/-1M, that is
>> too small to reach the detour buffer, hence the foudamental idea to
>> address OPTPROBES on RISCV is to replace 'EBREAK' with 'AUIPC+JALR'. which
>> means it needs to clobber one more instruction beside the kprobe
>> instruction, furthermore, RISCV supports hybird RVI and RVC in single
>> kernel binary, so in theory a pair of 'AUIPC/JALR' is about to clobber
>> 10 bytes(3 RVC and 1 RVI, 2 bytes is padding for alignment) at worst
>> case. The second hardsome problem is looking for one integer register as
>> the destination of 'AUIPC/JALR' without any side-effect.
>>
>> More solution details will be introduced in the coming commits.
> 
> nit: you can drop this reference to future commits.
> 
>>
>> Co-developed-by: Chen Guokai <chenguokai17 at mails.ucas.ac.cn>
>> Signed-off-by: Chen Guokai <chenguokai17 at mails.ucas.ac.cn>
>> Signed-off-by: Liao Chang <liaochang1 at huawei.com>
> 
> FYI, your signoff should come last since you're sending the patches, so
> this would become:
> 
>> Signed-off-by: Liao Chang <liaochang1 at huawei.com>
>> Co-developed-by: Chen Guokai <chenguokai17 at mails.ucas.ac.cn>
>> Signed-off-by: Chen Guokai <chenguokai17 at mails.ucas.ac.cn>
> 
> I noticed on some of the other patches that your SoB is missing there,
> for example patch 2.

Yes, i have sent patch 2 to mailing list long time ago, got some feedback from
Palmer Debbelt. Because that patch is designed for riscv optprobe, so i bring it
to this patchset.

Thanks.

> 
> Thanks,
> Conor.
> 
>> ---
>>  arch/riscv/Kconfig                        |  1 +
>>  arch/riscv/include/asm/kprobes.h          | 32 ++++++++++++++
>>  arch/riscv/kernel/probes/Makefile         |  1 +
>>  arch/riscv/kernel/probes/opt.c            | 51 +++++++++++++++++++++++
>>  arch/riscv/kernel/probes/opt_trampoline.S | 12 ++++++
>>  5 files changed, 97 insertions(+)
>>  create mode 100644 arch/riscv/kernel/probes/opt.c
>>  create mode 100644 arch/riscv/kernel/probes/opt_trampoline.S
>>
>> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
>> index 6b48a3ae9843..ca29306c93e2 100644
>> --- a/arch/riscv/Kconfig
>> +++ b/arch/riscv/Kconfig
>> @@ -99,6 +99,7 @@ config RISCV
>>  	select HAVE_KPROBES if !XIP_KERNEL
>>  	select HAVE_KPROBES_ON_FTRACE if !XIP_KERNEL
>>  	select HAVE_KRETPROBES if !XIP_KERNEL
>> +	select HAVE_OPTPROBES if !XIP_KERNEL
>>  	select HAVE_MOVE_PMD
>>  	select HAVE_MOVE_PUD
>>  	select HAVE_PCI
>> diff --git a/arch/riscv/include/asm/kprobes.h b/arch/riscv/include/asm/kprobes.h
>> index 217ef89f22b9..22b73a2fd1fd 100644
>> --- a/arch/riscv/include/asm/kprobes.h
>> +++ b/arch/riscv/include/asm/kprobes.h
>> @@ -43,5 +43,37 @@ bool kprobe_single_step_handler(struct pt_regs *regs);
>>  void __kretprobe_trampoline(void);
>>  void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
>>  
>> +#ifdef CONFIG_OPTPROBES
>> +
>> +/* optinsn template addresses */
>> +extern __visible kprobe_opcode_t optprobe_template_entry[];
>> +extern __visible kprobe_opcode_t optprobe_template_end[];
>> +
>> +#define MAX_OPTINSN_SIZE				\
>> +	((unsigned long)optprobe_template_end -		\
>> +	 (unsigned long)optprobe_template_entry)
>> +
>> +/*
>> + * For RVI and RVC hybird encoding kernel, althought long jump just needs
>> + * 2 RVI instructions(AUIPC+JALR), optimized instructions is 10 bytes long
>> + * at most to ensure no RVI would be truncated actually, so it means four
>> + * combinations:
>> + * - 2 RVI
>> + * - 4 RVC
>> + * - 2 RVC + 1 RVI
>> + * - 3 RVC + 1 RVI (truncated, need padding)
>> + */
>> +#define MAX_COPIED_INSN		4
>> +#define MAX_OPTIMIZED_LENGTH	10
>> +
>> +struct arch_optimized_insn {
>> +	kprobe_opcode_t copied_insn[MAX_COPIED_INSN];
>> +	/* detour code buffer */
>> +	kprobe_opcode_t *insn;
>> +	unsigned long length;
>> +	int rd;
>> +};
>> +
>> +#endif /* CONFIG_OPTPROBES */
>>  #endif /* CONFIG_KPROBES */
>>  #endif /* _ASM_RISCV_KPROBES_H */
>> diff --git a/arch/riscv/kernel/probes/Makefile b/arch/riscv/kernel/probes/Makefile
>> index 7f0840dcc31b..6255b4600875 100644
>> --- a/arch/riscv/kernel/probes/Makefile
>> +++ b/arch/riscv/kernel/probes/Makefile
>> @@ -3,4 +3,5 @@ obj-$(CONFIG_KPROBES)		+= kprobes.o decode-insn.o simulate-insn.o
>>  obj-$(CONFIG_KPROBES)		+= kprobes_trampoline.o
>>  obj-$(CONFIG_KPROBES_ON_FTRACE)	+= ftrace.o
>>  obj-$(CONFIG_UPROBES)		+= uprobes.o decode-insn.o simulate-insn.o
>> +obj-$(CONFIG_OPTPROBES)		+= opt.o opt_trampoline.o
>>  CFLAGS_REMOVE_simulate-insn.o = $(CC_FLAGS_FTRACE)
>> diff --git a/arch/riscv/kernel/probes/opt.c b/arch/riscv/kernel/probes/opt.c
>> new file mode 100644
>> index 000000000000..56c8a227c857
>> --- /dev/null
>> +++ b/arch/riscv/kernel/probes/opt.c
>> @@ -0,0 +1,51 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + *  Kernel Probes Jump Optimization (Optprobes)
>> + *
>> + * Copyright (C) Guokai Chen, 2022
>> + * Author: Guokai Chen chenguokai17 at mails.ucas.ac.cn
>> + */
>> +
>> +#define pr_fmt(fmt)	"optprobe: " fmt
>> +
>> +#include <linux/kprobes.h>
>> +#include <asm/kprobes.h>
>> +
>> +int arch_prepared_optinsn(struct arch_optimized_insn *optinsn)
>> +{
>> +	return 0;
>> +}
>> +
>> +int arch_check_optimized_kprobe(struct optimized_kprobe *op)
>> +{
>> +	return 0;
>> +}
>> +
>> +int arch_prepare_optimized_kprobe(struct optimized_kprobe *op,
>> +				  struct kprobe *orig)
>> +{
>> +	return 0;
>> +}
>> +
>> +void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
>> +{
>> +}
>> +
>> +void arch_optimize_kprobes(struct list_head *oplist)
>> +{
>> +}
>> +
>> +void arch_unoptimize_kprobes(struct list_head *oplist,
>> +			     struct list_head *done_list)
>> +{
>> +}
>> +
>> +void arch_unoptimize_kprobe(struct optimized_kprobe *op)
>> +{
>> +}
>> +
>> +int arch_within_optimized_kprobe(struct optimized_kprobe *op,
>> +				 kprobe_opcode_t *addr)
>> +{
>> +	return 0;
>> +}
>> diff --git a/arch/riscv/kernel/probes/opt_trampoline.S b/arch/riscv/kernel/probes/opt_trampoline.S
>> new file mode 100644
>> index 000000000000..16160c4367ff
>> --- /dev/null
>> +++ b/arch/riscv/kernel/probes/opt_trampoline.S
>> @@ -0,0 +1,12 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/*
>> + * Copyright (C) 2022 Guokai Chen
>> + */
>> +
>> +#include <linux/linkage.h>
>> +
>> +#incldue <asm/csr.h>
>> +#include <asm/asm-offsets.h>
>> +
>> +SYM_ENTRY(optprobe_template_entry, SYM_L_GLOBAL, SYM_A_NONE)
>> +SYM_ENTRY(optprobe_template_end, SYM_L_GLOBAL, SYM_A_NONE)
>> -- 
>> 2.25.1
>>
>>
>> _______________________________________________
>> linux-riscv mailing list
>> linux-riscv at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-riscv
> .

-- 
BR,
Liao, Chang



More information about the linux-riscv mailing list