Last active
October 16, 2020 10:27
-
-
Save joanbm/7438afd6126cf216b47f866355ed71d3 to your computer and use it in GitHub Desktop.
NVIDIA 450.57/450.66 driver patch for Linux 5.9-rc1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Tentative patch for NVIDIA driver compatibility for Linux 5.9-rc1 | |
NOTE: This allows the module to build and mostly work, but the nvidia-uvm | |
module won't load due to the new patch from Christoph Hellwig that | |
prevents modules to simultaneously link to GPL and proprietary symbols | |
(torvalds/linux commit 0fd9cc6b0c72245375520ffc8d97ce5857b63b94) | |
It seems to be non-trivial to fix this issue "for real" (workarounds not included) | |
--- | |
diff --git a/common/inc/nv-mm.h b/common/inc/nv-mm.h | |
index b04ff67..fc9f67e 100644 | |
--- a/common/inc/nv-mm.h | |
+++ b/common/inc/nv-mm.h | |
@@ -23,6 +23,7 @@ | |
#ifndef __NV_MM_H__ | |
#define __NV_MM_H__ | |
+#include <linux/version.h> | |
#include "conftest.h" | |
#if !defined(NV_VM_FAULT_T_IS_PRESENT) | |
@@ -139,7 +140,16 @@ typedef int vm_fault_t; | |
if (force) | |
flags |= FOLL_FORCE; | |
- #if defined(NV_GET_USER_PAGES_REMOTE_HAS_LOCKED_ARG) | |
+/* torvalds/linux commit 64019a2e467a288a16b65ab55ddcbf58c1b00187 | |
+ "After the cleanup of page fault accounting, gup does not need to pass | |
+ task_struct around any more. Remove that parameter in the whole gup | |
+ stack." */ | |
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)) | |
+ | |
+ return get_user_pages_remote(mm, start, nr_pages, flags, | |
+ pages, vmas, NULL); | |
+ | |
+ #elif defined(NV_GET_USER_PAGES_REMOTE_HAS_LOCKED_ARG) | |
return get_user_pages_remote(tsk, mm, start, nr_pages, flags, | |
pages, vmas, NULL); | |
diff --git a/nvidia-drm/nvidia-drm-drv.c b/nvidia-drm/nvidia-drm-drv.c | |
index c6ba478..fd6333e 100644 | |
--- a/nvidia-drm/nvidia-drm-drv.c | |
+++ b/nvidia-drm/nvidia-drm-drv.c | |
@@ -20,6 +20,7 @@ | |
* DEALINGS IN THE SOFTWARE. | |
*/ | |
+#include <linux/version.h> | |
#include "nvidia-drm-conftest.h" /* NV_DRM_AVAILABLE and NV_DRM_DRM_GEM_H_PRESENT */ | |
#include "nvidia-drm-priv.h" | |
@@ -473,16 +474,36 @@ static void nv_drm_unload(struct drm_device *dev) | |
#if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE) | |
+/* torvalds/linux commit 907f53200f982cd377e75abbc1b18ed624d7ae66 | |
+ "The function always returns zero (success). Ideally we'll remove it all | |
+ together - although that's requires a little more work. | |
+ | |
+ For now, we can drop the return type and simplify the drm core code | |
+ surrounding it." */ | |
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) | |
static int nv_drm_master_set(struct drm_device *dev, | |
+#else | |
+static void nv_drm_master_set(struct drm_device *dev, | |
+#endif | |
struct drm_file *file_priv, bool from_open) | |
{ | |
struct nv_drm_device *nv_dev = to_nv_device(dev); | |
+/* torvalds/linux commit 907f53200f982cd377e75abbc1b18ed624d7ae66 | |
+ "The function always returns zero (success). Ideally we'll remove it all | |
+ together - although that's requires a little more work. | |
+ | |
+ For now, we can drop the return type and simplify the drm core code | |
+ surrounding it." */ | |
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) | |
if (!nvKms->grabOwnership(nv_dev->pDevice)) { | |
return -EINVAL; | |
} | |
return 0; | |
+#else | |
+ nvKms->grabOwnership(nv_dev->pDevice); | |
+#endif | |
} | |
#if defined(NV_DRM_MASTER_DROP_HAS_FROM_RELEASE_ARG) | |
@@ -719,7 +740,16 @@ static struct drm_driver nv_drm_driver = { | |
#endif | |
DRIVER_GEM | DRIVER_RENDER, | |
+/* torvalds/linux commit 0a19b068acc47d05212f03e494381926dc0381e2 | |
+ Should work since NVIDIA does not use struct_mutex? | |
+ "- More struct_mutex removal for !legacy drivers: | |
+ - Remove gem_free_object() | |
+ - Removal of drm_gem_object_put_unlocked()." */ | |
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) | |
.gem_free_object = nv_drm_gem_free, | |
+#else | |
+ .gem_free_object_unlocked = nv_drm_gem_free, | |
+#endif | |
.ioctls = nv_drm_ioctls, | |
.num_ioctls = ARRAY_SIZE(nv_drm_ioctls), | |
diff --git a/nvidia-drm/nvidia-drm-gem.c b/nvidia-drm/nvidia-drm-gem.c | |
index ad4bca4..e63d352 100644 | |
--- a/nvidia-drm/nvidia-drm-gem.c | |
+++ b/nvidia-drm/nvidia-drm-gem.c | |
@@ -20,6 +20,7 @@ | |
* DEALINGS IN THE SOFTWARE. | |
*/ | |
+#include <linux/version.h> | |
#include "nvidia-drm-conftest.h" | |
#if defined(NV_DRM_AVAILABLE) | |
@@ -46,10 +47,17 @@ | |
void nv_drm_gem_free(struct drm_gem_object *gem) | |
{ | |
- struct drm_device *dev = gem->dev; | |
struct nv_drm_gem_object *nv_gem = to_nv_gem_object(gem); | |
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) | |
+/* torvalds/linux commit 0a19b068acc47d05212f03e494381926dc0381e2 | |
+ Should work since NVIDIA does not use struct_mutex? | |
+ "- More struct_mutex removal for !legacy drivers: | |
+ - Remove gem_free_object() | |
+ - Removal of drm_gem_object_put_unlocked()." */ | |
+ struct drm_device *dev = gem->dev; | |
WARN_ON(!mutex_is_locked(&dev->struct_mutex)); | |
+#endif | |
/* Cleanup core gem object */ | |
diff --git a/nvidia-drm/nvidia-drm-gem.h b/nvidia-drm/nvidia-drm-gem.h | |
index 4e7ffd3..b5dd705 100644 | |
--- a/nvidia-drm/nvidia-drm-gem.h | |
+++ b/nvidia-drm/nvidia-drm-gem.h | |
@@ -23,6 +23,7 @@ | |
#ifndef __NVIDIA_DRM_GEM_H__ | |
#define __NVIDIA_DRM_GEM_H__ | |
+#include <linux/version.h> | |
#include "nvidia-drm-conftest.h" | |
#if defined(NV_DRM_AVAILABLE) | |
@@ -96,7 +97,16 @@ static inline void | |
nv_drm_gem_object_unreference_unlocked(struct nv_drm_gem_object *nv_gem) | |
{ | |
#if defined(NV_DRM_GEM_OBJECT_GET_PRESENT) | |
+/* torvalds/linux commit 0a19b068acc47d05212f03e494381926dc0381e2 | |
+ Should work since NVIDIA does not use struct_mutex? | |
+ "- More struct_mutex removal for !legacy drivers: | |
+ - Remove gem_free_object() | |
+ - Removal of drm_gem_object_put_unlocked()." */ | |
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) | |
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/nvidia-drm/nvidia-drm-utils.c b/nvidia-drm/nvidia-drm-utils.c | |
index da485c6..a5d7a2a 100644 | |
--- a/nvidia-drm/nvidia-drm-utils.c | |
+++ b/nvidia-drm/nvidia-drm-utils.c | |
@@ -20,6 +20,7 @@ | |
* DEALINGS IN THE SOFTWARE. | |
*/ | |
+#include <linux/version.h> | |
#include "nvidia-drm-conftest.h" /* NV_DRM_ATOMIC_MODESET_AVAILABLE */ | |
#if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE) | |
@@ -103,7 +104,13 @@ void | |
nvkms_display_mode_to_drm_mode(const struct NvKmsKapiDisplayMode *displayMode, | |
struct drm_display_mode *mode) | |
{ | |
+/* torvalds/linux commit 0425662fdf05665235e768e2fbcb4ced12432b43 | |
+ "Get rid of mode->vrefresh and just calculate it on demand. Saves | |
+ a bit of space and avoids the cached value getting out of sync | |
+ with reality." */ | |
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) | |
mode->vrefresh = (displayMode->timings.refreshRate + 500) / 1000; /* In Hz */ | |
+#endif | |
mode->clock = (displayMode->timings.pixelClockHz + 500) / 1000; /* In Hz */ | |
@@ -159,7 +166,15 @@ nvkms_display_mode_to_drm_mode(const struct NvKmsKapiDisplayMode *displayMode, | |
void drm_mode_to_nvkms_display_mode(const struct drm_display_mode *src, | |
struct NvKmsKapiDisplayMode *dst) | |
{ | |
+/* torvalds/linux commit 0425662fdf05665235e768e2fbcb4ced12432b43 | |
+ "Get rid of mode->vrefresh and just calculate it on demand. Saves | |
+ a bit of space and avoids the cached value getting out of sync | |
+ with reality." */ | |
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) | |
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/nvidia-uvm/uvm8_tools.c b/nvidia-uvm/uvm8_tools.c | |
index 620e1cc..1aee896 100644 | |
--- a/nvidia-uvm/uvm8_tools.c | |
+++ b/nvidia-uvm/uvm8_tools.c | |
@@ -20,6 +20,7 @@ | |
DEALINGS IN THE SOFTWARE. | |
*******************************************************************************/ | |
+#include <linux/version.h> | |
#include "uvm_common.h" | |
#include "uvm_ioctl.h" | |
#include "uvm8_gpu.h" | |
@@ -192,7 +193,15 @@ static uvm_tools_event_tracker_t *tools_event_tracker(struct file *filp) | |
{ | |
long event_tracker = atomic_long_read((atomic_long_t *)&filp->private_data); | |
+/* torvalds/linux commit 145ff1ec090dce9beb5a9590b5dc288e7bb2e65d | |
+ "Removal of the tremendously unpopular read_barrier_depends() | |
+ barrier, which is a NOP on all architectures apart from Alpha, in | |
+ favour of allowing architectures to override READ_ONCE() and do | |
+ whatever dance they need to do to ensure address dependencies | |
+ provide LOAD -> LOAD/STORE ordering." */ | |
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) | |
smp_read_barrier_depends(); | |
+#endif | |
return (uvm_tools_event_tracker_t *)event_tracker; | |
} | |
diff --git a/nvidia-uvm/uvm8_va_range.h b/nvidia-uvm/uvm8_va_range.h | |
index 69cb0a0..edc21cc 100644 | |
--- a/nvidia-uvm/uvm8_va_range.h | |
+++ b/nvidia-uvm/uvm8_va_range.h | |
@@ -24,6 +24,7 @@ | |
#ifndef __UVM8_VA_RANGE_H__ | |
#define __UVM8_VA_RANGE_H__ | |
+#include <linux/version.h> | |
#include "uvm_linux.h" | |
#include "nv-kref.h" | |
#include "uvm_common.h" | |
@@ -755,7 +756,15 @@ 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. | |
+/* torvalds/linux commit 145ff1ec090dce9beb5a9590b5dc288e7bb2e65d | |
+ "Removal of the tremendously unpopular read_barrier_depends() | |
+ barrier, which is a NOP on all architectures apart from Alpha, in | |
+ favour of allowing architectures to override READ_ONCE() and do | |
+ whatever dance they need to do to ensure address dependencies | |
+ provide LOAD -> LOAD/STORE ordering." */ | |
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) | |
smp_read_barrier_depends(); | |
+#endif | |
return block; | |
} | |
diff --git a/nvidia/nv-pci.c b/nvidia/nv-pci.c | |
index 9a8a715..1e08a7c 100644 | |
--- a/nvidia/nv-pci.c | |
+++ b/nvidia/nv-pci.c | |
@@ -8,6 +8,7 @@ | |
* _NVRM_COPYRIGHT_END_ | |
*/ | |
+#include <linux/version.h> | |
#include "nv-pci-table.h" | |
#include "nv-pci.h" | |
#include "nv-ibmnpu.h" | |
@@ -424,7 +425,15 @@ nv_pci_probe | |
#if defined(CONFIG_VGA_ARB) && !defined(NVCPU_PPC64LE) | |
#if defined(VGA_DEFAULT_DEVICE) | |
+/* torvalds/linux commit f369bc3f9096f5d355e8b80540bc30ac9a602912 | |
+ Does this make sense? What happened when vga_tryget failed (ret -EBUSY)? Should be interruptible? | |
+ "vgaarb: mark vga_tryget static | |
+ This symbols isn't used anywhere outside of vgaarb.c." */ | |
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) | |
vga_tryget(VGA_DEFAULT_DEVICE, VGA_RSRC_LEGACY_MASK); | |
+#else | |
+ vga_get(VGA_DEFAULT_DEVICE, VGA_RSRC_LEGACY_MASK, 0); | |
+#endif | |
#endif | |
vga_set_legacy_decoding(pci_dev, VGA_RSRC_NONE); | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
PS: This is obsolete since NVIDIA has released new drivers that work on 5.9 (except the nvidia-uvm problem, which remains).