Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/bio_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,8 +588,7 @@ int bio_needs_cow(struct bio *bio, struct inode *inode)
bio_iter_t iter;
bio_iter_bvec_t bvec;

#if defined HAVE_ENUM_REQ_OPF || (defined HAVE_ENUM_REQ_OP && defined HAVE_ENUM_REQ_OPF_WRITE_ZEROES)
//#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
#if defined HAVE_ENUM_REQ_OP_WRITE_ZEROES
if (bio_op(bio) == REQ_OP_WRITE_ZEROES)
return 1;
#endif
Expand Down
8 changes: 7 additions & 1 deletion src/bio_request_callback.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,14 @@
// length of `% call __fentry__` on x86_64 - uses a 1 byte op and 4 byte
// relative address
#define FENTRY_CALL_INSTR_BYTES 5
#elif defined(CONFIG_ARM64)
// arm64 ftrace patch site: two 4-byte instructions emitted by
// -fpatchable-function-entry=2. NOTE: the passthrough using this
// (dattobd_submit_bio_real in submit_bio.c) is dead code on blk-mq devices, so
// this value is not load-bearing here -- it only needs to let the file compile.
#define FENTRY_CALL_INSTR_BYTES (2 * 4)
#else
#pragma error "Unsupported architecture"
#error "Unsupported architecture"
#endif

#define BIO_REQUEST_CALLBACK_FN submit_bio_fn
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-only

/*
* Copyright (C) 2026 Datto Inc.
*/

#include "includes.h"

MODULE_LICENSE("GPL");

static inline void dummy(void){
struct ftrace_regs *fregs = NULL;
ftrace_regs_set_instruction_pointer(fregs, 0);
}
11 changes: 7 additions & 4 deletions src/ftrace_hooking.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,14 +378,13 @@ static int resolve_hook_address(struct ftrace_hook *hook)
static void notrace ftrace_callback_handler(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *ops, struct ftrace_regs *fregs)
{
struct pt_regs *regs = ftrace_get_regs(fregs);
struct ftrace_hook *hook = container_of(ops, struct ftrace_hook, ops);

#if USE_FENTRY_OFFSET
regs->ip = (unsigned long)hook->function;
dattobd_ftrace_set_ip(fregs, hook->function);
#else
if (!dattobd_within_module(parent_ip, THIS_MODULE))
regs->ip = (unsigned long)hook->function;
dattobd_ftrace_set_ip(fregs, hook->function);
#endif //USE_FENTRY_OFFSET
}

Expand All @@ -409,7 +408,11 @@ static int register_hook(struct ftrace_hook *hook)
}

hook->ops.func = ftrace_callback_handler;
hook->ops.flags = FTRACE_OPS_FL_SAVE_REGS | FTRACE_OPS_FL_RECURSION | FTRACE_OPS_FL_IPMODIFY;
hook->ops.flags = FTRACE_OPS_FL_RECURSION | FTRACE_OPS_FL_IPMODIFY;

#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
hook->ops.flags |= FTRACE_OPS_FL_SAVE_REGS;
#endif

ret = ftrace_set_filter_ip(&hook->ops, hook->address, 0, 0);
if (ret) {
Expand Down
19 changes: 19 additions & 0 deletions src/ftrace_hooking.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,25 @@ static __always_inline struct pt_regs *ftrace_get_regs(struct ftrace_regs *fregs
}
#endif

/**
dattobd_ftrace_set_ip() - redirect execution from the ftrace callback by
setting the traced function's instruction pointer to our hook.
*/
#ifdef HAVE_FTRACE_REGS_SET_INSTRUCTION_POINTER
#define dattobd_ftrace_set_ip(fregs, addr) \
ftrace_regs_set_instruction_pointer((fregs), (unsigned long)(addr))
#elif defined(CONFIG_ARM64)
#define dattobd_ftrace_set_ip(fregs, addr) \
do { \
ftrace_get_regs(fregs)->pc = (unsigned long)(addr); \
} while (0)
#else
#define dattobd_ftrace_set_ip(fregs, addr) \
do { \
ftrace_get_regs(fregs)->ip = (unsigned long)(addr); \
} while (0)
#endif

#ifndef UMOUNT_NOFOLLOW
#define UMOUNT_NOFOLLOW 0
#endif
Expand Down
23 changes: 23 additions & 0 deletions src/paging_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "includes.h"
#include "paging_helper.h"

#ifdef CONFIG_X86

//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
#ifndef X86_CR0_WP
#define X86_CR0_WP (1UL << 16)
Expand Down Expand Up @@ -53,3 +55,24 @@ void reenable_page_protection(unsigned long *cr0)
{
write_cr0(*cr0);
}

#else

/**
* Page-level write-protect toggling via the CR0 register is x86-specific. It is
* only used by the legacy syscall-table hooking path, which is unused on the
* ftrace-based builds (5.9+) that non-x86 arches such as arm64 target. These
* functions have no callers in such builds, so provide no-op stubs to keep the
* module buildable on non-x86 without pulling in read_cr0()/write_cr0().
*/
void disable_page_protection(unsigned long *cr0)
{
*cr0 = 0;
}

void reenable_page_protection(unsigned long *cr0)
{
(void)cr0;
}

#endif
3 changes: 1 addition & 2 deletions src/tracer.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,7 @@ static int inc_trace_bio(struct snap_device *dev, struct bio *bio)
bio_iter_t iter;
bio_iter_bvec_t bvec;

#ifdef HAVE_ENUM_REQ_OPF
//#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
#if defined HAVE_ENUM_REQ_OP_WRITE_ZEROES
if (bio_op(bio) == REQ_OP_WRITE_ZEROES) {
ret = inc_make_sset(dev, bio_sector(bio),
bio_size(bio) / SECTOR_SIZE);
Expand Down