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
@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