Bleeding on the Edge: Kernel 4.9-rc5 vs. app-emulation/virtualbox-modules


Powerball Machine
Sometimes the Linux kernel source can be like the inside of one of those Powerball lottery machines. Things change names seemingly at random. Today it’s fetch_things(), tomorrow it’s things_to_fetch(). Don’t get me wrong, I’m not complaining. It’ll be a sad day when the kernel stops evolving, but I can understand why the nvidia developers can’t keep up (that is the one and only time I will defend nvidia on this site), and the Oracle folks aren’t too much better.

After booting into kernel 4.9-rc5, then trying to upgrade app-emulation/virtualbox-modules from 5.1.6 to 5.1.8, I got the following:

/mnt/gentoo/var/tmp/portage/app-emulation/virtualbox-modules-5.1.8/work/vboxdrv/r0drv/linux/memobj-r0drv-linux.c: In function ‘rtR0MemObjNativeLockUser’:
/mnt/gentoo/var/tmp/portage/app-emulation/virtualbox-modules-5.1.8/work/vboxdrv/r0drv/linux/memobj-r0drv-linux.c:1053:33: warning: passing argument 4 of ‘get_user_pages’ makes pointer from integer without a cast [-Wint-conversion]
                                 fWrite,                 /* force write access. */
                                 ^~~~~~
In file included from /mnt/gentoo/var/tmp/portage/app-emulation/virtualbox-modules-5.1.8/work/vboxdrv/r0drv/linux/the-linux-kernel.h:98:0,
                 from /mnt/gentoo/var/tmp/portage/app-emulation/virtualbox-modules-5.1.8/work/vboxdrv/r0drv/linux/memobj-r0drv-linux.c:31:
./include/linux/mm.h:1278:6: note: expected ‘struct page **’ but argument is of type ‘int’
 long get_user_pages(unsigned long start, unsigned long nr_pages,
      ^~~~~~~~~~~~~~
/mnt/gentoo/var/tmp/portage/app-emulation/virtualbox-modules-5.1.8/work/vboxdrv/r0drv/linux/memobj-r0drv-linux.c:1054:33: error: passing argument 5 of ‘get_user_pages’ from incompatible pointer type [-Werror=incompatible-pointer-types]
                                 &pMemLnx->apPages[0],   /* Page array. */
                                 ^
In file included from /mnt/gentoo/var/tmp/portage/app-emulation/virtualbox-modules-5.1.8/work/vboxdrv/r0drv/linux/the-linux-kernel.h:98:0,
                 from /mnt/gentoo/var/tmp/portage/app-emulation/virtualbox-modules-5.1.8/work/vboxdrv/r0drv/linux/memobj-r0drv-linux.c:31:
./include/linux/mm.h:1278:6: note: expected ‘struct vm_area_struct **’ but argument is of type ‘struct page **’
 long get_user_pages(unsigned long start, unsigned long nr_pages,
      ^~~~~~~~~~~~~~
/mnt/gentoo/var/tmp/portage/app-emulation/virtualbox-modules-5.1.8/work/vboxdrv/r0drv/linux/memobj-r0drv-linux.c:1050:18: error: too many arguments to function ‘get_user_pages’
             rc = get_user_pages(R3Ptr,                  /* Where from. */
                  ^~~~~~~~~~~~~~

Oh man, get_user_pages again? Those functions were giving my nvidia drivers fits just a few months ago. Per commits 9beae1ea89305a9667ceaab6d0bf46a045ad71e7 and 768ae309a96103ed02eb1e111e838c87854d8b51, they have indeed changed. The force and write flags are no longer passed in separately. Linus explains the reasoning behind the change in the merge message that followed. Surprisingly, I was able to take a page out of the nvidia driver developers’ book to make a user patch for this situation:

unsigned int flags = 0;

if (write)
	flags |= FOLL_WRITE;
if (force)
	flags |= FOLL_FORCE;

return get_user_pages(start, nr_pages, flags, pages, vmas);

Here you can see how they build up the flags to pass to the new get_user_pages function. Drop the patch below into /etc/portage/patches/app-emulation/virtualbox-modules-5.1.8/ and build away.


Leave a Reply