summaryrefslogtreecommitdiff
blob: b615064ddc4202abfa6b2879c83693c1fadb2b3a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
diff -urp work.orig/kernel/common/inc/nv-linux.h work/kernel/common/inc/nv-linux.h
--- work.orig/kernel/common/inc/nv-linux.h	2016-07-12 06:52:21.000000000 +0200
+++ work/kernel/common/inc/nv-linux.h	2016-07-16 22:45:59.870806346 +0200
@@ -1308,6 +1308,9 @@ extern void *nvidia_stack_t_cache;
 #define NV_KMEM_CACHE_CREATE(name, type)    \
     NV_KMEM_CACHE_CREATE_FULL(name, sizeof(type), 0, 0, NULL)
 
+#define NV_KMEM_CACHE_CREATE_USERCOPY(name, type)    \
+    NV_KMEM_CACHE_CREATE_FULL(name, sizeof(type), 0, SLAB_USERCOPY, NULL)
+
 #define NV_KMEM_CACHE_DESTROY(kmem_cache)   \
     kmem_cache_destroy(kmem_cache)
 
diff -urp work.orig/kernel/common/inc/nv-modeset-interface.h work/kernel/common/inc/nv-modeset-interface.h
--- work.orig/kernel/common/inc/nv-modeset-interface.h	2016-07-12 06:52:21.000000000 +0200
+++ work/kernel/common/inc/nv-modeset-interface.h	2016-07-16 22:46:16.223400774 +0200
@@ -72,7 +72,7 @@ typedef struct {
      * mix nvidia and nvidia-modeset kernel modules from different
      * releases.
      */
-    const char *version_string;
+//    const char *version_string;
 
     /*
      * Return system information.
@@ -117,6 +117,6 @@ typedef struct {
 
 } nvidia_modeset_rm_ops_t;
 
-NV_STATUS nvidia_get_rm_ops(nvidia_modeset_rm_ops_t *rm_ops);
+NV_STATUS nvidia_get_rm_ops(const nvidia_modeset_rm_ops_t **rm_ops, const char **version_string);
 
 #endif /* _NV_MODESET_INTERFACE_H_ */
diff -urp work.orig/kernel/common/inc/nv-register-module.h work/kernel/common/inc/nv-register-module.h
--- work.orig/kernel/common/inc/nv-register-module.h	2016-07-12 06:52:21.000000000 +0200
+++ work/kernel/common/inc/nv-register-module.h	2016-07-16 22:45:59.870806346 +0200
@@ -34,7 +34,7 @@ typedef struct nvidia_module_s {
     int (*ioctl)(struct inode *, struct file * file, unsigned int cmd, unsigned long arg);
     unsigned int (*poll)(struct file * file, poll_table *wait);
 
-} nvidia_module_t;
+} __do_const nvidia_module_t;
 
 int nvidia_register_module(nvidia_module_t *);
 int nvidia_unregister_module(nvidia_module_t *);
diff -urp work.orig/kernel/nvidia/nv.c work/kernel/nvidia/nv.c
--- work.orig/kernel/nvidia/nv.c	2016-07-12 06:52:21.000000000 +0200
+++ work/kernel/nvidia/nv.c	2016-07-16 22:45:59.874809435 +0200
@@ -654,7 +654,7 @@ int __init nvidia_init_module(void)
     NV_SPIN_LOCK_INIT(&km_lock);
 #endif
 
-    nvidia_stack_t_cache = NV_KMEM_CACHE_CREATE(nvidia_stack_cache_name,
+    nvidia_stack_t_cache = NV_KMEM_CACHE_CREATE_USERCOPY(nvidia_stack_cache_name,
                                                 nvidia_stack_t);
     if (nvidia_stack_t_cache == NULL)
     {
diff -urp work.orig/kernel/nvidia/nv-chrdev.c work/kernel/nvidia/nv-chrdev.c
--- work.orig/kernel/nvidia/nv-chrdev.c	2016-07-12 06:52:21.000000000 +0200
+++ work/kernel/nvidia/nv-chrdev.c	2016-07-16 22:45:59.874809435 +0200
@@ -20,8 +20,6 @@ int nv_register_chrdev(void *param)
 {
     nvidia_module_t *module = (nvidia_module_t *)param;
 
-    module->instance = nv_module_instance;
-
     return (nvidia_register_module(module));
 }
 
diff -urp work.orig/kernel/nvidia/nv-instance.c work/kernel/nvidia/nv-instance.c
--- work.orig/kernel/nvidia/nv-instance.c	2016-07-12 06:52:21.000000000 +0200
+++ work/kernel/nvidia/nv-instance.c	2016-07-16 22:45:59.874809435 +0200
@@ -51,6 +51,7 @@ struct pci_driver nv_pci_driver = {
 nvidia_module_t nv_fops = {
     .owner       = THIS_MODULE,
     .module_name = MODULE_NAME,
+    .instance    = MODULE_INSTANCE_NUMBER,
     .open        = nvidia_open,
     .close       = nvidia_close,
     .ioctl       = nvidia_ioctl,
diff -urp work.orig/kernel/nvidia/nv-mmap.c work/kernel/nvidia/nv-mmap.c
--- work.orig/kernel/nvidia/nv-mmap.c	2016-07-12 06:52:21.000000000 +0200
+++ work/kernel/nvidia/nv-mmap.c	2016-07-16 22:45:59.874809435 +0200
@@ -113,12 +113,12 @@ nvidia_vma_release(struct vm_area_struct
 }
 
 #if defined(NV_VM_OPERATIONS_STRUCT_HAS_ACCESS)
-static int
+static ssize_t
 nvidia_vma_access(
     struct vm_area_struct *vma,
     unsigned long addr,
     void *buffer,
-    int length,
+    size_t length,
     int write
 )
 {
diff -urp work.orig/kernel/nvidia/nv-modeset-interface.c work/kernel/nvidia/nv-modeset-interface.c
--- work.orig/kernel/nvidia/nv-modeset-interface.c	2016-07-12 06:52:21.000000000 +0200
+++ work/kernel/nvidia/nv-modeset-interface.c	2016-07-16 22:54:36.567962197 +0200
@@ -100,10 +100,9 @@ static NvU32 nvidia_modeset_enumerate_gp
     return count;
 }
 
-NV_STATUS nvidia_get_rm_ops(nvidia_modeset_rm_ops_t *rm_ops)
+NV_STATUS nvidia_get_rm_ops(const nvidia_modeset_rm_ops_t **rm_ops, const char **version_string)
 {
-    const nvidia_modeset_rm_ops_t local_rm_ops = {
-        .version_string = NV_VERSION_STRING,
+    static const nvidia_modeset_rm_ops_t local_rm_ops = {
         .system_info    = {
             .allow_write_combining = NV_FALSE,
         },
@@ -116,17 +115,26 @@ NV_STATUS nvidia_get_rm_ops(nvidia_modes
         .set_callbacks  = nvidia_modeset_set_callbacks,
     };
 
-    if (strcmp(rm_ops->version_string, NV_VERSION_STRING) != 0)
+    static const nvidia_modeset_rm_ops_t local_rm_ops_wc = {
+        .system_info    = {
+            .allow_write_combining = NV_TRUE,
+        },
+        .alloc_stack    = nvidia_modeset_rm_ops_alloc_stack,
+        .free_stack     = nvidia_modeset_rm_ops_free_stack,
+        .enumerate_gpus = nvidia_modeset_enumerate_gpus,
+        .open_gpu       = nvidia_dev_get,
+        .close_gpu      = nvidia_dev_put,
+        .op             = rm_kernel_rmapi_op, /* provided by nv-kernel.o */
+        .set_callbacks  = nvidia_modeset_set_callbacks,
+    };
+
+    if (strcmp(*version_string, NV_VERSION_STRING) != 0)
     {
-        rm_ops->version_string = NV_VERSION_STRING;
+        *version_string = NV_VERSION_STRING;
         return NV_ERR_GENERIC;
     }
 
-    *rm_ops = local_rm_ops;
-
-    if (NV_ALLOW_WRITE_COMBINING(NV_MEMORY_TYPE_FRAMEBUFFER)) {
-        rm_ops->system_info.allow_write_combining = NV_TRUE;
-    }
+    *rm_ops = NV_ALLOW_WRITE_COMBINING(NV_MEMORY_TYPE_FRAMEBUFFER) ? &local_rm_ops_wc : &local_rm_ops;
 
     return NV_OK;
 }
diff -urp work.orig/kernel/nvidia-drm/nvidia-drm-drv.c work/kernel/nvidia-drm/nvidia-drm-drv.c
--- work.orig/kernel/nvidia-drm/nvidia-drm-drv.c	2016-07-12 06:53:45.000000000 +0200
+++ work/kernel/nvidia-drm/nvidia-drm-drv.c	2016-07-16 22:45:59.878812524 +0200
@@ -592,7 +592,7 @@ static const struct drm_ioctl_desc nv_dr
                       DRM_CONTROL_ALLOW|DRM_RENDER_ALLOW|DRM_UNLOCKED),
 };
 
-static struct drm_driver nv_drm_driver = {
+static drm_driver_no_const nv_drm_driver __read_only = {
 
     .driver_features        = DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER,
 
@@ -649,6 +649,7 @@ static void nvidia_update_drm_driver_fea
         return;
     }
 
+    pax_open_kernel();
     nv_drm_driver.driver_features |= DRIVER_MODESET | DRIVER_ATOMIC;
 
     nv_drm_driver.master_set       = nvidia_drm_master_set;
@@ -657,6 +658,7 @@ static void nvidia_update_drm_driver_fea
     nv_drm_driver.dumb_create      = nvidia_drm_dumb_create;
     nv_drm_driver.dumb_map_offset  = nvidia_drm_dumb_map_offset;
     nv_drm_driver.dumb_destroy     = drm_gem_dumb_destroy;
+    pax_close_kernel();
 
 #endif /* NV_DRM_ATOMIC_MODESET_AVAILABLE */
 }
diff -urp work.orig/kernel/nvidia-modeset/nvidia-modeset-linux.c work/kernel/nvidia-modeset/nvidia-modeset-linux.c
--- work.orig/kernel/nvidia-modeset/nvidia-modeset-linux.c	2016-07-12 06:53:46.000000000 +0200
+++ work/kernel/nvidia-modeset/nvidia-modeset-linux.c	2016-07-16 22:47:09.334133112 +0200
@@ -317,29 +317,28 @@ static void nvkms_resume(NvU32 gpuId)
  * Interface with resman.
  *************************************************************************/
 
-static nvidia_modeset_rm_ops_t __rm_ops = { 0 };
+static const nvidia_modeset_rm_ops_t *__rm_ops;
 static nvidia_modeset_callbacks_t nvkms_rm_callbacks = {
-    nvkms_suspend,
-    nvkms_resume
+    .suspend = nvkms_suspend,
+    .resume = nvkms_resume
 };
 
 static int nvkms_alloc_rm(void)
 {
     NV_STATUS nvstatus;
     int ret;
+    const char *version_string = NV_VERSION_STRING;
 
-    __rm_ops.version_string = NV_VERSION_STRING;
-
-    nvstatus = nvidia_get_rm_ops(&__rm_ops);
+    nvstatus = nvidia_get_rm_ops(&__rm_ops, &version_string);
 
     if (nvstatus != NV_OK) {
         printk(KERN_ERR NVKMS_LOG_PREFIX "Version mismatch: "
                "nvidia.ko(%s) nvidia-modeset.ko(%s)\n",
-               __rm_ops.version_string, NV_VERSION_STRING);
+               version_string, NV_VERSION_STRING);
         return -EINVAL;
     }
 
-    ret = __rm_ops.set_callbacks(&nvkms_rm_callbacks);
+    ret = __rm_ops->set_callbacks(&nvkms_rm_callbacks);
     if (ret < 0) {
         printk(KERN_ERR NVKMS_LOG_PREFIX "Failed to register callbacks\n");
         return ret;
@@ -350,20 +349,20 @@ static int nvkms_alloc_rm(void)
 
 static void nvkms_free_rm(void)
 {
-    __rm_ops.set_callbacks(NULL);
+    __rm_ops->set_callbacks(NULL);
 }
 
 void NVKMS_API_CALL nvkms_call_rm(void *ops)
 {
     nvidia_modeset_stack_ptr stack = NULL;
 
-    if (__rm_ops.alloc_stack(&stack) != 0) {
+    if (__rm_ops->alloc_stack(&stack) != 0) {
         return;
     }
 
-    __rm_ops.op(stack, ops);
+    __rm_ops->op(stack, ops);
 
-    __rm_ops.free_stack(stack);
+    __rm_ops->free_stack(stack);
 }
 
 /*************************************************************************
@@ -685,13 +684,13 @@ NvBool NVKMS_API_CALL nvkms_open_gpu(NvU
     nvidia_modeset_stack_ptr stack = NULL;
     NvBool ret;
 
-    if (__rm_ops.alloc_stack(&stack) != 0) {
+    if (__rm_ops->alloc_stack(&stack) != 0) {
         return NV_FALSE;
     }
 
-    ret = __rm_ops.open_gpu(gpuId, stack) == 0;
+    ret = __rm_ops->open_gpu(gpuId, stack) == 0;
 
-    __rm_ops.free_stack(stack);
+    __rm_ops->free_stack(stack);
 
     return ret;
 }
@@ -700,23 +699,23 @@ void NVKMS_API_CALL nvkms_close_gpu(NvU3
 {
     nvidia_modeset_stack_ptr stack = NULL;
 
-    if (__rm_ops.alloc_stack(&stack) != 0) {
+    if (__rm_ops->alloc_stack(&stack) != 0) {
         return;
     }
 
-    __rm_ops.close_gpu(gpuId, stack);
+    __rm_ops->close_gpu(gpuId, stack);
 
-    __rm_ops.free_stack(stack);
+    __rm_ops->free_stack(stack);
 }
 
 NvU32 NVKMS_API_CALL nvkms_enumerate_gpus(nv_gpu_info_t *gpu_info)
 {
-    return __rm_ops.enumerate_gpus(gpu_info);
+    return __rm_ops->enumerate_gpus(gpu_info);
 }
 
 NvBool NVKMS_API_CALL nvkms_allow_write_combining(void)
 {
-    return __rm_ops.system_info.allow_write_combining;
+    return __rm_ops->system_info.allow_write_combining;
 }
 
 /*************************************************************************
diff -urp work.orig/kernel/nvidia-uvm/uvm8_global.c work/kernel/nvidia-uvm/uvm8_global.c
--- work.orig/kernel/nvidia-uvm/uvm8_global.c	2016-07-12 06:52:17.000000000 +0200
+++ work/kernel/nvidia-uvm/uvm8_global.c	2016-07-16 22:45:59.878812524 +0200
@@ -35,17 +35,17 @@
 #include "nv_uvm_interface.h"
 
 uvm_global_t g_uvm_global;
-static struct UvmOpsUvmEvents g_exported_uvm8_ops;
+static struct UvmOpsUvmEvents g_exported_uvm8_ops = {
+    .startDevice = NULL,
+    .stopDevice  = NULL,
+    .isrTopHalf  = uvm8_isr_top_half,
+};
 static bool g_ops_registered = false;
 
 static NV_STATUS uvm8_register_callbacks(void)
 {
     NV_STATUS status = NV_OK;
 
-    g_exported_uvm8_ops.startDevice = NULL;
-    g_exported_uvm8_ops.stopDevice  = NULL;
-    g_exported_uvm8_ops.isrTopHalf  = uvm8_isr_top_half;
-
     // Register the UVM callbacks with the main GPU driver:
     status = uvm_rm_locked_call(nvUvmInterfaceRegisterUvmCallbacks(&g_exported_uvm8_ops));
     if (status != NV_OK)
diff -urp work.orig/kernel/nvidia-uvm/uvm8_gpu_semaphore.c work/kernel/nvidia-uvm/uvm8_gpu_semaphore.c
--- work.orig/kernel/nvidia-uvm/uvm8_gpu_semaphore.c	2016-07-12 06:52:17.000000000 +0200
+++ work/kernel/nvidia-uvm/uvm8_gpu_semaphore.c	2016-07-16 22:45:59.878812524 +0200
@@ -368,7 +368,7 @@ void uvm_gpu_semaphore_set_payload(uvm_g
     // being optimized out on non-SMP configs (we need them for interacting with
     // the GPU correctly even on non-SMP).
     mb();
-    ACCESS_ONCE(*semaphore->payload) = payload;
+    ACCESS_ONCE_RW(*semaphore->payload) = payload;
 }
 
 // This function is intended to catch channels which have been left dangling in
diff -urp work.orig/kernel/nvidia-uvm/uvm8_hal.h work/kernel/nvidia-uvm/uvm8_hal.h
--- work.orig/kernel/nvidia-uvm/uvm8_hal.h	2016-07-12 06:52:17.000000000 +0200
+++ work/kernel/nvidia-uvm/uvm8_hal.h	2016-07-16 22:45:59.878812524 +0200
@@ -310,7 +310,7 @@ typedef struct
         // fault_buffer_ops: id is a hardware class
         uvm_fault_buffer_hal_t fault_buffer_ops;
     } u;
-} uvm_hal_class_ops_t;
+} __do_const uvm_hal_class_ops_t;
 
 // When UVM next support is enabled support for future chips in the hal is
 // enabled by providing additional hal table entries below.
diff -urp work.orig/kernel/nvidia-uvm/uvm8_mmu.h work/kernel/nvidia-uvm/uvm8_mmu.h
--- work.orig/kernel/nvidia-uvm/uvm8_mmu.h	2016-07-12 06:52:17.000000000 +0200
+++ work/kernel/nvidia-uvm/uvm8_mmu.h	2016-07-16 22:45:59.878812524 +0200
@@ -24,7 +24,6 @@
 #ifndef __UVM8_MMU_H__
 #define __UVM8_MMU_H__
 
-#include "uvm8_forward_decl.h"
 #include "uvm8_hal_types.h"
 #include "uvm8_pmm_gpu.h"
 #include "uvmtypes.h"
diff -urp work.orig/kernel/nvidia-uvm/uvm_common.c work/kernel/nvidia-uvm/uvm_common.c
--- work.orig/kernel/nvidia-uvm/uvm_common.c	2016-07-12 06:52:17.000000000 +0200
+++ work/kernel/nvidia-uvm/uvm_common.c	2016-07-16 22:45:59.878812524 +0200
@@ -51,7 +51,6 @@
 #define UVM_SPIN_LOOP_PRINT_TIMEOUT_SEC     30ULL
 
 static dev_t g_uvmBaseDev;
-struct UvmOpsUvmEvents g_exportedUvmOps;
 
 static char* uvm_driver_mode = "8";
 
@@ -175,8 +174,10 @@ static NV_STATUS uvmSetupGpuProvider(voi
 {
     NV_STATUS status = NV_OK;
 
-    g_exportedUvmOps.startDevice = uvm_gpu_event_start_device;
-    g_exportedUvmOps.stopDevice  = uvm_gpu_event_stop_device;
+    static struct UvmOpsUvmEvents g_exportedUvmOps = {
+        .startDevice = uvm_gpu_event_start_device,
+        .stopDevice  = uvm_gpu_event_stop_device,
+    };
 
     // call RM to exchange the function pointers.
     status = nvUvmInterfaceRegisterUvmCallbacks(&g_exportedUvmOps);
diff -urp work.orig/kernel/nvidia-uvm/uvm_full_fault_buffer.h work/kernel/nvidia-uvm/uvm_full_fault_buffer.h
--- work.orig/kernel/nvidia-uvm/uvm_full_fault_buffer.h	2016-07-12 06:52:17.000000000 +0200
+++ work/kernel/nvidia-uvm/uvm_full_fault_buffer.h	2016-07-16 22:45:59.878812524 +0200
@@ -31,6 +31,7 @@
 #define _UVM_FULL_FAULT_BUFFER_H_
 
 #include "uvmtypes.h"
+#include "linux/compiler.h"
 
 #define MAXWELL_FAULT_BUFFER_A (0xb069)
 #define MEM_RD32(a) (*(const volatile NvU32 *)(a)) 
@@ -303,7 +304,7 @@ typedef struct
     NvUvmControlPrefetch_t              controlPrefetch;
     NvUvmTestFaultBufferOverflow_t      testFaultBufferOverflow;
     NvUvmClearFaultBufferOverflow_t     clearFaultBufferOverflow;
-} UvmFaultBufferOps;
+} __no_const UvmFaultBufferOps;
 
 /******************************************************************************
     uvmfull_fault_buffer_init
diff -urp work.orig/kernel/nvidia-uvm/uvm_linux.h work/kernel/nvidia-uvm/uvm_linux.h
--- work.orig/kernel/nvidia-uvm/uvm_linux.h	2016-07-12 06:52:17.000000000 +0200
+++ work/kernel/nvidia-uvm/uvm_linux.h	2016-07-16 22:45:59.882815613 +0200
@@ -508,7 +508,7 @@ static inline NvU64 NV_GETTIME(void)
 
 // WRITE_ONCE/READ_ONCE have incompatible definitions across versions, which produces warnings.
 // Therefore, we define our own macros
-#define UVM_WRITE_ONCE(x, val) (ACCESS_ONCE(x) = (val))
+#define UVM_WRITE_ONCE(x, val) (ACCESS_ONCE_RW(x) = (val))
 #define UVM_READ_ONCE(x) ACCESS_ONCE(x)
 
 // Added in 3.11