summaryrefslogtreecommitdiff
path: root/arch/s390/kernel/ftrace.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-03-25 10:01:34 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2022-03-25 10:01:34 -0700
commitd710d370c4911e83da5d2bc43d4a2c3b56bd27e7 (patch)
tree9e7a702654feb88e2555c1bf41f71ef4a58b25aa /arch/s390/kernel/ftrace.c
parent744465da705f7d8cd893e97738a47b91f3321ce2 (diff)
parentc65f677b62d6180cc174e06f953f7fe860adf6d1 (diff)
downloadlinux-d710d370c4911e83da5d2bc43d4a2c3b56bd27e7.tar.gz
linux-d710d370c4911e83da5d2bc43d4a2c3b56bd27e7.tar.bz2
linux-d710d370c4911e83da5d2bc43d4a2c3b56bd27e7.zip
Merge tag 's390-5.18-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Vasily Gorbik: - Raise minimum supported machine generation to z10, which comes with various cleanups and code simplifications (usercopy/spectre mitigation/etc). - Rework extables and get rid of anonymous out-of-line fixups. - Page table helpers cleanup. Add set_pXd()/set_pte() helper functions. Covert pte_val()/pXd_val() macros to functions. - Optimize kretprobe handling by avoiding extra kprobe on __kretprobe_trampoline. - Add support for CEX8 crypto cards. - Allow to trigger AP bus rescan via writing to /sys/bus/ap/scans. - Add CONFIG_EXPOLINE_EXTERN option to build the kernel without COMDAT group sections which simplifies kpatch support. - Always use the packed stack layout and extend kernel unwinder tests. - Add sanity checks for ftrace code patching. - Add s390dbf debug log for the vfio_ap device driver. - Various virtual vs physical address confusion fixes. - Various small fixes and improvements all over the code. * tag 's390-5.18-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (69 commits) s390/test_unwind: add kretprobe tests s390/kprobes: Avoid additional kprobe in kretprobe handling s390: convert ".insn" encoding to instruction names s390: assume stckf is always present s390/nospec: move to single register thunks s390: raise minimum supported machine generation to z10 s390/uaccess: Add copy_from/to_user_key functions s390/nospec: align and size extern thunks s390/nospec: add an option to use thunk-extern s390/nospec: generate single register thunks if possible s390/pci: make zpci_set_irq()/zpci_clear_irq() static s390: remove unused expoline to BC instructions s390/irq: use assignment instead of cast s390/traps: get rid of magic cast for per code s390/traps: get rid of magic cast for program interruption code s390/signal: fix typo in comments s390/asm-offsets: remove unused defines s390/test_unwind: avoid build warning with W=1 s390: remove .fixup section s390/bpf: encode register within extable entry ...
Diffstat (limited to 'arch/s390/kernel/ftrace.c')
-rw-r--r--arch/s390/kernel/ftrace.c65
1 files changed, 31 insertions, 34 deletions
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index 89c0870d5679..1852d46babb1 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -4,8 +4,7 @@
*
* Copyright IBM Corp. 2009,2014
*
- * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>,
- * Martin Schwidefsky <schwidefsky@de.ibm.com>
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#include <linux/moduleloader.h>
@@ -61,18 +60,9 @@ asm(
#ifdef CONFIG_EXPOLINE
asm(
" .align 16\n"
- "ftrace_shared_hotpatch_trampoline_ex:\n"
- " lmg %r0,%r1,2(%r1)\n"
- " ex %r0," __stringify(__LC_BR_R1) "(%r0)\n"
- " j .\n"
- "ftrace_shared_hotpatch_trampoline_ex_end:\n"
-);
-
-asm(
- " .align 16\n"
"ftrace_shared_hotpatch_trampoline_exrl:\n"
" lmg %r0,%r1,2(%r1)\n"
- " .insn ril,0xc60000000000,%r0,0f\n" /* exrl */
+ " exrl %r0,0f\n"
" j .\n"
"0: br %r1\n"
"ftrace_shared_hotpatch_trampoline_exrl_end:\n"
@@ -91,12 +81,8 @@ static const char *ftrace_shared_hotpatch_trampoline(const char **end)
tend = ftrace_shared_hotpatch_trampoline_br_end;
#ifdef CONFIG_EXPOLINE
if (!nospec_disable) {
- tstart = ftrace_shared_hotpatch_trampoline_ex;
- tend = ftrace_shared_hotpatch_trampoline_ex_end;
- if (test_facility(35)) { /* exrl */
- tstart = ftrace_shared_hotpatch_trampoline_exrl;
- tend = ftrace_shared_hotpatch_trampoline_exrl_end;
- }
+ tstart = ftrace_shared_hotpatch_trampoline_exrl;
+ tend = ftrace_shared_hotpatch_trampoline_exrl_end;
}
#endif /* CONFIG_EXPOLINE */
if (end)
@@ -194,25 +180,26 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
return 0;
}
-static void brcl_disable(void *brcl)
+static int ftrace_patch_branch_mask(void *addr, u16 expected, bool enable)
{
- u8 op = 0x04; /* set mask field to zero */
+ u16 old;
+ u8 op;
- s390_kernel_write((char *)brcl + 1, &op, sizeof(op));
+ if (get_kernel_nofault(old, addr))
+ return -EFAULT;
+ if (old != expected)
+ return -EINVAL;
+ /* set mask field to all ones or zeroes */
+ op = enable ? 0xf4 : 0x04;
+ s390_kernel_write((char *)addr + 1, &op, sizeof(op));
+ return 0;
}
int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
unsigned long addr)
{
- brcl_disable((void *)rec->ip);
- return 0;
-}
-
-static void brcl_enable(void *brcl)
-{
- u8 op = 0xf4; /* set mask field to all ones */
-
- s390_kernel_write((char *)brcl + 1, &op, sizeof(op));
+ /* Expect brcl 0xf,... */
+ return ftrace_patch_branch_mask((void *)rec->ip, 0xc0f4, false);
}
int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
@@ -223,8 +210,8 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
if (IS_ERR(trampoline))
return PTR_ERR(trampoline);
s390_kernel_write(&trampoline->interceptor, &addr, sizeof(addr));
- brcl_enable((void *)rec->ip);
- return 0;
+ /* Expect brcl 0x0,... */
+ return ftrace_patch_branch_mask((void *)rec->ip, 0xc004, true);
}
int ftrace_update_ftrace_func(ftrace_func_t func)
@@ -297,14 +284,24 @@ NOKPROBE_SYMBOL(prepare_ftrace_return);
*/
int ftrace_enable_ftrace_graph_caller(void)
{
- brcl_disable(ftrace_graph_caller);
+ int rc;
+
+ /* Expect brc 0xf,... */
+ rc = ftrace_patch_branch_mask(ftrace_graph_caller, 0xa7f4, false);
+ if (rc)
+ return rc;
text_poke_sync_lock();
return 0;
}
int ftrace_disable_ftrace_graph_caller(void)
{
- brcl_enable(ftrace_graph_caller);
+ int rc;
+
+ /* Expect brc 0x0,... */
+ rc = ftrace_patch_branch_mask(ftrace_graph_caller, 0xa704, true);
+ if (rc)
+ return rc;
text_poke_sync_lock();
return 0;
}