donderdag 22 augustus 2019

Making VirtualBox vboxdrv kernel driver 5.1.x compatible with Linux 4.20.x


When Ubuntu 16.04.6 LTS users do:

sudo apt-get install virtualbox

...they receive VirtualBox 5.1.38-dfsg-0ubuntu1.16.04.3.

This should also install virtualbox-dkms, which compiles the vboxdrv kernel driver for their Linux kernel. If it doesn't (for example, because virtualbox-dkms is already installed) then it can be reinstalled with:

sudo apt-get install --reinstall virtualbox-dkms

But if they are running Linux kernel 4.20.x, they will find the following compilation errors in /var/lib/dkms/virtualbox/5.1.38/build/make.log:

  CC [M]  /var/lib/dkms/virtualbox/5.1.38/build/vboxdrv/r0drv/linux/time-r0drv-linux.o
/var/lib/dkms/virtualbox/5.1.38/build/vboxdrv/r0drv/linux/time-r0drv-linux.c: In function ‘VBoxHost_RTTimeNow’:
/var/lib/dkms/virtualbox/5.1.38/build/vboxdrv/r0drv/linux/time-r0drv-linux.c:175:5: error: implicit declaration of function ‘ktime_get_real_ts’ [-Werror=implicit-function-declaration]
     ktime_get_real_ts(&Ts);
     ^
cc1: some warnings being treated as errors
scripts/Makefile.build:291: recipe for target '/var/lib/dkms/virtualbox/5.1.38/build/vboxdrv/r0drv/linux/time-r0drv-linux.o' failed
make[2]: *** [/var/lib/dkms/virtualbox/5.1.38/build/vboxdrv/r0drv/linux/time-r0drv-linux.o] Error 1
scripts/Makefile.build:516: recipe for target '/var/lib/dkms/virtualbox/5.1.38/build/vboxdrv' failed
make[1]: *** [/var/lib/dkms/virtualbox/5.1.38/build/vboxdrv] Error 2
Makefile:1563: recipe for target '_module_/var/lib/dkms/virtualbox/5.1.38/build' failed
make: *** [_module_/var/lib/dkms/virtualbox/5.1.38/build] Error 2

To fix this issue, we need to make the VirtualBox vboxdrv code compatible with Linux 4.20 and after some trial and error, I came up with the following patches:

--- /var/lib/dkms/virtualbox/5.1.38/build/vboxdrv/include/iprt/time.h.orig 2019-08-22 10:09:34.909117248 +0200
+++ /var/lib/dkms/virtualbox/5.1.38/build/vboxdrv/include/iprt/time.h 2019-08-22 10:09:04.949044978 +0200
@@ -28,6 +28,7 @@
 #include <iprt/cdefs.h>
 #include <iprt/types.h>
+#include <linux/time64.h>
 RT_C_DECLS_BEGIN
@@ -429,6 +430,13 @@
 }
 #endif /* various ways of detecting struct timespec */
+// Added for Linux 4.20 compatibility
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetTimespec64(PRTTIMESPEC pTime, const struct timespec64 *pTimeval)
+{
+    return RTTimeSpecAddNano(RTTimeSpecSetSeconds(pTime, pTimeval->tv_sec), pTimeval->tv_nsec);
+}
+
+
 /** The offset of the unix epoch and the base for NT time (in 100ns units).
  * Nt time starts at 1601-01-01 00:00:00. */
 #define RTTIME_NT_TIME_OFFSET_UNIX      (116444736000000000LL)

--- /var/lib/dkms/virtualbox/5.1.38/build/vboxdrv/r0drv/linux/time-r0drv-linux.c.orig 2019-08-22 10:12:14.633414691 +0200
+++ /var/lib/dkms/virtualbox/5.1.38/build/vboxdrv/r0drv/linux/time-r0drv-linux.c 2019-08-22 10:12:29.865436296 +0200
@@ -171,10 +171,11 @@
 {
     IPRT_LINUX_SAVE_EFL_AC();
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16)
-    struct timespec Ts;
-    ktime_get_real_ts(&Ts);
+// Modified for Linux 4.20 compatibility
+    struct timespec64 Ts;
+    ktime_get_real_ts64(&Ts);
     IPRT_LINUX_RESTORE_EFL_AC();
-    return RTTimeSpecSetTimespec(pTime, &Ts);
+    return RTTimeSpecSetTimespec64(pTime, &Ts);
 #else   /* < 2.6.16 */
     struct timeval Tv;


To recompile the module, change to the directory /var/lib/dkms/virtualbox/5.1.38/build/vboxdrv and do:

sudo make

Finally, to load the vboxdrv module, do:

sudo insmod /var/lib/dkms/virtualbox/5.1.38/build/vboxdrv/vboxdrv.ko

Enjoy VirtualBox!

Geen opmerkingen:

Een reactie posten