Linux 4.0-rc1 346.47 build error _cr4() functions fix

Here’s the log:

/var/lib/dkms/nvidia/346.35/build/nv-pat.c: In function ‘nv_disable_caches’:
/var/lib/dkms/nvidia/346.35/build/nv-pat.c:38:5: error: implicit declaration of function ‘read_cr4’ [-Werror=implicit-function-declaration]
     *cr4 = read_cr4();
     ^
/var/lib/dkms/nvidia/346.35/build/nv-pat.c:39:5: error: implicit declaration of function ‘write_cr4’ [-Werror=implicit-function-declaration]
     if (*cr4 & 0x80) write_cr4(*cr4 & ~0x80);
     ^

This commit kernel/git/torvalds/linux.git - Linux kernel source tree changed CR4 read/write

Simple fix. Need to check kernel version though as it’ll break lower versions <4.0

--- nv-pat.c~	2015-02-22 20:39:43.889075396 -0800
+++ nv-pat.c	2015-02-22 20:29:33.519735577 -0800
@@ -35,8 +35,8 @@
     unsigned long cr0 = read_cr0();
     write_cr0(((cr0 & (0xdfffffff)) | 0x40000000));
     wbinvd();
-    *cr4 = read_cr4();
-    if (*cr4 & 0x80) write_cr4(*cr4 & ~0x80);
+    *cr4 = __read_cr4();
+    if (*cr4 & 0x80) __write_cr4(*cr4 & ~0x80);
     __flush_tlb();
 }
 
@@ -46,7 +46,7 @@
     wbinvd();
     __flush_tlb();
     write_cr0((cr0 & 0x9fffffff));
-    if (cr4 & 0x80) write_cr4(cr4);
+    if (cr4 & 0x80) __write_cr4(cr4);
 }
 
 static int nv_determine_pat_mode(void)

Thanks, worked.

--- a/nv-pat.c.orig     2015-02-20 02:49:40.000000000 +0100
+++ b/nv-pat.c  2015-02-25 07:56:40.000000000 +0100
@@ -35,8 +35,13 @@
     unsigned long cr0 = read_cr0();
     write_cr0(((cr0 & (0xdfffffff)) | 0x40000000));
     wbinvd();
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 20, 0)
     *cr4 = read_cr4();
     if (*cr4 & 0x80) write_cr4(*cr4 & ~0x80);
+#else
+    *cr4 = __read_cr4();
+    if (*cr4 & 0x80) __write_cr4(*cr4 & ~0x80);
+#endif
     __flush_tlb();
 }
 
@@ -46,7 +51,11 @@
     wbinvd();
     __flush_tlb();
     write_cr0((cr0 & 0x9fffffff));
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 20, 0)
     if (cr4 & 0x80) write_cr4(cr4);
+#else
+    if (cr4 & 0x80) __write_cr4(cr4);
+#endif   
 }

 static int nv_determine_pat_mode(void)

Would be better.

I’m still having trouble building the nvidia module for Linux 4.0.0-rc1. I’ve applied this patch to the nvidia 346.47 drivers. Inside /usr/src/NVIDIA-Linux-x86_64-346.47/kernel I run:

# make SYSSRC=/usr/src/linux-4.0.0-rc1/

Lots of stuff happens, then I get the following output:

make[1]: Leaving directory '/usr/src/linux-4.0.0-rc1'
NVIDIA: left KBUILD.
nvidia.ko failed to build!
nvidia-modules-common.mk:248: recipe for target 'module' failed
make: *** [module] Error 1

There don’t seem to be any errors in the output that I can find. I’ve repackaged the driver back into a NVIDIA-Linux-x86_64-346.47-patched.run using makeself.sh. This also fails to build, and the log in /var/log/nvidia-installer.log files says that it can’t find include/generated/autoconf.h or include/config/auto.conf.

Any ideas?

@towo
Thanks for adding the kernel version tests.

@tanslucent
Just tested patch with 346.47 and it installs fine for me on all my kernels. Must be something with your install. Are the autoconf files in your kernel workspace/headers?

I’m pretty new to building kernels. I thought I installed everything correctly. I built Linux 4.0 with make deb-pkg, then installed the headers and image. The autoconf files are in the correct directories. I tried giving the paths to the source and headers to the nvidia build, but I keep failing on nvidia-modules-common.mk.

I’ve never had an issue building for 3.16.1 and from what I can tell I’ve done everything the same for 4.0. But both drivers (using the repackaged .run installer) install fine on 3.16.1.

Edit
I started following the Linux guide to building out of tree modules. This is something I’d never done before. Using the following command

sudo make -C /lib/modules/4.0.0-rc1/build M=$PWD

I found I had an extra } added into the code. Which I thought was getting me back on track. Then I did a make clean, and reperformed the above command:

$ sudo make -C /lib/modules/4.0.0-rc1/build M=$PWD
make: Entering directory '/usr/src/linux-headers-4.0.0-rc1'
  CC [M]  /usr/src/NVIDIA-Linux-x86_64-346.47/kernel/nv.o
In file included from /usr/src/NVIDIA-Linux-x86_64-346.47/kernel/nv-linux.h:15:0,
                 from /usr/src/NVIDIA-Linux-x86_64-346.47/kernel/nv.c:13:
/usr/src/NVIDIA-Linux-x86_64-346.47/kernel/conftest.h:1:30: fatal error: conftest/headers.h: No such file or directory
compilation terminated.
scripts/Makefile.build:258: recipe for target '/usr/src/NVIDIA-Linux-x86_64-346.47/kernel/nv.o' failed
make[1]: *** [/usr/src/NVIDIA-Linux-x86_64-346.47/kernel/nv.o] Error 1
Makefile:1390: recipe for target '_module_/usr/src/NVIDIA-Linux-x86_64-346.47/kernel' failed
make: *** [_module_/usr/src/NVIDIA-Linux-x86_64-346.47/kernel] Error 2
make: Leaving directory '/usr/src/linux-headers-4.0.0-rc1'

This literally worked before I did a make clean, fixed the code patch, and re-ran make.

$ sudo make -C /lib/modules/4.0.0-rc1/build M=$PWD
make: Entering directory '/usr/src/linux-headers-4.0.0-rc1'
  LD      /usr/src/NVIDIA-Linux-x86_64-346.47/kernel/built-in.o
  CC [M]  /usr/src/NVIDIA-Linux-x86_64-346.47/kernel/nv.o

No errors after that point, just lots of build messages.

Just to update. Apparently performing a make clean removes conftest/. For some reason conftest.sh was not generating this directory during the build. Not sure why. I don’t think it could determine the kernel version for some reason. I’m not sure that it uses the correct kernel source directory. Building 4.0 on Linux 3.16.1; only speculation.

I attempted to build the nvidia module under 3.16.1 source. While it failed eventually, it got far enough to create conftest/ for me. Going back to build with 4.0 source everything seemed to work fine. I used the nvidia-installer at this point, and I’m now running just fine. I’m curious about why the whole thing wouldn’t build, but that will be for another day.

— nvidia-modules-common.mk.orig 2014-11-07 19:27:54.000000000 -0430
+++ nvidia-modules-common.mk 2014-11-13 22:43:42.996326770 -0430
@@ -244,6 +244,8 @@

Call into KBUILD to build the NVIDIA kernel module(s) defined in $(obj-m)

+run_conftest: $(CONFTEST_HEADERS)
+
module: build-sanity-checks $(CONFTEST_HEADERS)
@echo “NVIDIA: calling KBUILD…”;
$(MAKE) “CC=$(CC)” $(KBUILD_PARAMS) modules; \

after patch
run
sudo make run_conftest
sudo make -C /lib/modules/4.0.0-rc1/build M=$PWD

@andresu

Perfect! Thank you for that patch. Everything works as I expect now.

Works fine for me.
Thanks.

I am struggling to find the right version of nv-pat.c to edit. I’m assuming there is one inside my NVIDIA-Linux-x86_64-340.76.run file that overwrites the ones in /var/lib/dkms/nvidia/340.76/build/. I’m just not sure where to make the change so that when I execute NVIDIA-Linux-x86_64-340.76.run, my change is taken.

Any help would be greatly appreciated.

jlflammia: I think what’s you’re looking for is
$sh ./NVIDIA-Linux-x86_64-340.76.run --extract-only

Replace 340.76 if necessary with whatever version you’re using. You get a directory with all of the sources, nv-pat.c is under the kernel subfolder.

If you want to proceed with the standard installation, run (from the root of the source directory)

$sudo ./nvidia-installer

This is probably coming late and hopefully you worked this out by now, but seeing no response I figured I’d tell you just in case.

translucent: I’ve been trying to get this thing to build for the better part of a very frustrating day, getting the same “failed to build” with no errors!; still trying to get my GTX 970 to run Xorg on a Linux From Scratch system and I’m hoping this will do it. I have my nvidia.ko now at least, thanks to you! (I also used the suggestion by andresu so thanks to you as well!)

The problem seems to be fixed in 340.93
I dropped the “fixes-for-kernel-4.0.0.patch” in the debian 340.76 package (added in 340.76-2) and rebuild it with 340.93.
Tested against 3.16, 3.18 and 4.1. No errors and works great!