1 diff --git a/kernel/common/inc/nv-procfs.h b/kernel/common/inc/nv-procfs.h
2 index 8b53f86..4c5aceb 100644
3 --- a/kernel/common/inc/nv-procfs.h
4 +++ b/kernel/common/inc/nv-procfs.h
7 #define IS_EXERCISE_ERROR_FORWARDING_ENABLED() (EXERCISE_ERROR_FORWARDING)
9 +#if defined(NV_HAVE_PROC_OPS)
10 +#define NV_CREATE_PROC_FILE(filename,parent,__name,__data) \
12 + struct proc_dir_entry *__entry; \
13 + int mode = (S_IFREG | S_IRUGO); \
14 + const struct proc_ops *fops = &nv_procfs_##__name##_fops; \
15 + if (fops->proc_write != 0) \
17 + __entry = proc_create_data(filename, mode, parent, fops, __data);\
21 #define NV_CREATE_PROC_FILE(filename,parent,__name,__data) \
23 struct proc_dir_entry *__entry; \
25 __entry = proc_create_data(filename, mode, parent, fops, __data);\
31 * proc_mkdir_mode exists in Linux 2.6.9, but isn't exported until Linux 3.0.
33 remove_proc_entry(entry->name, entry->parent);
36 +#if defined(NV_HAVE_PROC_OPS)
37 +#define NV_DEFINE_SINGLE_PROCFS_FILE(name, open_callback, close_callback) \
38 + static int nv_procfs_open_##name( \
39 + struct inode *inode, \
40 + struct file *filep \
44 + ret = single_open(filep, nv_procfs_read_##name, \
45 + NV_PDE_DATA(inode)); \
50 + ret = open_callback(); \
53 + single_release(inode, filep); \
58 + static int nv_procfs_release_##name( \
59 + struct inode *inode, \
60 + struct file *filep \
64 + return single_release(inode, filep); \
67 + static const struct proc_ops nv_procfs_##name##_fops = { \
68 + .proc_open = nv_procfs_open_##name, \
69 + .proc_read = seq_read, \
70 + .proc_lseek = seq_lseek, \
71 + .proc_release = nv_procfs_release_##name, \
74 #define NV_DEFINE_SINGLE_PROCFS_FILE(name, open_callback, close_callback) \
75 static int nv_procfs_open_##name( \
76 struct inode *inode, \
78 .llseek = seq_lseek, \
79 .release = nv_procfs_release_##name, \
83 #endif /* CONFIG_PROC_FS */
85 diff --git a/kernel/common/inc/nv-time.h b/kernel/common/inc/nv-time.h
86 index 968b873..f03c7b0 100644
87 --- a/kernel/common/inc/nv-time.h
88 +++ b/kernel/common/inc/nv-time.h
91 #include <linux/ktime.h>
93 -static inline void nv_gettimeofday(struct timeval *tv)
94 +#include <linux/version.h>
95 +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
96 +#define nv_timeval timeval
99 + __kernel_long_t tv_sec;
100 + __kernel_suseconds_t tv_usec;
104 +static inline void nv_gettimeofday(struct nv_timeval *tv)
106 #ifdef NV_DO_GETTIMEOFDAY_PRESENT
108 @@ -36,7 +41,7 @@ static inline void nv_gettimeofday(struct timeval *tv)
110 ktime_get_real_ts64(&now);
112 - *tv = (struct timeval) {
113 + *tv = (struct nv_timeval) {
114 .tv_sec = now.tv_sec,
115 .tv_usec = now.tv_nsec/1000,
117 diff --git a/kernel/conftest.sh b/kernel/conftest.sh
118 index 57d85a4..4eb703f 100755
119 --- a/kernel/conftest.sh
120 +++ b/kernel/conftest.sh
121 @@ -806,6 +806,42 @@ compile_test() {
122 compile_check_conftest "$CODE" "NV_FILE_OPERATIONS_HAS_IOCTL" "" "types"
127 + #include <linux/proc_fs.h>
128 + int conftest_proc_ops(void) {
129 + return offsetof(struct proc_ops, proc_open);
132 + compile_check_conftest "$CODE" "NV_HAVE_PROC_OPS" "" "types"
135 + ktime_get_raw_ts64)
137 + # Determine if the ktime_get_raw_ts64() function is present.
140 + #include <linux/ktime.h>
141 + int conftest_ktime_get_raw_ts64(void) {
142 + ktime_get_raw_ts64();
145 + compile_check_conftest "$CODE" "NV_KTIME_GET_RAW_TS64_PRESENT" "" "functions"
148 + ktime_get_real_ts64)
150 + # Determine if the ktime_get_real_ts64() function is present.
153 + #include <linux/ktime.h>
154 + int conftest_ktime_get_raw_ts64(void) {
155 + ktime_get_real_ts64();
158 + compile_check_conftest "$CODE" "NV_KTIME_GET_REAL_TS64_PRESENT" "" "functions"
163 # sg_alloc_table_from_pages added by commit efc42bc98058
164 diff --git a/kernel/nvidia-modeset/nvidia-modeset-linux.c b/kernel/nvidia-modeset/nvidia-modeset-linux.c
165 index 0ca2c7d..8902143 100644
166 --- a/kernel/nvidia-modeset/nvidia-modeset-linux.c
167 +++ b/kernel/nvidia-modeset/nvidia-modeset-linux.c
168 @@ -266,7 +266,7 @@ void NVKMS_API_CALL nvkms_usleep(NvU64 usec)
170 NvU64 NVKMS_API_CALL nvkms_get_usec(void)
173 + struct nv_timeval tv;
175 nv_gettimeofday(&tv);
177 diff --git a/kernel/nvidia-uvm/uvm_linux.h b/kernel/nvidia-uvm/uvm_linux.h
178 index 30a9dea..1a20eff 100644
179 --- a/kernel/nvidia-uvm/uvm_linux.h
180 +++ b/kernel/nvidia-uvm/uvm_linux.h
181 @@ -301,7 +301,16 @@ static inline uint64_t NV_DIV64(uint64_t dividend, uint64_t divisor, uint64_t *r
185 -#if defined(CLOCK_MONOTONIC_RAW)
186 +#if defined(NV_KTIME_GET_RAW_TS64_PRESENT)
187 +static inline NvU64 NV_GETTIME(void)
189 + struct timespec64 ts;
191 + ktime_get_raw_ts64(&ts);
193 + return (ts.tv_sec * 1000000000ULL + ts.tv_nsec);
195 +#elif defined(CLOCK_MONOTONIC_RAW)
196 /* Return a nanosecond-precise value */
197 static inline NvU64 NV_GETTIME(void)
199 @@ -317,7 +326,7 @@ static inline NvU64 NV_GETTIME(void)
200 * available non-GPL symbols. */
201 static inline NvU64 NV_GETTIME(void)
203 - struct timeval tv = {0};
204 + struct nv_timeval tv = {0};
206 nv_gettimeofday(&tv);
208 diff --git a/kernel/nvidia/linux_nvswitch.c b/kernel/nvidia/linux_nvswitch.c
209 index 1d2c1bc..0a0b4e8 100644
210 --- a/kernel/nvidia/linux_nvswitch.c
211 +++ b/kernel/nvidia/linux_nvswitch.c
212 @@ -1578,10 +1578,17 @@ nvswitch_os_get_platform_time
216 +#if defined(NV_KTIME_GET_REAL_TS64_PRESENT)
217 + struct timespec64 ts64;
219 + ktime_get_real_ts64(&ts64);
220 + return ((NvU64)(ts64.tv_sec * NSEC_PER_SEC) + ts64.tv_nsec);
225 return ((NvU64) timespec_to_ns(&ts));
230 diff --git a/kernel/nvidia/nv-procfs.c b/kernel/nvidia/nv-procfs.c
231 index 064d727..a7308d3 100644
232 --- a/kernel/nvidia/nv-procfs.c
233 +++ b/kernel/nvidia/nv-procfs.c
234 @@ -452,6 +452,15 @@ done:
235 return ((status < 0) ? status : (int)count);
238 +#if defined(NV_HAVE_PROC_OPS)
239 +static struct proc_ops nv_procfs_registry_fops = {
240 + .proc_open = nv_procfs_open_registry,
241 + .proc_read = seq_read,
242 + .proc_write = nv_procfs_write_file,
243 + .proc_lseek = seq_lseek,
244 + .proc_release = nv_procfs_close_registry,
247 static struct file_operations nv_procfs_registry_fops = {
248 .owner = THIS_MODULE,
249 .open = nv_procfs_open_registry,
250 @@ -460,6 +469,7 @@ static struct file_operations nv_procfs_registry_fops = {
252 .release = nv_procfs_close_registry,
256 #if defined(CONFIG_PM)
258 @@ -531,6 +541,15 @@ nv_procfs_open_suspend_depth(
259 return single_open(file, nv_procfs_show_suspend_depth, NULL);
262 +#if defined(NV_HAVE_PROC_OPS)
263 +static struct proc_ops nv_procfs_suspend_depth_fops = {
264 + .proc_open = nv_procfs_open_suspend_depth,
265 + .proc_read = seq_read,
266 + .proc_write = nv_procfs_write_suspend_depth,
267 + .proc_lseek = seq_lseek,
268 + .proc_release = single_release
271 static struct file_operations nv_procfs_suspend_depth_fops = {
272 .owner = THIS_MODULE,
273 .open = nv_procfs_open_suspend_depth,
274 @@ -539,6 +558,7 @@ static struct file_operations nv_procfs_suspend_depth_fops = {
276 .release = single_release
281 nv_procfs_show_suspend(
282 @@ -613,6 +633,15 @@ nv_procfs_open_suspend(
283 return single_open(file, nv_procfs_show_suspend, NULL);
286 +#if defined(NV_HAVE_PROC_OPS)
287 +static struct proc_ops nv_procfs_suspend_fops = {
288 + .proc_open = nv_procfs_open_suspend,
289 + .proc_read = seq_read,
290 + .proc_write = nv_procfs_write_suspend,
291 + .proc_lseek = seq_lseek,
292 + .proc_release = single_release
295 static struct file_operations nv_procfs_suspend_fops = {
296 .owner = THIS_MODULE,
297 .open = nv_procfs_open_suspend,
298 @@ -622,6 +651,7 @@ static struct file_operations nv_procfs_suspend_fops = {
299 .release = single_release
305 * Forwards error to nv_log_error which exposes data to vendor callback
306 @@ -724,12 +754,20 @@ done:
310 +#if defined(NV_HAVE_PROC_OPS)
311 +static struct proc_ops nv_procfs_exercise_error_forwarding_fops = {
312 + .proc_open = nv_procfs_open_exercise_error_forwarding,
313 + .proc_write = nv_procfs_write_file,
314 + .proc_release = nv_procfs_close_exercise_error_forwarding,
317 static struct file_operations nv_procfs_exercise_error_forwarding_fops = {
318 .owner = THIS_MODULE,
319 .open = nv_procfs_open_exercise_error_forwarding,
320 .write = nv_procfs_write_file,
321 .release = nv_procfs_close_exercise_error_forwarding,
326 nv_procfs_read_unbind_lock(
327 @@ -851,6 +889,15 @@ done:
331 +#if defined(NV_HAVE_PROC_OPS)
332 +static struct proc_ops nv_procfs_unbind_lock_fops = {
333 + .proc_open = nv_procfs_open_unbind_lock,
334 + .proc_read = seq_read,
335 + .proc_write = nv_procfs_write_file,
336 + .proc_lseek = seq_lseek,
337 + .proc_release = nv_procfs_close_unbind_lock,
340 static struct file_operations nv_procfs_unbind_lock_fops = {
341 .owner = THIS_MODULE,
342 .open = nv_procfs_open_unbind_lock,
343 @@ -859,6 +906,7 @@ static struct file_operations nv_procfs_unbind_lock_fops = {
345 .release = nv_procfs_close_unbind_lock,
350 numa_status_describe(nv_numa_status_t state)
351 @@ -1187,6 +1235,22 @@ done:
355 +#if defined(NV_HAVE_PROC_OPS)
356 +static const struct proc_ops nv_procfs_numa_status_fops = {
357 + .proc_open = nv_procfs_open_numa_status,
358 + .proc_read = seq_read,
359 + .proc_write = nv_procfs_write_file,
360 + .proc_lseek = seq_lseek,
361 + .proc_release = nv_procfs_close_numa_status,
364 +static const struct proc_ops nv_procfs_offline_pages_fops = {
365 + .proc_open = nv_procfs_open_offline_pages,
366 + .proc_read = seq_read,
367 + .proc_lseek = seq_lseek,
368 + .proc_release = nv_procfs_close_offline_pages,
371 static const struct file_operations nv_procfs_numa_status_fops = {
372 .owner = THIS_MODULE,
373 .open = nv_procfs_open_numa_status,
374 @@ -1203,6 +1267,7 @@ static const struct file_operations nv_procfs_offline_pages_fops = {
376 .release = nv_procfs_close_offline_pages,
381 nv_procfs_read_text_file(
382 diff --git a/kernel/nvidia/nvidia.Kbuild b/kernel/nvidia/nvidia.Kbuild
383 index 5ec3e65..339a757 100644
384 --- a/kernel/nvidia/nvidia.Kbuild
385 +++ b/kernel/nvidia/nvidia.Kbuild
386 @@ -150,6 +150,9 @@ NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_swiotlb_dma_ops
387 NV_CONFTEST_TYPE_COMPILE_TESTS += acpi_op_remove
388 NV_CONFTEST_TYPE_COMPILE_TESTS += outer_flush_all
389 NV_CONFTEST_TYPE_COMPILE_TESTS += file_operations
390 +NV_CONFTEST_TYPE_COMPILE_TESTS += proc_ops
391 +NV_CONFTEST_TYPE_COMPILE_TESTS += ktime_get_raw_ts64
392 +NV_CONFTEST_TYPE_COMPILE_TESTS += ktime_get_real_ts64
393 NV_CONFTEST_TYPE_COMPILE_TESTS += file_inode
394 NV_CONFTEST_TYPE_COMPILE_TESTS += kuid_t
395 NV_CONFTEST_TYPE_COMPILE_TESTS += dma_ops
396 diff --git a/kernel/nvidia/nvlink_linux.c b/kernel/nvidia/nvlink_linux.c
397 index c84b36a..54fe244 100644
398 --- a/kernel/nvidia/nvlink_linux.c
399 +++ b/kernel/nvidia/nvlink_linux.c
400 @@ -513,8 +513,8 @@ int NVLINK_API_CALL nvlink_memcmp(const void *s1, const void *s2, NvLength size)
402 static NvBool nv_timer_less_than
404 - const struct timeval *a,
405 - const struct timeval *b
406 + const struct nv_timeval *a,
407 + const struct nv_timeval *b
410 return (a->tv_sec == b->tv_sec) ? (a->tv_usec < b->tv_usec)
411 @@ -523,9 +523,9 @@ static NvBool nv_timer_less_than
413 static void nv_timeradd
415 - const struct timeval *a,
416 - const struct timeval *b,
417 - struct timeval *result
418 + const struct nv_timeval *a,
419 + const struct nv_timeval *b,
420 + struct nv_timeval *result
423 result->tv_sec = a->tv_sec + b->tv_sec;
424 @@ -539,9 +539,9 @@ static void nv_timeradd
426 static void nv_timersub
428 - const struct timeval *a,
429 - const struct timeval *b,
430 - struct timeval *result
431 + const struct nv_timeval *a,
432 + const struct nv_timeval *b,
433 + struct nv_timeval *result
436 result->tv_sec = a->tv_sec - b->tv_sec;
437 @@ -561,7 +561,7 @@ void NVLINK_API_CALL nvlink_sleep(unsigned int ms)
439 unsigned long jiffies;
440 unsigned long mdelay_safe_msec;
441 - struct timeval tm_end, tm_aux;
442 + struct nv_timeval tm_end, tm_aux;
444 nv_gettimeofday(&tm_aux);
446 diff --git a/kernel/nvidia/os-interface.c b/kernel/nvidia/os-interface.c
447 index 07f1b77..239be58 100644
448 --- a/kernel/nvidia/os-interface.c
449 +++ b/kernel/nvidia/os-interface.c
450 @@ -463,7 +463,7 @@ NV_STATUS NV_API_CALL os_get_current_time(
455 + struct nv_timeval tm;
457 nv_gettimeofday(&tm);
459 @@ -477,9 +477,15 @@ NV_STATUS NV_API_CALL os_get_current_time(
461 void NV_API_CALL os_get_current_tick(NvU64 *nseconds)
463 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)
464 + struct timespec64 ts;
466 + jiffies_to_timespec64(jiffies, &ts);
470 jiffies_to_timespec(jiffies, &ts);
473 *nseconds = ((NvU64)ts.tv_sec * NSEC_PER_SEC + (NvU64)ts.tv_nsec);
475 @@ -549,7 +555,7 @@ NV_STATUS NV_API_CALL os_delay_us(NvU32 MicroSeconds)
478 #ifdef NV_CHECK_DELAY_ACCURACY
479 - struct timeval tm1, tm2;
480 + struct nv_timeval tm1, tm2;
482 nv_gettimeofday(&tm1);
484 @@ -589,9 +595,9 @@ NV_STATUS NV_API_CALL os_delay(NvU32 MilliSeconds)
485 unsigned long MicroSeconds;
486 unsigned long jiffies;
487 unsigned long mdelay_safe_msec;
488 - struct timeval tm_end, tm_aux;
489 + struct nv_timeval tm_end, tm_aux;
490 #ifdef NV_CHECK_DELAY_ACCURACY
491 - struct timeval tm_start;
492 + struct nv_timeval tm_start;
495 nv_gettimeofday(&tm_aux);
496 @@ -1954,7 +1960,7 @@ static NV_STATUS NV_API_CALL _os_ipmi_receive_resp
498 struct ipmi_recv_msg *rx_msg;
501 + struct nv_timeval tv;
504 nv_gettimeofday(&tv);