提交 7d9b185c 编写于 作者: Z Zou Cao 提交者: Shile Zhang

alinux: arm64: add livepatch support

Now we support FTRACE_WITH_REGS with -fpatchable-function-entry, here
enable the livepatch support depend on FTRACE_WITH_REGS.

Use task flag bit 6 to track patch transisiton state for the consistency
model. Add it to the work mask so it gets cleared on all kernel exits to
userland.

Tell livepatch regs->pc + 2*AARCH64_INSN_SIZE is the place to change the
return address.

these codes have a big change against reference link, beacause we use new
gcc featrue.

References:
https://patchwork.kernel.org/patch/10657431/

Based-on-code-from: Torsten Duwe <duwe@suse.de>
Signed-off-by: NZou Cao <zoucao@linux.alibaba.com>
Acked-by: NCaspar Zhang <caspar@linux.alibaba.com>
上级 95fc4624
...@@ -170,6 +170,7 @@ config ARM64 ...@@ -170,6 +170,7 @@ config ARM64
select SWIOTLB select SWIOTLB
select SYSCTL_EXCEPTION_TRACE select SYSCTL_EXCEPTION_TRACE
select THREAD_INFO_IN_TASK select THREAD_INFO_IN_TASK
select HAVE_LIVEPATCH
help help
ARM 64-bit (AArch64) Linux support. ARM 64-bit (AArch64) Linux support.
...@@ -1359,6 +1360,8 @@ source "drivers/acpi/Kconfig" ...@@ -1359,6 +1360,8 @@ source "drivers/acpi/Kconfig"
source "arch/arm64/kvm/Kconfig" source "arch/arm64/kvm/Kconfig"
source "kernel/livepatch/Kconfig"
if CRYPTO if CRYPTO
source "arch/arm64/crypto/Kconfig" source "arch/arm64/crypto/Kconfig"
endif endif
#ifndef _ASM_ARM64_LIVEPATCH_H
#define _ASM_ARM64_LIVEPATCH_H
#include <linux/module.h>
#include <linux/ftrace.h>
#ifdef CONFIG_LIVEPATCH
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
static inline int klp_check_compiler_support(void)
{
return 0;
}
static inline void klp_arch_set_pc(struct pt_regs *regs, unsigned long pc)
{
regs->pc = pc + 2*AARCH64_INSN_SIZE;
}
#define klp_get_ftrace_location klp_get_ftrace_location
static inline unsigned long klp_get_ftrace_location(unsigned long faddr)
{
return faddr + AARCH64_INSN_SIZE;
}
#else
static inline int klp_check_compiler_support(void)
{
return 1;
}
static inline void klp_arch_set_pc(struct pt_regs *regs, unsigned long pc)
{
}
#define klp_get_ftrace_location klp_get_ftrace_location
static inline unsigned long klp_get_ftrace_location(unsigned long faddr)
{
return faddr + AARCH64_INSN_SIZE;
}
#endif
#else
#error Live patching support is disabled; check CONFIG_LIVEPATCH
#endif
#endif /* _ASM_ARM64_LIVEPATCH_H */
...@@ -76,6 +76,7 @@ void arch_release_task_struct(struct task_struct *tsk); ...@@ -76,6 +76,7 @@ void arch_release_task_struct(struct task_struct *tsk);
#define TIF_FOREIGN_FPSTATE 3 /* CPU's FP state is not current's */ #define TIF_FOREIGN_FPSTATE 3 /* CPU's FP state is not current's */
#define TIF_UPROBE 4 /* uprobe breakpoint or singlestep */ #define TIF_UPROBE 4 /* uprobe breakpoint or singlestep */
#define TIF_FSCHECK 5 /* Check FS is USER_DS on return */ #define TIF_FSCHECK 5 /* Check FS is USER_DS on return */
#define TIF_PATCH_PENDING 6
#define TIF_NOHZ 7 #define TIF_NOHZ 7
#define TIF_SYSCALL_TRACE 8 #define TIF_SYSCALL_TRACE 8
#define TIF_SYSCALL_AUDIT 9 #define TIF_SYSCALL_AUDIT 9
...@@ -94,6 +95,7 @@ void arch_release_task_struct(struct task_struct *tsk); ...@@ -94,6 +95,7 @@ void arch_release_task_struct(struct task_struct *tsk);
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_FOREIGN_FPSTATE (1 << TIF_FOREIGN_FPSTATE) #define _TIF_FOREIGN_FPSTATE (1 << TIF_FOREIGN_FPSTATE)
#define _TIF_PATCH_PENDING (1 << TIF_PATCH_PENDING)
#define _TIF_NOHZ (1 << TIF_NOHZ) #define _TIF_NOHZ (1 << TIF_NOHZ)
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
...@@ -106,7 +108,9 @@ void arch_release_task_struct(struct task_struct *tsk); ...@@ -106,7 +108,9 @@ void arch_release_task_struct(struct task_struct *tsk);
#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
_TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \ _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \
_TIF_UPROBE | _TIF_FSCHECK) _TIF_UPROBE | _TIF_FSCHECK | \
_TIF_PATCH_PENDING)
#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
_TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \ _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/sizes.h> #include <linux/sizes.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/tracehook.h> #include <linux/tracehook.h>
#include <linux/livepatch.h>
#include <linux/ratelimit.h> #include <linux/ratelimit.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
...@@ -937,6 +938,9 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, ...@@ -937,6 +938,9 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
if (thread_flags & _TIF_UPROBE) if (thread_flags & _TIF_UPROBE)
uprobe_notify_resume(regs); uprobe_notify_resume(regs);
if (thread_flags & _TIF_PATCH_PENDING)
klp_update_patch_state(current);
if (thread_flags & _TIF_SIGPENDING) if (thread_flags & _TIF_SIGPENDING)
do_signal(regs); do_signal(regs);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册