Skip to content

Instantly share code, notes, and snippets.

@joanbm
Last active March 4, 2025 00:49
Show Gist options
  • Save joanbm/d1f89391a4b20f4b56ba931ef6ca62da to your computer and use it in GitHub Desktop.
Save joanbm/d1f89391a4b20f4b56ba931ef6ca62da to your computer and use it in GitHub Desktop.
Tentative fix for NVIDIA 470.256.02 driver for Linux 6.13-rc1
From 9f91b171f680648647580c163bbc9cc1641e3920 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20Bruguera=20Mic=C3=B3?= <[email protected]>
Date: Sat, 16 Nov 2024 22:45:21 +0000
Subject: [PATCH] Tentative fix for NVIDIA 470.256.02 driver for Linux 6.13-rc1
---
nvidia-modeset/nvidia-modeset.Kbuild | 8 +++++---
nvidia/nvidia.Kbuild | 8 +++++---
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/nvidia-modeset/nvidia-modeset.Kbuild b/nvidia-modeset/nvidia-modeset.Kbuild
index a7d84e0..d417c28 100644
--- a/nvidia-modeset/nvidia-modeset.Kbuild
+++ b/nvidia-modeset/nvidia-modeset.Kbuild
@@ -40,13 +40,15 @@ NV_KERNEL_MODULE_TARGETS += $(NVIDIA_MODESET_KO)
NVIDIA_MODESET_BINARY_OBJECT := $(src)/nvidia-modeset/nv-modeset-kernel.o_binary
NVIDIA_MODESET_BINARY_OBJECT_O := nvidia-modeset/nv-modeset-kernel.o
-quiet_cmd_symlink = SYMLINK $@
-cmd_symlink = ln -sf $< $@
+# Rel. commit 80f289101690 "kbuild: change working directory to external module directory with M=" (Masahiro Yamada, 10 Nov 2024)
+# Ensure `$<` is absolute, since the link target is resolved relative to its path, not from where `ln` is run from.
+quiet_cmd_symlinkabs = SYMLINK $@
+ cmd_symlinkabs = ln -sf $(abspath $<) $@
targets += $(NVIDIA_MODESET_BINARY_OBJECT_O)
$(obj)/$(NVIDIA_MODESET_BINARY_OBJECT_O): $(NVIDIA_MODESET_BINARY_OBJECT) FORCE
- $(call if_changed,symlink)
+ $(call if_changed,symlinkabs)
nvidia-modeset-y += $(NVIDIA_MODESET_BINARY_OBJECT_O)
diff --git a/nvidia/nvidia.Kbuild b/nvidia/nvidia.Kbuild
index 31a6f92..62689f6 100644
--- a/nvidia/nvidia.Kbuild
+++ b/nvidia/nvidia.Kbuild
@@ -40,13 +40,15 @@ NVIDIA_KO = nvidia/nvidia.ko
NVIDIA_BINARY_OBJECT := $(src)/nvidia/nv-kernel.o_binary
NVIDIA_BINARY_OBJECT_O := nvidia/nv-kernel.o
-quiet_cmd_symlink = SYMLINK $@
- cmd_symlink = ln -sf $< $@
+# Rel. commit 80f289101690 "kbuild: change working directory to external module directory with M=" (Masahiro Yamada, 10 Nov 2024)
+# Ensure `$<` is absolute, since the link target is resolved relative to its path, not from where `ln` is run from.
+quiet_cmd_symlinkabs = SYMLINK $@
+ cmd_symlinkabs = ln -sf $(abspath $<) $@
targets += $(NVIDIA_BINARY_OBJECT_O)
$(obj)/$(NVIDIA_BINARY_OBJECT_O): $(NVIDIA_BINARY_OBJECT) FORCE
- $(call if_changed,symlink)
+ $(call if_changed,symlinkabs)
nvidia-y += $(NVIDIA_BINARY_OBJECT_O)
--
2.47.0
@joanbm
Copy link
Author

joanbm commented Dec 2, 2024

PS: I haven't been able to test this on real hardware on the final 6.13-rc1 release yet - though it builds and should work.
PS2: It feels like there ought to be some better (simpler) way to fix this, but I haven't been able to dedicate much time to see if I can get anything better.

@hphilm
Copy link

hphilm commented Dec 2, 2024

@joanbm no worries. People will test and report back.

@SheMelody
Copy link

It should work considering the problem was with symlinks of those two files, we'll wait for feedback. I won't mess with it because I'm busy, just in case this patch doesn't work feel free to use my loop script (ugh).

@mjtappert
Copy link

Can confirm this worked for me, kinda. Thanks so much @joanbm for this patch!!! I wasn't able to sort out how exactly to apply the patch, per se, but, I was able to manually edit the two requisite files with the total six lines of changes. This allowed me to install Nvidia drivers 565.57.01 with 6.13.0-rc1 on Ubuntu 24.10, where before the Nvidia .run installer would just fail. Thanks again!

@iadegesso
Copy link

Hi,
the patch applies on my Gentoo, but when building now I get the fallowing error:

nvidia/os-mlock.c: In function ‘nv_follow_pfn’:
nvidia/os-mlock.c:23:12: error: implicit declaration of function ‘follow_pfn’; did you mean ‘folio_pfn’? [-Werror=implicit-function-declaration]
23 | return follow_pfn(vma, address, pfn);
| ^~~~~~~~~~
| folio_pfn
cc1: some warnings being treated as errors
make[4]: *** [/usr/src/linux-6.13.0-gentoo/scripts/Makefile.build:194: nvidia/os-mlock.o] Error 1

@joanbm
Copy link
Author

joanbm commented Jan 27, 2025

@iadegesso You also need to apply a few other patches to fix incompatibilities with older kernel versions (6.10, 6.12, ...), see the following links: 1, 2.

@injiniero
Copy link

injiniero commented Feb 4, 2025

Confirm that this patch worked like a charm in my Arch Linux with 6.13.1-arch1-1 kernel.
Thank you @joanbm for the patch & @softexpert for applying it to nvidia-470xx-dkms AUR package.

NVIDIA GeForce GTX 760

@ffeldner
Copy link

ffeldner commented Feb 6, 2025

agreed, thanks a lot @joanbm for your continued work on this nvidia branch! Folks over at the aur are full of praise as well.

@joanbm
Copy link
Author

joanbm commented Feb 6, 2025

You're welcome!

@nssy
Copy link

nssy commented Feb 7, 2025

Thanks for this patch @joanbm
Also worked for NVIDIA 535 with linux-6.13

@BruXy
Copy link

BruXy commented Feb 26, 2025

Hi guys, could you please advise me on how to apply this patch?

I am building with this command:

rpmbuild --rebuild --define='_smp_build_ncpus 1' --define='kernels $(uname -r)'  https://koji.rpmfusion.org/kojifiles/packages/nvidia-kmod/565.77/1.fc41/src/nvidia-kmod-565.77-1.fc41.src.rpm

Without reducing NCPU, I would not even reach the error with symlinks. However, some shenanigans are happening behind the scenes, so the new source is pulled to rpmbuilds everytime, so I cannot edit it manually 😒

@hadjiprocopis
Copy link

Hi all,
I can confirm that this patch works for linux kernel 6.13.4 on Fedora 41.
@joanbm THANK YOU VERY MUCH!!! This is a fight on two fronts, against all odds, and you keep winning it.

As my humble contribution, this is a script I will be using from now on to patch the NVIDIA drivers.
The reason to have a script is that every time the linux kernel developers break the legacy NVIDIA driver a new patch appears (hopefully) which must be applied on top of all the previous patches, and I can't cope with all that manual work, so:

#!/bin/bash

# Patcher script for legacy NVIDIA drivers 470.xxx

DRIVERVERSION='470.256.02'

# add here patch URLs or FULL PATH to local patch files
# change patches depending on your case, this works for me on Fedora41
# with kernel 6.13.4
declare -a PATCHURLSORFILES=(
	'https://aur.archlinux.org/cgit/aur.git/plain/0001-Fix-conftest-to-ignore-implicit-function-declaration.patch?h=nvidia-470xx-utils&id=df0426ab325cb0ad8909a3058d66336ce1f872ce'
	'https://aur.archlinux.org/cgit/aur.git/plain/0002-Fix-conftest-to-use-a-short-wchar_t.patch?h=nvidia-470xx-utils&id=df0426ab325cb0ad8909a3058d66336ce1f872ce'
	'https://aur.archlinux.org/cgit/aur.git/plain/0003-Fix-conftest-to-use-nv_drm_gem_vmap-which-has-the-se.patch?h=nvidia-470xx-utils&id=df0426ab325cb0ad8909a3058d66336ce1f872ce'
	'https://aur.archlinux.org/cgit/aur.git/plain/kernel-6.10.patch?h=nvidia-470xx-utils&id=df0426ab325cb0ad8909a3058d66336ce1f872ce'
	# joanbm's Tentative fix for NVIDIA 470.256.02 driver for Linux 6.12-rc1
	'https://gist.githubusercontent.com/joanbm/a6d3f7f873a60dec0aa4a734c0f1d64e/raw/6bae5606c033b6c6c08233523091992370e357b7/nvidia-470xx-fix-linux-6.12.patch'
	# joanbm's Tentative fix for NVIDIA 470.256.02 driver for Linux 6.13-rc1
	'https://gist.githubusercontent.com/joanbm/d1f89391a4b20f4b56ba931ef6ca62da/raw/8458c7c58249a0dceb5ab1b5aada7e705a88b4ff/nvidia-470xx-fix-linux-6.13.patch'
)

#### nothing to change below

DRIVERNAME="NVIDIA-Linux-x86_64-${DRIVERVERSION}"
DRIVERFILE="${DRIVERNAME}.run"
DRIVERDIR="${DRIVERNAME}"

# fetch the NVIDIA driver from NVIDIA's site if not exist
if [ ! -f NVIDIA-Linux-x86_64-470.256.02.run ]; then
	read -p "Do you want to download the NVIDIA driver ${DRIVERVERSION} ? (Y/n) " answ
	if ! [[ "${answ}" =~ ^[yY].*$ ]]; then echo "can not continue"; exit 1; fi
	CMD="curl 'https://us.download.nvidia.com/XFree86/Linux-x86_64/${DRIVERVERSION}/${DRIVERFILE}' -o '${DRIVERFILE}'"
	eval ${CMD}; if [ $? -ne 0 ]; then echo "$0 : command has failed: ${CMD}"; exit 1; fi
	echo "$0 : done, downloaded NVIDIA driver."
fi

# erase the old NVIDIA driver dir if exists
if [ -d "${DRIVERDIR}" ]; then
	read -p "Do you want to erase old NVIDIA driver dir (${DRIVERDIR})? (Y/n) " answ
	if ! [[ "${answ}" =~ ^[yY].*$ ]]; then echo "can not continue"; exit 1; fi
	CMD="rm -rf '${DRIVERDIR}'"
	eval ${CMD}; if [ $? -ne 0 ]; then echo "$0 : command has failed: ${CMD}"; exit 1; fi
	echo "$0 : done, erased old NVIDIA driver dir (${DRIVERDIR})."
fi

# extract the NVIDIA driver archive (*.run) to a dir
CMD="sh '${DRIVERFILE}' --extract-only"
eval ${CMD}; if [ $? -ne 0 ]; then echo "$0 : command has failed: ${CMD}"; exit 1; fi
echo "$0 : done, extracted files from the NVIDIA driver archive (${DRIVERFILE}) into '${DRIVERDIR}'."

# go into the NVIDIA driver dir
CMD="cd '${DRIVERDIR}'"
eval ${CMD}; if [ $? -ne 0 ]; then echo "$0 : command has failed: ${CMD}"; exit 1; fi

# apply the patches from inside the NVIDIA driver dir
for ap in "${PATCHURLSORFILES[@]}"; do
	if [[ "${ap}" =~ ^http ]]; then
		CMD="curl '${ap}' | patch -Np1 -d kernel"
	else
		CMD="patch -Np1 -d kernel < '${ap}'"
	fi
	echo "$0 : patching with this command : ${CMD}"
	eval ${CMD}; if [ $? -ne 0 ]; then echo "$0 : command has failed: ${CMD}"; exit 1; fi
done

@hadjiprocopis
Copy link

@joanbm THANK YOU VERY MUCH for yet again winning on this two-front war. It's a life saver for our "legacy" GPU and for the planet by reusing perfectly working hardware and buying less.

I can confirm that your patch worked again, this time for Linux kernel 6.13.4 on Fedora41.

I now realise that the 470.xxx NVIDIA driver will break several more times in the future as linux kernel development continues and NVIDIA does not seem to care to follow, although they did at the beginning. I guess they have more worries right now.

As a humble contribution, here is a script which automates the cumulative application of all the patches needed (by my systtems) to have a working GPU:

#!/bin/bash

# Patcher script for legacy NVIDIA drivers 470.xxx

DRIVERVERSION='470.256.02'

# add here patch URLs or FULL PATH to local patch files
declare -a PATCHURLSORFILES=(
	'https://aur.archlinux.org/cgit/aur.git/plain/0001-Fix-conftest-to-ignore-implicit-function-declaration.patch?h=nvidia-470xx-utils&id=df0426ab325cb0ad8909a3058d66336ce1f872ce'
	'https://aur.archlinux.org/cgit/aur.git/plain/0002-Fix-conftest-to-use-a-short-wchar_t.patch?h=nvidia-470xx-utils&id=df0426ab325cb0ad8909a3058d66336ce1f872ce'
	'https://aur.archlinux.org/cgit/aur.git/plain/0003-Fix-conftest-to-use-nv_drm_gem_vmap-which-has-the-se.patch?h=nvidia-470xx-utils&id=df0426ab325cb0ad8909a3058d66336ce1f872ce'
	'https://aur.archlinux.org/cgit/aur.git/plain/kernel-6.10.patch?h=nvidia-470xx-utils&id=df0426ab325cb0ad8909a3058d66336ce1f872ce'
	# joanbm's Tentative fix for NVIDIA 470.256.02 driver for Linux 6.12-rc1
	'https://gist.githubusercontent.com/joanbm/a6d3f7f873a60dec0aa4a734c0f1d64e/raw/6bae5606c033b6c6c08233523091992370e357b7/nvidia-470xx-fix-linux-6.12.patch'
	# joanbm's Tentative fix for NVIDIA 470.256.02 driver for Linux 6.13-rc1
	'https://gist.githubusercontent.com/joanbm/d1f89391a4b20f4b56ba931ef6ca62da/raw/8458c7c58249a0dceb5ab1b5aada7e705a88b4ff/nvidia-470xx-fix-linux-6.13.patch'
)

#### nothing to change below

DRIVERNAME="NVIDIA-Linux-x86_64-${DRIVERVERSION}"
DRIVERFILE="${DRIVERNAME}.run"
DRIVERDIR="${DRIVERNAME}"

# fetch the NVIDIA driver from NVIDIA's site if not exist
if [ ! -f NVIDIA-Linux-x86_64-470.256.02.run ]; then
	read -p "Do you want to download the NVIDIA driver ${DRIVERVERSION} ? (Y/n) " answ
	if ! [[ "${answ}" =~ ^[yY].*$ ]]; then echo "can not continue"; exit 1; fi
	CMD="curl 'https://us.download.nvidia.com/XFree86/Linux-x86_64/${DRIVERVERSION}/${DRIVERFILE}' -o '${DRIVERFILE}'"
	eval ${CMD}; if [ $? -ne 0 ]; then echo "$0 : command has failed: ${CMD}"; exit 1; fi
	echo "$0 : done, downloaded NVIDIA driver."
fi

# erase the old NVIDIA driver dir if exists
if [ -d "${DRIVERDIR}" ]; then
	read -p "Do you want to erase old NVIDIA driver dir (${DRIVERDIR})? (Y/n) " answ
	if ! [[ "${answ}" =~ ^[yY].*$ ]]; then echo "can not continue"; exit 1; fi
	CMD="rm -rf '${DRIVERDIR}'"
	eval ${CMD}; if [ $? -ne 0 ]; then echo "$0 : command has failed: ${CMD}"; exit 1; fi
	echo "$0 : done, erased old NVIDIA driver dir (${DRIVERDIR})."
fi

# extract the NVIDIA driver archive (*.run) to a dir
CMD="sh '${DRIVERFILE}' --extract-only"
eval ${CMD}; if [ $? -ne 0 ]; then echo "$0 : command has failed: ${CMD}"; exit 1; fi
echo "$0 : done, extracted files from the NVIDIA driver archive (${DRIVERFILE}) into '${DRIVERDIR}'."

# go into the NVIDIA driver dir
CMD="cd '${DRIVERDIR}'"
eval ${CMD}; if [ $? -ne 0 ]; then echo "$0 : command has failed: ${CMD}"; exit 1; fi

# apply the patches from inside the NVIDIA driver dir
for ap in "${PATCHURLSORFILES[@]}"; do
	if [[ "${ap}" =~ ^http ]]; then
		CMD="curl '${ap}' | patch -Np1 -d kernel"
	else
		CMD="patch -Np1 -d kernel < '${ap}'"
	fi
	echo "$0 : patching with this command : ${CMD}"
	eval ${CMD}; if [ $? -ne 0 ]; then echo "$0 : command has failed: ${CMD}"; exit 1; fi
done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment