diff --git a/Makefile b/Makefile index b8b7f74696b409..d7292df8122ccc 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 13 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -networkmmapv0.8 NAME = One Giant Leap for Frogkind # *DOCUMENTATION* diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl index aabfb8380a1c6c..c7827a4a8ed7fd 100644 --- a/arch/x86/syscalls/syscall_32.tbl +++ b/arch/x86/syscalls/syscall_32.tbl @@ -357,3 +357,5 @@ 348 i386 process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev 349 i386 kcmp sys_kcmp 350 i386 finit_module sys_finit_module +351 i386 network_mmap sys_network_mmap_pgoff +352 i386 network_msync sys_network_msync diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl index 38ae65dfd14ffe..a4ec20349bb8b5 100644 --- a/arch/x86/syscalls/syscall_64.tbl +++ b/arch/x86/syscalls/syscall_64.tbl @@ -320,6 +320,8 @@ 311 64 process_vm_writev sys_process_vm_writev 312 common kcmp sys_kcmp 313 common finit_module sys_finit_module +314 common network_mmap sys_network_mmap_pgoff +315 common network_msync sys_network_msync # # x32-specific system call numbers start at 512 to avoid cache impact diff --git a/include/linux/mm.h b/include/linux/mm.h index 35527173cf50c7..c131c8125ca9cc 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2011,5 +2011,11 @@ void __init setup_nr_node_ids(void); static inline void setup_nr_node_ids(void) {} #endif +typedef int (*network_mmap_fault_handler)(struct vm_area_struct *vma, struct vm_fault *vmf); +extern void set_kmod_network_mmap_fault_handler(network_mmap_fault_handler func); + +typedef int (*network_msync)(unsigned long start, size_t len, int flags); +extern void set_kmod_network_msync(network_msync func); + #endif /* __KERNEL__ */ #endif /* _LINUX_MM_H */ diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 94273bbe605007..14fa4cfbbb0dcc 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -847,4 +847,10 @@ asmlinkage long sys_process_vm_writev(pid_t pid, asmlinkage long sys_kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2); asmlinkage long sys_finit_module(int fd, const char __user *uargs, int flags); + +asmlinkage long sys_network_mmap_pgoff(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff); + +asmlinkage long sys_network_msync(unsigned long start, size_t len, int flags); #endif diff --git a/mm/mmap.c b/mm/mmap.c index 834b2d785f1e2f..7855f5db30f9fd 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1400,6 +1400,65 @@ SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, return retval; } +network_mmap_fault_handler network_mmap_fault_handler_ptr = NULL; + +static int default_network_mmap_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf) { + int retval = VM_FAULT_SIGBUS; + printk(KERN_INFO "1. Calling default_network_mmap_fault_handler: %016llX\n", (uint64_t)network_mmap_fault_handler_ptr); + if (network_mmap_fault_handler_ptr) { + printk(KERN_INFO "2. Calling network_mmap_fault_handler_ptr\n"); + retval = network_mmap_fault_handler_ptr(vma, vmf); + printk(KERN_INFO "3. Done calling network_mmap_fault_handler_ptr: %d\n", retval); + } + printk(KERN_INFO "4. default_network_mmap_fault_handler: %d\n", retval); + + return retval; +} + +static const struct vm_operations_struct network_mmap_vm_ops = { + .fault = default_network_mmap_fault_handler, +}; + +SYSCALL_DEFINE6(network_mmap_pgoff, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, + unsigned long, fd, unsigned long, pgoff) +{ + unsigned long retval; + struct vm_area_struct *vma; + struct mm_struct *mm = current->mm; + + printk(KERN_INFO "network_mmap_pgoff: 1. Entering network_mmap_pgoff\n"); + + printk(KERN_INFO "network_mmap_pgoff: 2. Calling sys_mmap_pgoff\n"); + retval = sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); + printk(KERN_INFO "network_mmap_pgoff: 3. Completed sys_mmap_pgoff: %lu\n", retval); + + // Was there an error? Just return the error code + if ((signed long)retval < 0 && (signed long)retval >= -133) { + return retval; + } + + printk(KERN_INFO "network_mmap_pgoff: 4. Getting vma\n"); + // Override the fault handler with our own! + vma = find_vma(mm, retval); // retval contains our address at the start of our mmaped region + if (!vma) { + retval = -ENOMEM; + } + printk(KERN_INFO "network_mmap_pgoff: 5. Completed getting vma: %016llX\n", (uint64_t)vma); + printk(KERN_INFO "network_mmap_pgoff: 6. Overriding fault handler to: %016llX\n", (uint64_t)&network_mmap_vm_ops); + vma->vm_ops = &network_mmap_vm_ops; + printk(KERN_INFO "network_mmap_pgoff: 7. Completed overriding fault handler\n"); + + return retval; +} + +void set_kmod_network_mmap_fault_handler(network_mmap_fault_handler func) { + printk(KERN_INFO "set_kmod_network_mmap_fault_handler: 1. Entering set_kmod_network_mmap_fault_handler: %016llX\n", (uint64_t)func); + network_mmap_fault_handler_ptr = func; + printk(KERN_INFO "set_kmod_network_mmap_fault_handler: 2. Completed setting set_kmod_network_mmap_fault_handler: %016llX\n", (uint64_t)network_mmap_fault_handler_ptr); +} +EXPORT_SYMBOL(set_kmod_network_mmap_fault_handler); + #ifdef __ARCH_WANT_SYS_OLD_MMAP struct mmap_arg_struct { unsigned long addr; diff --git a/mm/msync.c b/mm/msync.c index 632df4527c0122..4aae51e709f6ec 100644 --- a/mm/msync.c +++ b/mm/msync.c @@ -101,3 +101,26 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags) out: return error ? : unmapped_error; } + +network_msync network_msync_ptr = NULL; + +SYSCALL_DEFINE3(network_msync, unsigned long, start, size_t, len, int, flags) +{ + int retval = -EINVAL; + printk(KERN_INFO "1. Calling default_network_msync: %016llX\n", (uint64_t)network_msync_ptr); + if (network_msync_ptr) { + printk(KERN_INFO "2. Calling network_msync_ptr\n"); + retval = network_msync_ptr(start, len, flags); + printk(KERN_INFO "3. Done calling network_msync_ptr: %d\n", retval); + } + printk(KERN_INFO "4. default_network_msync: %d\n", retval); + + return retval; +} + +void set_kmod_network_msync(network_msync func) { + printk(KERN_INFO "set_kmod_network_msync: 1. Entering set_kmod_network_msync: %016llX\n", (uint64_t)func); + network_msync_ptr = func; + printk(KERN_INFO "set_kmod_network_msync: 2. Completed setting set_kmod_network_msync: %016llX\n", (uint64_t)network_msync_ptr); +} +EXPORT_SYMBOL(set_kmod_network_msync);