diff --git a/vmmon/Makefile b/vmmon/Makefile index de8162e..6124a71 100644 --- a/vmmon/Makefile +++ b/vmmon/Makefile @@ -43,7 +43,11 @@ INCLUDE += -I$(SRCROOT)/shared endif +ifdef KVERSION +VM_UNAME = $(KVERSION) +else VM_UNAME = $(shell uname -r) +endif # Header directory for the running kernel ifdef LINUXINCLUDE diff --git a/vmmon/Makefile.kernel b/vmmon/Makefile.kernel index bf805e0..9aac585 100644 --- a/vmmon/Makefile.kernel +++ b/vmmon/Makefile.kernel @@ -22,7 +22,7 @@ CC_OPTS += -DVMMON -DVMCORE INCLUDE := -I$(SRCROOT)/include -I$(SRCROOT)/common -I$(SRCROOT)/linux \ -I$(SRCROOT)/vmcore -EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE) +EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE) $(LINUXINCLUDE) obj-m += $(DRIVER).o diff --git a/vmmon/include/compat_module.h b/vmmon/include/compat_module.h index 2af7372..729aedc 100644 --- a/vmmon/include/compat_module.h +++ b/vmmon/include/compat_module.h @@ -80,4 +80,13 @@ static const char __module_cat(tag, __LINE__)[] \ typedef int compat_mod_param_bool; #endif +/* + * Linux kernel >= 4.3.0 does not return anything from misc_deregister + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0) +#define compat_misc_deregister(misc) misc_deregister(misc) +#else +#define compat_misc_deregister(misc) ({misc_deregister(misc);0;}) +#endif + #endif /* __COMPAT_MODULE_H__ */ diff --git a/vmmon-only/include/compat_timer.h b/vmmon-only/include/compat_timer.h new file mode 100644 index 0000000..b68d9b2 --- /dev/null +++ b/vmmon-only/include/compat_timer.h @@ -0,0 +1,33 @@ +#ifndef __COMPAT_TIMER_H__ +#define __COMPAT_TIMER_H__ + +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)) && !defined(timer_setup) + +typedef unsigned long compat_timer_arg_t; + +static inline void compat_timer_setup(struct timer_list *timer, + void (*func)(compat_timer_arg_t), + unsigned int flags) +{ + init_timer(timer); + timer->function = func; + timer->data = 0; + timer->flags = flags; +} + +#else /* new timer interface since 4.15 */ + +typedef struct timer_list *compat_timer_arg_t; + +static inline void compat_timer_setup(struct timer_list *timer, + void (*func)(compat_timer_arg_t), + unsigned int flags) +{ + timer_setup(timer, func, flags); +} + +#endif /* new timer interface since 4.15 */ + +#endif /* __COMPAT_TIMER_H__ */ diff --git a/vmmon/linux/driver.c b/vmmon/linux/driver.c index 87cf45b..5390a93 100644 --- a/vmmon/linux/driver.c +++ b/vmmon/linux/driver.c @@ -21,6 +21,7 @@ #define EXPORT_SYMTAB +#include "compat_timer.h" #include #include #include @@ -109,7 +109,15 @@ static struct vm_operations_struct vmuser_mops = { .fault = LinuxDriverFault }; -static struct file_operations vmuser_fops; +static struct file_operations vmuser_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = LinuxDriver_Ioctl, + .compat_ioctl = LinuxDriver_Ioctl, + .open = LinuxDriver_Open, + .release = LinuxDriver_Close, + .mmap = LinuxDriverMmap +}; + static struct timer_list tscTimer; static Atomic_uint32 tsckHz; static VmTimeStart tsckHzStartTime; @@ -216,7 +217,7 @@ LinuxDriverEstimateTSCkHz(void) *---------------------------------------------------------------------- */ static void -LinuxDriverEstimateTSCkHzDeferred(unsigned long data) +LinuxDriverEstimateTSCkHzDeferred(compat_timer_arg_t unused) { LinuxDriverEstimateTSCkHz(); } @@ -251,9 +252,7 @@ LinuxDriverInitTSCkHz(void) } LinuxDriverReadTSCAndUptime(&tsckHzStartTime); - tscTimer.function = LinuxDriverEstimateTSCkHzDeferred; tscTimer.expires = jiffies + 4 * HZ; - tscTimer.data = 0; add_timer(&tscTimer); } @@ -295,20 +304,6 @@ init_module(void) linuxState.fastClockRate = 0; linuxState.swapSize = VMMON_UNKNOWN_SWAP_SIZE; - /* - * Initialize the file_operations structure. Because this code is always - * compiled as a module, this is fine to do it here and not in a static - * initializer. - */ - - memset(&vmuser_fops, 0, sizeof vmuser_fops); - vmuser_fops.owner = THIS_MODULE; - vmuser_fops.unlocked_ioctl = LinuxDriver_Ioctl; - vmuser_fops.compat_ioctl = LinuxDriver_Ioctl; - vmuser_fops.open = LinuxDriver_Open; - vmuser_fops.release = LinuxDriver_Close; - vmuser_fops.mmap = LinuxDriverMmap; - #ifdef VMX86_DEVEL devel_init_module(); linuxState.minor = 0; @@ -335,7 +334,7 @@ init_module(void) linuxState.deviceName, linuxState.major, linuxState.minor); HostIF_InitUptime(); - init_timer(&tscTimer); + compat_timer_setup(&tscTimer, LinuxDriverEstimateTSCkHzDeferred, 0); LinuxDriverInitTSCkHz(); Vmx86_InitIDList(); @@ -364,7 +373,9 @@ cleanup_module(void) #ifdef VMX86_DEVEL unregister_chrdev(linuxState.major, linuxState.deviceName); #else - misc_deregister(&linuxState.misc); + if (compat_misc_deregister(&linuxState.misc)) { + Warning("Module %s: error unregistering\n", linuxState.deviceName); + } #endif Log("Module %s: unloaded\n", linuxState.deviceName); @@ -977,7 +988,7 @@ LinuxDriverReadTSC(void *data, // OUT: TSC values *----------------------------------------------------------------------------- */ -__attribute__((always_inline)) static Bool +inline __attribute__((always_inline)) static Bool LinuxDriverSyncReadTSCs(uint64 *delta) // OUT: TSC max - TSC min { TSCDelta tscDelta; diff --git a/vmmon/linux/hostif.c b/vmmon/linux/hostif.c index fd32013..583d6da 100644 --- a/vmmon/linux/hostif.c +++ b/vmmon/linux/hostif.c @@ -29,6 +29,7 @@ #include "driver-config.h" /* Must come before vmware.h --hpreg */ +#include "compat_timer.h" #include #include #include @@ -36,6 +36,9 @@ #include #include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) +#include +#endif #include #include @@ -51,6 +54,7 @@ #include #include #include +#include #include #include #include // For linux/sched/signal.h without version check @@ -115,6 +149,10 @@ */ #define LOCKED_PAGE_SLACK 10000 +#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 8, 0) +#define NR_ANON_PAGES NR_ANON_MAPPED +#endif + static struct { Atomic_uint64 uptimeBase; VersionedAtomic version; @@ -1705,7 +1714,7 @@ HostIFReadUptimeWork(unsigned long *j) // OUT: current jiffies */ static void -HostIFUptimeResyncMono(unsigned long data) // IN: ignored +HostIFUptimeResyncMono(compat_timer_arg_t unused) // IN: ignored { unsigned long jifs; uintptr_t flags; @@ -1767,8 +1776,7 @@ HostIF_InitUptime(void) -(tv.tv_usec * (UPTIME_FREQ / 1000000) + tv.tv_sec * UPTIME_FREQ)); - init_timer(&uptimeState.timer); - uptimeState.timer.function = HostIFUptimeResyncMono; + compat_timer_setup(&uptimeState.timer, HostIFUptimeResyncMono, 0); mod_timer(&uptimeState.timer, jiffies + HZ); }