You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

406 lines
14 KiB
Diff

diff --git a/kernel-dkms/nvidia/nvidia.Kbuild b/kernel-dkms/nvidia/nvidia.Kbuild
index 5ec3e65..2897e31 100644
--- a/kernel-dkms/nvidia/nvidia.Kbuild
+++ b/kernel-dkms/nvidia/nvidia.Kbuild
@@ -150,6 +151,7 @@ NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_swiotlb_dma_ops
NV_CONFTEST_TYPE_COMPILE_TESTS += acpi_op_remove
NV_CONFTEST_TYPE_COMPILE_TESTS += outer_flush_all
NV_CONFTEST_TYPE_COMPILE_TESTS += file_operations
+NV_CONFTEST_TYPE_COMPILE_TESTS += proc_ops
NV_CONFTEST_TYPE_COMPILE_TESTS += file_inode
NV_CONFTEST_TYPE_COMPILE_TESTS += kuid_t
NV_CONFTEST_TYPE_COMPILE_TESTS += dma_ops
diff --git a/kernel-dkms/common/inc/nv-procfs.h b/kernel-dkms/common/inc/nv-procfs.h
index 8b53f86..4c5aceb 100644
--- a/kernel-dkms/common/inc/nv-procfs.h
+++ b/kernel-dkms/common/inc/nv-procfs.h
@@ -28,6 +28,18 @@
#define IS_EXERCISE_ERROR_FORWARDING_ENABLED() (EXERCISE_ERROR_FORWARDING)
+#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 = proc_create_data(filename, mode, parent, fops, __data);\
+ __entry; \
+ })
+#else
#define NV_CREATE_PROC_FILE(filename,parent,__name,__data) \
({ \
struct proc_dir_entry *__entry; \
@@ -38,6 +50,7 @@
__entry = proc_create_data(filename, mode, parent, fops, __data);\
__entry; \
})
+#endif
/*
* proc_mkdir_mode exists in Linux 2.6.9, but isn't exported until Linux 3.0.
@@ -77,6 +90,44 @@
remove_proc_entry(entry->name, entry->parent);
#endif
+#if defined(NV_HAVE_PROC_OPS)
+#define NV_DEFINE_SINGLE_PROCFS_FILE(name, open_callback, close_callback) \
+ static int nv_procfs_open_##name( \
+ struct inode *inode, \
+ struct file *filep \
+ ) \
+ { \
+ int ret; \
+ ret = single_open(filep, nv_procfs_read_##name, \
+ NV_PDE_DATA(inode)); \
+ if (ret < 0) \
+ { \
+ return ret; \
+ } \
+ ret = open_callback(); \
+ if (ret < 0) \
+ { \
+ single_release(inode, filep); \
+ } \
+ return ret; \
+ } \
+ \
+ static int nv_procfs_release_##name( \
+ struct inode *inode, \
+ struct file *filep \
+ ) \
+ { \
+ close_callback(); \
+ return single_release(inode, filep); \
+ } \
+ \
+ 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 = nv_procfs_release_##name, \
+ };
+#else
#define NV_DEFINE_SINGLE_PROCFS_FILE(name, open_callback, close_callback) \
static int nv_procfs_open_##name( \
struct inode *inode, \
@@ -114,6 +165,7 @@
.llseek = seq_lseek, \
.release = nv_procfs_release_##name, \
};
+#endif
#endif /* CONFIG_PROC_FS */
diff --git a/kernel-dkms/conftest.sh b/kernel-dkms/conftest.sh
index 57d85a4..4902248 100755
--- a/kernel-dkms/conftest.sh
+++ b/kernel-dkms/conftest.sh
@@ -806,6 +822,16 @@ compile_test() {
compile_check_conftest "$CODE" "NV_FILE_OPERATIONS_HAS_IOCTL" "" "types"
;;
+ proc_ops)
+ CODE="
+ #include <linux/proc_fs.h>
+ int conftest_proc_ops(void) {
+ return offsetof(struct proc_ops, proc_open);
+ }"
+
+ compile_check_conftest "$CODE" "NV_HAVE_PROC_OPS" "" "types"
+ ;;
+
sg_alloc_table)
#
# sg_alloc_table_from_pages added by commit efc42bc98058
diff --git a/kernel-dkms/nvidia/nv-procfs.c b/kernel-dkms/nvidia/nv-procfs.c
index 064d727..a7308d3 100644
--- a/kernel-dkms/nvidia/nv-procfs.c
+++ b/kernel-dkms/nvidia/nv-procfs.c
@@ -452,6 +452,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,
@@ -460,6 +469,7 @@ static struct file_operations nv_procfs_registry_fops = {
.llseek = seq_lseek,
.release = nv_procfs_close_registry,
};
+#endif
#if defined(CONFIG_PM)
static int
@@ -531,6 +541,15 @@ nv_procfs_open_suspend_depth(
return single_open(file, nv_procfs_show_suspend_depth, NULL);
}
+#if defined(NV_HAVE_PROC_OPS)
+static struct proc_ops nv_procfs_suspend_depth_fops = {
+ .proc_open = nv_procfs_open_suspend_depth,
+ .proc_read = seq_read,
+ .proc_write = nv_procfs_write_suspend_depth,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release
+};
+#else
static struct file_operations nv_procfs_suspend_depth_fops = {
.owner = THIS_MODULE,
.open = nv_procfs_open_suspend_depth,
@@ -539,6 +558,7 @@ static struct file_operations nv_procfs_suspend_depth_fops = {
.llseek = seq_lseek,
.release = single_release
};
+#endif
static int
nv_procfs_show_suspend(
@@ -613,6 +633,15 @@ nv_procfs_open_suspend(
return single_open(file, nv_procfs_show_suspend, NULL);
}
+#if defined(NV_HAVE_PROC_OPS)
+static struct proc_ops nv_procfs_suspend_fops = {
+ .proc_open = nv_procfs_open_suspend,
+ .proc_read = seq_read,
+ .proc_write = nv_procfs_write_suspend,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release
+};
+#else
static struct file_operations nv_procfs_suspend_fops = {
.owner = THIS_MODULE,
.open = nv_procfs_open_suspend,
@@ -622,6 +651,7 @@ static struct file_operations nv_procfs_suspend_fops = {
.release = single_release
};
#endif
+#endif
/*
* Forwards error to nv_log_error which exposes data to vendor callback
@@ -724,12 +754,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(
@@ -851,6 +889,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,
@@ -859,6 +906,7 @@ static struct file_operations nv_procfs_unbind_lock_fops = {
.llseek = seq_lseek,
.release = nv_procfs_close_unbind_lock,
};
+#endif
static const char*
numa_status_describe(nv_numa_status_t state)
@@ -1187,6 +1235,22 @@ done:
return retval;
}
+#if defined(NV_HAVE_PROC_OPS)
+static const struct proc_ops nv_procfs_numa_status_fops = {
+ .proc_open = nv_procfs_open_numa_status,
+ .proc_read = seq_read,
+ .proc_write = nv_procfs_write_file,
+ .proc_lseek = seq_lseek,
+ .proc_release = nv_procfs_close_numa_status,
+};
+
+static const struct proc_ops nv_procfs_offline_pages_fops = {
+ .proc_open = nv_procfs_open_offline_pages,
+ .proc_read = seq_read,
+ .proc_lseek = seq_lseek,
+ .proc_release = nv_procfs_close_offline_pages,
+};
+#else
static const struct file_operations nv_procfs_numa_status_fops = {
.owner = THIS_MODULE,
.open = nv_procfs_open_numa_status,
@@ -1203,6 +1267,7 @@ static const struct file_operations nv_procfs_offline_pages_fops = {
.llseek = seq_lseek,
.release = nv_procfs_close_offline_pages,
};
+#endif
static int
nv_procfs_read_text_file(
diff --git a/kernel-dkms/nvidia/os-interface.c b/kernel-dkms/nvidia/os-interface.c
index 07f1b77..a8f1d85 100644
--- a/kernel-dkms/nvidia/os-interface.c
+++ b/kernel-dkms/nvidia/os-interface.c
@@ -477,9 +477,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, 6, 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);
}
diff --git a/kernel-dkms/common/inc/56rc3uglyhack.h b/kernel-dkms/common/inc/56rc3uglyhack.h
new file mode 100644
index 0000000..389d02f
--- /dev/null
+++ b/kernel-dkms/common/inc/56rc3uglyhack.h
@@ -0,0 +1,80 @@
+
+typedef __kernel_long_t __kernel_time_t;
+
+#ifndef _STRUCT_TIMESPEC
+#define _STRUCT_TIMESPEC
+struct timespec {
+ __kernel_old_time_t tv_sec; /* seconds */
+ long tv_nsec; /* nanoseconds */
+};
+#endif
+
+struct timeval {
+ __kernel_old_time_t tv_sec; /* seconds */
+ __kernel_suseconds_t tv_usec; /* microseconds */
+};
+
+struct itimerspec {
+ struct timespec it_interval;/* timer period */
+ struct timespec it_value; /* timer expiration */
+};
+
+struct itimerval {
+ struct timeval it_interval;/* timer interval */
+ struct timeval it_value; /* current value */
+};
+
+#if __BITS_PER_LONG == 64
+
+/* timespec64 is defined as timespec here */
+static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64)
+{
+ return *(const struct timespec *)&ts64;
+}
+
+static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
+{
+ return *(const struct timespec64 *)&ts;
+}
+
+#else
+static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64)
+{
+ struct timespec ret;
+
+ ret.tv_sec = (time_t)ts64.tv_sec;
+ ret.tv_nsec = ts64.tv_nsec;
+ return ret;
+}
+
+static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
+{
+ struct timespec64 ret;
+
+ ret.tv_sec = ts.tv_sec;
+ ret.tv_nsec = ts.tv_nsec;
+ return ret;
+}
+#endif
+
+static inline void getnstimeofday(struct timespec *ts)
+{
+ struct timespec64 ts64;
+
+ ktime_get_real_ts64(&ts64);
+ *ts = timespec64_to_timespec(ts64);
+}
+
+static inline s64 timespec_to_ns(const struct timespec *ts)
+{
+ return ((s64) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec;
+}
+
+static inline void getrawmonotonic(struct timespec *ts)
+{
+ struct timespec64 ts64;
+
+ ktime_get_raw_ts64(&ts64);
+ *ts = timespec64_to_timespec(ts64);
+}
+
diff --git a/kernel-dkms/common/inc/nv-time.h b/kernel-dkms/common/inc/nv-time.h
index 968b873..165f18b 100644
--- a/kernel-dkms/common/inc/nv-time.h
+++ b/kernel-dkms/common/inc/nv-time.h
@@ -27,6 +27,10 @@
#include <linux/ktime.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
+#include "56rc3uglyhack.h"
+#endif
+
static inline void nv_gettimeofday(struct timeval *tv)
{
#ifdef NV_DO_GETTIMEOFDAY_PRESENT
diff --git a/kernel-dkms/nvidia/linux_nvswitch.c b/kernel-dkms/nvidia/linux_nvswitch.c
index 1d2c1bc..388d64f 100644
--- a/kernel-dkms/nvidia/linux_nvswitch.c
+++ b/kernel-dkms/nvidia/linux_nvswitch.c
@@ -26,6 +26,9 @@
#include "conftest.h"
#include "nvmisc.h"
#include "nv-linux.h"
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
+#include "nv-time.h"
+#endif
#include "nv-procfs.h"
#include "nvlink_common.h"
#include "nvlink_errors.h"