]>
Commit | Line | Data |
---|---|---|
1d545142 JR |
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) { | |
1d545142 JR |
156 | diff --git a/kernel/nvidia/os-mlock.c b/kernel/nvidia/os-mlock.c |
157 | index f88daed4..ad5cb9a1 100644 | |
158 | --- a/kernel/nvidia/os-mlock.c | |
159 | +++ b/kernel/nvidia/kernel/os-mlock.c | |
160 | @@ -127,8 +127,13 @@ NV_STATUS NV_API_CALL os_lock_user_pages( | |
161 | } | |
162 | ||
163 | nv_mmap_read_lock(mm); | |
164 | +#if defined(NV_GET_USER_PAGES_DROPPED_VMA) | |
165 | + ret = NV_GET_USER_PAGES((unsigned long)address, | |
166 | + page_count, write, force, user_pages); | |
167 | +#else | |
168 | ret = NV_GET_USER_PAGES((unsigned long)address, | |
169 | page_count, write, force, user_pages, NULL); | |
170 | +#endif | |
171 | nv_mmap_read_unlock(mm); | |
172 | pinned = ret; | |
173 | ||
174 | -- | |
175 | 2.40.1 | |
176 |