364.1[2,5] won't compile against latest kernel git tree (patches for 4.6.0-rc3+ included)

diff -ruN NVIDIA-Linux-x86_64-364.15/kernel/nvidia/os-mlock.c NVIDIA-Linux-x86_64-364.15.patched/kernel/nvidia/os-mlock.c
--- NVIDIA-Linux-x86_64-364.15/kernel/nvidia/os-mlock.c	2016-04-03 05:07:03.000000000 +0200
+++ NVIDIA-Linux-x86_64-364.15.patched/kernel/nvidia/os-mlock.c	2016-04-19 17:23:58.000000000 +0200
@@ -13,6 +13,7 @@
 
 #include "os-interface.h"
 #include "nv-linux.h"
+#include <linux/version.h>
 
 NV_STATUS NV_API_CALL os_lookup_user_io_memory(
     void   *address,
@@ -116,8 +117,13 @@
     }
 
     down_read(&mm->mmap_sem);
+    #if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0)
     ret = get_user_pages(current, mm, (unsigned long)address,
             page_count, write, force, user_pages, NULL);
+    #else
+    ret = get_user_pages((unsigned long)address,
+            page_count, write, force, user_pages, NULL);
+    #endif
     up_read(&mm->mmap_sem);
     pinned = ret;
 
@@ -129,7 +135,11 @@
     else if (pinned < page_count)
     {
         for (i = 0; i < pinned; i++)
+            #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
             page_cache_release(user_pages[i]);
+            #else
+            put_page(user_pages[i]);
+            #endif
         os_free_mem(user_pages);
         return NV_ERR_INVALID_ADDRESS;
     }
@@ -156,7 +166,11 @@
     {
         if (write)
             set_page_dirty_lock(user_pages[i]);
+        #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
         page_cache_release(user_pages[i]);
+        #else
+        put_page(user_pages[i]);
+        #endif
     }
 
     os_free_mem(user_pages);
diff -ruN NVIDIA-Linux-x86_64-364.15/kernel/nvidia-drm/nvidia-drm-fb.c NVIDIA-Linux-x86_64-364.15.patched/kernel/nvidia-drm/nvidia-drm-fb.c
--- NVIDIA-Linux-x86_64-364.15/kernel/nvidia-drm/nvidia-drm-fb.c	2016-04-03 05:05:22.000000000 +0200
+++ NVIDIA-Linux-x86_64-364.15.patched/kernel/nvidia-drm/nvidia-drm-fb.c	2016-04-06 21:27:00.000000000 +0200
@@ -29,7 +29,7 @@
 #include "nvidia-drm-fb.h"
 #include "nvidia-drm-utils.h"
 #include "nvidia-drm-gem.h"
-
+#include <linux/version.h>
 #include <drm/drm_crtc_helper.h>
 
 static void nvidia_framebuffer_destroy(struct drm_framebuffer *fb)
@@ -199,7 +199,12 @@
 struct drm_framebuffer *nvidia_drm_framebuffer_create
 (
     struct drm_device *dev,
+    #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
     struct drm_file *file, struct drm_mode_fb_cmd2 *cmd
+    #else
+    struct drm_file *file,
+    const struct drm_mode_fb_cmd2 *cmd
+    #endif
 )
 {
     return internal_framebuffer_create(dev, file, cmd, 0, 0);
diff -ruN NVIDIA-Linux-x86_64-364.15/kernel/nvidia-drm/nvidia-drm-fb.h NVIDIA-Linux-x86_64-364.15.patched/kernel/nvidia-drm/nvidia-drm-fb.h
--- NVIDIA-Linux-x86_64-364.15/kernel/nvidia-drm/nvidia-drm-fb.h	2016-04-03 05:05:22.000000000 +0200
+++ NVIDIA-Linux-x86_64-364.15.patched/kernel/nvidia-drm/nvidia-drm-fb.h	2016-04-06 21:27:00.000000000 +0200
@@ -24,7 +24,7 @@
 #define __NVIDIA_DRM_FB_H__
 
 #include "conftest.h"
-
+#include <linux/version.h>
 #if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
 
 #include <drm/drmP.h>
@@ -45,7 +45,12 @@
 struct drm_framebuffer *nvidia_drm_framebuffer_create
 (
     struct drm_device *dev,
+    #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
     struct drm_file *file, struct drm_mode_fb_cmd2 *cmd
+    #else
+    struct drm_file *file,
+    const struct drm_mode_fb_cmd2 *cmd
+    #endif
 );
 
 int nvidia_drm_add_nvkms_fb(
diff -ruN NVIDIA-Linux-x86_64-364.15/kernel/nvidia-drm/nvidia-drm-linux.c NVIDIA-Linux-x86_64-364.15.patched/kernel/nvidia-drm/nvidia-drm-linux.c
--- NVIDIA-Linux-x86_64-364.15/kernel/nvidia-drm/nvidia-drm-linux.c	2016-04-03 05:05:22.000000000 +0200
+++ NVIDIA-Linux-x86_64-364.15.patched/kernel/nvidia-drm/nvidia-drm-linux.c	2016-04-19 17:26:14.000000000 +0200
@@ -28,6 +28,7 @@
 #include "nvidia-drm.h"
 
 #include "conftest.h"
+#include <linux/version.h>
 
 #if defined(NV_DRM_AVAILABLE)
 
@@ -121,9 +122,14 @@
 
     down_read(&mm->mmap_sem);
 
+    #if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0)
     pages_pinned = get_user_pages(current, mm,
                                   address, pages_count, write, force,
                                   user_pages, NULL);
+    #else
+    pages_pinned = get_user_pages(address, pages_count, write, force,
+                                  user_pages, NULL);
+    #endif
     up_read(&mm->mmap_sem);
 
     if (pages_pinned < 0 || (unsigned)pages_pinned < pages_count)
diff -ruN NVIDIA-Linux-x86_64-364.15/kernel/nvidia-uvm/uvm8_tools.c NVIDIA-Linux-x86_64-364.15.patched/kernel/nvidia-uvm/uvm8_tools.c
--- NVIDIA-Linux-x86_64-364.15/kernel/nvidia-uvm/uvm8_tools.c	2016-04-03 05:08:49.000000000 +0200
+++ NVIDIA-Linux-x86_64-364.15.patched/kernel/nvidia-uvm/uvm8_tools.c	2016-04-19 17:28:33.000000000 +0200
@@ -27,6 +27,7 @@
 #include "uvm8_api.h"
 #include "uvm8_hal_types.h"
 #include "uvm8_va_block.h"
+#include <linux/version.h>
 
 // We limit the number of times a page can be retained by the kernel
 // to prevent the user from maliciously passing UVM tools the same page
@@ -158,7 +159,11 @@
     }
 
     down_read(&current->mm->mmap_sem);
+    #if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0)
     ret = get_user_pages(current, current->mm, user_va, num_pages, 1, 0, *pages, NULL);
+    #else
+    ret = get_user_pages(user_va, num_pages, 1, 0, *pages, NULL);
+    #endif
     up_read(&current->mm->mmap_sem);
     if (ret != num_pages) {
         status = NV_ERR_INVALID_ARGUMENT;
diff -ruN NVIDIA-Linux-x86_64-364.15/kernel/nvidia-uvm/uvm_full_fault_handler.c NVIDIA-Linux-x86_64-364.15.patched/kernel/nvidia-uvm/uvm_full_fault_handler.c
--- NVIDIA-Linux-x86_64-364.15/kernel/nvidia-uvm/uvm_full_fault_handler.c	2016-04-03 05:08:49.000000000 +0200
+++ NVIDIA-Linux-x86_64-364.15.patched/kernel/nvidia-uvm/uvm_full_fault_handler.c	2016-04-06 21:26:59.000000000 +0200
@@ -32,6 +32,7 @@
 #include "uvm_full_fault_buffer.h"
 #include "uvm_full_identity_map.h"
 #include "uvm_full_perf.h"
+#include <linux/version.h>
 
 #define FAULTS_PER_ITER    4
 
diff -ruN NVIDIA-Linux-x86_64-364.15/kernel/nvidia-uvm/uvm_full_pagetbl_mgmt.c NVIDIA-Linux-x86_64-364.15.patched/kernel/nvidia-uvm/uvm_full_pagetbl_mgmt.c
--- NVIDIA-Linux-x86_64-364.15/kernel/nvidia-uvm/uvm_full_pagetbl_mgmt.c	2016-04-03 05:08:49.000000000 +0200
+++ NVIDIA-Linux-x86_64-364.15.patched/kernel/nvidia-uvm/uvm_full_pagetbl_mgmt.c	2016-04-19 17:30:30.000000000 +0200
@@ -31,6 +31,7 @@
 #include "uvm_full_ctx_mgmt.h"
 #include "uvm_hashmap.h"
 #include "uvm_full_fault_handler.h"
+#include <linux/version.h>
 
 #define UVM_PUSHBUFFER_INLINE_REGION_SIZE_MAX     (((1 << 13) - 1) * 4)
 #define UVM_MEMSET_BUFFER_SIZE_MAX                64
@@ -2909,7 +2910,11 @@
 
         // get userPA for this range
         down_read(&current->mm->mmap_sem);
+        #if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0)
         returnVal = get_user_pages(current, current->mm, (unsigned long)(UVM_ALIGN_ADDR(userCopyBuffer, PAGE_SIZE_4K)),
+        #else
+        returnVal = get_user_pages( (unsigned long)(UVM_ALIGN_ADDR(userCopyBuffer, PAGE_SIZE_4K)),
+        #endif
             userPagesReq, 1, 0, tempUserPageArray, NULL);
         up_read(&current->mm->mmap_sem);
 
@@ -2939,7 +2944,11 @@
                     set_page_dirty_lock(tempUserPageArray[i]);
 
             UVM_PANIC_ON(tempUserPageArray[i] == 0);
+            #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
             page_cache_release(tempUserPageArray[i]);
+            #else
+            put_page(tempUserPageArray[i]);
+            #endif
             tempUserPageArray[i] = 0;
         }

That’s my combined patch.

This should “just work” against rc4+ tree, it’s not as nice as other patches tho (with kernel version ifdefs or propper formatting):

Thank you. Dropped that in as an epatch (I run Gentoo) and it builds fine, and seems to work (only tested with glxgears)

A proper fully redone patch against kernel 4.6.0-rc4 and for nvidia 364.15 as been remade
[url]https://dav.ioda.net/index.php/s/0EPP4QY9akESsYr/download[/url]

I’m using it since 2 days with openSUSE Tumbleweed (+Kernel:Head) with plasma5 as desktop.

and of course, now 364.19 is out and broken things again :)

kernel/nvidia-drm/nvidia-drm-drv.c:67:18: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
.fb_create = nvidia_drm_framebuffer_create,

Here my used patch:

diff -rup NVIDIA-Linux-x86_64-364.19.orig/kernel/nvidia-drm/nvidia-drm-fb.c NVIDIA-Linux-x86_64-364.19/kernel/nvidia-drm/nvidia-drm-fb.c
--- NVIDIA-Linux-x86_64-364.19.orig/kernel/nvidia-drm/nvidia-drm-fb.c	2016-04-19 22:31:08.000000000 +0200
+++ NVIDIA-Linux-x86_64-364.19/kernel/nvidia-drm/nvidia-drm-fb.c	2016-04-22 19:46:46.000000000 +0200
@@ -29,6 +29,7 @@
 #include "nvidia-drm-fb.h"
 #include "nvidia-drm-utils.h"
 #include "nvidia-drm-gem.h"
+#include <linux/version.h>
 
 #include <drm/drm_crtc_helper.h>
 
@@ -77,7 +78,12 @@ static struct drm_framebuffer_funcs nv_f
 static struct drm_framebuffer *internal_framebuffer_create
 (
     struct drm_device *dev,
+    #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
     struct drm_file *file, struct drm_mode_fb_cmd2 *cmd,
+    #else
+    struct drm_file *file,
+    const struct drm_mode_fb_cmd2 *cmd,
+    #endif
     uint64_t nvkms_params_ptr,
     uint64_t nvkms_params_size
 )
@@ -199,7 +205,11 @@ failed_fb_create:
 struct drm_framebuffer *nvidia_drm_framebuffer_create
 (
     struct drm_device *dev,
+    #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
     struct drm_file *file, struct drm_mode_fb_cmd2 *cmd
+    #else
+    struct drm_file *file, const struct drm_mode_fb_cmd2 *cmd
+    #endif
 )
 {
     return internal_framebuffer_create(dev, file, cmd, 0, 0);
diff -rup NVIDIA-Linux-x86_64-364.19.orig/kernel/nvidia-drm/nvidia-drm-fb.h NVIDIA-Linux-x86_64-364.19/kernel/nvidia-drm/nvidia-drm-fb.h
--- NVIDIA-Linux-x86_64-364.19.orig/kernel/nvidia-drm/nvidia-drm-fb.h	2016-04-19 22:31:08.000000000 +0200
+++ NVIDIA-Linux-x86_64-364.19/kernel/nvidia-drm/nvidia-drm-fb.h	2016-04-22 19:36:49.000000000 +0200
@@ -29,6 +29,7 @@
 
 #include <drm/drmP.h>
 #include "nvkms-kapi.h"
+#include <linux/version.h>
 
 struct nvidia_drm_framebuffer
 {
@@ -45,7 +46,12 @@ struct nvidia_drm_framebuffer
 struct drm_framebuffer *nvidia_drm_framebuffer_create
 (
     struct drm_device *dev,
+    #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
     struct drm_file *file, struct drm_mode_fb_cmd2 *cmd
+    #else
+    struct drm_file *file,
+    const struct drm_mode_fb_cmd2 *cmd
+    #endif
 );
 
 int nvidia_drm_add_nvkms_fb(
diff -rup NVIDIA-Linux-x86_64-364.19.orig/kernel/nvidia-drm/nvidia-drm-linux.c NVIDIA-Linux-x86_64-364.19/kernel/nvidia-drm/nvidia-drm-linux.c
--- NVIDIA-Linux-x86_64-364.19.orig/kernel/nvidia-drm/nvidia-drm-linux.c	2016-04-19 22:31:08.000000000 +0200
+++ NVIDIA-Linux-x86_64-364.19/kernel/nvidia-drm/nvidia-drm-linux.c	2016-04-22 19:51:07.000000000 +0200
@@ -23,7 +23,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/err.h>
-
+#include <linux/version.h>
 #include "nvidia-drm-os-interface.h"
 #include "nvidia-drm.h"
 
@@ -121,9 +121,14 @@ int nvidia_drm_lock_user_pages(unsigned
 
     down_read(&mm->mmap_sem);
 
+    #if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0)
     pages_pinned = get_user_pages(current, mm,
                                   address, pages_count, write, force,
                                   user_pages, NULL);
+    #else
+    pages_pinned = get_user_pages(address, pages_count, write, force,
+                                  user_pages, NULL);
+    #endif
     up_read(&mm->mmap_sem);
 
     if (pages_pinned < 0 || (unsigned)pages_pinned < pages_count)

For better reading:
http://paste.debian.net/?show=440329;lines=0

Mine for 364.19 (pastebin), which is essentially the same:

--- a/kernel/nvidia-drm/nvidia-drm-fb.c
+++ b/kernel/nvidia-drm/nvidia-drm-fb.c
@@ -77,7 +77,7 @@
 static struct drm_framebuffer *internal_framebuffer_create
 (
     struct drm_device *dev,
-    struct drm_file *file, struct drm_mode_fb_cmd2 *cmd,
+    struct drm_file *file, const struct drm_mode_fb_cmd2 *cmd,
     uint64_t nvkms_params_ptr,
     uint64_t nvkms_params_size
 )
@@ -199,7 +199,7 @@
 struct drm_framebuffer *nvidia_drm_framebuffer_create
 (
     struct drm_device *dev,
-    struct drm_file *file, struct drm_mode_fb_cmd2 *cmd
+    struct drm_file *file, const struct drm_mode_fb_cmd2 *cmd
 )
 {
     return internal_framebuffer_create(dev, file, cmd, 0, 0);
--- a/kernel/nvidia-drm/nvidia-drm-fb.h
+++ b/kernel/nvidia-drm/nvidia-drm-fb.h
@@ -45,7 +45,7 @@
 struct drm_framebuffer *nvidia_drm_framebuffer_create
 (
     struct drm_device *dev,
-    struct drm_file *file, struct drm_mode_fb_cmd2 *cmd
+    struct drm_file *file, const struct drm_mode_fb_cmd2 *cmd
 );
 
 int nvidia_drm_add_nvkms_fb(
--- a/kernel/nvidia-drm/nvidia-drm-linux.c
+++ b/kernel/nvidia-drm/nvidia-drm-linux.c
@@ -31,6 +31,7 @@
 
 #if defined(NV_DRM_AVAILABLE)
 
+#include "nv-mm.h"
 #include "nv-pgprot.h"
 
 MODULE_PARM_DESC(
@@ -121,8 +122,7 @@
 
     down_read(&mm->mmap_sem);
 
-    pages_pinned = get_user_pages(current, mm,
-                                  address, pages_count, write, force,
+    pages_pinned = NV_GET_USER_PAGES(address, pages_count, write, force,
                                   user_pages, NULL);
     up_read(&mm->mmap_sem);

Thanks nwwt it help me to find the last missing bits, your patch is only working for 4.6
getting the IF < 4.6.0 is a must for user having to compile on both version.

towo patch should be adapted to the new NV_GET_USER_PAGES

One day we will get newer version, including the community work, and not a half backed :-)

Flawless, thank you.

For lurkers: Save that pastebin paste as NVIDIA-Linux-x86_64-364.19/patch.txt and go in NVIDIA-Linux-x86_64-364.19 and run ‘patch -p1 < patch.txt’ without quotes. Then make/compile/package as usual.

I am using nvidia 361.42 now, but it is still not compatible with kernel 4.6.0-rc5. Should this patch also work for the current driver version? How to apply the patch? I am not familiar with compiling and applying drivers. If you anyone can point out a reference for me, that would be nice! Thanks!

Now that I use linux 4.6 rc7 on Ubuntu Yakkety, these patches were not necessary with the following ppa: https://launchpad.net/~graphics-drivers/+archive/ubuntu/ppa

It did fail, needed to append in
EXTRA_CFLAGS += -fno-pie -fno-stack-protector
to /usr/src/nvidia-364-364.19/Kbuild

And to top /usr/src/bbswitch-0.8/Makefile
EXTRA_CFLAGS := -fno-pie -fno-stack-protector

Then issue a command:
ls /usr/src/linux-headers-* -d | sed -e ‘s/.*linux-headers-//’ | sort -V | tac | sudo xargs -n1 /usr/lib/dkms/dkms_autoinstaller start

EXTRA_CFLAGS := -fno-pie -fno-stack-protector

This may, or may not be relevant to you folks… but at least with the graphics-ppa in Ubuntu, the patches seem no longer necessary.
[edit]
It seems to be a gcc related issue, but nonetheless, this is fixable. See also https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1574982

Hey TwiceJR! I didn’t think we had to edit the Makefile as long as we added the CFLAGs to the Kbuild file. Your fix seems the easiest so I’ll try it right now! Thank you!

No problem, hopefully this makes to #1 in Google :)
I can confirm this working in Yakkety + graphics-ppa .

Time for a btrfs snapshot.

It would seem that latest nvidia beta driver (NVIDIA-Linux-x86_64-367.18) compiles just fine against current git tree (3.6+ staging, HEAD cca6c2547). I guess this thread becomes obsolete now.

Hey guys!

I am running 4.6 (stable) on Debian 8 (jessie). After almost one day trying to get my both monitors working and the nvidia driver up and running (GTX 750), this solved everything in a pretty fast and simple way http://www.nvidia.com/download/driverResults.aspx/102879/en-us .

Cheers!