]> git.pld-linux.org Git - packages/xorg-driver-video-nvidia-legacy-390xx.git/commitdiff
- kerel 6.5 build fixes from ubuntu, rel 5
authorJan Rękorajski <baggins@pld-linux.org>
Thu, 7 Sep 2023 12:47:00 +0000 (14:47 +0200)
committerJan Rękorajski <baggins@pld-linux.org>
Thu, 7 Sep 2023 12:47:00 +0000 (14:47 +0200)
kernel-6.5-garbage-collect-all-references-to-get_user.patch [new file with mode: 0644]
kernel-6.5-handle-get_user_pages-vmas-argument-remova.patch [new file with mode: 0644]
xorg-driver-video-nvidia-legacy-390xx.spec

diff --git a/kernel-6.5-garbage-collect-all-references-to-get_user.patch b/kernel-6.5-garbage-collect-all-references-to-get_user.patch
new file mode 100644 (file)
index 0000000..2d75121
--- /dev/null
@@ -0,0 +1,271 @@
+From 6fe0c6bd4b3bbac5cf868b927973255961b28ff4 Mon Sep 17 00:00:00 2001
+From: Paolo Pisati <paolo.pisati@canonical.com>
+Date: Tue, 18 Jul 2023 12:14:47 +0000
+Subject: [PATCH 1/2] Linux 6.5: garbage collect all references to
+ get_user_pages_remote()
+
+Upstream commit ca5e863233e8f6acd1792fd85d6bc2729a1b2c10 "mm/gup: remove
+vmas parameter from get_user_pages_remote()" changed the API: since we
+reference get_user_pages_remote() (but don't use it anywhere), garbage
+collect all reference.
+
+Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
+---
+ common/inc/nv-mm.h |  99 -------------
+ conftest.sh        | 130 ------------------
+ 2 files changed, 229 deletions(-)
+
+diff --git a/kernel/common/inc/nv-mm.h b/kernel/common/inc/nv-mm.h
+index aec55b0b..51d0df4a 100644
+--- a/kernel/common/inc/nv-mm.h
++++ b/kernel/common/inc/nv-mm.h
+@@ -98,105 +98,6 @@ typedef int vm_fault_t;
+     #endif
+ #endif
+-/*
+- * get_user_pages_remote() was added by commit 1e9877902dc7
+- * ("mm/gup: Introduce get_user_pages_remote()") in v4.6 (2016-02-12).
+- *
+- * The very next commit cde70140fed8 ("mm/gup: Overload get_user_pages()
+- * functions") deprecated the 8-argument version of get_user_pages for the
+- * non-remote case (calling get_user_pages with current and current->mm).
+- *
+- * The guidelines are: call NV_GET_USER_PAGES_REMOTE if you need the 8-argument
+- * version that uses something other than current and current->mm. Use
+- * NV_GET_USER_PAGES if you are refering to current and current->mm.
+- *
+- * Note that get_user_pages_remote() requires the caller to hold a reference on
+- * the task_struct (if non-NULL and if this API has tsk argument) and the mm_struct.
+- * This will always be true when using current and current->mm. If the kernel passes
+- * the driver a vma via driver callback, the kernel holds a reference on vma->vm_mm
+- * over that callback.
+- *
+- * get_user_pages_remote() write/force parameters were replaced
+- * with gup_flags by commit 9beae1ea8930 ("mm: replace get_user_pages_remote()
+- * write/force parameters with gup_flags") in v4.9 (2016-10-13).
+- *
+- * get_user_pages_remote() added 'locked' parameter by commit 5b56d49fc31d
+- * ("mm: add locked parameter to get_user_pages_remote()") in
+- * v4.10 (2016-12-14).
+- *
+- * get_user_pages_remote() removed 'tsk' parameter by
+- * commit 64019a2e467a ("mm/gup: remove task_struct pointer for
+- * all gup code") in v5.9-rc1 (2020-08-11).
+- *
+- */
+-
+-#if defined(NV_GET_USER_PAGES_REMOTE_PRESENT)
+-    #if defined(NV_GET_USER_PAGES_REMOTE_HAS_WRITE_AND_FORCE_ARGS)
+-        #define NV_GET_USER_PAGES_REMOTE    get_user_pages_remote
+-    #else
+-        static inline long NV_GET_USER_PAGES_REMOTE(struct task_struct *tsk,
+-                                                    struct mm_struct *mm,
+-                                                    unsigned long start,
+-                                                    unsigned long nr_pages,
+-                                                    int write,
+-                                                    int force,
+-                                                    struct page **pages,
+-                                                    struct vm_area_struct **vmas)
+-        {
+-            unsigned int flags = 0;
+-
+-            if (write)
+-                flags |= FOLL_WRITE;
+-            if (force)
+-                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
+-
+-               return get_user_pages_remote(tsk, mm, start, nr_pages, flags,
+-                                            pages, vmas);
+-
+-        #endif
+-
+-        }
+-    #endif
+-#else
+-    #if defined(NV_GET_USER_PAGES_HAS_WRITE_AND_FORCE_ARGS)
+-        #define NV_GET_USER_PAGES_REMOTE    NV_GET_USER_PAGES
+-    #else
+-        #include <linux/mm.h>
+-        #include <linux/sched.h>
+-
+-        static inline long NV_GET_USER_PAGES_REMOTE(struct task_struct *tsk,
+-                                                    struct mm_struct *mm,
+-                                                    unsigned long start,
+-                                                    unsigned long nr_pages,
+-                                                    int write,
+-                                                    int force,
+-                                                    struct page **pages,
+-                                                    struct vm_area_struct **vmas)
+-        {
+-            unsigned int flags = 0;
+-
+-            if (write)
+-                flags |= FOLL_WRITE;
+-            if (force)
+-                flags |= FOLL_FORCE;
+-
+-            return get_user_pages(tsk, mm, start, nr_pages, flags, pages, vmas);
+-        }
+-    #endif
+-#endif
+-
+-
+ /*
+  * The .virtual_address field was effectively renamed to .address, by these
+  * two commits:
+diff --git a/kernel/conftest.sh b/kernel/conftest.sh
+index 24daa850..abe435ff 100755
+--- a/kernel/conftest.sh
++++ b/kernel/conftest.sh
+@@ -3081,136 +3081,6 @@ compile_test() {
+             return
+         ;;
+-        get_user_pages_remote)
+-            #
+-            # Determine if the function get_user_pages_remote() is
+-            # present and has write/force/locked/tsk parameters.
+-            #
+-            # get_user_pages_remote() was added by:
+-            #   2016 Feb 12: 1e9877902dc7e11d2be038371c6fbf2dfcd469d7
+-            #
+-            # get_user_pages[_remote]() write/force parameters
+-            # replaced with gup_flags:
+-            #   2016 Oct 12: 768ae309a96103ed02eb1e111e838c87854d8b51
+-            #   2016 Oct 12: 9beae1ea89305a9667ceaab6d0bf46a045ad71e7
+-            #
+-            # get_user_pages_remote() added 'locked' parameter
+-            #   2016 Dec 14:5b56d49fc31dbb0487e14ead790fc81ca9fb2c99
+-            #
+-            # get_user_pages_remote() removed 'tsk' parameter by
+-            # commit 64019a2e467a ("mm/gup: remove task_struct pointer for
+-            # all gup code") in v5.9-rc1 (2020-08-11).
+-            #
+-            # conftest #1: check if get_user_pages_remote() is available
+-            # return if not available.
+-            # Fall through to conftest #2 if it is present
+-
+-            echo "$CONFTEST_PREAMBLE
+-            #include <linux/mm.h>
+-            void conftest_get_user_pages_remote(void) {
+-                get_user_pages_remote();
+-            }" > 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_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
+-                return
+-            fi
+-
+-            # conftest #2: check if get_user_pages_remote() has write and
+-            # force arguments. Return if these arguments are present
+-            # Fall through to conftest #3 if these args are absent.
+-            echo "#define NV_GET_USER_PAGES_REMOTE_PRESENT" | append_conftest "functions"
+-            echo "$CONFTEST_PREAMBLE
+-            #include <linux/mm.h>
+-            long get_user_pages_remote(struct task_struct *tsk,
+-                                       struct mm_struct *mm,
+-                                       unsigned long start,
+-                                       unsigned long nr_pages,
+-                                       int write,
+-                                       int force,
+-                                       struct page **pages,
+-                                       struct vm_area_struct **vmas) {
+-                return 0;
+-            }" > conftest$$.c
+-
+-            $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
+-            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,
+-                                       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 "#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
+-        ;;
+-
+         usleep_range)
+             #
+             # Determine if the function usleep_range() is present.
+-- 
+2.40.1
+
diff --git a/kernel-6.5-handle-get_user_pages-vmas-argument-remova.patch b/kernel-6.5-handle-get_user_pages-vmas-argument-remova.patch
new file mode 100644 (file)
index 0000000..9e997d8
--- /dev/null
@@ -0,0 +1,218 @@
+From a8b9fa3504163bfe29fc9faa2aac201ace66e4da Mon Sep 17 00:00:00 2001
+From: Paolo Pisati <paolo.pisati@canonical.com>
+Date: Thu, 13 Jul 2023 13:35:33 +0000
+Subject: [PATCH 2/2] Linux 6.5: handle get_user_pages() vmas argument removal
+
+commit b2cac248191b7466c5819e0da617b0705a26e197 "mm/gup: removed vmas
+array from internal GUP functions" removed vmas arg from
+__get_user_pages_locked()[*], and to handle that we do two things:
+
+1) when caller vmas arg was NULL, blindly substitute the call with the new API.
+
+2) when caller vmas was a real array (and the caller expected it to be
+   populated upon return), reimplement the internal "for(;;) vma = vma_find(); vmas[i] = vma;"
+   loop that was partially removed.
+
+*: get_user_pages() is a wrapper around __get_user_pages_locked()
+
+Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
+---
+ common/inc/nv-mm.h | 56 +++++++++++++------
+ conftest.sh        | 26 ++++++++-
+ nvidia-drm/nvidia-drm-linux.c             |  5 ++
+ nvidia-uvm/uvm8_tools.c    | 24 ++++++++
+ nvidia/kernel/os-mlock.c  |  5 ++
+ 5 files changed, 97 insertions(+), 19 deletions(-)
+
+diff --git a/kernel/common/inc/nv-mm.h b/kernel/common/inc/nv-mm.h
+index 51d0df4a..86bf6036 100644
+--- a/kernel/common/inc/nv-mm.h
++++ b/kernel/common/inc/nv-mm.h
+@@ -77,24 +77,44 @@ typedef int vm_fault_t;
+     #if defined(NV_GET_USER_PAGES_HAS_WRITE_AND_FORCE_ARGS)
+         #define NV_GET_USER_PAGES get_user_pages
+     #else
+-        #include <linux/mm.h>
+-
+-        static inline long NV_GET_USER_PAGES(unsigned long start,
+-                                             unsigned long nr_pages,
+-                                             int write,
+-                                             int force,
+-                                             struct page **pages,
+-                                             struct vm_area_struct **vmas)
+-        {
+-            unsigned int flags = 0;
+-
+-            if (write)
+-                flags |= FOLL_WRITE;
+-            if (force)
+-                flags |= FOLL_FORCE;
+-
+-            return get_user_pages(start, nr_pages, flags, pages, vmas);
+-        }
++      #if defined(NV_GET_USER_PAGES_DROPPED_VMA)
++            #include <linux/mm.h>
++
++            static inline long NV_GET_USER_PAGES(unsigned long start,
++                                                 unsigned long nr_pages,
++                                                 int write,
++                                                 int force,
++                                                 struct page **pages)
++            {
++                unsigned int flags = 0;
++
++                if (write)
++                    flags |= FOLL_WRITE;
++                if (force)
++                    flags |= FOLL_FORCE;
++
++                return get_user_pages(start, nr_pages, flags, pages);
++            }
++      #else
++            #include <linux/mm.h>
++
++            static inline long NV_GET_USER_PAGES(unsigned long start,
++                                                 unsigned long nr_pages,
++                                                 int write,
++                                                 int force,
++                                                 struct page **pages,
++                                                 struct vm_area_struct **vmas)
++            {
++                unsigned int flags = 0;
++
++                if (write)
++                    flags |= FOLL_WRITE;
++                if (force)
++                    flags |= FOLL_FORCE;
++
++                return get_user_pages(start, nr_pages, flags, pages, vmas);
++            }
++      #endif
+     #endif
+ #endif
+diff --git a/kernel/conftest.sh b/kernel/conftest.sh
+index abe435ff..0131fab5 100755
+--- a/kernel/conftest.sh
++++ b/kernel/conftest.sh
+@@ -3051,7 +3051,6 @@ compile_test() {
+             # write and force parameters AND that gup has task_struct and
+             # mm_struct as its first arguments.
+             # Return if available.
+-            # Fall through to default case if absent.
+             echo "$CONFTEST_PREAMBLE
+             #include <linux/mm.h>
+@@ -3075,6 +3074,31 @@ compile_test() {
+                 return
+             fi
++            # Conftest #4: check if vma arg was dropped
++            # Return if available.
++            # Fall through to default case if absent.
++
++            echo "$CONFTEST_PREAMBLE
++            #include <linux/mm.h>
++            long get_user_pages(unsigned long start,
++                                unsigned long nr_pages,
++                                unsigned int gup_flags,
++                                struct page **pages) {
++                return 0;
++            }" > conftest$$.c
++
++            $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
++            rm -f conftest$$.c
++
++            if [ -f conftest$$.o ]; then
++                echo "#define NV_GET_USER_PAGES_DROPPED_VMA" | append_conftest "functions"
++                echo "#undef NV_GET_USER_PAGES_HAS_WRITE_AND_FORCE_ARGS" | append_conftest "functions"
++                echo "#undef NV_GET_USER_PAGES_HAS_TASK_STRUCT" | append_conftest "functions"
++                 rm -f conftest$$.o
++                return
++            fi
++
++
+             echo "#define NV_GET_USER_PAGES_HAS_WRITE_AND_FORCE_ARGS" | append_conftest "functions"
+             echo "#define NV_GET_USER_PAGES_HAS_TASK_STRUCT" | append_conftest "functions"
+diff --git a/kernel/nvidia-drm/nvidia-drm-linux.c b/kernel/nvidia-drm/nvidia-drm-linux.c
+index be405f29..dd4a2a6d 100644
+--- a/kernel/nvidia-drm/nvidia-drm-linux.c
++++ b/kernel/nvidia-drm/nvidia-drm-linux.c
+@@ -115,8 +115,13 @@ int nv_drm_lock_user_pages(unsigned long address,
+     nv_mmap_read_lock(mm);
++#if defined(NV_GET_USER_PAGES_DROPPED_VMA)
++    pages_pinned = NV_GET_USER_PAGES(address, pages_count, write, force,
++                                   user_pages);
++#else
+     pages_pinned = NV_GET_USER_PAGES(address, pages_count, write, force,
+                                      user_pages, NULL);
++#endif
+     nv_mmap_read_unlock(mm);
+     if (pages_pinned < 0 || (unsigned)pages_pinned < pages_count) {
+diff --git a/kernel/nvidia-uvm/uvm8_tools.c b/kernel/nvidia-uvm/uvm8_tools.c
+index 1dc7c97d..ea521945 100644
+--- a/kernel/nvidia-uvm/uvm8_tools.c
++++ b/kernel/nvidia-uvm/uvm8_tools.c
+@@ -251,13 +251,37 @@ static NV_STATUS map_user_pages(NvU64 user_va, NvU64 size, void **addr, struct p
+     }
+     nv_mmap_read_lock(current->mm);
++#if defined(NV_GET_USER_PAGES_DROPPED_VMA)
++    ret = NV_GET_USER_PAGES(user_va, num_pages, 1, 0, *pages);
++#else
+     ret = NV_GET_USER_PAGES(user_va, num_pages, 1, 0, *pages, vmas);
++#endif
+     nv_mmap_read_unlock(current->mm);
+     if (ret != num_pages) {
+         status = NV_ERR_INVALID_ARGUMENT;
+         goto fail;
+     }
++#if defined(NV_GET_USER_PAGES_DROPPED_VMA)
++    struct vm_area_struct *vma;
++    unsigned long start;
++
++    nv_mmap_read_lock(current->mm);
++    start = user_va;
++    for (i = 0; i < num_pages; i++) {
++        vma = find_vma(current->mm, start);
++        if (!vma) {
++          nv_mmap_read_unlock(current->mm);
++          status = NV_ERR_INVALID_ARGUMENT;
++          goto fail;
++      }
++
++        vmas[i] = vma;
++        start = (start + PAGE_SIZE) & PAGE_MASK;
++    }
++    nv_mmap_read_unlock(current->mm);
++#endif
++
+     for (i = 0; i < num_pages; i++) {
+         if (page_count((*pages)[i]) > MAX_PAGE_COUNT || uvm_file_is_nvidia_uvm(vmas[i]->vm_file)) {
+             status = NV_ERR_INVALID_ARGUMENT;
+diff --git a/kernel/nvidia/os-mlock.c b/kernel/nvidia/os-mlock.c
+index f88daed4..ad5cb9a1 100644
+--- a/kernel/nvidia/os-mlock.c
++++ b/kernel/nvidia/kernel/os-mlock.c
+@@ -127,8 +127,13 @@ NV_STATUS NV_API_CALL os_lock_user_pages(
+     }
+     nv_mmap_read_lock(mm);
++#if defined(NV_GET_USER_PAGES_DROPPED_VMA)
++    ret = NV_GET_USER_PAGES((unsigned long)address,
++                            page_count, write, force, user_pages);
++#else
+     ret = NV_GET_USER_PAGES((unsigned long)address,
+                             page_count, write, force, user_pages, NULL);
++#endif
+     nv_mmap_read_unlock(mm);
+     pinned = ret;
+-- 
+2.40.1
+
index 916f16eca5a6e4f4202b254a7ecff466deb47ba3..44e506bf50dec7d319b0e42778ad18a5320edbcb 100644 (file)
@@ -29,7 +29,7 @@ exit 1
 
 %define                no_install_post_check_so 1
 
-%define                rel     4
+%define                rel     5
 %define                pname   xorg-driver-video-nvidia-legacy-390xx
 Summary:       Linux Drivers for nVidia GeForce/Quadro Chips
 Summary(hu.UTF-8):     Linux meghajtók nVidia GeForce/Quadro chipekhez
@@ -55,6 +55,8 @@ Patch2:               kenrel-6.2.patch
 Patch3:                kernel-6.3.patch
 Patch4:                kernel-6.3-uvm.patch
 Patch5:                kernel-6.4.patch
+Patch6:                kernel-6.5-garbage-collect-all-references-to-get_user.patch
+Patch7:                kernel-6.5-handle-get_user_pages-vmas-argument-remova.patch
 URL:           https://www.nvidia.com/en-us/drivers/unix/
 BuildRequires: rpm-build >= 4.6
 BuildRequires: rpmbuild(macros) >= 1.752
@@ -321,6 +323,8 @@ rm -rf NVIDIA-Linux-x86*-%{version}*
 %patch4 -p1
 %endif
 %patch5 -p1
+%patch6 -p1
+%patch7 -p1
 echo 'EXTRA_CFLAGS += -Wno-pointer-arith -Wno-sign-compare -Wno-unused' >> kernel/Makefile.kbuild
 
 %build
This page took 0.087408 seconds and 4 git commands to generate.