]> git.pld-linux.org Git - packages/xorg-driver-video-nvidia-legacy-390xx.git/blob - kernel-6.5-handle-get_user_pages-vmas-argument-remova.patch
- kerel 6.5 build fixes from ubuntu, rel 5
[packages/xorg-driver-video-nvidia-legacy-390xx.git] / kernel-6.5-handle-get_user_pages-vmas-argument-remova.patch
1 From a8b9fa3504163bfe29fc9faa2aac201ace66e4da Mon Sep 17 00:00:00 2001
2 From: Paolo Pisati <paolo.pisati@canonical.com>
3 Date: Thu, 13 Jul 2023 13:35:33 +0000
4 Subject: [PATCH 2/2] Linux 6.5: handle get_user_pages() vmas argument removal
5
6 commit b2cac248191b7466c5819e0da617b0705a26e197 "mm/gup: removed vmas
7 array from internal GUP functions" removed vmas arg from
8 __get_user_pages_locked()[*], and to handle that we do two things:
9
10 1) when caller vmas arg was NULL, blindly substitute the call with the new API.
11
12 2) when caller vmas was a real array (and the caller expected it to be
13    populated upon return), reimplement the internal "for(;;) vma = vma_find(); vmas[i] = vma;"
14    loop that was partially removed.
15
16 *: get_user_pages() is a wrapper around __get_user_pages_locked()
17
18 Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
19 ---
20  common/inc/nv-mm.h | 56 +++++++++++++------
21  conftest.sh        | 26 ++++++++-
22  nvidia-drm/nvidia-drm-linux.c             |  5 ++
23  nvidia-uvm/uvm8_tools.c    | 24 ++++++++
24  nvidia/kernel/os-mlock.c  |  5 ++
25  5 files changed, 97 insertions(+), 19 deletions(-)
26
27 diff --git a/kernel/common/inc/nv-mm.h b/kernel/common/inc/nv-mm.h
28 index 51d0df4a..86bf6036 100644
29 --- a/kernel/common/inc/nv-mm.h
30 +++ b/kernel/common/inc/nv-mm.h
31 @@ -77,24 +77,44 @@ typedef int vm_fault_t;
32      #if defined(NV_GET_USER_PAGES_HAS_WRITE_AND_FORCE_ARGS)
33          #define NV_GET_USER_PAGES get_user_pages
34      #else
35 -        #include <linux/mm.h>
36 -
37 -        static inline long NV_GET_USER_PAGES(unsigned long start,
38 -                                             unsigned long nr_pages,
39 -                                             int write,
40 -                                             int force,
41 -                                             struct page **pages,
42 -                                             struct vm_area_struct **vmas)
43 -        {
44 -            unsigned int flags = 0;
45 -
46 -            if (write)
47 -                flags |= FOLL_WRITE;
48 -            if (force)
49 -                flags |= FOLL_FORCE;
50 -
51 -            return get_user_pages(start, nr_pages, flags, pages, vmas);
52 -        }
53 +       #if defined(NV_GET_USER_PAGES_DROPPED_VMA)
54 +            #include <linux/mm.h>
55 +
56 +            static inline long NV_GET_USER_PAGES(unsigned long start,
57 +                                                 unsigned long nr_pages,
58 +                                                 int write,
59 +                                                 int force,
60 +                                                 struct page **pages)
61 +            {
62 +                unsigned int flags = 0;
63 +
64 +                if (write)
65 +                    flags |= FOLL_WRITE;
66 +                if (force)
67 +                    flags |= FOLL_FORCE;
68 +
69 +                return get_user_pages(start, nr_pages, flags, pages);
70 +            }
71 +       #else
72 +            #include <linux/mm.h>
73 +
74 +            static inline long NV_GET_USER_PAGES(unsigned long start,
75 +                                                 unsigned long nr_pages,
76 +                                                 int write,
77 +                                                 int force,
78 +                                                 struct page **pages,
79 +                                                 struct vm_area_struct **vmas)
80 +            {
81 +                unsigned int flags = 0;
82 +
83 +                if (write)
84 +                    flags |= FOLL_WRITE;
85 +                if (force)
86 +                    flags |= FOLL_FORCE;
87 +
88 +                return get_user_pages(start, nr_pages, flags, pages, vmas);
89 +            }
90 +       #endif
91      #endif
92  #endif
93  
94 diff --git a/kernel/conftest.sh b/kernel/conftest.sh
95 index abe435ff..0131fab5 100755
96 --- a/kernel/conftest.sh
97 +++ b/kernel/conftest.sh
98 @@ -3051,7 +3051,6 @@ compile_test() {
99              # write and force parameters AND that gup has task_struct and
100              # mm_struct as its first arguments.
101              # Return if available.
102 -            # Fall through to default case if absent.
103  
104              echo "$CONFTEST_PREAMBLE
105              #include <linux/mm.h>
106 @@ -3075,6 +3074,31 @@ compile_test() {
107                  return
108              fi
109  
110 +            # Conftest #4: check if vma arg was dropped
111 +            # Return if available.
112 +            # Fall through to default case if absent.
113 +
114 +            echo "$CONFTEST_PREAMBLE
115 +            #include <linux/mm.h>
116 +            long get_user_pages(unsigned long start,
117 +                                unsigned long nr_pages,
118 +                                unsigned int gup_flags,
119 +                                struct page **pages) {
120 +                return 0;
121 +            }" > conftest$$.c
122 +
123 +            $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
124 +            rm -f conftest$$.c
125 +
126 +            if [ -f conftest$$.o ]; then
127 +                echo "#define NV_GET_USER_PAGES_DROPPED_VMA" | append_conftest "functions"
128 +                echo "#undef NV_GET_USER_PAGES_HAS_WRITE_AND_FORCE_ARGS" | append_conftest "functions"
129 +                echo "#undef NV_GET_USER_PAGES_HAS_TASK_STRUCT" | append_conftest "functions"
130 +                 rm -f conftest$$.o
131 +                return
132 +            fi
133 +
134 +
135              echo "#define NV_GET_USER_PAGES_HAS_WRITE_AND_FORCE_ARGS" | append_conftest "functions"
136              echo "#define NV_GET_USER_PAGES_HAS_TASK_STRUCT" | append_conftest "functions"
137  
138 diff --git a/kernel/nvidia-drm/nvidia-drm-linux.c b/kernel/nvidia-drm/nvidia-drm-linux.c
139 index be405f29..dd4a2a6d 100644
140 --- a/kernel/nvidia-drm/nvidia-drm-linux.c
141 +++ b/kernel/nvidia-drm/nvidia-drm-linux.c
142 @@ -115,8 +115,13 @@ int nv_drm_lock_user_pages(unsigned long address,
143  
144      nv_mmap_read_lock(mm);
145  
146 +#if defined(NV_GET_USER_PAGES_DROPPED_VMA)
147 +    pages_pinned = NV_GET_USER_PAGES(address, pages_count, write, force,
148 +                                    user_pages);
149 +#else
150      pages_pinned = NV_GET_USER_PAGES(address, pages_count, write, force,
151                                       user_pages, NULL);
152 +#endif
153      nv_mmap_read_unlock(mm);
154  
155      if (pages_pinned < 0 || (unsigned)pages_pinned < pages_count) {
156 diff --git a/kernel/nvidia-uvm/uvm8_tools.c b/kernel/nvidia-uvm/uvm8_tools.c
157 index 1dc7c97d..ea521945 100644
158 --- a/kernel/nvidia-uvm/uvm8_tools.c
159 +++ b/kernel/nvidia-uvm/uvm8_tools.c
160 @@ -251,13 +251,37 @@ static NV_STATUS map_user_pages(NvU64 user_va, NvU64 size, void **addr, struct p
161      }
162  
163      nv_mmap_read_lock(current->mm);
164 +#if defined(NV_GET_USER_PAGES_DROPPED_VMA)
165 +    ret = NV_GET_USER_PAGES(user_va, num_pages, 1, 0, *pages);
166 +#else
167      ret = NV_GET_USER_PAGES(user_va, num_pages, 1, 0, *pages, vmas);
168 +#endif
169      nv_mmap_read_unlock(current->mm);
170      if (ret != num_pages) {
171          status = NV_ERR_INVALID_ARGUMENT;
172          goto fail;
173      }
174  
175 +#if defined(NV_GET_USER_PAGES_DROPPED_VMA)
176 +    struct vm_area_struct *vma;
177 +    unsigned long start;
178 +
179 +    nv_mmap_read_lock(current->mm);
180 +    start = user_va;
181 +    for (i = 0; i < num_pages; i++) {
182 +        vma = find_vma(current->mm, start);
183 +        if (!vma) {
184 +           nv_mmap_read_unlock(current->mm);
185 +           status = NV_ERR_INVALID_ARGUMENT;
186 +           goto fail;
187 +       }
188 +
189 +        vmas[i] = vma;
190 +        start = (start + PAGE_SIZE) & PAGE_MASK;
191 +    }
192 +    nv_mmap_read_unlock(current->mm);
193 +#endif
194 +
195      for (i = 0; i < num_pages; i++) {
196          if (page_count((*pages)[i]) > MAX_PAGE_COUNT || uvm_file_is_nvidia_uvm(vmas[i]->vm_file)) {
197              status = NV_ERR_INVALID_ARGUMENT;
198 diff --git a/kernel/nvidia/os-mlock.c b/kernel/nvidia/os-mlock.c
199 index f88daed4..ad5cb9a1 100644
200 --- a/kernel/nvidia/os-mlock.c
201 +++ b/kernel/nvidia/kernel/os-mlock.c
202 @@ -127,8 +127,13 @@ NV_STATUS NV_API_CALL os_lock_user_pages(
203      }
204  
205      nv_mmap_read_lock(mm);
206 +#if defined(NV_GET_USER_PAGES_DROPPED_VMA)
207 +    ret = NV_GET_USER_PAGES((unsigned long)address,
208 +                            page_count, write, force, user_pages);
209 +#else
210      ret = NV_GET_USER_PAGES((unsigned long)address,
211                              page_count, write, force, user_pages, NULL);
212 +#endif
213      nv_mmap_read_unlock(mm);
214      pinned = ret;
215  
216 -- 
217 2.40.1
218
This page took 0.075255 seconds and 4 git commands to generate.