--- 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 @@ -98,6 +98,13 @@ auto-build: $(DRIVER_KO) $(DRIVER): $(DRIVER_KO) if [ $< -nt $@ ] || [ ! -e $@ ] ; then cp -f $< $@; fi +# Use SUBDIRS on 2.x, 3.x, 4.x. Use M on newer kernels. +ifeq ($(filter-out 2 3 4,$(firstword $(subst ., ,$(VM_UNAME)))),) +DIRVAR := SUBDIRS +else +DIRVAR := M +endif + # # Define a setup target that gets built before the actual driver. # This target may not be used at all, but if it is then it will be defined @@ -107,7 +114,7 @@ prebuild:: ; postbuild:: ; $(DRIVER_KO): prebuild - $(MAKE) -C $(BUILD_DIR) SUBDIRS=$$PWD SRCROOT=$$PWD/$(SRCROOT) \ + $(MAKE) -C $(BUILD_DIR) $(DIRVAR)=$$PWD SRCROOT=$$PWD/$(SRCROOT) \ MODULEBUILDDIR=$(MODULEBUILDDIR) modules $(MAKE) -C $$PWD SRCROOT=$$PWD/$(SRCROOT) \ MODULEBUILDDIR=$(MODULEBUILDDIR) postbuild --- a/vmmon/linux/driver.c +++ b/vmmon/linux/driver.c @@ -96,7 +95,9 @@ long LinuxDriver_Ioctl(struct file *filp, u_int iocmd, unsigned long ioarg); static int LinuxDriver_Close(struct inode *inode, struct file *filp); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) +static vm_fault_t LinuxDriverFault(struct vm_fault *fault); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) static int LinuxDriverFault(struct vm_fault *fault); #else static int LinuxDriverFault(struct vm_area_struct *vma, struct vm_fault *fault); @@ -594,7 +596,12 @@ LinuxDriver_Close(struct inode *inode, // IN *----------------------------------------------------------------------------- */ -static int +static +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) +vm_fault_t +#else +int +#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) LinuxDriverFault(struct vm_fault *fault) //IN/OUT #else --- a/vmmon/linux/hostif.c +++ a/vmmon/linux/hostif.c @@ -1499,9 +1499,13 @@ * since at least 2.6.0. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0) extern unsigned long totalram_pages; unsigned int totalPhysicalPages = totalram_pages; +#else + unsigned int totalPhysicalPages = totalram_pages(); +#endif /* * Use the memory information linux exports as of late for a more @@ -1602,6 +1606,49 @@ /* *---------------------------------------------------------------------- * + * HostIFGetTime -- + * + * Reads the current time in UPTIME_FREQ units. + * + * Results: + * The uptime, in units of UPTIME_FREQ. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static uint64 +HostIFGetTime(void) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0) + struct timeval tv; + + do_gettimeofday(&tv); + return tv.tv_usec * (UPTIME_FREQ / 1000000) + tv.tv_sec * UPTIME_FREQ; +#else + struct timespec64 now; + + /* + * Use raw time used by Posix timers. This time is not affected by + * NTP adjustments, so it may drift from real time and monotonic time, + * but it will stay in sync with other timers. + */ + ktime_get_raw_ts64(&now); + /* + * UPTIME_FREQ resolution is lower than tv_nsec, + * so we have to do division... + */ + ASSERT_ON_COMPILE(1000000000 % UPTIME_FREQ == 0); + return now.tv_nsec / (1000000000 / UPTIME_FREQ) + now.tv_sec * UPTIME_FREQ; +#endif +} + + +/* + *---------------------------------------------------------------------- + * * HostIFReadUptimeWork -- * * Reads the current uptime. The uptime is based on getimeofday, @@ -1630,7 +1677,6 @@ static uint64 HostIFReadUptimeWork(unsigned long *j) // OUT: current jiffies { - struct timeval tv; uint64 monotime, uptime, upBase, monoBase; int64 diff; uint32 version; @@ -1645,13 +1691,12 @@ monoBase = uptimeState.monotimeBase; } while (!VersionedAtomic_EndTryRead(&uptimeState.version, version)); - do_gettimeofday(&tv); + uptime = HostIFGetTime(); upBase = Atomic_Read64(&uptimeState.uptimeBase); monotime = (uint64)(jifs - jifBase) * (UPTIME_FREQ / HZ); monotime += monoBase; - uptime = tv.tv_usec * (UPTIME_FREQ / 1000000) + tv.tv_sec * UPTIME_FREQ; uptime += upBase; /* @@ -1756,13 +1801,11 @@ void HostIF_InitUptime(void) { - struct timeval tv; + uint64 tm; uptimeState.jiffiesBase = jiffies; - do_gettimeofday(&tv); - Atomic_Write64(&uptimeState.uptimeBase, - -(tv.tv_usec * (UPTIME_FREQ / 1000000) + - tv.tv_sec * UPTIME_FREQ)); + tm = HostIFGetTime(); + Atomic_Write64(&uptimeState.uptimeBase, -tm); #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) && !defined(timer_setup) init_timer(&uptimeState.timer); @@ -2164,7 +2207,7 @@ isVAReadable(VA r) // IN: int ret; old_fs = get_fs(); - set_fs(get_ds()); + set_fs(KERNEL_DS); r = APICR_TO_ADDR(r, APICR_VERSION); ret = HostIF_CopyFromUser(&dummy, r, sizeof dummy); set_fs(old_fs); @@ -2365,7 +2408,7 @@ HostIF_SemaphoreWait(VMDriver *vm, // IN: } old_fs = get_fs(); - set_fs(get_ds()); + set_fs(KERNEL_DS); { struct poll_wqueues table; @@ -2494,7 +2537,7 @@ HostIF_SemaphoreSignal(uint64 *args) // IN: } old_fs = get_fs(); - set_fs(get_ds()); + set_fs(KERNEL_DS); /* * Always write sizeof(uint64) bytes. This works fine for eventfd and @@ -3154,7 +3202,6 @@ HostIF_SetFastClockRate(unsigned int rate) // IN: Frequency in Hz. } } else { if (linuxState.fastClockThread) { - force_sig(SIGKILL, linuxState.fastClockThread); kthread_stop(linuxState.fastClockThread); linuxState.fastClockThread = NULL; @@ -3200,7 +3243,12 @@ ASSERT(handle); - if (!access_ok(VERIFY_WRITE, p, size)) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0) + if (!access_ok(VERIFY_WRITE, p, size)) +#else + if (!access_ok(p, size)) +#endif + { printk(KERN_ERR "%s: Couldn't verify write to uva 0x%p with size %" FMTSZ"u\n", __func__, p, size);