summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLenard Spencer <lenardrspencer@gmai.com>2020-12-26 11:29:05 +0700
committerWilly Sudiarto Raharjo <willysr@slackbuilds.org>2020-12-26 11:29:17 +0700
commit9685fdb8966431b726f4a07d191bb8f147dd713c (patch)
treec6538780f3077a1dec49d5fe2c973945413a78bd
parent0c0be152aa4f11fbe69a06d6224bbcbeeeb6ed9c (diff)
downloadslackbuilds-9685fdb8966431b726f4a07d191bb8f147dd713c.tar.gz
system/nvidia-legacy390-kernel: Added patches to build for 5.10+.
Signed-off-by: Willy Sudiarto Raharjo <willysr@slackbuilds.org>
-rw-r--r--system/nvidia-legacy390-kernel/README11
-rw-r--r--system/nvidia-legacy390-kernel/nvidia-legacy390-kernel.SlackBuild19
-rw-r--r--system/nvidia-legacy390-kernel/patches/README19
-rw-r--r--system/nvidia-legacy390-kernel/patches/kernel-4.16.patch47
-rw-r--r--system/nvidia-legacy390-kernel/patches/kernel-5.10.patch162
-rw-r--r--system/nvidia-legacy390-kernel/patches/kernel-5.8-license-bypass.patch23
-rw-r--r--system/nvidia-legacy390-kernel/patches/kernel-5.8.patch123
-rw-r--r--system/nvidia-legacy390-kernel/patches/kernel-5.9-x86.patch340
-rw-r--r--system/nvidia-legacy390-kernel/patches/kernel-5.9-x86_64.patch364
9 files changed, 1101 insertions, 7 deletions
diff --git a/system/nvidia-legacy390-kernel/README b/system/nvidia-legacy390-kernel/README
index 44c0369dd2..adb7c9d3fd 100644
--- a/system/nvidia-legacy390-kernel/README
+++ b/system/nvidia-legacy390-kernel/README
@@ -7,9 +7,12 @@ start the script setting the KERNEL variable as in
KERNEL=4.6.3 ./nvidia-legacy390-kernel.SlackBuild
A default config file is placed at
-/usr/share/X11/xorg.conf.d/10-nvidia.conf to make sure that X loads the
-nvidia module. If you need to make changes, move that file to
-/etc/X11/xorg.conf.d/ and edit the copy. You do not need this file at
-all if you have a proper and complete xorg.conf.
+/usr/share/X11/xorg.conf.d/10-nvidia.conf to make sure that X loads
+the nvidia module. If you need to make changes, copy that file to
+/etc/X11/xorg.conf.d/ and edit the copy. You do not need this file
+at all if you have a proper and complete xorg.conf.
+
+This script now includes the patches to enable building on newer
+kernels. (MANY thanks to willysr and Herecura for the fixes.)
The xf86-video-nouveau-blacklist package from /extra is required.
diff --git a/system/nvidia-legacy390-kernel/nvidia-legacy390-kernel.SlackBuild b/system/nvidia-legacy390-kernel/nvidia-legacy390-kernel.SlackBuild
index fba0d38bd0..6737648d36 100644
--- a/system/nvidia-legacy390-kernel/nvidia-legacy390-kernel.SlackBuild
+++ b/system/nvidia-legacy390-kernel/nvidia-legacy390-kernel.SlackBuild
@@ -29,7 +29,7 @@
PRGNAM=nvidia-legacy390-kernel
VERSION=${VERSION:-390.138}
-BUILD=${BUILD:-1}
+BUILD=${BUILD:-2}
TAG=${TAG:-_SBo}
KERNEL=${KERNEL:-$(uname -r)}
@@ -49,10 +49,8 @@ fi
if [ "$ARCH" = "i586" ]; then
TARGET="x86"
- SRCSUFFIX=""
elif [ "$ARCH" = "i686" ]; then
TARGET="x86"
- SRCSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
TARGET="x86_64"
fi
@@ -79,6 +77,17 @@ find -L . \
\( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
-o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
+# Patches for the newer kernels:
+patch -p1 < $CWD/patches/kernel-4.16.patch
+patch -p1 < $CWD/patches/kernel-5.8.patch
+if [ "$TARGET" = "x86" ]; then
+ patch -p1 < $CWD/patches/kernel-5.9-x86.patch
+else
+ patch -p1 < $CWD/patches/kernel-5.8-license-bypass.patch
+ patch -p1 < $CWD/patches/kernel-5.9-x86_64.patch
+fi
+patch -p1 < $CWD/patches/kernel-5.10.patch
+
(cd kernel || exit 1
make SYSSRC=$KERNELPATH module || exit 1
)
@@ -92,6 +101,10 @@ if [ "$TARGET" = "x86_64" ]; then
install -m 0664 kernel/nvidia-uvm.ko $PKG/lib/modules/$KERNEL/kernel/drivers/video/
fi
+# Make sure the X is specified to automagically load the
+# correct driver, since I always forget. You can remove
+# this file if you have an equivilent entry in /etc/X11/xorg.d
+
mkdir -p $PKG/usr/share/X11/xorg.conf.d/
cat $TMP/$SRCNAM/nvidia-drm-outputclass.conf > $PKG/usr/share/X11/xorg.conf.d/10-nvidia.conf
diff --git a/system/nvidia-legacy390-kernel/patches/README b/system/nvidia-legacy390-kernel/patches/README
new file mode 100644
index 0000000000..6f7b193d18
--- /dev/null
+++ b/system/nvidia-legacy390-kernel/patches/README
@@ -0,0 +1,19 @@
+HOW TO PATCH
+
+1. Extract NVidia Driver (64 bit)
+ ./NVIDIA-Linux-x86_64-390.138.run --extract-only
+2. Go to the extracted directory
+ cd NVIDIA-Linux-x86_64-390.138
+3. Patch it
+ patch -p1 < /path/to/kernel-4.16.patch
+ patch -p1 < /path/to/kernel-5.8.patch
+ patch -p1 < /path/to/kernel-5.8-license-bypass.patch
+ patch -p1 < /path/to/kernel-5.9.patch
+ patch -p1 < /path/to/kernel-5.10.patch
+4. Run the nvidia-installer
+ ./nvidia-installer --no-unified-memory
+5. Have fun :)
+
+
+20 December 2020
+Willy Sudiarto Raharjo
diff --git a/system/nvidia-legacy390-kernel/patches/kernel-4.16.patch b/system/nvidia-legacy390-kernel/patches/kernel-4.16.patch
new file mode 100644
index 0000000000..7d4501eca8
--- /dev/null
+++ b/system/nvidia-legacy390-kernel/patches/kernel-4.16.patch
@@ -0,0 +1,47 @@
+From 38a66ed47f5340abd370edcd1f7cf816b8ad478e Mon Sep 17 00:00:00 2001
+From: BlackEagle <ike.devolder@gmail.com>
+Date: Thu, 6 Aug 2020 12:11:38 +0200
+Subject: [PATCH 1/2] kernel-4.16.patch
+
+Signed-off-by: BlackEagle <ike.devolder@gmail.com>
+---
+ kernel/common/inc/nv-linux.h | 4 ++++
+ kernel/conftest.sh | 5 +++++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/kernel/common/inc/nv-linux.h b/kernel/common/inc/nv-linux.h
+index ac5bb95..ce6f891 100644
+--- a/kernel/common/inc/nv-linux.h
++++ b/kernel/common/inc/nv-linux.h
+@@ -175,7 +175,11 @@ static inline uid_t __kuid_val(kuid_t uid)
+
+ #if defined(NV_VM_INSERT_PAGE_PRESENT)
+ #include <linux/pagemap.h>
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0)
+ #include <linux/dma-mapping.h>
++#else
++#include <linux/dma-direct.h>
++#endif
+ #endif
+
+ #if defined(CONFIG_SWIOTLB) && defined(NVCPU_AARCH64)
+diff --git a/kernel/conftest.sh b/kernel/conftest.sh
+index 7da7505..0778ba1 100755
+--- a/kernel/conftest.sh
++++ b/kernel/conftest.sh
+@@ -2045,7 +2045,12 @@ compile_test() {
+ # Determine if the phys_to_dma function is present.
+ #
+ CODE="
++ #include <linux/version.h>
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0)
+ #include <linux/dma-mapping.h>
++#else
++ #include <linux/dma-direct.h>
++#endif
+ void conftest_phys_to_dma(void) {
+ phys_to_dma();
+ }"
+--
+2.28.0
+
diff --git a/system/nvidia-legacy390-kernel/patches/kernel-5.10.patch b/system/nvidia-legacy390-kernel/patches/kernel-5.10.patch
new file mode 100644
index 0000000000..6fa40d0f94
--- /dev/null
+++ b/system/nvidia-legacy390-kernel/patches/kernel-5.10.patch
@@ -0,0 +1,162 @@
+From a7b47c7adad039c65e75cfc31e0ca77d29b915f7 Mon Sep 17 00:00:00 2001
+From: BlackEagle <ike.devolder@gmail.com>
+Date: Sat, 19 Dec 2020 14:50:07 +0100
+Subject: [PATCH] kernel-5.10
+
+based on: https://gist.github.com/xtrymind/70919c82347670e788d4787dc321b72f
+
+Signed-off-by: BlackEagle <ike.devolder@gmail.com>
+---
+ kernel/common/inc/nv-linux.h | 3 ++
+ kernel/conftest.sh | 29 +++++++++++++++++--
+ .../nvidia-drm/nvidia-drm-gem-user-memory.c | 10 +++++--
+ 3 files changed, 38 insertions(+), 4 deletions(-)
+
+diff --git a/kernel/common/inc/nv-linux.h b/kernel/common/inc/nv-linux.h
+index 30afd4a..c9e5af7 100644
+--- a/kernel/common/inc/nv-linux.h
++++ b/kernel/common/inc/nv-linux.h
+@@ -179,6 +179,9 @@ static inline uid_t __kuid_val(kuid_t uid)
+ #include <linux/dma-mapping.h>
+ #else
+ #include <linux/dma-direct.h>
++#if defined(NV_LINUX_DMA_MAP_OPS_H_PRESENT)
++#include <linux/dma-map-ops.h>
++#endif
+ #endif
+ #endif
+
+diff --git a/kernel/conftest.sh b/kernel/conftest.sh
+index 9612796..1c1eb30 100755
+--- a/kernel/conftest.sh
++++ b/kernel/conftest.sh
+@@ -134,6 +134,7 @@ test_headers() {
+ FILES="$FILES linux/fence.h"
+ FILES="$FILES linux/ktime.h"
+ FILES="$FILES linux/dma-resv.h"
++ FILES="$FILES linux/dma-map-ops.h"
+
+ # Arch specific headers which need testing
+ FILES_ARCH="asm/book3s/64/hash-64k.h"
+@@ -2050,6 +2051,9 @@ compile_test() {
+ #include <linux/dma-mapping.h>
+ #else
+ #include <linux/dma-direct.h>
++#if defined(NV_LINUX_DMA_MAP_OPS_H_PRESENT)
++ #include <linux/dma-map-ops.h>
++#endif
+ #endif
+ void conftest_phys_to_dma(void) {
+ phys_to_dma();
+@@ -2064,6 +2068,9 @@ compile_test() {
+ #
+ CODE="
+ #include <linux/dma-mapping.h>
++#if defined(NV_LINUX_DMA_MAP_OPS_H_PRESENT)
++ #include <linux/dma-map-ops.h>
++#endif
+ void conftest_dma_ops(void) {
+ (void)dma_ops;
+ }"
+@@ -2078,6 +2085,9 @@ compile_test() {
+ #
+ CODE="
+ #include <linux/dma-mapping.h>
++#if defined(NV_LINUX_DMA_MAP_OPS_H_PRESENT)
++ #include <linux/dma-map-ops.h>
++#endif
+ void conftest_dma_ops(void) {
+ (void)swiotlb_dma_ops;
+ }"
+@@ -2088,22 +2098,28 @@ compile_test() {
+ dma_map_ops)
+ #
+ # Determine if the 'struct dma_map_ops' type is present.
+- #
++ #
+ CODE="
+ #include <linux/dma-mapping.h>
++#if defined(NV_LINUX_DMA_MAP_OPS_H_PRESENT)
++ #include <linux/dma-map-ops.h>
++#endif
+ void conftest_dma_map_ops(void) {
+ struct dma_map_ops ops;
+ }"
+
+ compile_check_conftest "$CODE" "NV_DMA_MAP_OPS_PRESENT" "" "types"
+ ;;
+-
++
+ get_dma_ops)
+ #
+ # Determine if the get_dma_ops() function is present.
+ #
+ CODE="
+ #include <linux/dma-mapping.h>
++#if defined(NV_LINUX_DMA_MAP_OPS_H_PRESENT)
++ #include <linux/dma-map-ops.h>
++#endif
+ void conftest_get_dma_ops(void) {
+ get_dma_ops();
+ }"
+@@ -2117,6 +2133,9 @@ compile_test() {
+ #
+ CODE="
+ #include <linux/dma-mapping.h>
++#if defined(NV_LINUX_DMA_MAP_OPS_H_PRESENT)
++ #include <linux/dma-map-ops.h>
++#endif
+ void conftest_noncoherent_swiotlb_dma_ops(void) {
+ (void)noncoherent_swiotlb_dma_ops;
+ }"
+@@ -2133,6 +2152,9 @@ compile_test() {
+ #
+ CODE="
+ #include <linux/dma-mapping.h>
++#if defined(NV_LINUX_DMA_MAP_OPS_H_PRESENT)
++ #include <linux/dma-map-ops.h>
++#endif
+ void conftest_dma_map_resource(void) {
+ dma_map_resource();
+ }"
+@@ -3961,6 +3983,9 @@ compile_test() {
+ #
+ CODE="
+ #include <linux/dma-mapping.h>
++#if defined(NV_LINUX_DMA_MAP_OPS_H_PRESENT)
++ #include <linux/dma-map-ops.h>
++#endif
+ void conftest_dma_is_direct(void) {
+ dma_is_direct();
+ }"
+diff --git a/kernel/nvidia-drm/nvidia-drm-gem-user-memory.c b/kernel/nvidia-drm/nvidia-drm-gem-user-memory.c
+index 76dedba..92a5192 100644
+--- a/kernel/nvidia-drm/nvidia-drm-gem-user-memory.c
++++ b/kernel/nvidia-drm/nvidia-drm-gem-user-memory.c
+@@ -20,6 +20,7 @@
+ * DEALINGS IN THE SOFTWARE.
+ */
+
++#include <linux/version.h>
+ #include "nvidia-drm-conftest.h"
+
+ #if defined(NV_DRM_AVAILABLE)
+@@ -47,8 +48,13 @@ static struct sg_table *__nv_drm_gem_user_memory_prime_get_sg_table(
+ {
+ struct nv_drm_gem_user_memory *nv_user_memory = to_nv_user_memory(nv_gem);
+
+- return drm_prime_pages_to_sg(nv_user_memory->pages,
+- nv_user_memory->pages_count);
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0))
++ return drm_prime_pages_to_sg(nv_gem->nv_dev->dev, nv_user_memory->pages,
++ nv_user_memory->pages_count);
++#else
++ return drm_prime_pages_to_sg(nv_user_memory->pages,
++ nv_user_memory->pages_count);
++#endif
+ }
+
+ static void *__nv_drm_gem_user_memory_prime_vmap(
+--
+2.29.2
+
diff --git a/system/nvidia-legacy390-kernel/patches/kernel-5.8-license-bypass.patch b/system/nvidia-legacy390-kernel/patches/kernel-5.8-license-bypass.patch
new file mode 100644
index 0000000000..702c9c2786
--- /dev/null
+++ b/system/nvidia-legacy390-kernel/patches/kernel-5.8-license-bypass.patch
@@ -0,0 +1,23 @@
+diff --git a/kernel/nvidia-uvm/uvm_common.c b/kernel/nvidia-uvm/uvm_common.c
+index 0f4516a..9e9811e 100644
+--- a/kernel/nvidia-uvm/uvm_common.c
++++ b/kernel/nvidia-uvm/uvm_common.c
+@@ -379,5 +379,5 @@ module_param(uvm_enable_builtin_tests, int, S_IRUGO);
+ MODULE_PARM_DESC(uvm_enable_builtin_tests,
+ "Enable the UVM built-in tests. (This is a security risk)");
+
+-MODULE_LICENSE("MIT");
++MODULE_LICENSE("GPL");
+ MODULE_INFO(supported, "external");
+diff --git a/kernel/nvidia-uvm/uvm_unsupported.c b/kernel/nvidia-uvm/uvm_unsupported.c
+index 0419121..1ccd1f4 100644
+--- a/kernel/nvidia-uvm/uvm_unsupported.c
++++ b/kernel/nvidia-uvm/uvm_unsupported.c
+@@ -171,6 +171,6 @@ static void __exit uvm_unsupported_exit(void)
+ module_init(uvm_unsupported_module_init);
+ module_exit(uvm_unsupported_exit);
+
+-MODULE_LICENSE("MIT");
++MODULE_LICENSE("GPL");
+ MODULE_INFO(supported, "external");
+
diff --git a/system/nvidia-legacy390-kernel/patches/kernel-5.8.patch b/system/nvidia-legacy390-kernel/patches/kernel-5.8.patch
new file mode 100644
index 0000000000..128d072198
--- /dev/null
+++ b/system/nvidia-legacy390-kernel/patches/kernel-5.8.patch
@@ -0,0 +1,123 @@
+From c3a26ae7fc4a5ca857f829c1943abcf3c1d4d173 Mon Sep 17 00:00:00 2001
+From: BlackEagle <ike.devolder@gmail.com>
+Date: Thu, 6 Aug 2020 12:35:38 +0200
+Subject: [PATCH 2/2] kernel-5.8.patch
+
+Signed-off-by: BlackEagle <ike.devolder@gmail.com>
+---
+ kernel/common/inc/nv-linux.h | 6 +++++
+ kernel/common/inc/nv-mm.h | 4 ++++
+ kernel/conftest.sh | 43 ++++++++++++++++++++++++++++++++++++
+ kernel/nvidia/nvidia.Kbuild | 2 ++
+ 4 files changed, 55 insertions(+)
+
+diff --git a/kernel/common/inc/nv-linux.h b/kernel/common/inc/nv-linux.h
+index ce6f891..872c4ca 100644
+--- a/kernel/common/inc/nv-linux.h
++++ b/kernel/common/inc/nv-linux.h
+@@ -535,7 +535,13 @@ extern int nv_pat_mode;
+
+ static inline void *nv_vmalloc(unsigned long size)
+ {
++#if NV_VMALLOC_ARGUMENT_COUNT_ARGUMENT_COUNT == 3
+ void *ptr = __vmalloc(size, GFP_KERNEL, PAGE_KERNEL);
++#elif NV_VMALLOC_ARGUMENT_COUNT_ARGUMENT_COUNT == 2
++ void *ptr = __vmalloc(size, GFP_KERNEL);
++#else
++#error "NV_VMALLOC_ARGUMENT_COUNT_ARGUMENT_COUNT value unrecognized!"
++#endif
+ if (ptr)
+ NV_MEMDBG_ADD(ptr, size);
+ return ptr;
+diff --git a/kernel/common/inc/nv-mm.h b/kernel/common/inc/nv-mm.h
+index 1270bf3..dfcd12b 100644
+--- a/kernel/common/inc/nv-mm.h
++++ b/kernel/common/inc/nv-mm.h
+@@ -25,6 +25,10 @@
+
+ #include "conftest.h"
+
++#if defined(NV_MM_STRUCT_HAS_MMAP_LOCK)
++#define mmap_sem mmap_lock
++#endif
++
+ #if !defined(NV_VM_FAULT_T_IS_PRESENT)
+ typedef int vm_fault_t;
+ #endif
+diff --git a/kernel/conftest.sh b/kernel/conftest.sh
+index 0778ba1..7d5821a 100755
+--- a/kernel/conftest.sh
++++ b/kernel/conftest.sh
+@@ -2629,6 +2629,49 @@ compile_test() {
+ compile_check_conftest "$CODE" "NV_VZALLOC_PRESENT" "" "functions"
+ ;;
+
++ vmalloc_argument_count)
++ #
++ # Determine how many arguments __vmalloc takes.
++ #
++ # Changed by commit fc3af83c4fca ("mm: remove the pgprot argument
++ # to __vmalloc")
++ #
++ echo "$CONFTEST_PREAMBLE
++ #include <linux/mm.h>
++ #include <linux/vmalloc.h>
++ void conftest_vmalloc_argument_count(void) {
++ __vmalloc(0, GFP_KERNEL, PAGE_KERNEL);
++ }" > conftest$$.c
++
++ $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
++ rm -f conftest$$.c
++
++ if [ -f conftest$$.o ]; then
++ echo "#define NV_VMALLOC_ARGUMENT_COUNT_ARGUMENT_COUNT 3" | append_conftest "functions"
++ else
++ echo "#define NV_VMALLOC_ARGUMENT_COUNT_ARGUMENT_COUNT 2" | append_conftest "functions"
++ fi
++
++ rm -f conftest$$.o
++ ;;
++
++ mm_struct_has_mmap_lock)
++ #
++ # Determine if the mm_struct structure has 'mmap_lock'.
++ #
++ # Changed by commit ea7b54944ef9 ("mmap locking API: rename mmap_sem
++ # to mmap_lock")
++ #
++ CODE="
++ #include <linux/mm.h>
++
++ int conftest_mm_struct_has_mmap_lock(void) {
++ return offsetof(struct mm_struct, mmap_lock);
++ }"
++
++ compile_check_conftest "$CODE" "NV_MM_STRUCT_HAS_MMAP_LOCK" "" "types"
++ ;;
++
+ drm_driver_has_set_busid)
+ #
+ # Determine if the drm_driver structure has a 'set_busid' callback
+diff --git a/kernel/nvidia/nvidia.Kbuild b/kernel/nvidia/nvidia.Kbuild
+index 63e369f..5b45144 100644
+--- a/kernel/nvidia/nvidia.Kbuild
++++ b/kernel/nvidia/nvidia.Kbuild
+@@ -158,6 +158,7 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += jiffies_to_timespec
+ NV_CONFTEST_FUNCTION_COMPILE_TESTS += ktime_get_raw_ts64
+ NV_CONFTEST_FUNCTION_COMPILE_TESTS += ktime_get_real_ts64
+ NV_CONFTEST_FUNCTION_COMPILE_TESTS += ioremap_nocache
++NV_CONFTEST_FUNCTION_COMPILE_TESTS += vmalloc_argument_count
+
+ NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_gpl_of_node_to_nid
+ NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_swiotlb_map_sg_attrs
+@@ -196,6 +197,7 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += timeval
+ NV_CONFTEST_TYPE_COMPILE_TESTS += kmem_cache_has_kobj_remove_work
+ NV_CONFTEST_TYPE_COMPILE_TESTS += sysfs_slab_unlink
+ NV_CONFTEST_TYPE_COMPILE_TESTS += pci_dev_has_skip_bus_pm
++NV_CONFTEST_TYPE_COMPILE_TESTS += mm_struct_has_mmap_lock
+
+ NV_CONFTEST_GENERIC_COMPILE_TESTS += dom0_kernel_present
+ NV_CONFTEST_GENERIC_COMPILE_TESTS += nvidia_vgpu_kvm_build
+--
+2.28.0
+
diff --git a/system/nvidia-legacy390-kernel/patches/kernel-5.9-x86.patch b/system/nvidia-legacy390-kernel/patches/kernel-5.9-x86.patch
new file mode 100644
index 0000000000..fb70ddfc7e
--- /dev/null
+++ b/system/nvidia-legacy390-kernel/patches/kernel-5.9-x86.patch
@@ -0,0 +1,340 @@
+diff --git a/kernel/common/inc/nv-linux.h b/kernel/common/inc/nv-linux.h
+index ab06dbc..dd335b5 100644
+--- a/kernel/common/inc/nv-linux.h
++++ b/kernel/common/inc/nv-linux.h
+@@ -159,7 +159,7 @@ static inline uid_t __kuid_val(kuid_t uid)
+ }
+ #endif
+
+-#if defined(NVCPU_X86_64) && !defined(HAVE_COMPAT_IOCTL)
++#if defined(NVCPU_X86_64) && !defined(NV_FILE_OPERATIONS_HAS_COMPAT_IOCTL)
+ #include <linux/syscalls.h> /* sys_ioctl() */
+ #include <linux/ioctl32.h> /* register_ioctl32_conversion() */
+ #endif
+diff --git a/kernel/common/inc/nv-mm.h b/kernel/common/inc/nv-mm.h
+index d2d7657..a5325fe 100644
+--- a/kernel/common/inc/nv-mm.h
++++ b/kernel/common/inc/nv-mm.h
+@@ -144,9 +144,13 @@ typedef int vm_fault_t;
+ flags |= FOLL_FORCE;
+
+ #if defined(NV_GET_USER_PAGES_REMOTE_HAS_LOCKED_ARG)
+-
++ #if defined (NV_GET_USER_PAGES_REMOTE_HAS_TSK_ARG)
+ return get_user_pages_remote(tsk, mm, start, nr_pages, flags,
+ pages, vmas, NULL);
++ #else
++ return get_user_pages_remote(mm, start, nr_pages, flags,
++ pages, vmas, NULL);
++ #endif
+
+ #else
+
+@@ -159,7 +163,7 @@ typedef int vm_fault_t;
+ #endif
+ #else
+ #if defined(NV_GET_USER_PAGES_HAS_WRITE_AND_FORCE_ARGS)
+- #define NV_GET_USER_PAGES_REMOTE NV_GET_USER_PAGES
++ #define NV_GET_USER_PAGES_REMOTE get_user_pages
+ #else
+ #include <linux/mm.h>
+ #include <linux/sched.h>
+diff --git a/kernel/conftest.sh b/kernel/conftest.sh
+index e900963..ef82dee 100755
+--- a/kernel/conftest.sh
++++ b/kernel/conftest.sh
+@@ -3043,6 +3043,7 @@ compile_test() {
+
+ if [ -f conftest$$.o ]; then
+ echo "#undef NV_GET_USER_PAGES_REMOTE_PRESENT" | append_conftest "functions"
++ echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_TSK_ARG" | append_conftest "functions"
+ echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_WRITE_AND_FORCE_ARGS" | append_conftest "functions"
+ echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_LOCKED_ARG" | append_conftest "functions"
+ rm -f conftest$$.o
+@@ -3070,14 +3071,20 @@ compile_test() {
+ rm -f conftest$$.c
+
+ if [ -f conftest$$.o ]; then
++ echo "#define NV_GET_USER_PAGES_REMOTE_HAS_TSK_ARG" | append_conftest "functions"
+ echo "#define NV_GET_USER_PAGES_REMOTE_HAS_WRITE_AND_FORCE_ARGS" | append_conftest "functions"
+ echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_LOCKED_ARG" | append_conftest "functions"
+ rm -f conftest$$.o
+ return
+ fi
+
++ echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_WRITE_AND_FORCE_ARGS" | append_conftest "functions"
++
++ #
+ # conftest #3: check if get_user_pages_remote() has locked argument
+-
++ # Return if these arguments are present. Fall through to conftest #4
++ # if these args are absent.
++ #
+ echo "$CONFTEST_PREAMBLE
+ #include <linux/mm.h>
+ long get_user_pages_remote(struct task_struct *tsk,
+@@ -3095,13 +3102,40 @@ compile_test() {
+ rm -f conftest$$.c
+
+ if [ -f conftest$$.o ]; then
++ echo "#define NV_GET_USER_PAGES_REMOTE_HAS_TSK_ARG" | append_conftest "functions"
++ echo "#define NV_GET_USER_PAGES_REMOTE_HAS_LOCKED_ARG" | append_conftest "functions"
++ rm -f conftest$$.o
++ return
++ fi
++
++ #
++ # conftest #4: check if get_user_pages_remote() does not take
++ # tsk argument.
++ #
++ echo "$CONFTEST_PREAMBLE
++ #include <linux/mm.h>
++ long get_user_pages_remote(struct mm_struct *mm,
++ unsigned long start,
++ unsigned long nr_pages,
++ unsigned int gup_flags,
++ struct page **pages,
++ struct vm_area_struct **vmas,
++ int *locked) {
++ return 0;
++ }" > conftest$$.c
++
++ $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
++ rm -f conftest$$.c
++
++ if [ -f conftest$$.o ]; then
++ echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_TSK_ARG" | append_conftest "functions"
+ echo "#define NV_GET_USER_PAGES_REMOTE_HAS_LOCKED_ARG" | append_conftest "functions"
+ rm -f conftest$$.o
+ else
++
++ echo "#define NV_GET_USER_PAGES_REMOTE_HAS_TSK_ARG" | append_conftest "functions"
+ echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_LOCKED_ARG" | append_conftest "functions"
+ fi
+- echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_WRITE_AND_FORCE_ARGS" | append_conftest "functions"
+-
+ ;;
+
+ usleep_range)
+@@ -4131,6 +4165,115 @@ compile_test() {
+ compile_check_conftest "$CODE" "NV_PCI_DEV_HAS_SKIP_BUS_PM" "" "types"
+ ;;
+
++ drm_gem_object_put_unlocked)
++ #
++ # Determine if the function drm_gem_object_put_unlocked() is present.
++ #
++ # In v5.9-rc1, commit 2f4dd13d4bb8 ("drm/gem: add
++ # drm_gem_object_put helper") removes drm_gem_object_put_unlocked()
++ # function and replace its definition by transient macro. Commit
++ # ab15d56e27be ("drm: remove transient
++ # drm_gem_object_put_unlocked()") finally removes
++ # drm_gem_object_put_unlocked() macro.
++ #
++ CODE="
++ #if defined(NV_DRM_DRMP_H_PRESENT)
++ #include <drm/drmP.h>
++ #endif
++
++ #if defined(NV_DRM_DRM_GEM_H_PRESENT)
++ #include <drm/drm_gem.h>
++ #endif
++ void conftest_drm_gem_object_put_unlocked(void) {
++ drm_gem_object_put_unlocked();
++ }"
++
++ compile_check_conftest "$CODE" "NV_DRM_GEM_OBJECT_PUT_UNLOCK_PRESENT" "" "functions"
++ ;;
++
++ drm_display_mode_has_vrefresh)
++ #
++ # Determine if the 'drm_display_mode' structure has a 'vrefresh'
++ # field.
++ #
++ # Removed by commit 0425662fdf05 ("drm: Nuke mode->vrefresh") in
++ # v5.9-rc1.
++ #
++ CODE="
++ #include <drm/drm_modes.h>
++
++ int conftest_drm_display_mode_has_vrefresh(void) {
++ return offsetof(struct drm_display_mode, vrefresh);
++ }"
++
++ compile_check_conftest "$CODE" "NV_DRM_DISPLAY_MODE_HAS_VREFRESH" "types"
++
++ ;;
++
++ drm_driver_master_set_has_int_return_type)
++ #
++ # Determine if drm_driver::master_set() returns integer value
++ #
++ # Changed to void by commit 907f53200f98 ("drm: vmwgfx: remove
++ # drm_driver::master_set() return type") in v5.9-rc1.
++ #
++ CODE="
++ #if defined(NV_DRM_DRMP_H_PRESENT)
++ #include <drm/drmP.h>
++ #endif
++
++ #if defined(NV_DRM_DRM_DRV_H_PRESENT)
++ #include <drm/drm_drv.h>
++ #endif
++
++ int conftest_drm_driver_master_set_has_int_return_type(struct drm_driver *drv,
++ struct drm_device *dev, struct drm_file *file_priv, bool from_open) {
++
++ return drv->master_set(dev, file_priv, from_open);
++ }"
++
++ compile_check_conftest "$CODE" "NV_DRM_DRIVER_SET_MASTER_HAS_INT_RETURN_TYPE" "" "types"
++ ;;
++
++ drm_driver_has_gem_free_object)
++ #
++ # Determine if the 'drm_driver' structure has a 'gem_free_object'
++ # function pointer.
++ #
++ # drm_driver::gem_free_object is removed by commit 1a9458aeb8eb
++ # ("drm: remove drm_driver::gem_free_object") in v5.9-rc1.
++ #
++ CODE="
++ #if defined(NV_DRM_DRMP_H_PRESENT)
++ #include <drm/drmP.h>
++ #endif
++
++ #if defined(NV_DRM_DRM_DRV_H_PRESENT)
++ #include <drm/drm_drv.h>
++ #endif
++
++ int conftest_drm_driver_has_gem_free_object(void) {
++ return offsetof(struct drm_driver, gem_free_object);
++ }"
++
++ compile_check_conftest "$CODE" "NV_DRM_DRIVER_HAS_GEM_FREE_OBJECT" "" "types"
++ ;;
++
++ vga_tryget)
++ #
++ # Determine if vga_tryget() is present
++ #
++ # vga_tryget() was removed by commit f369bc3f9096 ("vgaarb: mark
++ # vga_tryget static") in v5.9-rc1 (2020-08-01).
++ #
++ CODE="
++ #include <linux/vgaarb.h>
++ void conftest_vga_tryget(void) {
++ vga_tryget();
++ }"
++
++ compile_check_conftest "$CODE" "NV_VGA_TRYGET_PRESENT" "" "functions"
++ ;;
+ esac
+ }
+
+diff --git a/kernel/nvidia-drm/nvidia-drm-drv.c b/kernel/nvidia-drm/nvidia-drm-drv.c
+index 17e377d..85d9798 100644
+--- a/kernel/nvidia-drm/nvidia-drm-drv.c
++++ b/kernel/nvidia-drm/nvidia-drm-drv.c
+@@ -466,8 +466,8 @@ static void nv_drm_unload(struct drm_device *dev)
+
+ #if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
+
+-static int nv_drm_master_set(struct drm_device *dev,
+- struct drm_file *file_priv, bool from_open)
++static int __nv_drm_master_set(struct drm_device *dev,
++ struct drm_file *file_priv, bool from_open)
+ {
+ struct nv_drm_device *nv_dev = to_nv_device(dev);
+
+@@ -478,6 +478,22 @@ static int nv_drm_master_set(struct drm_device *dev,
+ return 0;
+ }
+
++#include <linux/version.h>
++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)
++static int nv_drm_master_set(struct drm_device *dev,
++ struct drm_file *file_priv, bool from_open)
++{
++ return __nv_drm_master_set(dev, file_priv, from_open);
++}
++#else
++static void nv_drm_master_set(struct drm_device *dev,
++ struct drm_file *file_priv, bool from_open)
++{
++ WARN_ON(__nv_drm_master_set(dev, file_priv, from_open) != 0);
++}
++#endif
++
++
+ #if defined(NV_DRM_MASTER_DROP_HAS_FROM_RELEASE_ARG)
+ static
+ void nv_drm_master_drop(struct drm_device *dev,
+@@ -677,7 +693,9 @@ static struct drm_driver nv_drm_driver = {
+ #endif
+ DRIVER_GEM | DRIVER_RENDER,
+
++#if defined(NV_DRM_DRIVER_HAS_GEM_FREE_OBJECT)
+ .gem_free_object = nv_drm_gem_free,
++#endif
+
+ .ioctls = nv_drm_ioctls,
+ .num_ioctls = ARRAY_SIZE(nv_drm_ioctls),
+diff --git a/kernel/nvidia-drm/nvidia-drm-gem.h b/kernel/nvidia-drm/nvidia-drm-gem.h
+index 5691a7a..18c50ca 100644
+--- a/kernel/nvidia-drm/nvidia-drm-gem.h
++++ b/kernel/nvidia-drm/nvidia-drm-gem.h
+@@ -87,7 +87,13 @@ static inline void
+ nv_drm_gem_object_unreference_unlocked(struct nv_drm_gem_object *nv_gem)
+ {
+ #if defined(NV_DRM_GEM_OBJECT_GET_PRESENT)
++
++#if defined(NV_DRM_GEM_OBJECT_PUT_UNLOCK_PRESENT)
+ drm_gem_object_put_unlocked(&nv_gem->base);
++#else
++ drm_gem_object_put(&nv_gem->base);
++#endif
++
+ #else
+ drm_gem_object_unreference_unlocked(&nv_gem->base);
+ #endif
+diff --git a/kernel/nvidia-drm/nvidia-drm-utils.c b/kernel/nvidia-drm/nvidia-drm-utils.c
+index 8cb2d5e..e30b2b6 100644
+--- a/kernel/nvidia-drm/nvidia-drm-utils.c
++++ b/kernel/nvidia-drm/nvidia-drm-utils.c
+@@ -103,7 +103,9 @@ void
+ nvkms_display_mode_to_drm_mode(const struct NvKmsKapiDisplayMode *displayMode,
+ struct drm_display_mode *mode)
+ {
++#if defined(NV_DRM_DISPLAY_MODE_HAS_VREFRESH)
+ mode->vrefresh = (displayMode->timings.refreshRate + 500) / 1000; /* In Hz */
++#endif
+
+ mode->clock = (displayMode->timings.pixelClockHz + 500) / 1000; /* In Hz */
+
+@@ -189,7 +191,11 @@ bool drm_format_to_nvkms_format(u32 format,
+ void drm_mode_to_nvkms_display_mode(const struct drm_display_mode *src,
+ struct NvKmsKapiDisplayMode *dst)
+ {
++#if defined(NV_DRM_DISPLAY_MODE_HAS_VREFRESH)
+ dst->timings.refreshRate = src->vrefresh * 1000;
++#else
++ dst->timings.refreshRate = drm_mode_vrefresh(src) * 1000;
++#endif
+
+ dst->timings.pixelClockHz = src->clock * 1000; /* In Hz */
+
+diff --git a/kernel/nvidia/nv.c b/kernel/nvidia/nv.c
+index 15983f6..cfb2375 100644
+--- a/kernel/nvidia/nv.c
++++ b/kernel/nvidia/nv.c
+@@ -3872,7 +3872,9 @@ nvidia_probe
+
+ #if defined(CONFIG_VGA_ARB) && !defined(NVCPU_PPC64LE)
+ #if defined(VGA_DEFAULT_DEVICE)
++#if defined(NV_VGA_TRYGET_PRESENT)
+ vga_tryget(VGA_DEFAULT_DEVICE, VGA_RSRC_LEGACY_MASK);
++#endif
+ #endif
+ vga_set_legacy_decoding(dev, VGA_RSRC_NONE);
+ #endif
diff --git a/system/nvidia-legacy390-kernel/patches/kernel-5.9-x86_64.patch b/system/nvidia-legacy390-kernel/patches/kernel-5.9-x86_64.patch
new file mode 100644
index 0000000000..d01eba7ab6
--- /dev/null
+++ b/system/nvidia-legacy390-kernel/patches/kernel-5.9-x86_64.patch
@@ -0,0 +1,364 @@
+diff --git a/kernel/common/inc/nv-linux.h b/kernel/common/inc/nv-linux.h
+index ab06dbc..dd335b5 100644
+--- a/kernel/common/inc/nv-linux.h
++++ b/kernel/common/inc/nv-linux.h
+@@ -159,7 +159,7 @@ static inline uid_t __kuid_val(kuid_t uid)
+ }
+ #endif
+
+-#if defined(NVCPU_X86_64) && !defined(HAVE_COMPAT_IOCTL)
++#if defined(NVCPU_X86_64) && !defined(NV_FILE_OPERATIONS_HAS_COMPAT_IOCTL)
+ #include <linux/syscalls.h> /* sys_ioctl() */
+ #include <linux/ioctl32.h> /* register_ioctl32_conversion() */
+ #endif
+diff --git a/kernel/common/inc/nv-mm.h b/kernel/common/inc/nv-mm.h
+index d2d7657..a5325fe 100644
+--- a/kernel/common/inc/nv-mm.h
++++ b/kernel/common/inc/nv-mm.h
+@@ -144,9 +144,13 @@ typedef int vm_fault_t;
+ flags |= FOLL_FORCE;
+
+ #if defined(NV_GET_USER_PAGES_REMOTE_HAS_LOCKED_ARG)
+-
++ #if defined (NV_GET_USER_PAGES_REMOTE_HAS_TSK_ARG)
+ return get_user_pages_remote(tsk, mm, start, nr_pages, flags,
+ pages, vmas, NULL);
++ #else
++ return get_user_pages_remote(mm, start, nr_pages, flags,
++ pages, vmas, NULL);
++ #endif
+
+ #else
+
+@@ -159,7 +163,7 @@ typedef int vm_fault_t;
+ #endif
+ #else
+ #if defined(NV_GET_USER_PAGES_HAS_WRITE_AND_FORCE_ARGS)
+- #define NV_GET_USER_PAGES_REMOTE NV_GET_USER_PAGES
++ #define NV_GET_USER_PAGES_REMOTE get_user_pages
+ #else
+ #include <linux/mm.h>
+ #include <linux/sched.h>
+diff --git a/kernel/conftest.sh b/kernel/conftest.sh
+index e900963..ef82dee 100755
+--- a/kernel/conftest.sh
++++ b/kernel/conftest.sh
+@@ -3043,6 +3043,7 @@ compile_test() {
+
+ if [ -f conftest$$.o ]; then
+ echo "#undef NV_GET_USER_PAGES_REMOTE_PRESENT" | append_conftest "functions"
++ echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_TSK_ARG" | append_conftest "functions"
+ echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_WRITE_AND_FORCE_ARGS" | append_conftest "functions"
+ echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_LOCKED_ARG" | append_conftest "functions"
+ rm -f conftest$$.o
+@@ -3070,14 +3071,20 @@ compile_test() {
+ rm -f conftest$$.c
+
+ if [ -f conftest$$.o ]; then
++ echo "#define NV_GET_USER_PAGES_REMOTE_HAS_TSK_ARG" | append_conftest "functions"
+ echo "#define NV_GET_USER_PAGES_REMOTE_HAS_WRITE_AND_FORCE_ARGS" | append_conftest "functions"
+ echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_LOCKED_ARG" | append_conftest "functions"
+ rm -f conftest$$.o
+ return
+ fi
+
++ echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_WRITE_AND_FORCE_ARGS" | append_conftest "functions"
++
++ #
+ # conftest #3: check if get_user_pages_remote() has locked argument
+-
++ # Return if these arguments are present. Fall through to conftest #4
++ # if these args are absent.
++ #
+ echo "$CONFTEST_PREAMBLE
+ #include <linux/mm.h>
+ long get_user_pages_remote(struct task_struct *tsk,
+@@ -3095,13 +3102,40 @@ compile_test() {
+ rm -f conftest$$.c
+
+ if [ -f conftest$$.o ]; then
++ echo "#define NV_GET_USER_PAGES_REMOTE_HAS_TSK_ARG" | append_conftest "functions"
++ echo "#define NV_GET_USER_PAGES_REMOTE_HAS_LOCKED_ARG" | append_conftest "functions"
++ rm -f conftest$$.o
++ return
++ fi
++
++ #
++ # conftest #4: check if get_user_pages_remote() does not take
++ # tsk argument.
++ #
++ echo "$CONFTEST_PREAMBLE
++ #include <linux/mm.h>
++ long get_user_pages_remote(struct mm_struct *mm,
++ unsigned long start,
++ unsigned long nr_pages,
++ unsigned int gup_flags,
++ struct page **pages,
++ struct vm_area_struct **vmas,
++ int *locked) {
++ return 0;
++ }" > conftest$$.c
++
++ $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
++ rm -f conftest$$.c
++
++ if [ -f conftest$$.o ]; then
++ echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_TSK_ARG" | append_conftest "functions"
+ echo "#define NV_GET_USER_PAGES_REMOTE_HAS_LOCKED_ARG" | append_conftest "functions"
+ rm -f conftest$$.o
+ else
++
++ echo "#define NV_GET_USER_PAGES_REMOTE_HAS_TSK_ARG" | append_conftest "functions"
+ echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_LOCKED_ARG" | append_conftest "functions"
+ fi
+- echo "#undef NV_GET_USER_PAGES_REMOTE_HAS_WRITE_AND_FORCE_ARGS" | append_conftest "functions"
+-
+ ;;
+
+ usleep_range)
+@@ -4131,6 +4165,115 @@ compile_test() {
+ compile_check_conftest "$CODE" "NV_PCI_DEV_HAS_SKIP_BUS_PM" "" "types"
+ ;;
+
++ drm_gem_object_put_unlocked)
++ #
++ # Determine if the function drm_gem_object_put_unlocked() is present.
++ #
++ # In v5.9-rc1, commit 2f4dd13d4bb8 ("drm/gem: add
++ # drm_gem_object_put helper") removes drm_gem_object_put_unlocked()
++ # function and replace its definition by transient macro. Commit
++ # ab15d56e27be ("drm: remove transient
++ # drm_gem_object_put_unlocked()") finally removes
++ # drm_gem_object_put_unlocked() macro.
++ #
++ CODE="
++ #if defined(NV_DRM_DRMP_H_PRESENT)
++ #include <drm/drmP.h>
++ #endif
++
++ #if defined(NV_DRM_DRM_GEM_H_PRESENT)
++ #include <drm/drm_gem.h>
++ #endif
++ void conftest_drm_gem_object_put_unlocked(void) {
++ drm_gem_object_put_unlocked();
++ }"
++
++ compile_check_conftest "$CODE" "NV_DRM_GEM_OBJECT_PUT_UNLOCK_PRESENT" "" "functions"
++ ;;
++
++ drm_display_mode_has_vrefresh)
++ #
++ # Determine if the 'drm_display_mode' structure has a 'vrefresh'
++ # field.
++ #
++ # Removed by commit 0425662fdf05 ("drm: Nuke mode->vrefresh") in
++ # v5.9-rc1.
++ #
++ CODE="
++ #include <drm/drm_modes.h>
++
++ int conftest_drm_display_mode_has_vrefresh(void) {
++ return offsetof(struct drm_display_mode, vrefresh);
++ }"
++
++ compile_check_conftest "$CODE" "NV_DRM_DISPLAY_MODE_HAS_VREFRESH" "types"
++
++ ;;
++
++ drm_driver_master_set_has_int_return_type)
++ #
++ # Determine if drm_driver::master_set() returns integer value
++ #
++ # Changed to void by commit 907f53200f98 ("drm: vmwgfx: remove
++ # drm_driver::master_set() return type") in v5.9-rc1.
++ #
++ CODE="
++ #if defined(NV_DRM_DRMP_H_PRESENT)
++ #include <drm/drmP.h>
++ #endif
++
++ #if defined(NV_DRM_DRM_DRV_H_PRESENT)
++ #include <drm/drm_drv.h>
++ #endif
++
++ int conftest_drm_driver_master_set_has_int_return_type(struct drm_driver *drv,
++ struct drm_device *dev, struct drm_file *file_priv, bool from_open) {
++
++ return drv->master_set(dev, file_priv, from_open);
++ }"
++
++ compile_check_conftest "$CODE" "NV_DRM_DRIVER_SET_MASTER_HAS_INT_RETURN_TYPE" "" "types"
++ ;;
++
++ drm_driver_has_gem_free_object)
++ #
++ # Determine if the 'drm_driver' structure has a 'gem_free_object'
++ # function pointer.
++ #
++ # drm_driver::gem_free_object is removed by commit 1a9458aeb8eb
++ # ("drm: remove drm_driver::gem_free_object") in v5.9-rc1.
++ #
++ CODE="
++ #if defined(NV_DRM_DRMP_H_PRESENT)
++ #include <drm/drmP.h>
++ #endif
++
++ #if defined(NV_DRM_DRM_DRV_H_PRESENT)
++ #include <drm/drm_drv.h>
++ #endif
++
++ int conftest_drm_driver_has_gem_free_object(void) {
++ return offsetof(struct drm_driver, gem_free_object);
++ }"
++
++ compile_check_conftest "$CODE" "NV_DRM_DRIVER_HAS_GEM_FREE_OBJECT" "" "types"
++ ;;
++
++ vga_tryget)
++ #
++ # Determine if vga_tryget() is present
++ #
++ # vga_tryget() was removed by commit f369bc3f9096 ("vgaarb: mark
++ # vga_tryget static") in v5.9-rc1 (2020-08-01).
++ #
++ CODE="
++ #include <linux/vgaarb.h>
++ void conftest_vga_tryget(void) {
++ vga_tryget();
++ }"
++
++ compile_check_conftest "$CODE" "NV_VGA_TRYGET_PRESENT" "" "functions"
++ ;;
+ esac
+ }
+
+diff --git a/kernel/nvidia-drm/nvidia-drm-drv.c b/kernel/nvidia-drm/nvidia-drm-drv.c
+index 17e377d..85d9798 100644
+--- a/kernel/nvidia-drm/nvidia-drm-drv.c
++++ b/kernel/nvidia-drm/nvidia-drm-drv.c
+@@ -466,8 +466,8 @@ static void nv_drm_unload(struct drm_device *dev)
+
+ #if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
+
+-static int nv_drm_master_set(struct drm_device *dev,
+- struct drm_file *file_priv, bool from_open)
++static int __nv_drm_master_set(struct drm_device *dev,
++ struct drm_file *file_priv, bool from_open)
+ {
+ struct nv_drm_device *nv_dev = to_nv_device(dev);
+
+@@ -478,6 +478,22 @@ static int nv_drm_master_set(struct drm_device *dev,
+ return 0;
+ }
+
++#include <linux/version.h>
++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)
++static int nv_drm_master_set(struct drm_device *dev,
++ struct drm_file *file_priv, bool from_open)
++{
++ return __nv_drm_master_set(dev, file_priv, from_open);
++}
++#else
++static void nv_drm_master_set(struct drm_device *dev,
++ struct drm_file *file_priv, bool from_open)
++{
++ WARN_ON(__nv_drm_master_set(dev, file_priv, from_open) != 0);
++}
++#endif
++
++
+ #if defined(NV_DRM_MASTER_DROP_HAS_FROM_RELEASE_ARG)
+ static
+ void nv_drm_master_drop(struct drm_device *dev,
+@@ -677,7 +693,9 @@ static struct drm_driver nv_drm_driver = {
+ #endif
+ DRIVER_GEM | DRIVER_RENDER,
+
++#if defined(NV_DRM_DRIVER_HAS_GEM_FREE_OBJECT)
+ .gem_free_object = nv_drm_gem_free,
++#endif
+
+ .ioctls = nv_drm_ioctls,
+ .num_ioctls = ARRAY_SIZE(nv_drm_ioctls),
+diff --git a/kernel/nvidia-drm/nvidia-drm-gem.h b/kernel/nvidia-drm/nvidia-drm-gem.h
+index 5691a7a..18c50ca 100644
+--- a/kernel/nvidia-drm/nvidia-drm-gem.h
++++ b/kernel/nvidia-drm/nvidia-drm-gem.h
+@@ -87,7 +87,13 @@ static inline void
+ nv_drm_gem_object_unreference_unlocked(struct nv_drm_gem_object *nv_gem)
+ {
+ #if defined(NV_DRM_GEM_OBJECT_GET_PRESENT)
++
++#if defined(NV_DRM_GEM_OBJECT_PUT_UNLOCK_PRESENT)
+ drm_gem_object_put_unlocked(&nv_gem->base);
++#else
++ drm_gem_object_put(&nv_gem->base);
++#endif
++
+ #else
+ drm_gem_object_unreference_unlocked(&nv_gem->base);
+ #endif
+diff --git a/kernel/nvidia-drm/nvidia-drm-utils.c b/kernel/nvidia-drm/nvidia-drm-utils.c
+index 8cb2d5e..e30b2b6 100644
+--- a/kernel/nvidia-drm/nvidia-drm-utils.c
++++ b/kernel/nvidia-drm/nvidia-drm-utils.c
+@@ -103,7 +103,9 @@ void
+ nvkms_display_mode_to_drm_mode(const struct NvKmsKapiDisplayMode *displayMode,
+ struct drm_display_mode *mode)
+ {
++#if defined(NV_DRM_DISPLAY_MODE_HAS_VREFRESH)
+ mode->vrefresh = (displayMode->timings.refreshRate + 500) / 1000; /* In Hz */
++#endif
+
+ mode->clock = (displayMode->timings.pixelClockHz + 500) / 1000; /* In Hz */
+
+@@ -189,7 +191,11 @@ bool drm_format_to_nvkms_format(u32 format,
+ void drm_mode_to_nvkms_display_mode(const struct drm_display_mode *src,
+ struct NvKmsKapiDisplayMode *dst)
+ {
++#if defined(NV_DRM_DISPLAY_MODE_HAS_VREFRESH)
+ dst->timings.refreshRate = src->vrefresh * 1000;
++#else
++ dst->timings.refreshRate = drm_mode_vrefresh(src) * 1000;
++#endif
+
+ dst->timings.pixelClockHz = src->clock * 1000; /* In Hz */
+
+diff --git a/kernel/nvidia-uvm/uvm8_tools.c b/kernel/nvidia-uvm/uvm8_tools.c
+index 86dbb77..63d0b64 100644
+--- a/kernel/nvidia-uvm/uvm8_tools.c
++++ b/kernel/nvidia-uvm/uvm8_tools.c
+@@ -190,7 +190,6 @@ static uvm_tools_event_tracker_t *tools_event_tracker(struct file *filp)
+ {
+ long event_tracker = atomic_long_read((atomic_long_t *)&filp->private_data);
+
+- smp_read_barrier_depends();
+ return (uvm_tools_event_tracker_t *)event_tracker;
+ }
+
+diff --git a/kernel/nvidia-uvm/uvm8_va_range.h b/kernel/nvidia-uvm/uvm8_va_range.h
+index 8cae357..6166cc8 100644
+--- a/kernel/nvidia-uvm/uvm8_va_range.h
++++ b/kernel/nvidia-uvm/uvm8_va_range.h
+@@ -717,7 +717,6 @@ static uvm_va_block_t *uvm_va_range_block(uvm_va_range_t *va_range, size_t index
+ // make sure that any initialization of this block by the creating thread is
+ // visible to later accesses in this thread, which requires a data
+ // dependency barrier.
+- smp_read_barrier_depends();
+ return block;
+ }
+
+diff --git a/kernel/nvidia/nv.c b/kernel/nvidia/nv.c
+index 15983f6..cfb2375 100644
+--- a/kernel/nvidia/nv.c
++++ b/kernel/nvidia/nv.c
+@@ -3872,7 +3872,9 @@ nvidia_probe
+
+ #if defined(CONFIG_VGA_ARB) && !defined(NVCPU_PPC64LE)
+ #if defined(VGA_DEFAULT_DEVICE)
++#if defined(NV_VGA_TRYGET_PRESENT)
+ vga_tryget(VGA_DEFAULT_DEVICE, VGA_RSRC_LEGACY_MASK);
++#endif
+ #endif
+ vga_set_legacy_decoding(dev, VGA_RSRC_NONE);
+ #endif