diff --git a/kernel/common/inc/nv-linux.h b/kernel/common/inc/nv-linux.h index 85041c2..ac5bb95 100644 --- a/kernel/common/inc/nv-linux.h +++ b/kernel/common/inc/nv-linux.h @@ -553,7 +553,11 @@ static inline void *nv_ioremap(NvU64 phys, NvU64 size) static inline void *nv_ioremap_nocache(NvU64 phys, NvU64 size) { +#if defined(NV_IOREMAP_NOCACHE_PRESENT) void *ptr = ioremap_nocache(phys, size); +#else + void *ptr = ioremap(phys, size); +#endif if (ptr) NV_MEMDBG_ADD(ptr, size); return ptr; diff --git a/kernel/common/inc/nv-procfs.h b/kernel/common/inc/nv-procfs.h index 3c812ea..e57c4f9 100644 --- a/kernel/common/inc/nv-procfs.h +++ b/kernel/common/inc/nv-procfs.h @@ -52,6 +52,19 @@ }) #endif +#if defined(NV_HAVE_PROC_OPS) +#define NV_CREATE_PROC_FILE(filename,parent,__name,__data) \ + ({ \ + struct proc_dir_entry *__entry; \ + int mode = (S_IFREG | S_IRUGO); \ + const struct proc_ops *fops = &nv_procfs_##__name##_fops; \ + if (fops->proc_write != 0) \ + mode |= S_IWUSR; \ + __entry = NV_CREATE_PROC_ENTRY(filename, mode, parent, fops, \ + __data); \ + __entry; \ + }) +#else #define NV_CREATE_PROC_FILE(filename,parent,__name,__data) \ ({ \ struct proc_dir_entry *__entry; \ @@ -63,6 +76,7 @@ __data); \ __entry; \ }) +#endif /* * proc_mkdir_mode exists in Linux 2.6.9, but isn't exported until Linux 3.0. @@ -104,6 +118,24 @@ remove_proc_entry(entry->name, entry->parent); #endif +#if defined(NV_HAVE_PROC_OPS) +#define NV_DEFINE_PROCFS_SINGLE_FILE(__name) \ + static int nv_procfs_open_##__name( \ + struct inode *inode, \ + struct file *filep \ + ) \ + { \ + return single_open(filep, nv_procfs_read_##__name, \ + NV_PDE_DATA(inode)); \ + } \ + \ + static const struct proc_ops nv_procfs_##__name##_fops = { \ + .proc_open = nv_procfs_open_##__name, \ + .proc_read = seq_read, \ + .proc_lseek = seq_lseek, \ + .proc_release = single_release, \ + }; +#else #define NV_DEFINE_PROCFS_SINGLE_FILE(__name) \ static int nv_procfs_open_##__name( \ struct inode *inode, \ @@ -121,6 +153,7 @@ .llseek = seq_lseek, \ .release = single_release, \ }; +#endif #endif /* CONFIG_PROC_FS */ diff --git a/kernel/common/inc/nv-time.h b/kernel/common/inc/nv-time.h index 2c799c9..0206062 100644 --- a/kernel/common/inc/nv-time.h +++ b/kernel/common/inc/nv-time.h @@ -30,7 +30,12 @@ #include #endif -static inline void nv_gettimeofday(struct timeval *tv) +struct nv_timeval { + __kernel_long_t tv_sec; + __kernel_suseconds_t tv_usec; +}; + +static inline void nv_gettimeofday(struct nv_timeval *tv) { #ifdef NV_DO_GETTIMEOFDAY_PRESENT do_gettimeofday(tv); @@ -39,7 +44,7 @@ static inline void nv_gettimeofday(struct timeval *tv) ktime_get_real_ts64(&now); - *tv = (struct timeval) { + *tv = (struct nv_timeval) { .tv_sec = now.tv_sec, .tv_usec = now.tv_nsec/1000, }; diff --git a/kernel/conftest.sh b/kernel/conftest.sh index ec9e093..463a464 100755 --- a/kernel/conftest.sh +++ b/kernel/conftest.sh @@ -1197,6 +1197,22 @@ compile_test() { compile_check_conftest "$CODE" "NV_IOREMAP_CACHE_PRESENT" "" "functions" ;; + ioremap_nocache) + # + # Determine if the ioremap_nocache() function is present. + # + # Removed by commit 4bdc0d676a64 ("remove ioremap_nocache and + # devm_ioremap_nocache") in v5.6 (2020-01-06) + # + CODE=" + #include + void conftest_ioremap_nocache(void) { + ioremap_nocache(); + }" + + compile_check_conftest "$CODE" "NV_IOREMAP_NOCACHE_PRESENT" "" "functions" + ;; + ioremap_wc) # # Determine if the ioremap_wc() function is present. @@ -1430,6 +1446,31 @@ compile_test() { compile_check_conftest "$CODE" "NV_SG_ALLOC_TABLE_FROM_PAGES_PRESENT" "" "functions" ;; + proc_ops) + CODE=" + #include + int conftest_proc_ops(void) { + return offsetof(struct proc_ops, proc_open); + }" + + compile_check_conftest "$CODE" "NV_HAVE_PROC_OPS" "" "types" + ;; + + ktime_get_raw_ts64) + # + # Determine if the ktime_get_raw_ts64() function is present. + # + CODE=" + #include + int conftest_ktime_get_raw_ts64(void) { + struct timespec64 ts = {0}; + + ktime_get_raw_ts64(&ts64); + }" + + compile_check_conftest "$CODE" "NV_KTIME_GET_RAW_TS64_PRESENT" "" "functions" + ;; + efi_enabled) # # Determine if the efi_enabled symbol is present, or if diff --git a/kernel/nvidia-modeset/nvidia-modeset-linux.c b/kernel/nvidia-modeset/nvidia-modeset-linux.c index d42aabb..f0404fb 100644 --- a/kernel/nvidia-modeset/nvidia-modeset-linux.c +++ b/kernel/nvidia-modeset/nvidia-modeset-linux.c @@ -216,7 +216,7 @@ void NVKMS_API_CALL nvkms_usleep(NvU64 usec) NvU64 NVKMS_API_CALL nvkms_get_usec(void) { - struct timeval tv; + struct nv_timeval tv; nv_gettimeofday(&tv); diff --git a/kernel/nvidia-uvm/uvm_linux.h b/kernel/nvidia-uvm/uvm_linux.h index 8784a82..c256cdb 100644 --- a/kernel/nvidia-uvm/uvm_linux.h +++ b/kernel/nvidia-uvm/uvm_linux.h @@ -329,7 +329,16 @@ static inline uint64_t NV_DIV64(uint64_t dividend, uint64_t divisor, uint64_t *r } #endif -#if defined(CLOCK_MONOTONIC_RAW) +#if defined(NV_KTIME_GET_RAW_TS64_PRESENT) +static inline NvU64 NV_GETTIME(void) +{ + struct timespec64 ts64 = {0}; + + ktime_get_raw_ts64(&ts64); + + return (ts64.tv_sec * 1000000000ULL + ts64.tv_nsec); +} +#elif defined(CLOCK_MONOTONIC_RAW) /* Return a nanosecond-precise value */ static inline NvU64 NV_GETTIME(void) { @@ -345,7 +354,7 @@ static inline NvU64 NV_GETTIME(void) * available non-GPL symbols. */ static inline NvU64 NV_GETTIME(void) { - struct timeval tv = {0}; + struct nv_timeval tv = {0}; nv_gettimeofday(&tv); diff --git a/kernel/nvidia/nv-procfs.c b/kernel/nvidia/nv-procfs.c index 5808a88..bc60a08 100644 --- a/kernel/nvidia/nv-procfs.c +++ b/kernel/nvidia/nv-procfs.c @@ -414,6 +414,15 @@ done: return ((status < 0) ? status : (int)count); } +#if defined(NV_HAVE_PROC_OPS) +static struct proc_ops nv_procfs_registry_fops = { + .proc_open = nv_procfs_open_registry, + .proc_read = seq_read, + .proc_write = nv_procfs_write_file, + .proc_lseek = seq_lseek, + .proc_release = nv_procfs_close_registry, +}; +#else static struct file_operations nv_procfs_registry_fops = { .owner = THIS_MODULE, .open = nv_procfs_open_registry, @@ -422,6 +431,7 @@ static struct file_operations nv_procfs_registry_fops = { .llseek = seq_lseek, .release = nv_procfs_close_registry, }; +#endif /* * Forwards error to nv_log_error which exposes data to vendor callback @@ -517,12 +527,20 @@ done: return status; } +#if defined(NV_HAVE_PROC_OPS) +static struct proc_ops nv_procfs_exercise_error_forwarding_fops = { + .proc_open = nv_procfs_open_exercise_error_forwarding, + .proc_write = nv_procfs_write_file, + .proc_release = nv_procfs_close_exercise_error_forwarding, +}; +#else static struct file_operations nv_procfs_exercise_error_forwarding_fops = { .owner = THIS_MODULE, .open = nv_procfs_open_exercise_error_forwarding, .write = nv_procfs_write_file, .release = nv_procfs_close_exercise_error_forwarding, }; +#endif static int nv_procfs_read_unbind_lock( @@ -650,6 +668,15 @@ done: return rc; } +#if defined(NV_HAVE_PROC_OPS) +static struct proc_ops nv_procfs_unbind_lock_fops = { + .proc_open = nv_procfs_open_unbind_lock, + .proc_read = seq_read, + .proc_write = nv_procfs_write_file, + .proc_lseek = seq_lseek, + .proc_release = nv_procfs_close_unbind_lock, +}; +#else static struct file_operations nv_procfs_unbind_lock_fops = { .owner = THIS_MODULE, .open = nv_procfs_open_unbind_lock, @@ -658,6 +685,7 @@ static struct file_operations nv_procfs_unbind_lock_fops = { .llseek = seq_lseek, .release = nv_procfs_close_unbind_lock, }; +#endif static int nv_procfs_read_text_file( diff --git a/kernel/nvidia/nvidia.Kbuild b/kernel/nvidia/nvidia.Kbuild index 8ae1016..da7f135 100644 --- a/kernel/nvidia/nvidia.Kbuild +++ b/kernel/nvidia/nvidia.Kbuild @@ -117,6 +117,7 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += on_each_cpu NV_CONFTEST_FUNCTION_COMPILE_TESTS += smp_call_function NV_CONFTEST_FUNCTION_COMPILE_TESTS += acpi_evaluate_integer NV_CONFTEST_FUNCTION_COMPILE_TESTS += ioremap_cache +NV_CONFTEST_FUNCTION_COMPILE_TESTS += ioremap_nocache NV_CONFTEST_FUNCTION_COMPILE_TESTS += ioremap_wc NV_CONFTEST_FUNCTION_COMPILE_TESTS += acpi_walk_namespace NV_CONFTEST_FUNCTION_COMPILE_TESTS += pci_domain_nr @@ -169,7 +170,9 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += outer_flush_all NV_CONFTEST_TYPE_COMPILE_TESTS += proc_dir_entry NV_CONFTEST_TYPE_COMPILE_TESTS += scatterlist NV_CONFTEST_TYPE_COMPILE_TESTS += sg_table +NV_CONFTEST_TYPE_COMPILE_TESTS += proc_ops NV_CONFTEST_TYPE_COMPILE_TESTS += file_operations +NV_CONFTEST_TYPE_COMPILE_TESTS += ktime_get_raw_ts64 NV_CONFTEST_TYPE_COMPILE_TESTS += vm_operations_struct NV_CONFTEST_TYPE_COMPILE_TESTS += atomic_long_type NV_CONFTEST_TYPE_COMPILE_TESTS += pci_save_state diff --git a/kernel/nvidia/nvlink_linux.c b/kernel/nvidia/nvlink_linux.c index 0014280..537b257 100644 --- a/kernel/nvidia/nvlink_linux.c +++ b/kernel/nvidia/nvlink_linux.c @@ -518,8 +518,8 @@ void * NVLINK_API_CALL nvlink_memcpy(void *dest, void *src, NvLength size) static NvBool nv_timer_less_than ( - const struct timeval *a, - const struct timeval *b + const struct nv_timeval *a, + const struct nv_timeval *b ) { return (a->tv_sec == b->tv_sec) ? (a->tv_usec < b->tv_usec) @@ -528,9 +528,9 @@ static NvBool nv_timer_less_than static void nv_timeradd ( - const struct timeval *a, - const struct timeval *b, - struct timeval *result + const struct nv_timeval *a, + const struct nv_timeval *b, + struct nv_timeval *result ) { result->tv_sec = a->tv_sec + b->tv_sec; @@ -544,9 +544,9 @@ static void nv_timeradd static void nv_timersub ( - const struct timeval *a, - const struct timeval *b, - struct timeval *result + const struct nv_timeval *a, + const struct nv_timeval *b, + struct nv_timeval *result ) { result->tv_sec = a->tv_sec - b->tv_sec; @@ -566,7 +566,7 @@ void NVLINK_API_CALL nvlink_sleep(unsigned int ms) unsigned long us; unsigned long jiffies; unsigned long mdelay_safe_msec; - struct timeval tm_end, tm_aux; + struct nv_timeval tm_end, tm_aux; nv_gettimeofday(&tm_aux); diff --git a/kernel/nvidia/os-interface.c b/kernel/nvidia/os-interface.c index 344daa8..39d0a19 100644 --- a/kernel/nvidia/os-interface.c +++ b/kernel/nvidia/os-interface.c @@ -430,7 +430,7 @@ NV_STATUS NV_API_CALL os_get_current_time( NvU32 *useconds ) { - struct timeval tm; + struct nv_timeval tm; nv_gettimeofday(&tm); @@ -444,9 +444,15 @@ NV_STATUS NV_API_CALL os_get_current_time( void NV_API_CALL os_get_current_tick(NvU64 *nseconds) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0) + struct timespec64 ts; + + jiffies_to_timespec64(jiffies, &ts); +#else struct timespec ts; jiffies_to_timespec(jiffies, &ts); +#endif *nseconds = ((NvU64)ts.tv_sec * NSEC_PER_SEC + (NvU64)ts.tv_nsec); } @@ -502,7 +508,7 @@ NV_STATUS NV_API_CALL os_delay_us(NvU32 MicroSeconds) unsigned long usec; #ifdef NV_CHECK_DELAY_ACCURACY - struct timeval tm1, tm2; + struct nv_timeval tm1, tm2; nv_gettimeofday(&tm1); #endif @@ -542,9 +548,9 @@ NV_STATUS NV_API_CALL os_delay(NvU32 MilliSeconds) unsigned long MicroSeconds; unsigned long jiffies; unsigned long mdelay_safe_msec; - struct timeval tm_end, tm_aux; + struct nv_timeval tm_end, tm_aux; #ifdef NV_CHECK_DELAY_ACCURACY - struct timeval tm_start; + struct nv_timeval tm_start; #endif nv_gettimeofday(&tm_aux); @@ -1926,7 +1932,7 @@ static NV_STATUS NV_API_CALL _os_ipmi_receive_resp { struct ipmi_recv_msg *rx_msg; int err_no; - struct timeval tv; + struct nv_timeval tv; NvU64 start_time; nv_gettimeofday(&tv);