367 lines
16 KiB
Diff
367 lines
16 KiB
Diff
diff --ignore-space-change --unified --recursive --no-dereference a/common/inc/nv-mm.h b/common/inc/nv-mm.h
|
|
--- a/common/inc/nv-mm.h 2022-10-12 06:30:26.000000000 -0300
|
|
+++ b/common/inc/nv-mm.h 2023-09-02 15:39:35.376520074 -0300
|
|
@@ -77,71 +77,14 @@
|
|
#if defined(NV_GET_USER_PAGES_HAS_WRITE_AND_FORCE_ARGS)
|
|
#define NV_GET_USER_PAGES get_user_pages
|
|
#else
|
|
+ #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,
|
|
- 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
|
|
-
|
|
-/*
|
|
- * 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)
|
|
+ struct page **pages)
|
|
{
|
|
unsigned int flags = 0;
|
|
|
|
@@ -150,34 +93,12 @@
|
|
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
|
|
-
|
|
+ return get_user_pages(start, nr_pages, flags, pages);
|
|
}
|
|
- #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,
|
|
+ static inline long NV_GET_USER_PAGES(unsigned long start,
|
|
unsigned long nr_pages,
|
|
int write,
|
|
int force,
|
|
@@ -191,12 +112,12 @@
|
|
if (force)
|
|
flags |= FOLL_FORCE;
|
|
|
|
- return get_user_pages(tsk, mm, start, nr_pages, flags, pages, vmas);
|
|
+ return get_user_pages(start, nr_pages, flags, pages, vmas);
|
|
}
|
|
#endif
|
|
+ #endif
|
|
#endif
|
|
|
|
-
|
|
/*
|
|
* The .virtual_address field was effectively renamed to .address, by these
|
|
* two commits:
|
|
diff --ignore-space-change --unified --recursive --no-dereference a/conftest.sh b/conftest.sh
|
|
--- a/conftest.sh 2022-10-11 13:00:50.000000000 -0300
|
|
+++ b/conftest.sh 2023-09-02 15:40:49.460261403 -0300
|
|
@@ -3051,7 +3051,6 @@
|
|
# 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,99 +3074,16 @@
|
|
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"
|
|
-
|
|
- 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 #4: check if vma arg was dropped
|
|
+ # Return if available.
|
|
+ # Fall through to default case if absent.
|
|
|
|
- #
|
|
- # 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,
|
|
+ long get_user_pages(unsigned long start,
|
|
unsigned long nr_pages,
|
|
unsigned int gup_flags,
|
|
- struct page **pages,
|
|
- struct vm_area_struct **vmas,
|
|
- int *locked) {
|
|
+ struct page **pages) {
|
|
return 0;
|
|
}" > conftest$$.c
|
|
|
|
@@ -3175,40 +3091,17 @@
|
|
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"
|
|
+ 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
|
|
|
|
- #
|
|
- # 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_HAS_WRITE_AND_FORCE_ARGS" | append_conftest "functions"
|
|
+ echo "#define NV_GET_USER_PAGES_HAS_TASK_STRUCT" | append_conftest "functions"
|
|
|
|
- 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
|
|
+ return
|
|
;;
|
|
|
|
usleep_range)
|
|
diff --ignore-space-change --unified --recursive --no-dereference a/nvidia/os-mlock.c b/nvidia/os-mlock.c
|
|
--- a/nvidia/os-mlock.c 2022-10-12 06:30:26.000000000 -0300
|
|
+++ b/nvidia/os-mlock.c 2023-09-02 15:46:43.108702285 -0300
|
|
@@ -127,8 +127,13 @@
|
|
}
|
|
|
|
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;
|
|
|
|
diff --ignore-space-change --unified --recursive --no-dereference a/nvidia-drm/nvidia-drm-linux.c b/nvidia-drm/nvidia-drm-linux.c
|
|
--- a/nvidia-drm/nvidia-drm-linux.c 2022-10-12 06:30:31.000000000 -0300
|
|
+++ b/nvidia-drm/nvidia-drm-linux.c 2023-09-02 15:44:37.601432752 -0300
|
|
@@ -114,9 +114,13 @@
|
|
}
|
|
|
|
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 --ignore-space-change --unified --recursive --no-dereference a/nvidia-uvm/uvm8_tools.c b/nvidia-uvm/uvm8_tools.c
|
|
--- a/nvidia-uvm/uvm8_tools.c 2022-10-12 06:30:28.000000000 -0300
|
|
+++ b/nvidia-uvm/uvm8_tools.c 2023-09-02 15:45:13.038272134 -0300
|
|
@@ -251,13 +251,35 @@
|
|
}
|
|
|
|
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;
|