Skip to content

Commit

Permalink
LoongArch: Add kernel livepatching support
Browse files Browse the repository at this point in the history
Signed-off-by: Jinyang He <hejinyang@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
  • Loading branch information
chenhuacai committed Dec 3, 2023
1 parent 239397d commit 744942c
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 0 deletions.
4 changes: 4 additions & 0 deletions arch/loongarch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ config LOONGARCH
select HAVE_KPROBES_ON_FTRACE
select HAVE_KRETPROBES
select HAVE_KVM
select HAVE_LIVEPATCH
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_NMI
select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS
Expand All @@ -139,6 +140,7 @@ config LOONGARCH
select HAVE_PERF_USER_STACK_DUMP
select HAVE_PREEMPT_DYNAMIC_KEY
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_RELIABLE_STACKTRACE if UNWINDER_ORC
select HAVE_RETHOOK
select HAVE_RSEQ
select HAVE_SAMPLE_FTRACE_DIRECT
Expand Down Expand Up @@ -689,6 +691,8 @@ config KASAN_SHADOW_OFFSET
default 0x0
depends on KASAN

source "kernel/livepatch/Kconfig"

menu "Power management options"

config ARCH_SUSPEND_POSSIBLE
Expand Down
18 changes: 18 additions & 0 deletions arch/loongarch/include/asm/livepatch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_LIVEPATCH_H
#define _ASM_LIVEPATCH_H

#include <asm/inst.h>

static inline int klp_check_compiler_support(void)
{
return 0;
}

static inline void klp_arch_set_pc(struct ftrace_regs *fregs, unsigned long ip)
{
struct pt_regs *regs = ftrace_get_regs(fregs);

regs->csr_era = ip;
}
#endif /* _ASM_LIVEPATCH_H */
2 changes: 2 additions & 0 deletions arch/loongarch/include/asm/thread_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ register unsigned long current_stack_pointer __asm__("$sp");
#define TIF_LASX_CTX_LIVE 18 /* LASX context must be preserved */
#define TIF_USEDLBT 19 /* LBT was used by this task this quantum (SMP) */
#define TIF_LBT_CTX_LIVE 20 /* LBT context must be preserved */
#define TIF_PATCH_PENDING 21 /* pending live patching update */

#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
Expand All @@ -105,6 +106,7 @@ register unsigned long current_stack_pointer __asm__("$sp");
#define _TIF_LASX_CTX_LIVE (1<<TIF_LASX_CTX_LIVE)
#define _TIF_USEDLBT (1<<TIF_USEDLBT)
#define _TIF_LBT_CTX_LIVE (1<<TIF_LBT_CTX_LIVE)
#define _TIF_PATCH_PENDING (1<<TIF_PATCH_PENDING)

#endif /* __KERNEL__ */
#endif /* _ASM_THREAD_INFO_H */
40 changes: 40 additions & 0 deletions arch/loongarch/kernel/stacktrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,46 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
}
}

int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry,
void *cookie, struct task_struct *task)
{
unsigned long addr;
struct pt_regs dummyregs;
struct pt_regs *regs = &dummyregs;
struct unwind_state state;

if (task == current) {
regs->regs[3] = (unsigned long)__builtin_frame_address(0);
regs->csr_era = (unsigned long)__builtin_return_address(0);
} else {
regs->regs[3] = thread_saved_fp(task);
regs->csr_era = thread_saved_ra(task);
}
regs->regs[1] = 0;
regs->regs[22] = 0;

for (unwind_start(&state, task, regs);
!unwind_done(&state) && !unwind_error(&state); unwind_next_frame(&state)) {
addr = unwind_get_return_address(&state);

/*
* A NULL or invalid return address probably means there's some
* generated code which __kernel_text_address() doesn't know about.
*/
if (!addr)
return -EINVAL;

if (!consume_entry(cookie, addr))
return -EINVAL;
}

/* Check for stack corruption */
if (unwind_error(&state))
return -EINVAL;

return 0;
}

static int
copy_stack_frame(unsigned long fp, struct stack_frame *frame)
{
Expand Down

0 comments on commit 744942c

Please sign in to comment.