[PATCH v2 3/4] ARC: implement syscall tracepoints

2022-04-14 Thread Sergey Matyukevich
From: Sergey Matyukevich 

Implement all the bits required to support HAVE_SYSCALL_TRACEPOINTS
according to Documentation/trace/ftrace-design.rst.

Signed-off-by: Sergey Matyukevich 
---
 arch/arc/Kconfig   |  1 +
 arch/arc/include/asm/syscall.h |  2 ++
 arch/arc/include/asm/thread_info.h |  5 -
 arch/arc/kernel/entry.S| 12 ++--
 arch/arc/kernel/ptrace.c   | 21 ++---
 5 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 3c850d0f431c..9e3653253ef2 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -39,6 +39,7 @@ config ARC
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_PERF_EVENTS
+   select HAVE_SYSCALL_TRACEPOINTS
select IRQ_DOMAIN
select MODULES_USE_ELF_RELA
select OF
diff --git a/arch/arc/include/asm/syscall.h b/arch/arc/include/asm/syscall.h
index 94529e89dff0..9709256e31c8 100644
--- a/arch/arc/include/asm/syscall.h
+++ b/arch/arc/include/asm/syscall.h
@@ -12,6 +12,8 @@
 #include 
 #include /* in_syscall() */
 
+extern void *sys_call_table[];
+
 static inline long
 syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
 {
diff --git a/arch/arc/include/asm/thread_info.h 
b/arch/arc/include/asm/thread_info.h
index 1e0b2e3914d5..6ba7fe417095 100644
--- a/arch/arc/include/asm/thread_info.h
+++ b/arch/arc/include/asm/thread_info.h
@@ -78,9 +78,9 @@ static inline __attribute_const__ struct thread_info 
*current_thread_info(void)
 #define TIF_SYSCALL_AUDIT  4   /* syscall auditing active */
 #define TIF_NOTIFY_SIGNAL  5   /* signal notifications exist */
 #define TIF_SYSCALL_TRACE  15  /* syscall trace active */
-
 /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE 16
+#define TIF_SYSCALL_TRACEPOINT 17  /* syscall tracepoint instrumentation */
 
 #define _TIF_SYSCALL_TRACE (1<
 #include 
 
+#define CREATE_TRACE_POINTS
+#include 
+
 struct pt_regs_offset {
const char *name;
int offset;
@@ -340,15 +343,27 @@ long arch_ptrace(struct task_struct *child, long request,
 
 asmlinkage int syscall_trace_entry(struct pt_regs *regs)
 {
-   if (ptrace_report_syscall_entry(regs))
-   return ULONG_MAX;
+   if (test_thread_flag(TIF_SYSCALL_TRACE))
+   if (ptrace_report_syscall_entry(regs))
+   return ULONG_MAX;
+
+#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
+   if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+   trace_sys_enter(regs, syscall_get_nr(current, regs));
+#endif
 
return regs->r8;
 }
 
 asmlinkage void syscall_trace_exit(struct pt_regs *regs)
 {
-   ptrace_report_syscall_exit(regs, 0);
+   if (test_thread_flag(TIF_SYSCALL_TRACE))
+   ptrace_report_syscall_exit(regs, 0);
+
+#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
+   if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+   trace_sys_exit(regs, regs_return_value(regs));
+#endif
 }
 
 int regs_query_register_offset(const char *name)
-- 
2.35.1


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH v2 4/4] ARC: disasm: handle ARCv2 case in kprobe get/set functions

2022-04-14 Thread Sergey Matyukevich
From: Sergey Matyukevich 

Current implementation of get_reg/set_reg implies ARCompact layout
of pt_regs structure. Meanwhile pt_regs structure differs between
ARCompact and ARCv2. Update those functions to handle ARCv2.

Signed-off-by: Sergey Matyukevich 
---
 arch/arc/kernel/disasm.c | 64 ++--
 1 file changed, 62 insertions(+), 2 deletions(-)

diff --git a/arch/arc/kernel/disasm.c b/arch/arc/kernel/disasm.c
index 03f8b1be0c3a..38f5f8325322 100644
--- a/arch/arc/kernel/disasm.c
+++ b/arch/arc/kernel/disasm.c
@@ -434,14 +434,31 @@ long __kprobes get_reg(int reg, struct pt_regs *regs,
 {
long *p;
 
+#if defined(CONFIG_ISA_ARCOMPACT)
if (reg <= 12) {
p = ®s->r0;
return p[-reg];
}
+#else /* CONFIG_ISA_ARCV2 */
+   if (reg <= 11) {
+   p = ®s->r0;
+   return p[reg];
+   }
 
+   if (reg == 12)
+   return regs->r12;
+   if (reg == 30)
+   return regs->r30;
+#ifdef CONFIG_ARC_HAS_ACCL_REGS
+   if (reg == 58)
+   return regs->r58;
+   if (reg == 59)
+   return regs->r59;
+#endif
+#endif
if (cregs && (reg <= 25)) {
p = &cregs->r13;
-   return p[13-reg];
+   return p[13 - reg];
}
 
if (reg == 26)
@@ -461,6 +478,7 @@ void __kprobes set_reg(int reg, long val, struct pt_regs 
*regs,
 {
long *p;
 
+#if defined(CONFIG_ISA_ARCOMPACT)
switch (reg) {
case 0 ... 12:
p = ®s->r0;
@@ -469,7 +487,37 @@ void __kprobes set_reg(int reg, long val, struct pt_regs 
*regs,
case 13 ... 25:
if (cregs) {
p = &cregs->r13;
-   p[13-reg] = val;
+   p[13 - reg] = val;
+   }
+   break;
+   case 26:
+   regs->gp = val;
+   break;
+   case 27:
+   regs->fp = val;
+   break;
+   case 28:
+   regs->sp = val;
+   break;
+   case 31:
+   regs->blink = val;
+   break;
+   default:
+   break;
+   }
+#else /* CONFIG_ISA_ARCV2 */
+   switch (reg) {
+   case 0 ... 11:
+   p = ®s->r0;
+   p[reg] = val;
+   break;
+   case 12:
+   regs->r12 = val;
+   break;
+   case 13 ... 25:
+   if (cregs) {
+   p = &cregs->r13;
+   p[13 - reg] = val;
}
break;
case 26:
@@ -481,12 +529,24 @@ void __kprobes set_reg(int reg, long val, struct pt_regs 
*regs,
case 28:
regs->sp = val;
break;
+   case 30:
+   regs->r30 = val;
+   break;
case 31:
regs->blink = val;
break;
+#ifdef CONFIG_ARC_HAS_ACCL_REGS
+   case 58:
+   regs->r58 = val;
+   break;
+   case 59:
+   regs->r59 = val;
+   break;
+#endif
default:
break;
}
+#endif
 }
 
 /*
-- 
2.35.1


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH v2 2/4] ARC: entry: fix syscall_trace_exit argument

2022-04-14 Thread Sergey Matyukevich
From: Sergey Matyukevich 

Function syscall_trace_exit expects pointer to pt_regs. However
r0 is also used to keep syscall return value. Restore pointer
to pt_regs before calling syscall_trace_exit.

Signed-off-by: Sergey Matyukevich 
---
 arch/arc/kernel/entry.S | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S
index dd77a0c8f740..66ba549b520f 100644
--- a/arch/arc/kernel/entry.S
+++ b/arch/arc/kernel/entry.S
@@ -196,6 +196,7 @@ tracesys_exit:
st  r0, [sp, PT_r0] ; sys call return value in pt_regs
 
;POST Sys Call Ptrace Hook
+   mov r0, sp  ; pt_regs needed
bl  @syscall_trace_exit
b   ret_from_exception ; NOT ret_from_system_call at is saves r0 which
; we'd done before calling post hook above
-- 
2.35.1


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH v2 1/4] ARC: enable HAVE_REGS_AND_STACK_ACCESS_API feature

2022-04-14 Thread Sergey Matyukevich
From: Sergey Matyukevich 

Enable HAVE_REGS_AND_STACK_ACCESS_API feature for ARC architecture,
including ARCcompact and ARCv2 flavors. Add supporting functions
and defines.

Signed-off-by: Sergey Matyukevich 
---
 arch/arc/Kconfig  |   1 +
 arch/arc/include/asm/ptrace.h |  27 
 arch/arc/kernel/ptrace.c  | 119 ++
 3 files changed, 147 insertions(+)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index e0a60a27e14d..3c850d0f431c 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -36,6 +36,7 @@ config ARC
select HAVE_KERNEL_LZMA
select HAVE_KPROBES
select HAVE_KRETPROBES
+   select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_PERF_EVENTS
select IRQ_DOMAIN
diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h
index cca8d6583e31..5869a74c0db2 100644
--- a/arch/arc/include/asm/ptrace.h
+++ b/arch/arc/include/asm/ptrace.h
@@ -8,6 +8,7 @@
 #define __ASM_ARC_PTRACE_H
 
 #include 
+#include 
 
 #ifndef __ASSEMBLY__
 
@@ -54,6 +55,9 @@ struct pt_regs {
 
unsigned long user_r25;
 };
+
+#define MAX_REG_OFFSET offsetof(struct pt_regs, user_r25)
+
 #else
 
 struct pt_regs {
@@ -102,6 +106,8 @@ struct pt_regs {
unsigned long status32;
 };
 
+#define MAX_REG_OFFSET offsetof(struct pt_regs, status32)
+
 #endif
 
 /* Callee saved registers - need to be saved only when you are scheduled out */
@@ -154,6 +160,27 @@ static inline void instruction_pointer_set(struct pt_regs 
*regs,
 {
instruction_pointer(regs) = val;
 }
+
+static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
+{
+   return regs->sp;
+}
+
+extern int regs_query_register_offset(const char *name);
+extern const char *regs_query_register_name(unsigned int offset);
+extern bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr);
+extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
+  unsigned int n);
+
+static inline unsigned long regs_get_register(struct pt_regs *regs,
+ unsigned int offset)
+{
+   if (unlikely(offset > MAX_REG_OFFSET))
+   return 0;
+
+   return *(unsigned long *)((unsigned long)regs + offset);
+}
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_PTRACE_H */
diff --git a/arch/arc/kernel/ptrace.c b/arch/arc/kernel/ptrace.c
index 54b419ac8bda..5fa5bceb83f3 100644
--- a/arch/arc/kernel/ptrace.c
+++ b/arch/arc/kernel/ptrace.c
@@ -9,6 +9,89 @@
 #include 
 #include 
 
+struct pt_regs_offset {
+   const char *name;
+   int offset;
+};
+
+#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)}
+#define REG_OFFSET_END {.name = NULL, .offset = 0}
+
+#ifdef CONFIG_ISA_ARCOMPACT
+static const struct pt_regs_offset regoffset_table[] = {
+   REG_OFFSET_NAME(bta),
+   REG_OFFSET_NAME(lp_start),
+   REG_OFFSET_NAME(lp_end),
+   REG_OFFSET_NAME(lp_count),
+   REG_OFFSET_NAME(status32),
+   REG_OFFSET_NAME(ret),
+   REG_OFFSET_NAME(blink),
+   REG_OFFSET_NAME(fp),
+   REG_OFFSET_NAME(r26),
+   REG_OFFSET_NAME(r12),
+   REG_OFFSET_NAME(r11),
+   REG_OFFSET_NAME(r10),
+   REG_OFFSET_NAME(r9),
+   REG_OFFSET_NAME(r8),
+   REG_OFFSET_NAME(r7),
+   REG_OFFSET_NAME(r6),
+   REG_OFFSET_NAME(r5),
+   REG_OFFSET_NAME(r4),
+   REG_OFFSET_NAME(r3),
+   REG_OFFSET_NAME(r2),
+   REG_OFFSET_NAME(r1),
+   REG_OFFSET_NAME(r0),
+   REG_OFFSET_NAME(sp),
+   REG_OFFSET_NAME(orig_r0),
+   REG_OFFSET_NAME(event),
+   REG_OFFSET_NAME(user_r25),
+   REG_OFFSET_END,
+};
+
+#else
+
+static const struct pt_regs_offset regoffset_table[] = {
+   REG_OFFSET_NAME(orig_r0),
+   REG_OFFSET_NAME(event),
+   REG_OFFSET_NAME(bta),
+   REG_OFFSET_NAME(user_r25),
+   REG_OFFSET_NAME(r26),
+   REG_OFFSET_NAME(fp),
+   REG_OFFSET_NAME(sp),
+   REG_OFFSET_NAME(r12),
+   REG_OFFSET_NAME(r30),
+#ifdef CONFIG_ARC_HAS_ACCL_REGS
+   REG_OFFSET_NAME(r58),
+   REG_OFFSET_NAME(r59),
+#endif
+#ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS
+   REG_OFFSET_NAME(DSP_CTRL),
+#endif
+   REG_OFFSET_NAME(r0),
+   REG_OFFSET_NAME(r1),
+   REG_OFFSET_NAME(r2),
+   REG_OFFSET_NAME(r3),
+   REG_OFFSET_NAME(r4),
+   REG_OFFSET_NAME(r5),
+   REG_OFFSET_NAME(r6),
+   REG_OFFSET_NAME(r7),
+   REG_OFFSET_NAME(r8),
+   REG_OFFSET_NAME(r9),
+   REG_OFFSET_NAME(r10),
+   REG_OFFSET_NAME(r11),
+   REG_OFFSET_NAME(blink),
+   REG_OFFSET_NAME(lp_end),
+   REG_OFFSET_NAME(lp_start),
+   REG_OFFSET_NAME(lp_count),
+   REG_OFFSET_NAME(ei),
+   REG_OFFSET_NAME(ldi),
+   REG_OFFSET_NAME(jli),
+   REG_OFFSET_NAME(ret),
+   REG_OFFSET_NAME(status32),
+   REG_OFFSET_END,
+};
+#endif
+
 static struct callee_regs *task_callee_regs(struct tas

[PATCH v2 0/4] ARC: add missing bits for better BPF support

2022-04-14 Thread Sergey Matyukevich
Hi Vineet and all,

Here is the second revision of the patch series implementing
the following two features for ARC:
- HAVE_REGS_AND_STACK_ACCESS_API
- HAVE_SYSCALL_TRACEPOINTS

Adding these features enables more BPF programs for ARC kernels,
including KPROBE, TRACEPOINT, PERF_EVENT program types.

Regards,
Sergey

v1 -> v2:

- drop path with uapi for BPF_PROG_TYPE_PERF_EVENT program type: send it via 
bpf mailing list
- add patch with ARCv2 changes for kprobe disasm

Sergey Matyukevich (4):
  ARC: enable HAVE_REGS_AND_STACK_ACCESS_API feature
  ARC: entry: fix syscall_trace_exit argument
  ARC: implement syscall tracepoints
  ARC: disasm: handle ARCv2 case in kprobe get/set functions

 arch/arc/Kconfig   |   2 +
 arch/arc/include/asm/ptrace.h  |  27 ++
 arch/arc/include/asm/syscall.h |   2 +
 arch/arc/include/asm/thread_info.h |   5 +-
 arch/arc/kernel/disasm.c   |  64 -
 arch/arc/kernel/entry.S|  13 +--
 arch/arc/kernel/ptrace.c   | 140 -
 7 files changed, 241 insertions(+), 12 deletions(-)

-- 
2.35.1


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc