summaryrefslogtreecommitdiff
path: root/x11-drivers/nvidia-drivers/files
diff options
context:
space:
mode:
authorV3n3RiX <venerix@redcorelinux.org>2017-10-09 18:53:29 +0100
committerV3n3RiX <venerix@redcorelinux.org>2017-10-09 18:53:29 +0100
commit4f2d7949f03e1c198bc888f2d05f421d35c57e21 (patch)
treeba5f07bf3f9d22d82e54a462313f5d244036c768 /x11-drivers/nvidia-drivers/files
reinit the tree, so we can have metadata
Diffstat (limited to 'x11-drivers/nvidia-drivers/files')
-rw-r--r--x11-drivers/nvidia-drivers/files/50nvidia-prelink-blacklist1
-rw-r--r--x11-drivers/nvidia-drivers/files/95-nvidia-settings2
-rw-r--r--x11-drivers/nvidia-drivers/files/95-nvidia-settings-r12
-rw-r--r--x11-drivers/nvidia-drivers/files/NVIDIA_glx-defines.patch11
-rw-r--r--x11-drivers/nvidia-drivers/files/NVIDIA_glx-glheader.patch13
-rw-r--r--x11-drivers/nvidia-drivers/files/nvidia-169.0714
-rw-r--r--x11-drivers/nvidia-drivers/files/nvidia-drivers-331.13-pax-usercopy.patch52
-rw-r--r--x11-drivers/nvidia-drivers/files/nvidia-drivers-337.12-pax-constify.patch25
-rw-r--r--x11-drivers/nvidia-drivers/files/nvidia-drivers-375.20-pax.patch406
-rw-r--r--x11-drivers/nvidia-drivers/files/nvidia-drivers-375.82-profiles-rc.patch11
-rw-r--r--x11-drivers/nvidia-drivers/files/nvidia-drivers-387.12-linker.patch22
-rw-r--r--x11-drivers/nvidia-drivers/files/nvidia-drivers-pax-const.patch17
-rw-r--r--x11-drivers/nvidia-drivers/files/nvidia-drivers-pax-usercopy.patch54
-rw-r--r--x11-drivers/nvidia-drivers/files/nvidia-persistenced.conf8
-rw-r--r--x11-drivers/nvidia-drivers/files/nvidia-persistenced.init24
-rw-r--r--x11-drivers/nvidia-drivers/files/nvidia-rmmod.conf3
-rw-r--r--x11-drivers/nvidia-drivers/files/nvidia-settings.desktop7
-rw-r--r--x11-drivers/nvidia-drivers/files/nvidia-smi.init24
-rw-r--r--x11-drivers/nvidia-drivers/files/nvidia-udev.sh17
-rw-r--r--x11-drivers/nvidia-drivers/files/nvidia-udev.sh-r120
-rw-r--r--x11-drivers/nvidia-drivers/files/nvidia-uvm.conf3
-rw-r--r--x11-drivers/nvidia-drivers/files/nvidia.udev-rule6
22 files changed, 742 insertions, 0 deletions
diff --git a/x11-drivers/nvidia-drivers/files/50nvidia-prelink-blacklist b/x11-drivers/nvidia-drivers/files/50nvidia-prelink-blacklist
new file mode 100644
index 000000000000..5e139de33211
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/50nvidia-prelink-blacklist
@@ -0,0 +1 @@
+PRELINK_PATH_MASK="/usr/lib{,64}/tls/libnvidia-tls*:/usr/lib{,64}/libnvidia*:/usr/lib{,64}/libGL*:/usr/lib{,64}/opengl/nvidia/*:/usr/lib{,64}/OpenCL/vendors/nvidia/*:/usr/lib{,64}/xorg/modules/drivers/nvidia*:/usr/lib{,64}/libvdpau_nvidia*:/usr/lib{,64}/libXvMCNVIDIA*:/usr/lib{,64}/libcuda*:/usr/lib{,64}/libnvcuvid*"
diff --git a/x11-drivers/nvidia-drivers/files/95-nvidia-settings b/x11-drivers/nvidia-drivers/files/95-nvidia-settings
new file mode 100644
index 000000000000..e9d62742e1e9
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/95-nvidia-settings
@@ -0,0 +1,2 @@
+#!/bin/sh
+/opt/bin/nvidia-settings --load-config-only
diff --git a/x11-drivers/nvidia-drivers/files/95-nvidia-settings-r1 b/x11-drivers/nvidia-drivers/files/95-nvidia-settings-r1
new file mode 100644
index 000000000000..48c41d8aad0d
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/95-nvidia-settings-r1
@@ -0,0 +1,2 @@
+#!/bin/sh
+/usr/bin/nvidia-settings --load-config-only
diff --git a/x11-drivers/nvidia-drivers/files/NVIDIA_glx-defines.patch b/x11-drivers/nvidia-drivers/files/NVIDIA_glx-defines.patch
new file mode 100644
index 000000000000..da9933f6337c
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/NVIDIA_glx-defines.patch
@@ -0,0 +1,11 @@
+diff -ur NVIDIA_GLX-1.0-4191/usr/include/GL/glx.h NVIDIA_GLX-1.0-4191.new/usr/include/GL/glx.h
+--- NVIDIA_GLX-1.0-4191/usr/include/GL/glx.h 2002-12-09 21:26:55.000000000 +0100
++++ NVIDIA_GLX-1.0-4191.new/usr/include/GL/glx.h 2003-01-30 18:20:23.000000000 +0100
+@@ -39,6 +39,7 @@
+ typedef XID GLXPixmap;
+ typedef XID GLXDrawable;
+ typedef XID GLXPbuffer;
++typedef XID GLXPbufferSGIX;
+ typedef XID GLXWindow;
+ typedef XID GLXFBConfigID;
+
diff --git a/x11-drivers/nvidia-drivers/files/NVIDIA_glx-glheader.patch b/x11-drivers/nvidia-drivers/files/NVIDIA_glx-glheader.patch
new file mode 100644
index 000000000000..e0393e1b9ab0
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/NVIDIA_glx-glheader.patch
@@ -0,0 +1,13 @@
+--- usr/include/GL/gl.g.orig 2004-07-17 19:56:59.789410584 +1000
++++ usr/include/GL/gl.h 2004-07-17 19:59:08.844791184 +1000
+@@ -66,6 +66,10 @@
+ typedef double GLclampd;
+ typedef void GLvoid;
+
++/* Patching for some better defines in the global system */
++#ifndef GL_GLEXT_LEGACY
++#include <GL/glext.h>
++#endif
+
+ /*************************************************************/
+
diff --git a/x11-drivers/nvidia-drivers/files/nvidia-169.07 b/x11-drivers/nvidia-drivers/files/nvidia-169.07
new file mode 100644
index 000000000000..a96b0cd1e40f
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/nvidia-169.07
@@ -0,0 +1,14 @@
+# Nvidia drivers support
+alias char-major-195 nvidia
+alias /dev/nvidiactl char-major-195
+
+# To tweak the driver the following options can be used, note that
+# you should be careful, as it could cause instability!! For more
+# options see /usr/share/doc/PACKAGE/README
+#
+# !!! SECURITY WARNING !!!
+# DO NOT MODIFY OR REMOVE THE DEVICE FILE RELATED OPTIONS UNLESS YOU KNOW
+# WHAT YOU ARE DOING.
+# ONLY ADD TRUSTED USERS TO THE VIDEO GROUP, THESE USERS MAY BE ABLE TO CRASH,
+# COMPROMISE, OR IRREPARABLY DAMAGE THE MACHINE.
+options nvidia NVreg_DeviceFileMode=432 NVreg_DeviceFileUID=0 NVreg_DeviceFileGID=VIDEOGID NVreg_ModifyDeviceFiles=1
diff --git a/x11-drivers/nvidia-drivers/files/nvidia-drivers-331.13-pax-usercopy.patch b/x11-drivers/nvidia-drivers/files/nvidia-drivers-331.13-pax-usercopy.patch
new file mode 100644
index 000000000000..9777ce6c2d43
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/nvidia-drivers-331.13-pax-usercopy.patch
@@ -0,0 +1,52 @@
+--- a/kernel/nv-linux.h
++++ b/kernel/nv-linux.h
+@@ -757,16 +757,16 @@
+
+ #if defined(NV_KMEM_CACHE_CREATE_PRESENT)
+ #if (NV_KMEM_CACHE_CREATE_ARGUMENT_COUNT == 6)
+-#define NV_KMEM_CACHE_CREATE(kmem_cache, name, type) \
++#define NV_KMEM_CACHE_CREATE(kmem_cache, name, type, flags) \
+ { \
+ kmem_cache = kmem_cache_create(name, sizeof(type), \
+- 0, 0, NULL, NULL); \
++ 0, flags, NULL, NULL); \
+ }
+ #elif (NV_KMEM_CACHE_CREATE_ARGUMENT_COUNT == 5)
+-#define NV_KMEM_CACHE_CREATE(kmem_cache, name, type) \
++#define NV_KMEM_CACHE_CREATE(kmem_cache, name, type, flags) \
+ { \
+ kmem_cache = kmem_cache_create(name, sizeof(type), \
+- 0, 0, NULL); \
++ 0, flags, NULL); \
+ }
+ #else
+ #error "NV_KMEM_CACHE_CREATE_ARGUMENT_COUNT value unrecognized!"
+--- a/kernel/nv.c
++++ b/kernel/nv.c
+@@ -794,7 +794,7 @@
+ NV_SPIN_LOCK_INIT(&km_lock);
+ #endif
+
+- NV_KMEM_CACHE_CREATE(nv_stack_t_cache, NV_STACK_CACHE_STR, nv_stack_t);
++ NV_KMEM_CACHE_CREATE(nv_stack_t_cache, NV_STACK_CACHE_STR, nv_stack_t, SLAB_USERCOPY);
+ if (nv_stack_t_cache == NULL)
+ {
+ nv_printf(NV_DBG_ERRORS, "NVRM: stack cache allocation failed!\n");
+@@ -924,7 +924,7 @@
+ nv->os_state = (void *) &nv_ctl_device;
+ nv_lock_init_locks(nv);
+
+- NV_KMEM_CACHE_CREATE(nv_pte_t_cache, NV_PTE_CACHE_STR, nv_pte_t);
++ NV_KMEM_CACHE_CREATE(nv_pte_t_cache, NV_PTE_CACHE_STR, nv_pte_t, 0);
+ if (nv_pte_t_cache == NULL)
+ {
+ rc = -ENOMEM;
+@@ -935,7 +935,7 @@
+ if (NV_BUILD_MODULE_INSTANCES == 0)
+ {
+ NV_KMEM_CACHE_CREATE(nvidia_p2p_page_t_cache, "nvidia_p2p_page_t",
+- nvidia_p2p_page_t);
++ nvidia_p2p_page_t, 0);
+ if (nvidia_p2p_page_t_cache == NULL)
+ {
+ rc = -ENOMEM;
diff --git a/x11-drivers/nvidia-drivers/files/nvidia-drivers-337.12-pax-constify.patch b/x11-drivers/nvidia-drivers/files/nvidia-drivers-337.12-pax-constify.patch
new file mode 100644
index 000000000000..0ec9edf99cc8
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/nvidia-drivers-337.12-pax-constify.patch
@@ -0,0 +1,25 @@
+--- a/kernel/uvm/nvidia_uvm_common.c
++++ b/kernel/uvm/nvidia_uvm_common.c
+@@ -95,7 +95,6 @@ static RM_STATUS uvmnext_gpu_event_stop_
+ #endif // NVIDIA_UVM_NEXT_ENABLED
+
+ static dev_t g_uvmBaseDev;
+-struct UvmOpsUvmEvents g_exportedUvmOps;
+
+ // TODO: This would be easier if RM allowed for multiple registrations, since we
+ // could register UVM-Lite and UVM-Next separately (bug 1372835).
+@@ -147,9 +146,11 @@ static RM_STATUS uvmSetupGpuProvider(voi
+ RM_STATUS status = RM_OK;
+
+ #ifdef NVIDIA_UVM_RM_ENABLED
+- g_exportedUvmOps.startDevice = uvm_gpu_event_start_device;
+- g_exportedUvmOps.stopDevice = uvm_gpu_event_stop_device;
+- g_exportedUvmOps.isrTopHalf = uvmnext_isr_top_half;
++ static struct UvmOpsUvmEvents g_exportedUvmOps = {
++ .startDevice = uvm_gpu_event_start_device,
++ .stopDevice = uvm_gpu_event_stop_device,
++ .isrTopHalf = uvmnext_isr_top_half,
++ };
+
+ // call RM to exchange the function pointers.
+ status = nvUvmInterfaceRegisterUvmCallbacks(&g_exportedUvmOps);
diff --git a/x11-drivers/nvidia-drivers/files/nvidia-drivers-375.20-pax.patch b/x11-drivers/nvidia-drivers/files/nvidia-drivers-375.20-pax.patch
new file mode 100644
index 000000000000..9dd245a1f16a
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/nvidia-drivers-375.20-pax.patch
@@ -0,0 +1,406 @@
+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-11-27 21:56:50.391617167 +0100
++++ work/kernel/common/inc/nv-linux.h 2016-11-27 22:04:14.045516163 +0100
+@@ -1310,7 +1310,8 @@ extern void *nvidia_stack_t_cache;
+ #if (NV_KMEM_CACHE_CREATE_ARGUMENT_COUNT == 5)
+ #define NV_KMEM_CACHE_CREATE_FULL(name, size, align, flags, ctor) \
+ kmem_cache_create(name, size, align, flags, ctor)
+-
++#define NV_KMEM_CACHE_CREATE_FULL_USERCOPY(name, size, align, flags, useroffset, usersize, ctor) \
++ kmem_cache_create_usercopy(name, size, align, flags, useroffset, usersize, ctor)
+ #else
+ #define NV_KMEM_CACHE_CREATE_FULL(name, size, align, flags, ctor) \
+ kmem_cache_create(name, size, align, flags, ctor, NULL)
+@@ -1319,6 +1320,14 @@ extern void *nvidia_stack_t_cache;
+ #define NV_KMEM_CACHE_CREATE(name, type) \
+ NV_KMEM_CACHE_CREATE_FULL(name, sizeof(type), 0, 0, NULL)
+
++#ifdef SLAB_USERCOPY
++#define NV_KMEM_CACHE_CREATE_USERCOPY(name, type) \
++ NV_KMEM_CACHE_CREATE_FULL(name, sizeof(type), 0, SLAB_USERCOPY, NULL)
++#else
++#define NV_KMEM_CACHE_CREATE_USERCOPY(name, type) \
++ NV_KMEM_CACHE_CREATE_FULL_USERCOPY(name, sizeof(type), 0, 0, 0, sizeof(type), NULL)
++#endif
++
+ #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-11-27 21:56:50.391617167 +0100
++++ work/kernel/common/inc/nv-modeset-interface.h 2016-11-27 21:54:23.971706350 +0100
+@@ -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-11-27 21:56:50.391617167 +0100
++++ work/kernel/common/inc/nv-register-module.h 2016-11-27 21:54:23.971706350 +0100
+@@ -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-11-27 21:56:50.395629748 +0100
++++ work/kernel/nvidia/nv.c 2016-11-27 21:54:23.971706350 +0100
+@@ -666,7 +666,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-11-27 21:56:50.395629748 +0100
++++ work/kernel/nvidia/nv-chrdev.c 2016-11-27 21:54:23.971706350 +0100
+@@ -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-11-27 21:56:50.395629748 +0100
++++ work/kernel/nvidia/nv-instance.c 2016-11-27 21:54:23.971706350 +0100
+@@ -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-11-27 21:56:50.395629748 +0100
++++ work/kernel/nvidia/nv-mmap.c 2016-11-27 21:54:23.971706350 +0100
+@@ -102,12 +102,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-11-27 21:56:50.395629748 +0100
++++ work/kernel/nvidia/nv-modeset-interface.c 2016-11-27 21:54:23.971706350 +0100
+@@ -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-11-27 21:56:50.395629748 +0100
++++ work/kernel/nvidia-drm/nvidia-drm-drv.c 2016-11-27 21:54:23.971706350 +0100
+@@ -594,7 +594,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,
+
+@@ -654,6 +654,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;
+@@ -664,6 +665,7 @@ static void nvidia_update_drm_driver_fea
+ nv_drm_driver.dumb_destroy = drm_gem_dumb_destroy;
+
+ nv_drm_driver.gem_vm_ops = &nv_drm_gem_vma_ops;
++ 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-11-27 21:56:50.395629748 +0100
++++ work/kernel/nvidia-modeset/nvidia-modeset-linux.c 2016-11-27 21:54:23.971706350 +0100
+@@ -335,29 +335,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;
+@@ -368,20 +367,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);
+ }
+
+ /*************************************************************************
+@@ -705,13 +704,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;
+ }
+@@ -720,23 +719,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-11-27 21:56:50.399642330 +0100
++++ work/kernel/nvidia-uvm/uvm8_global.c 2016-11-27 21:54:23.975709978 +0100
+@@ -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-11-27 21:56:50.399642330 +0100
++++ work/kernel/nvidia-uvm/uvm8_gpu_semaphore.c 2016-11-27 21:54:23.975709978 +0100
+@@ -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-11-27 21:56:50.399642330 +0100
++++ work/kernel/nvidia-uvm/uvm8_hal.h 2016-11-27 21:54:23.975709978 +0100
+@@ -316,7 +316,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-11-27 21:56:50.399642330 +0100
++++ work/kernel/nvidia-uvm/uvm8_mmu.h 2016-11-27 21:54:23.975709978 +0100
+@@ -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-11-27 21:56:50.399642330 +0100
++++ work/kernel/nvidia-uvm/uvm_common.c 2016-11-27 21:54:23.975709978 +0100
+@@ -42,7 +42,6 @@
+ #define UVM_SPIN_LOOP_PRINT_TIMEOUT_SEC 30ULL
+
+ static dev_t g_uvmBaseDev;
+-struct UvmOpsUvmEvents g_exportedUvmOps;
+
+ static char* uvm_driver_mode = "8";
+
+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-11-27 21:56:50.399642330 +0100
++++ work/kernel/nvidia-uvm/uvm_full_fault_buffer.h 2016-11-27 21:54:23.975709978 +0100
+@@ -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-11-27 21:56:50.399642330 +0100
++++ work/kernel/nvidia-uvm/uvm_linux.h 2016-11-27 21:54:23.975709978 +0100
+@@ -420,7 +420,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
diff --git a/x11-drivers/nvidia-drivers/files/nvidia-drivers-375.82-profiles-rc.patch b/x11-drivers/nvidia-drivers/files/nvidia-drivers-375.82-profiles-rc.patch
new file mode 100644
index 000000000000..552f0d6df0ed
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/nvidia-drivers-375.82-profiles-rc.patch
@@ -0,0 +1,11 @@
+--- a/nvidia-application-profiles-375.82-rc
++++ b/nvidia-application-profiles-375.82-rc
+@@ -48,7 +48,7 @@
+ {
+ "name" : "NoEnforceShaderInputOutputMatching",
+ "settings" : [ "GLShaderPortabilityWarnings", false ]
+- },
++ }
+ ],
+ "rules" : [
+ {
diff --git a/x11-drivers/nvidia-drivers/files/nvidia-drivers-387.12-linker.patch b/x11-drivers/nvidia-drivers/files/nvidia-drivers-387.12-linker.patch
new file mode 100644
index 000000000000..4bf84e66856d
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/nvidia-drivers-387.12-linker.patch
@@ -0,0 +1,22 @@
+--- a/nvidia-settings-387.12/utils.mk
++++ b/nvidia-settings-387.12/utils.mk
+@@ -475,7 +475,7 @@
+ define READ_ONLY_OBJECT_FROM_FILE_RULE
+ $$(OUTPUTDIR)/$$(notdir $(1)).o: $(1)
+ $(at_if_quiet)cd $$(dir $(1)); \
+- $$(call quiet_cmd_no_at,LD) -r -z noexecstack --format=binary \
++ $$(call quiet_cmd_no_at,NVLD) -r -z noexecstack --format=binary \
+ $$(notdir $(1)) -o $$(OUTPUTDIR_ABSOLUTE)/$$(notdir $$@)
+ $$(call quiet_cmd,OBJCOPY) \
+ --rename-section .data=.rodata,contents,alloc,load,data,readonly \
+--- a/nvidia-settings-387.12/src/libXNVCtrl/utils.mk
++++ b/nvidia-settings-387.12/src/libXNVCtrl/utils.mk
+@@ -475,7 +475,7 @@
+ define READ_ONLY_OBJECT_FROM_FILE_RULE
+ $$(OUTPUTDIR)/$$(notdir $(1)).o: $(1)
+ $(at_if_quiet)cd $$(dir $(1)); \
+- $$(call quiet_cmd_no_at,LD) -r -z noexecstack --format=binary \
++ $$(call quiet_cmd_no_at,NVLD) -r -z noexecstack --format=binary \
+ $$(notdir $(1)) -o $$(OUTPUTDIR_ABSOLUTE)/$$(notdir $$@)
+ $$(call quiet_cmd,OBJCOPY) \
+ --rename-section .data=.rodata,contents,alloc,load,data,readonly \
diff --git a/x11-drivers/nvidia-drivers/files/nvidia-drivers-pax-const.patch b/x11-drivers/nvidia-drivers/files/nvidia-drivers-pax-const.patch
new file mode 100644
index 000000000000..f3b82593570e
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/nvidia-drivers-pax-const.patch
@@ -0,0 +1,17 @@
+Binary files kernel.orig/.nv-procfs.c.swp and kernel/.nv-procfs.c.swp differ
+diff -urp kernel.orig/nv-procfs.c kernel/nv-procfs.c
+--- kernel.orig/nv-procfs.c 2011-07-13 03:29:30.000000000 +0200
++++ kernel/nv-procfs.c 2011-07-19 15:45:27.982993911 +0200
+@@ -707,8 +707,10 @@ int nv_register_procfs(void)
+ * However, in preparation for this, we need to preserve
+ * the procfs read() and write() operations.
+ */
+- nv_procfs_registry_fops.read = entry->proc_fops->read;
+- nv_procfs_registry_fops.write = entry->proc_fops->write;
++ pax_open_kernel();
++ *(void **)&nv_procfs_registry_fops.read = entry->proc_fops->read;
++ *(void **)&nv_procfs_registry_fops.write = entry->proc_fops->write;
++ pax_close_kernel();
+
+ entry = NV_CREATE_PROC_FILE("registry", proc_nvidia,
+ nv_procfs_read_registry,
diff --git a/x11-drivers/nvidia-drivers/files/nvidia-drivers-pax-usercopy.patch b/x11-drivers/nvidia-drivers/files/nvidia-drivers-pax-usercopy.patch
new file mode 100644
index 000000000000..ce8c201b8e05
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/nvidia-drivers-pax-usercopy.patch
@@ -0,0 +1,54 @@
+diff -urp kernel.orig/nv.c kernel/nv.c
+--- kernel.orig/nv.c 2011-09-24 02:32:09.000000000 +0200
++++ kernel/nv.c 2011-10-05 19:13:41.474242252 +0200
+@@ -1105,7 +1105,7 @@ static int __init nvidia_init_module(voi
+ NV_SPIN_LOCK_INIT(&km_lock);
+ #endif
+
+- NV_KMEM_CACHE_CREATE(nv_stack_t_cache, "nv_stack_t", nv_stack_t);
++ NV_KMEM_CACHE_CREATE(nv_stack_t_cache, "nv_stack_t", nv_stack_t, SLAB_USERCOPY);
+ if (nv_stack_t_cache == NULL)
+ {
+ nv_printf(NV_DBG_ERRORS, "NVRM: stack cache allocation failed!\n");
+@@ -1220,7 +1220,7 @@ static int __init nvidia_init_module(voi
+ }
+ #endif
+
+- NV_KMEM_CACHE_CREATE(nv_pte_t_cache, "nv_pte_t", nv_pte_t);
++ NV_KMEM_CACHE_CREATE(nv_pte_t_cache, "nv_pte_t", nv_pte_t, 0);
+ if (nv_pte_t_cache == NULL)
+ {
+ rc = -ENOMEM;
+@@ -1229,7 +1229,7 @@ static int __init nvidia_init_module(voi
+ }
+
+ NV_KMEM_CACHE_CREATE(nvidia_p2p_page_t_cache, "nvidia_p2p_page_t",
+- nvidia_p2p_page_t);
++ nvidia_p2p_page_t, 0);
+ if (nvidia_p2p_page_t_cache == NULL)
+ {
+ rc = -ENOMEM;
+diff -urp kernel.orig/nv-linux.h kernel/nv-linux.h
+--- kernel.orig/nv-linux.h 2011-09-24 02:32:09.000000000 +0200
++++ kernel/nv-linux.h 2011-10-05 19:14:42.522238996 +0200
+@@ -695,16 +695,16 @@ extern nv_spinlock_t km_lock;
+
+ #if defined(NV_KMEM_CACHE_CREATE_PRESENT)
+ #if (NV_KMEM_CACHE_CREATE_ARGUMENT_COUNT == 6)
+-#define NV_KMEM_CACHE_CREATE(kmem_cache, name, type) \
++#define NV_KMEM_CACHE_CREATE(kmem_cache, name, type, flags) \
+ { \
+ kmem_cache = kmem_cache_create(name, sizeof(type), \
+- 0, 0, NULL, NULL); \
++ 0, flags, NULL, NULL); \
+ }
+ #elif (NV_KMEM_CACHE_CREATE_ARGUMENT_COUNT == 5)
+-#define NV_KMEM_CACHE_CREATE(kmem_cache, name, type) \
++#define NV_KMEM_CACHE_CREATE(kmem_cache, name, type, flags) \
+ { \
+ kmem_cache = kmem_cache_create(name, sizeof(type), \
+- 0, 0, NULL); \
++ 0, flags, NULL); \
+ }
+ #else
+ #error "NV_KMEM_CACHE_CREATE_ARGUMENT_COUNT value unrecognized!"
diff --git a/x11-drivers/nvidia-drivers/files/nvidia-persistenced.conf b/x11-drivers/nvidia-drivers/files/nvidia-persistenced.conf
new file mode 100644
index 000000000000..637ac1afb415
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/nvidia-persistenced.conf
@@ -0,0 +1,8 @@
+# run-time configuration file for /etc/init.d/nvidia-persistenced
+
+# NVPD_USER: The user nvidia-persistenced is intended to run for
+NVPD_USER=""
+
+# ARGS: Additional arguments to set the default persistence mode
+# (see nvidia-persistenced(1))
+ARGS=""
diff --git a/x11-drivers/nvidia-drivers/files/nvidia-persistenced.init b/x11-drivers/nvidia-drivers/files/nvidia-persistenced.init
new file mode 100644
index 000000000000..f80456d16036
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/nvidia-persistenced.init
@@ -0,0 +1,24 @@
+#!/sbin/openrc-run
+# Copyright 1999-2014 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+pidfile="/var/run/nvidia-persistenced/nvidia-persistenced.pid"
+
+start() {
+ if ! [ "${NVPD_USER}x" = x ]; then
+ ebegin "Starting nvidia-persistenced for ${NVPD_USER}"
+ NVPD_USER_ARG="--user ${NVPD_USER}"
+ else
+ ebegin "Starting nvidia-persistenced"
+ fi
+ start-stop-daemon --start --quiet --pidfile ${pidfile} \
+ --background --exec /opt/bin/nvidia-persistenced \
+ -- ${NVPD_USER_ARG} ${ARGS}
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping nvidia-persistenced"
+ start-stop-daemon --stop --quiet --pidfile ${pidfile}
+ eend $?
+}
diff --git a/x11-drivers/nvidia-drivers/files/nvidia-rmmod.conf b/x11-drivers/nvidia-drivers/files/nvidia-rmmod.conf
new file mode 100644
index 000000000000..618b9b30b86d
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/nvidia-rmmod.conf
@@ -0,0 +1,3 @@
+# Nvidia UVM support
+
+remove nvidia modprobe -r --ignore-remove nvidia-drm nvidia-modeset nvidia-uvm nvidia
diff --git a/x11-drivers/nvidia-drivers/files/nvidia-settings.desktop b/x11-drivers/nvidia-drivers/files/nvidia-settings.desktop
new file mode 100644
index 000000000000..b4b452ec829a
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/nvidia-settings.desktop
@@ -0,0 +1,7 @@
+[Desktop Entry]
+Type=Application
+Name=NVIDIA X Server Settings
+Comment=Configure NVIDIA X Server Settings
+Exec=/usr/bin/nvidia-settings
+Icon=nvidia-settings
+Categories=System;Settings;
diff --git a/x11-drivers/nvidia-drivers/files/nvidia-smi.init b/x11-drivers/nvidia-drivers/files/nvidia-smi.init
new file mode 100644
index 000000000000..8ee51e348939
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/nvidia-smi.init
@@ -0,0 +1,24 @@
+#!/sbin/openrc-run
+# Copyright 1999-2013 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+pidfile="/run/nvidia-smi.pid"
+
+depend() {
+ after modules
+}
+
+start() {
+ ebegin "Starting NVIDIA System Management Interface"
+ rm -f ${pidfile}
+ start-stop-daemon --start --quiet --pidfile ${pidfile} \
+ --make-pidfile --background --exec /opt/bin/nvidia-smi -- \
+ -q -l 300
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping NVIDIA System Management Interface"
+ start-stop-daemon --stop --quiet --pidfile ${pidfile}
+ eend $?
+}
diff --git a/x11-drivers/nvidia-drivers/files/nvidia-udev.sh b/x11-drivers/nvidia-drivers/files/nvidia-udev.sh
new file mode 100644
index 000000000000..9487b08e7a5e
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/nvidia-udev.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+if [ $# -ne 1 ]; then
+ echo "Invalid args" >&2
+ exit 1
+fi
+
+case $1 in
+ add|ADD)
+ /opt/bin/nvidia-smi > /dev/null
+ ;;
+ remove|REMOVE)
+ rm -f /dev/nvidia*
+ ;;
+esac
+
+exit 0
diff --git a/x11-drivers/nvidia-drivers/files/nvidia-udev.sh-r1 b/x11-drivers/nvidia-drivers/files/nvidia-udev.sh-r1
new file mode 100644
index 000000000000..6579bf74adb2
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/nvidia-udev.sh-r1
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+if [ $# -ne 1 ]; then
+ echo "Invalid args" >&2
+ exit 1
+fi
+
+case $1 in
+ add|ADD)
+ #hopefully this prevents infinite loops like bug #454740
+ if lsmod | grep -iq nvidia; then
+ /opt/bin/nvidia-smi > /dev/null
+ fi
+ ;;
+ remove|REMOVE)
+ rm -f /dev/nvidia*
+ ;;
+esac
+
+exit 0
diff --git a/x11-drivers/nvidia-drivers/files/nvidia-uvm.conf b/x11-drivers/nvidia-drivers/files/nvidia-uvm.conf
new file mode 100644
index 000000000000..222c5ba39265
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/nvidia-uvm.conf
@@ -0,0 +1,3 @@
+# Nvidia UVM support
+
+remove nvidia modprobe -r --ignore-remove nvidia-uvm nvidia
diff --git a/x11-drivers/nvidia-drivers/files/nvidia.udev-rule b/x11-drivers/nvidia-drivers/files/nvidia.udev-rule
new file mode 100644
index 000000000000..2eb30bb0eba5
--- /dev/null
+++ b/x11-drivers/nvidia-drivers/files/nvidia.udev-rule
@@ -0,0 +1,6 @@
+ACTION=="add", DEVPATH=="/module/nvidia", SUBSYSTEM=="module", RUN+="nvidia-udev.sh $env{ACTION}"
+# Previously the ACTION was "add|remove" but one user on bug #376527 had a
+# problem until he recompiled udev-171-r5, which is one of the versions I
+# tested with and it was fine. I'm breaking the rules out just to be safe
+# so someone else doesn't have an issue
+ACTION=="remove", DEVPATH=="/module/nvidia", SUBSYSTEM=="module", RUN+="nvidia-udev.sh $env{ACTION}"