Skip to content

Commit

Permalink
Merge tag 'arc-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/vgupta/arc

Pull ARC updates from Vineet Gupta:

 - Basic eBPF support (Sergey)

* tag 'arc-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc:
  ARC: bpf: define uapi for BPF_PROG_TYPE_PERF_EVENT program type
  ARC: disasm: handle ARCv2 case in kprobe get/set functions
  ARC: implement syscall tracepoints
  ARC: enable HAVE_REGS_AND_STACK_ACCESS_API feature
  • Loading branch information
Linus Torvalds committed May 27, 2022
2 parents ef98f9c + 6aa98f6 commit ba62a53
Show file tree
Hide file tree
Showing 9 changed files with 253 additions and 12 deletions.
2 changes: 2 additions & 0 deletions arch/arc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ 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 HAVE_SYSCALL_TRACEPOINTS
select IRQ_DOMAIN
select MODULES_USE_ELF_RELA
select OF
Expand Down
4 changes: 4 additions & 0 deletions arch/arc/include/asm/perf_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,8 @@ struct arc_reg_cc_build {

#define PERF_COUNT_ARC_HW_MAX (PERF_COUNT_HW_MAX + 8)

#ifdef CONFIG_PERF_EVENTS
#define perf_arch_bpf_user_pt_regs(regs) (struct user_regs_struct *)regs
#endif

#endif /* __ASM_PERF_EVENT_H */
27 changes: 27 additions & 0 deletions arch/arc/include/asm/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define __ASM_ARC_PTRACE_H

#include <uapi/asm/ptrace.h>
#include <linux/compiler.h>

#ifndef __ASSEMBLY__

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
2 changes: 2 additions & 0 deletions arch/arc/include/asm/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <asm/unistd.h>
#include <asm/ptrace.h> /* in_syscall() */

extern void *sys_call_table[];

static inline long
syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
{
Expand Down
5 changes: 4 additions & 1 deletion arch/arc/include/asm/thread_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
Expand All @@ -89,11 +89,14 @@ static inline __attribute_const__ struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_NOTIFY_SIGNAL (1<<TIF_NOTIFY_SIGNAL)
#define _TIF_MEMDIE (1<<TIF_MEMDIE)
#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)

/* work to do on interrupt/exception return */
#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
_TIF_NOTIFY_RESUME | _TIF_NOTIFY_SIGNAL)

#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT)

/*
* _TIF_ALLWORK_MASK includes SYSCALL_TRACE, but we don't need it.
* SYSCALL_TRACE is anyway separately/unconditionally tested right after a
Expand Down
9 changes: 9 additions & 0 deletions arch/arc/include/uapi/asm/bpf_perf_event.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _UAPI__ASM_BPF_PERF_EVENT_H__
#define _UAPI__ASM_BPF_PERF_EVENT_H__

#include <asm/ptrace.h>

typedef struct user_regs_struct bpf_user_pt_regs_t;

#endif /* _UAPI__ASM_BPF_PERF_EVENT_H__ */
64 changes: 62 additions & 2 deletions arch/arc/kernel/disasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = &regs->r0;
return p[-reg];
}
#else /* CONFIG_ISA_ARCV2 */
if (reg <= 11) {
p = &regs->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)
Expand All @@ -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 = &regs->r0;
Expand All @@ -469,7 +487,7 @@ 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:
Expand All @@ -487,6 +505,48 @@ void __kprobes set_reg(int reg, long val, struct pt_regs *regs,
default:
break;
}
#else /* CONFIG_ISA_ARCV2 */
switch (reg) {
case 0 ... 11:
p = &regs->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:
regs->r26 = val;
break;
case 27:
regs->fp = val;
break;
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
}

/*
Expand Down
12 changes: 6 additions & 6 deletions arch/arc/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ ENTRY(sys_clone_wrapper)
DISCARD_CALLEE_SAVED_USER

GET_CURR_THR_INFO_FLAGS r10
btst r10, TIF_SYSCALL_TRACE
bnz tracesys_exit
and.f 0, r10, _TIF_SYSCALL_WORK
bnz tracesys_exit

b .Lret_from_system_call
END(sys_clone_wrapper)
Expand All @@ -41,8 +41,8 @@ ENTRY(sys_clone3_wrapper)
DISCARD_CALLEE_SAVED_USER

GET_CURR_THR_INFO_FLAGS r10
btst r10, TIF_SYSCALL_TRACE
bnz tracesys_exit
and.f 0, r10, _TIF_SYSCALL_WORK
bnz tracesys_exit

b .Lret_from_system_call
END(sys_clone3_wrapper)
Expand Down Expand Up @@ -247,8 +247,8 @@ ENTRY(EV_Trap)

; If syscall tracing ongoing, invoke pre-post-hooks
GET_CURR_THR_INFO_FLAGS r10
btst r10, TIF_SYSCALL_TRACE
bnz tracesys ; this never comes back
and.f 0, r10, _TIF_SYSCALL_WORK
bnz tracesys ; this never comes back

;============ Normal syscall case

Expand Down
Loading

0 comments on commit ba62a53

Please sign in to comment.