[DTrace-devel] DTrace-V1-ized 5.18 pushed to github
Nick Alcock
nick.alcock at oracle.com
Wed Jun 15 12:16:03 UTC 2022
Tests passed on x86-64 with https://github.com/oracle/dtrace-utils
(1.x-branch-dev branch). No tests run on aarch64 because I'm having
trouble building kernels that boot there at all right now.
Pushed to <https://github.com/oracle/dtrace-linux-kernel>, as a branch
with v1 in the name.
This push is of DTrace v1, using a specialized kernel module rather than BPF.
Changes since 5.16.12 are largely routine, excepting more changes in the
tristate machinery, some adjustments for newer binutils, and some fiddly
stuff in aarch64's entry.S (which is why I'm somewhat annoyed that I
can't test it):
1: 8a27c5b94ddd ! 1: 4607c707dea0 kbuild: bring back tristate.conf
@@ scripts/kconfig/confdata.c: static const char *conf_get_autoheader_name(void)
{
char *p2;
@@ scripts/kconfig/confdata.c: static char *escape_string_value(const char *in)
+
enum output_n { OUTPUT_N, OUTPUT_N_AS_UNSET, OUTPUT_N_NONE };
++#define PRINT_ESCAPE 0x01
++#define PRINT_UPCASE 0x02
++#define PRINT_TRISTATE_ONLY 0x04
++
static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n,
- bool escape_string)
-+ bool escape_string, bool upcase_string)
++ int flags)
{
const char *val;
char *escaped = NULL;
@@ scripts/kconfig/confdata.c: static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n,
+ if (sym->type == S_UNKNOWN)
+ return;
+
++ if (flags & PRINT_TRISTATE_ONLY && sym->type != S_TRISTATE)
++ return;
++
+ val = sym_get_string_value(sym);
+
+ if ((sym->type == S_BOOLEAN || sym->type == S_TRISTATE) &&
+@@ scripts/kconfig/confdata.c: static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n,
+ return;
+ }
+
+- if (sym->type == S_STRING && escape_string) {
++ if (sym->type == S_STRING && flags & PRINT_ESCAPE) {
+ escaped = escape_string_value(val);
val = escaped;
}
- fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, val);
-+ if (upcase_string)
++ if (flags & PRINT_UPCASE)
+ fprintf(fp, "%s%s=%c\n", CONFIG_, sym->name, (char)toupper(*val));
+ else
+ fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, val);
@@ scripts/kconfig/confdata.c: static void __print_symbol(FILE *fp, struct symbol *
static void print_symbol_for_dotconfig(FILE *fp, struct symbol *sym)
{
- __print_symbol(fp, sym, OUTPUT_N_AS_UNSET, true);
-+ __print_symbol(fp, sym, OUTPUT_N_AS_UNSET, true, false);
++ __print_symbol(fp, sym, OUTPUT_N_AS_UNSET, PRINT_ESCAPE);
}
static void print_symbol_for_autoconf(FILE *fp, struct symbol *sym)
{
-- __print_symbol(fp, sym, OUTPUT_N_NONE, true);
-+ __print_symbol(fp, sym, OUTPUT_N_NONE, true, false);
+- __print_symbol(fp, sym, OUTPUT_N_NONE, false);
++ __print_symbol(fp, sym, OUTPUT_N_NONE, 0);
+}
+
+static void print_symbol_for_tristate(FILE *fp, struct symbol *sym)
+{
-+ __print_symbol(fp, sym, OUTPUT_N_NONE, true, true);
++ __print_symbol(fp, sym, OUTPUT_N_NONE, PRINT_ESCAPE | PRINT_UPCASE |
++ PRINT_TRISTATE_ONLY);
}
void print_symbol_for_listconfig(struct symbol *sym)
{
- __print_symbol(stdout, sym, OUTPUT_N, true);
-+ __print_symbol(stdout, sym, OUTPUT_N, true, false);
++ __print_symbol(stdout, sym, OUTPUT_N, PRINT_ESCAPE);
}
static void print_symbol_for_c(FILE *fp, struct symbol *sym)
2: fa9b89605fbe = 2: 3d6eb3755d33 kbuild: add modules_thick.builtin
3: e70128bb7ff2 ! 3: 5d54938ca7ba kbuild: generate an address ranges map at vmlinux link time
@@ scripts/link-vmlinux.sh: kallsyms()
+ ' .tmp_vmlinux.map | sort > .tmp_vmlinux.ranges
+
+ # get kallsyms options
- if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then
+ if is_enabled CONFIG_KALLSYMS_ALL; then
kallsymopt="${kallsymopt} --all-symbols"
fi
4: 19627fc77123 ! 4: 22c4e5cbaec3 kallsyms: introduce sections needed to map symbols to built-in modules
@@ init/Kconfig: config POSIX_TIMERS
bool "Enable support for printk" if EXPERT
## scripts/Makefile ##
-@@ scripts/Makefile: HOSTCFLAGS_sorttable.o += -DUNWINDER_ORC_ENABLED
- HOSTLDLIBS_sorttable = -lpthread
+@@ scripts/Makefile: ifdef CONFIG_BUILDTIME_MCOUNT_SORT
+ HOSTCFLAGS_sorttable.o += -DMCOUNT_SORT_ENABLED
endif
+kallsyms-objs := kallsyms.o
5: 229ca9e53906 = 5: a40111889adf kallsyms: optimize .kallsyms_modules*
6: 6124167f9cdf = 6: 4c8d99a42243 kallsyms: add /proc/kallmodsyms
7: 0e838ac55a3b = 7: 915f208c3c7a kallsyms: add reliable symbol size info
8: b952790e4935 ! 8: 10a63f6d073f waitfd: new syscall implementing waitpid() over fds
@@ Commit message
## arch/x86/entry/syscalls/syscall_32.tbl ##
@@
- 447 i386 memfd_secret sys_memfd_secret
448 i386 process_mrelease sys_process_mrelease
449 i386 futex_waitv sys_futex_waitv
+ 450 i386 set_mempolicy_home_node sys_set_mempolicy_home_node
+# This one is a temporary number, designed for no clashes.
+# Nothing but DTrace should use it.
+473 i386 waitfd sys_waitfd
## arch/x86/entry/syscalls/syscall_64.tbl ##
@@
- 447 common memfd_secret sys_memfd_secret
448 common process_mrelease sys_process_mrelease
449 common futex_waitv sys_futex_waitv
+ 450 common set_mempolicy_home_node sys_set_mempolicy_home_node
+# This one is a temporary number, designed for no clashes.
+# Nothing but DTrace should use it.
+473 common waitfd sys_waitfd
@@ fs/io_uring.c
@@ fs/io_uring.c: static void __io_queue_proc(struct io_poll_iocb *poll, struct io_poll_table *pt,
}
- static void io_async_queue_proc(struct file *file, struct wait_queue_head *head,
+ static void io_poll_queue_proc(struct file *file, struct wait_queue_head *head,
- struct poll_table_struct *p)
-+ struct poll_table_struct *p,
-+ unsigned long fixed_event)
++ struct poll_table_struct *p, unsigned long fixed_event)
{
struct io_poll_table *pt = container_of(p, struct io_poll_table, pt);
- struct async_poll *apoll = pt->req->apoll;
-@@ fs/io_uring.c: static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
+
+@@ fs/io_uring.c: static int __io_arm_poll_handler(struct io_kiocb *req,
}
- static void io_poll_queue_proc(struct file *file, struct wait_queue_head *head,
+ static void io_async_queue_proc(struct file *file, struct wait_queue_head *head,
- struct poll_table_struct *p)
-+ struct poll_table_struct *p, unsigned long fixed_event)
++ struct poll_table_struct *p,
++ unsigned long fixed_event)
{
struct io_poll_table *pt = container_of(p, struct io_poll_table, pt);
-
+ struct async_poll *apoll = pt->req->apoll;
## fs/select.c ##
@@ fs/select.c: struct poll_table_page {
@@ include/linux/syscalls.h: long compat_ksys_semtimedop(int semid, struct sembuf _
int __user *optlen);
## include/uapi/asm-generic/unistd.h ##
-@@ include/uapi/asm-generic/unistd.h: __SYSCALL(__NR_process_mrelease, sys_process_mrelease)
- #define __NR_futex_waitv 449
- __SYSCALL(__NR_futex_waitv, sys_futex_waitv)
+@@ include/uapi/asm-generic/unistd.h: __SYSCALL(__NR_futex_waitv, sys_futex_waitv)
+ #define __NR_set_mempolicy_home_node 450
+ __SYSCALL(__NR_set_mempolicy_home_node, sys_set_mempolicy_home_node)
+#define __NR_waitfd 473
+__SYSCALL(__NR_waitfd, sys_waitfd)
+
#undef __NR_syscalls
--#define __NR_syscalls 450
+-#define __NR_syscalls 451
+#define __NR_syscalls 474
/*
9: 7032fcdde2fb = 9: 1e0d60ff2a42 ctf: generate CTF information for the kernel from DWARF
10: bd08dc14847d ! 10: 61dec356b36c ctf: kernel build with -gctf for CTF generation using GCC (sans ld atm)
@@ Makefile: else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
# gcc-10 renamed --param=allow-store-data-races=0 to
## init/Kconfig ##
-@@ init/Kconfig: config CC_HAS_ASM_INLINE
- config CC_HAS_NO_PROFILE_FN_ATTR
- def_bool $(success,echo '__attribute__((no_profile_instrument_function)) int x();' | $(CC) -x c - -c -o /dev/null -Werror)
+@@ init/Kconfig: config PAHOLE_VERSION
+ int
+ default $(shell,$(srctree)/scripts/pahole-version.sh $(PAHOLE))
+config HAVE_CTF_TOOLCHAIN
+ def_bool ($(cc-option,-gctf) || $(cc-option,-gt)) && $(ld-option,-lctf)
11: f1e9c80bfe18 ! 11: d241d7ab40fc ctf: toolchain-based CTF support
@@ scripts/Makefile.modfinal: quiet_cmd_ld_ko_o = LD [M] $@
$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
+ ## scripts/ctf/.gitignore ##
+@@
++ctfarchive
+ dwarf2ctf
+
## scripts/ctf/Makefile ##
@@
ifdef CONFIG_CTF
12: 07e2a33dead9 = 12: f19d01528522 kbuild: arm64: Set objects.builtin dependency to Image for CONFIG_CTF
13: c65bd6620293 ! 13: 42296dcda737 ctf: discard CTF from the vDSO
@@ arch/arm/vdso/Makefile: obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
+
ldflags-$(CONFIG_CPU_ENDIAN_BE8) := --be8
ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \
- -z max-page-size=4096 -nostdlib -shared $(ldflags-y) \
+ -z max-page-size=4096 -shared $(ldflags-y) \
## arch/arm64/kernel/vdso/Makefile ##
@@ arch/arm64/kernel/vdso/Makefile: UBSAN_SANITIZE := n
@@ arch/mips/vdso/Makefile: cflags-vdso := $(ccflags-vdso) \
CFLAGS_vgettimeofday.o = -include $(c-gettimeofday-y)
- ## arch/nds32/kernel/vdso/Makefile ##
-@@ arch/nds32/kernel/vdso/Makefile: ccflags-y := -shared -fno-common -fno-builtin -nostdlib -fPIC -Wl,-shared -g \
- # Disable gcov profiling for VDSO code
- GCOV_PROFILE := n
-
-+vdso-cflags :=
-+ifdef CONFIG_CTF_USING_BINUTILS
-+vdso-cflags += $(call cc-option,-gctf0) $(call cc-option,-gt0)
-+endif
-
- obj-y += vdso.o
- targets += vdso.lds
-@@ arch/nds32/kernel/vdso/Makefile: quiet_cmd_vdsold = VDSOL $@
- quiet_cmd_vdsoas = VDSOA $@
- cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $<
- quiet_cmd_vdsocc = VDSOA $@
-- cmd_vdsocc = $(CC) $(c_flags) -c -o $@ $<
-+ cmd_vdsocc = $(CC) $(c_flags) $(vdso-cflags) -c -o $@ $<
-
- # Install commands for the unstripped file
- quiet_cmd_vdso_install = INSTALL $@
-
## arch/sparc/vdso/Makefile ##
@@
# Building vDSO images for sparc.
14: aed370a14ce1 = 14: c00f8de60827 ctf: adjust to upcoming binutils ctf_link_add_ctf API change
15: 5d8af2596bfb = 15: 05aacef5c67e ctf: support ld --ctf-variables, if available
16: c55a68e14021 = 16: 2b9a177bb51d ctf: add *.ctf to .gitignore
17: 418fcd6a7e2f ! 17: b4ff02bfde44 dtrace: core and x86
@@ arch/x86/mm/fault.c: void do_user_addr_fault(struct pt_regs *regs,
## fs/exec.c ##
@@
- #include <linux/vmalloc.h>
#include <linux/io_uring.h>
#include <linux/syscall_user_dispatch.h>
+ #include <linux/coredump.h>
+#include <linux/dtrace_os.h>
#include <linux/uaccess.h>
@@ include/dtrace/dtrace_impl.h (new)
+extern int dtrace_toxranges;
+
+extern void dtrace_nullop(void);
-+extern int dtrace_enable_nullop(void);
++extern int dtrace_enable_nullop(void *, dtrace_id_t, void *);
+extern int dtrace_istoxic(uintptr_t, size_t);
+
+/*
@@ init/Kconfig: config PROFILING
## init/main.c ##
@@
- #include <linux/kcsan.h>
#include <linux/init_syscalls.h>
#include <linux/stackdepot.h>
+ #include <net/net_namespace.h>
+#include <linux/dtrace_cpu.h>
+#include <linux/dtrace_os.h>
@@ kernel/dtrace/dtrace_task.c (new)
## kernel/exit.c ##
@@
- #include <linux/compat.h>
#include <linux/io_uring.h>
#include <linux/kprobes.h>
+ #include <linux/rethook.h>
+#include <linux/dtrace_os.h>
#include <linux/uaccess.h>
@@ kernel/exit.c: void __noreturn do_exit(long code)
## kernel/fork.c ##
@@
- #include <linux/scs.h>
#include <linux/io_uring.h>
#include <linux/bpf.h>
+ #include <linux/sched/mm.h>
+#include <linux/dtrace_task_impl.h>
#include <asm/pgalloc.h>
@@ kernel/fork.c: static __latent_entropy struct task_struct *copy_process(
+#endif
+
proc_fork_connector(p);
- sched_post_fork(p, args);
+ sched_post_fork(p);
cgroup_post_fork(p, args);
## kernel/locking/mutex.c ##
@@ kernel/module.c: SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
+ goto out;
+ }
+
- /* Stop the machine so refcounts can't move and disable module. */
ret = try_stop_module(mod, flags, &forced);
if (ret != 0)
+ goto out;
@@ kernel/module.c: static void cfi_cleanup(struct module *mod);
/* Free a module, remove from lists, etc. */
static void free_module(struct module *mod)
@@ kernel/module.c: static int load_module(struct load_info *info, const char __use
## kernel/sched/core.c ##
@@
-
- #include <linux/nospec.h>
- #include <linux/blkdev.h>
+ #include <linux/interrupt.h>
+ #include <linux/ioprio.h>
+ #include <linux/kallsyms.h>
+
+#include <linux/dtrace_os.h>
+
#include <linux/kcov.h>
- #include <linux/scs.h>
-
+ #include <linux/kprobes.h>
+ #include <linux/llist_api.h>
@@ kernel/sched/core.c: static struct rq *finish_task_switch(struct task_struct *prev)
rq->prev_mm = NULL;
@@ kernel/sched/core.c: static struct rq *finish_task_switch(struct task_struct *pr
* A task struct has one reference for the use as "current".
* If a task dies, then it sets TASK_DEAD in tsk->state and calls
@@ kernel/sched/core.c: void __init sched_init(void)
- rq->core_forceidle = false;
+ rq->core_forceidle_start = 0;
rq->core_cookie = 0UL;
+#endif
@@ kernel/sched/core.c: void __init sched_init(void)
## kernel/sched/sched.h ##
-@@ kernel/sched/sched.h: extern bool dl_cpu_busy(unsigned int cpu);
+@@ kernel/sched/sched.h: extern int dl_cpu_busy(int cpu, struct task_struct *p);
+
#ifdef CONFIG_CGROUP_SCHED
- #include <linux/cgroup.h>
+#include <linux/dtrace_cpu.h>
- #include <linux/psi.h>
-
++
struct cfs_rq;
+ struct rt_rq;
+
@@ kernel/sched/sched.h: struct rq {
- unsigned char core_forceidle;
- unsigned int core_forceidle_seq;
+ unsigned int core_forceidle_occupation;
+ u64 core_forceidle_start;
#endif
+#ifdef CONFIG_DTRACE
+ struct cpuinfo *dtrace_cpu_info;
18: c02f2af0388d ! 18: d283c0ae5b64 dtrace: modular components and x86 support
@@ arch/x86/dtrace/dtrace_asm_x86_64.S (new)
+ SYM_CODE_END(dtrace_fuword64_nocheck)
+
+#endif /* __i386__ */
++
++.section .note.GNU-stack, "", @progbits
## arch/x86/dtrace/dtrace_isa_x86_64.c (new) ##
@@
@@ dtrace/dtrace_dev.c (new)
+{
+}
+
-+int dtrace_enable_nullop(void)
++int dtrace_enable_nullop(void *unused, dtrace_id_t unused2, void *unused3)
+{
+ return 0;
+}
19: 17492dfd7016 = 19: 20cc15f28a57 dtrace: systrace provider core components
20: feabfa639515 = 20: 877486250b67 dtrace: systrace provider
21: f653bdb8cb35 ! 21: a63aadd817ff dtrace: sdt provider core components
@@ scripts/.gitignore
+kmodsdt
## scripts/Makefile ##
-@@ scripts/Makefile: hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file
- hostprogs-always-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert
+@@ scripts/Makefile: hostprogs-always-$(CONFIG_BUILDTIME_TABLE_SORT) += sorttable
+ hostprogs-always-$(CONFIG_ASN1) += asn1_compiler
+ hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file
hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert
- hostprogs-always-$(CONFIG_SYSTEM_REVOCATION_LIST) += extract-cert
+hostprogs-always-$(CONFIG_DTRACE) += kmodsdt
HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include
- HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include
+ HOSTLDLIBS_sorttable = -lpthread
@@ scripts/Makefile: ifdef CONFIG_KALLMODSYMS
kallsyms-objs += modules_thick.o
endif
@@ scripts/link-vmlinux.sh: vmlinux_link()
+ shift
shift
- if [ -n "${CONFIG_LTO_CLANG}" ]; then
+ if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then
@@ scripts/link-vmlinux.sh: vmlinux_link()
ldflags="${ldflags} ${wl}-Map=${output}.map"
fi
@@ scripts/link-vmlinux.sh: fi;
+sdtstubo=""
+sdtinfoo=""
-+if [ -n "${CONFIG_DTRACE}" ]; then
++if is_enabled CONFIG_DTRACE; then
+ sdtstubo=.tmp_sdtstub.o
+ sdtinfoo=.tmp_sdtinfo.o
+ sdtstub ${sdtstubo}
@@ scripts/link-vmlinux.sh: fi;
#link vmlinux.o
modpost_link vmlinux.o
objtool_link vmlinux.o
-@@ scripts/link-vmlinux.sh: if [ -n "${CONFIG_KALLSYMS}" ]; then
+@@ scripts/link-vmlinux.sh: if is_enabled CONFIG_KALLSYMS; then
# a) Verify that the System.map from vmlinux matches the map from
# ${kallsymso}.
+ # step 1
-+ if [ -n "${CONFIG_DTRACE}" ]; then
++ if is_enabled CONFIG_DTRACE; then
+ sdtinfo vmlinux.o ${sdtinfoo}
+ fi
+
kallsyms_step 1
+
-+ if [ -n "${CONFIG_DTRACE}" ]; then
-+ if [ -n "${CONFIG_ARM64}" ]; then
-+ kallsyms_step 1
-+ else
-+ kallsyms_step 1 -r
-+ fi
++ if is_enabled CONFIG_DTRACE; then
++ kallsyms_step 1 -r
+ sdtinfo ${kallsyms_vmlinux} ${sdtinfoo} vmlinux.o
+ fi
+
@@ scripts/link-vmlinux.sh: if [ -n "${CONFIG_KALLSYMS}" ]; then
kallsyms_step 2
# step 3
-@@ scripts/link-vmlinux.sh: if [ -n "${CONFIG_KALLSYMS}" ]; then
+@@ scripts/link-vmlinux.sh: if is_enabled CONFIG_KALLSYMS; then
fi
fi
@@ scripts/link-vmlinux.sh: if [ -n "${CONFIG_KALLSYMS}" ]; then
+vmlinux_link vmlinux "" "${kallsymso}" ${btf_vmlinux_bin_o} ${sdtstubo} ${sdtinfoo}
# fill in BTF IDs
- if [ -n "${CONFIG_DEBUG_INFO_BTF}" -a -n "${CONFIG_BPF}" ]; then
+ if is_enabled CONFIG_DEBUG_INFO_BTF && is_enabled CONFIG_BPF; then
## scripts/mod/modpost.c ##
@@ scripts/mod/modpost.c: static void check_exports(struct module *mod)
22: 64a5bda461ac = 22: c6f718096444 dtrace: sdt provider for x86
23: 99e7f778d284 = 23: cd76f9aa1d96 dtrace: profile provider and test probe core components
24: 9cd06d200cd4 = 24: c83294385d61 dtrace: profile and tick providers built on cyclics
25: dc1420fdeaf6 = 25: 0606dbef86e0 dtrace: USDT and pid provider core and x86 components
26: 05435cc19e8f = 26: 993cba1caa8e dtrace: USDT and pid providers
27: 5bdb5aa98618 ! 27: 21c819ef56ca dtrace: function boundary tracing (FBT) core and x86 components
@@ Commit message
## arch/x86/entry/entry_64.S ##
@@
- #include <asm/frame.h>
#include <asm/trapnr.h>
#include <asm/nospec-branch.h>
--#include <asm/fsgsbase.h>
+ #include <asm/fsgsbase.h>
+#include <asm/dtrace_util.h>
#include <linux/err.h>
#include "calling.h"
@@ arch/x86/entry/entry_64.S: SYM_CODE_END(ret_from_fork)
-
- call \cfunc
+ /* For some configurations \cfunc ends up being a noreturn. */
+ REACHABLE
+#ifdef CONFIG_DTRACE
+ /*
@@ arch/x86/entry/entry_64.S: SYM_CODE_START_LOCAL(error_return)
+ movq %rax,8(%rsp) /* store calling RIP */
+ movq 32(%rsp),%rbp /* load %rsp into %rbp */
+ popq %rax /* pop off temp */
-+
-+ INTERRUPT_RETURN
++ jmp .Lnative_iret
+
+dtrace_emu_push:
+ POP_REGS
@@ arch/x86/entry/entry_64.S: SYM_CODE_START_LOCAL(error_return)
+ movq 32(%rsp),%rax /* reload calling RSP */
+ movq %rbp,(%rax) /* store %rbp there */
+ popq %rax /* pop off temp */
-+
-+ INTERRUPT_RETURN
++ jmp .Lnative_iret
+
+dtrace_emu_nop:
+ POP_REGS
@@ arch/x86/entry/entry_64.S: SYM_CODE_START_LOCAL(error_return)
+
+ /* Emulate a "nop" instruction. */
+ incq (%rsp)
-+
-+ INTERRUPT_RETURN
++ jmp .Lnative_iret
+
+dtrace_emu_leave:
+ POP_REGS
@@ arch/x86/entry/entry_64.S: SYM_CODE_START_LOCAL(error_return)
+ movq %rbp,32(%rsp) /* store new %rsp */
+ movq %rax,%rbp /* set new %rbp */
+ popq %rax /* pop off temp */
-+
-+ INTERRUPT_RETURN
++ jmp .Lnative_iret
+
+dtrace_emu_ret:
+ POP_REGS
@@ arch/x86/entry/entry_64.S: SYM_CODE_START_LOCAL(error_return)
+ movq %rax,8(%rsp) /* store calling RIP */
+ addq $8,32(%rsp) /* adjust new %rsp */
+ popq %rax /* pop off temp */
-+
-+ INTERRUPT_RETURN
++ jmp .Lnative_iret
+SYM_CODE_END(dtrace_error_return)
+
+.pushsection .rodata, "a"
@@ arch/x86/kernel/fbt_blacklist.h (new)
+BL_DENTRY(void *, kgdb_ll_trap)
+BL_DENTRY(void *, error_entry)
+BL_DENTRY(void *, xen_int3)
++BL_DENTRY(void *, do_int3)
+BL_DENTRY(void *, ftrace_int3_handler)
+BL_DENTRY(typeof(poke_int3_handler), poke_int3_handler)
+BL_DENTRY(void *, fixup_bad_iret)
@@ arch/x86/kernel/traps.c: static __always_inline void __user *error_get_trap_addr
+ 0, NULL);
}
- #ifdef CONFIG_X86_F00F_BUG
+ #ifdef CONFIG_X86_KERNEL_IBT
@@ arch/x86/kernel/traps.c: DEFINE_IDTENTRY_RAW(exc_invalid_op)
* in case exception entry is the one triggering WARNs.
*/
@@ arch/x86/kernel/traps.c: DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
- int ret;
+ int ret = 0;
+ if (user_mode(regs) && try_fixup_enqcmd_gp())
+- return;
++ return 0;
+
cond_local_irq_enable(regs);
@@ arch/x86/kernel/traps.c: DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
@@ arch/x86/kernel/traps.c: static bool do_int3(struct pt_regs *regs)
+
+ return false;
}
+ NOKPROBE_SYMBOL(do_int3);
-static void do_int3_user(struct pt_regs *regs)
+static int do_int3_user(struct pt_regs *regs)
28: b6f33af47506 = 28: 05a94c64d9df dtrace: fbt provider, modular components
29: a9e2b1ea772c ! 29: d2387e32af9b dtrace, arm: arm64 port
@@ arch/arm64/dtrace/dtrace_asm_arm64.S (new)
+ ldr x0, [x0]
+ ret
+SYM_CODE_END(dtrace_fuword64_nocheck)
++
++.section .note.GNU-stack, "", @progbits
## arch/arm64/dtrace/dtrace_isa_arm64.c (new) ##
@@
@@ arch/arm64/kernel/entry.S: alternative_else_nop_endif
ldp x4, x5, [sp, #16 * 2]
ldp x6, x7, [sp, #16 * 3]
@@ arch/arm64/kernel/entry.S: alternative_else_nop_endif
- ldp x26, x27, [sp, #16 * 13]
- ldp x28, x29, [sp, #16 * 14]
+ .if \el == 0
+ alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0
ldr lr, [sp, #S_LR]
++ .if \fbt_emu != 0 // FBT emulation needed?
++ mrs x0, esr_el1 // check if ESR is FBT probe
++ and x0, x0, #0x1f // ... mask code
++ cmp x0, #DPROBES_FBE_BRK_IMM // ... compare with FBE code
++ beq 6f // FBT entry -> emulate instr.
++ cmp x0, #DPROBES_FBR_BRK_IMM // ... compare with FBR code
++ beq 7f // FBT return -> emulate instr.
++ b 8f // not FBT -> skip next section
++
++6:
++ mrs x0, elr_el1 // retrieve xeceptionx link reg
++ add x0, x0, #0x4 // advance to next instr
++ msr elr_el1, x0 // set exception link reg
++
++ ldp x0, x1, [sp, #16 * 0] // done with x0, restore orig
++ add sp, sp, #PT_REGS_SIZE // restore sp
++ mov x29, sp // instr we put probe on
++ b 9f // FBT done -> branch to eret
+
++7:
++ msr elr_el1, lr // set exception link reg to
++ // link register value, to
++ // simulate the 'ret' instr.
++
++ ldp x0, x1, [sp, #16 * 0] // done with x0, restore orig
++ add sp, sp, #PT_REGS_SIZE // restore sp
++ b 9f // FBT done -> branch to eret
++
++8:
++ ldp x0, x1, [sp, #16 * 0] // done with x0, restore orig
++ add sp, sp, #PT_REGS_SIZE // restore sp
++9:
++ .else
++ ldp x0, x1, [sp, #16 * 0] // done with x0, restore orig
++ add sp, sp, #PT_REGS_SIZE // restore sp
++
++ .endif
+ add sp, sp, #PT_REGS_SIZE // restore sp
+ eret
+ alternative_else_nop_endif
+@@ arch/arm64/kernel/entry.S: alternative_else_nop_endif
+ #endif
+ .else
+ ldr lr, [sp, #S_LR]
+ .if \fbt_emu != 0 // FBT emulation needed?
+ mrs x0, esr_el1 // check if ESR is FBT probe
+ and x0, x0, #0x1f // ... mask code
@@ arch/arm64/kernel/entry.S: alternative_else_nop_endif
+9:
+ .else
+ ldp x0, x1, [sp, #16 * 0] // done with x0, restore orig
++ add sp, sp, #PT_REGS_SIZE // restore sp
++
++ .endif
add sp, sp, #PT_REGS_SIZE // restore sp
-+ .endif
-+
- .if \el == 0
- alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0
- #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
+ /* Ensure any device/NC reads complete */
@@ arch/arm64/kernel/entry.S: SYM_CODE_END(__bad_stack)
#endif /* CONFIG_VMAP_STACK */
@@ scripts/dtrace_sdt_arm64.sh (new)
+ print "dtrace_fbt_nfuncs:";
+ printf "\tPTR\t%d\n", funcc;
+
++ print "\t.section .note.GNU-stack, \042\042, @progbits";
++ print "";
++
+ exit(errc == 0 ? 0 : 1);
+ }' > ${tfn}
+
@@ scripts/link-vmlinux.sh: sdtinfo()
info SDTINF ${2}
- ${srctree}/scripts/dtrace_sdt.sh sdtinfo .tmp_sdtinfo.S ${1}
-+ if [ -n "${CONFIG_ARM64}" ]; then
++ if is_enabled CONFIG_ARM64; then
+ ${srctree}/scripts/dtrace_sdt_arm64.sh sdtinfo .tmp_sdtinfo.S \
+ ${1} ${3}
+ else
@@ scripts/link-vmlinux.sh: sdtinfo()
local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \
${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}"
-@@ scripts/link-vmlinux.sh: if [ -n "${CONFIG_KALLSYMS}" ]; then
+@@ scripts/link-vmlinux.sh: if is_enabled CONFIG_KALLSYMS; then
# step 1
- if [ -n "${CONFIG_DTRACE}" ]; then
+ if is_enabled CONFIG_DTRACE; then
- sdtinfo vmlinux.o ${sdtinfoo}
+ sdtinfo vmlinux.o ${sdtinfoo} vmlinux.o
fi
kallsyms_step 1
- if [ -n "${CONFIG_DTRACE}" ]; then
-- if [ -n "${CONFIG_ARM64}" ]; then
-- kallsyms_step 1
-- else
-- kallsyms_step 1 -r
-+ if [ -n "${CONFIG_X86_64}" ]; then
+ if is_enabled CONFIG_DTRACE; then
+- kallsyms_step 1 -r
++ if is_enabled CONFIG_X86_64; then
+ kallsyms_step 1 --emit-relocs
- fi
++ fi
sdtinfo ${kallsyms_vmlinux} ${sdtinfoo} vmlinux.o
fi
+
30: 977c882388a4 ! 30: ea374a163bee dtrace: add SDT probes
@@ block/bio.c: void bio_endio(struct bio *bio)
if (bio->bi_end_io)
## block/blk-core.c ##
-@@ block/blk-core.c: noinline_for_stack bool submit_bio_checks(struct bio *bio)
+@@ block/blk-core.c: void submit_bio_noacct(struct bio *bio)
+ * completion as well.
*/
bio_set_flag(bio, BIO_TRACE_COMPLETION);
++ DTRACE_IO(start, struct bio * : (bufinfo_t *, devinfo_t *), bio,
++ struct file * : fileinfo_t *, NULL);
}
-+ DTRACE_IO(start, struct bio * : (bufinfo_t *, devinfo_t *), bio,
-+ struct file * : fileinfo_t *, NULL);
- return true;
-
+ submit_bio_noacct_nocheck(bio);
+ return;
+@@ block/blk-core.c: void submit_bio_noacct(struct bio *bio)
not_supported:
status = BLK_STS_NOTSUPP;
end_io:
@@ block/blk-core.c: noinline_for_stack bool submit_bio_checks(struct bio *bio)
+ struct file * : fileinfo_t *, NULL);
bio->bi_status = status;
bio_endio(bio);
- return false;
+ }
## fs/exec.c ##
@@
- #include <linux/vmalloc.h>
#include <linux/io_uring.h>
#include <linux/syscall_user_dispatch.h>
+ #include <linux/coredump.h>
+#include <linux/sdt.h>
#include <linux/dtrace_os.h>
@@ fs/nfs/internal.h: static inline void nfs_set_port(struct sockaddr *sap, int *po
## fs/nfs/read.c ##
@@ fs/nfs/read.c: static void nfs_initiate_read(struct nfs_pgio_header *hdr,
- struct inode *inode = hdr->inode;
- int swap_flags = IS_SWAPFILE(inode) ? NFS_RPC_SWAPFLAGS : 0;
-
+ const struct nfs_rpc_ops *rpc_ops,
+ struct rpc_task_setup *task_setup_data, int how)
+ {
+ DTRACE_IO_NFS(start, REQ_OP_READ, hdr->args.count, hdr->inode);
-+
- task_setup_data->flags |= swap_flags;
rpc_ops->read_setup(hdr, msg);
trace_nfs_initiate_read(hdr);
+ }
@@ fs/nfs/read.c: static int nfs_readpage_done(struct rpc_task *task,
struct inode *inode)
{
@@ include/linux/rwlock_api_smp.h: static inline void __raw_write_lock(rwlock_t *lo
+ DTRACE_LOCKSTAT_RW_WRITER);
}
- #endif /* !CONFIG_GENERIC_LOCKBREAK || CONFIG_DEBUG_LOCK_ALLOC */
+ static inline void __raw_write_lock_nested(rwlock_t *lock, int subclass)
@@ include/linux/rwlock_api_smp.h: static inline void __raw_write_unlock(rwlock_t *lock)
{
rwlock_release(&lock->dep_map, _RET_IP_);
@@ include/linux/spinlock_api_smp.h: static inline int __raw_spin_trylock_bh(raw_sp
## kernel/exit.c ##
@@
- #include <linux/compat.h>
#include <linux/io_uring.h>
#include <linux/kprobes.h>
+ #include <linux/rethook.h>
+#include <linux/sdt.h>
#include <linux/dtrace_os.h>
@@ kernel/exit.c: void __noreturn do_exit(long code)
## kernel/fork.c ##
@@
- #include <linux/scs.h>
#include <linux/io_uring.h>
#include <linux/bpf.h>
+ #include <linux/sched/mm.h>
+#include <linux/sdt.h>
#include <linux/dtrace_task_impl.h>
@@ kernel/sched/core.c: static inline void enqueue_task(struct rq *rq, struct task_
+ int, 0);
+
if (sched_core_enabled(rq))
- sched_core_dequeue(rq, p);
+ sched_core_dequeue(rq, p, flags);
@@ kernel/sched/core.c: try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
goto unlock;
@@ kernel/signal.c: int send_sigqueue(struct sigqueue *q, struct pid *pid, enum pid
out:
trace_signal_generate(sig, &q->info, t, type != PIDTYPE_PID, result);
@@ kernel/signal.c: bool get_signal(struct ksignal *ksig)
-
/* Has this task already been marked for death? */
- if (signal_group_exit(signal)) {
+ if ((signal->flags & SIGNAL_GROUP_EXIT) ||
+ signal->group_exec_task) {
+ DTRACE_PROC(signal__handle,
+ int, signal->group_exit_code
+ ? signal->group_exit_code
@@ net/ipv4/ip_input.c: static int ip_rcv_finish(struct net *net, struct sock *sk,
{
- const struct iphdr *iph;
+ const struct iphdr *iph = NULL;
- u32 len;
+ const char *dropreason = "header invalid";
+ int drop_reason;
+ u32 len;
- /* When the interface is in promisc. mode, drop all the crap
- * that it receives, do not try to analyse it.
+@@ net/ipv4/ip_input.c: static struct sk_buff *ip_rcv_core(struct sk_buff *skb, struct net *net)
*/
-- if (skb->pkt_type == PACKET_OTHERHOST)
-+ if (skb->pkt_type == PACKET_OTHERHOST) {
+ if (skb->pkt_type == PACKET_OTHERHOST) {
+ drop_reason = SKB_DROP_REASON_OTHERHOST;
+ dropreason = "for other host";
goto drop;
-+ }
+ }
- __IP_UPD_PO_STATS(net, IPSTATS_MIB_IN, skb->len);
+@@ net/ipv4/ip_input.c: static struct sk_buff *ip_rcv_core(struct sk_buff *skb, struct net *net)
skb = skb_share_check(skb, GFP_ATOMIC);
if (!skb) {
@@ net/ipv4/ip_input.c: static int ip_rcv_finish(struct net *net, struct sock *sk,
+ goto drop;
}
-- if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+ drop_reason = SKB_DROP_REASON_NOT_SPECIFIED;
+ if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+ if (!pskb_may_pull(skb, sizeof(struct iphdr))) {
+ dropreason = "could not pull skb";
goto inhdr_error;
@@ net/ipv4/ip_input.c: static int ip_rcv_finish(struct net *net, struct sock *sk,
iph = ip_hdr(skb);
@@ net/ipv4/ip_input.c: static struct sk_buff *ip_rcv_core(struct sk_buff *skb, struct net *net)
-
len = ntohs(iph->tot_len);
if (skb->len < len) {
+ drop_reason = SKB_DROP_REASON_PKT_TOO_SMALL;
+ dropreason = "packet too short";
__IP_INC_STATS(net, IPSTATS_MIB_INTRUNCATEDPKTS);
goto drop;
@@ net/ipv4/ip_input.c: static struct sk_buff *ip_rcv_core(struct sk_buff *skb, str
goto drop;
}
@@ net/ipv4/ip_input.c: static struct sk_buff *ip_rcv_core(struct sk_buff *skb, struct net *net)
-
csum_error:
+ drop_reason = SKB_DROP_REASON_IP_CSUM;
__IP_INC_STATS(net, IPSTATS_MIB_CSUMERRORS);
+ dropreason = "checksum error";
inhdr_error:
+ if (drop_reason == SKB_DROP_REASON_NOT_SPECIFIED)
+ drop_reason = SKB_DROP_REASON_IP_INHDR;
__IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS);
drop:
+ DTRACE_IP(drop__in,
@@ net/ipv4/ip_input.c: static struct sk_buff *ip_rcv_core(struct sk_buff *skb, str
+ struct iphdr * : ipv4info_t *, iph,
+ void * : ipv6info_t *, NULL,
+ const char * : string, dropreason);
- kfree_skb(skb);
+ kfree_skb_reason(skb, drop_reason);
-out:
return NULL;
}
@@ net/ipv4/tcp_ipv4.c: int tcp_v4_rcv(struct sk_buff *skb)
+ struct sock *sk = NULL;
int ret;
- if (skb->pkt_type != PACKET_HOST)
+ drop_reason = SKB_DROP_REASON_NOT_SPECIFIED;
@@ net/ipv4/tcp_ipv4.c: int tcp_v4_rcv(struct sk_buff *skb)
if (!sk)
goto no_tcp_socket;
@@ net/ipv4/tcp_ipv4.c: int tcp_v4_rcv(struct sk_buff *skb)
+ sk ? sk->sk_state : TCP_CLOSE,
+ int, sk ? sk->sk_state : TCP_CLOSE,
+ int, DTRACE_NET_PROBE_INBOUND);
- kfree_skb(skb);
+ kfree_skb_reason(skb, drop_reason);
return 0;
@@ net/ipv6/ip6_output.c: static int ip6_finish_output2(struct net *net, struct soc
+ dropreason = "no route to host";
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTNOROUTES);
+ kfree_skb_reason(skb, SKB_DROP_REASON_NEIGH_CREATEFAIL);
+- return -EINVAL;
+ ret = -EINVAL;
+drop:
+ DTRACE_IP(drop__out,
@@ net/ipv6/ip6_output.c: static int ip6_finish_output2(struct net *net, struct soc
+ struct iphdr * : ipv4info_t *, NULL,
+ struct ipv6hdr * : ipv6info_t *, ipv6_hdr(skb),
+ const char * : string, dropreason);
- kfree_skb(skb);
-- return -EINVAL;
++ kfree_skb(skb);
+ return ret;
+oom:
+ DTRACE_IP(drop__out,
@@ net/ipv6/ip6_output.c: static int ip6_finish_output2(struct net *net, struct soc
+ const char * : string, "out of memory");
+ IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
+ return -ENOMEM;
-+
}
static int
@@ net/ipv6/ip6_output.c: int ip6_output(struct net *net, struct sock *sk, struct s
+ const char * : string, "IPv6 is disabled");
+
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
- kfree_skb(skb);
+ kfree_skb_reason(skb, SKB_DROP_REASON_IPV6DISABLED);
return 0;
@@ net/ipv6/ip6_output.c: int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
struct ipv6hdr *hdr;
@@ net/ipv6/ip6_output.c: int ip6_forward(struct sk_buff *skb)
+ }
if (!net->ipv6.devconf_all->disable_policy &&
- !idev->cnf.disable_policy &&
+ (!idev || !idev->cnf.disable_policy) &&
!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
__IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
+ dropreason = "forwarding disabled by policy";
@@ net/ipv6/ndisc.c
static u32 ndisc_hash(const void *pkey,
const struct net_device *dev,
-@@ net/ipv6/ndisc.c: static void ndisc_send_skb(struct sk_buff *skb,
+@@ net/ipv6/ndisc.c: void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr,
idev = __in6_dev_get(dst->dev);
IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
@@ net/ipv6/tcp_ipv6.c: INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
+ sk ? sk->sk_state : TCP_CLOSE,
+ int, sk ? sk->sk_state : TCP_CLOSE,
+ int, DTRACE_NET_PROBE_INBOUND);
- kfree_skb(skb);
+ kfree_skb_reason(skb, drop_reason);
return 0;
31: 0a0cc7a9b97e = 31: 5b1b99679cc3 dtrace: add sample script for building DTrace on Fedora
32: 144b97a50865 = 32: 40833f183449 locking: publicize mutex_owner and mutex_owned again
33: bed950a2e105 = 33: 52c7d130daf0 dtrace: fix buffer overflow in profile provider
34: 52a1464a77af = 34: 4cf79d12ff3d Revert "module: mark module_mutex static"
35: ef0f88d9f251 = 35: 3ea56a099ead ctf, dwarf2ctf: handle cv-qualified unnamed structure members
-: ------------ > 36: e17855d31348 sdt: provide .note.GNU-stack section
More information about the DTrace-devel
mailing list