diff options
author | Jonathon Fernyhough | 2021-01-01 16:11:40 +0000 |
---|---|---|
committer | Jonathon Fernyhough | 2021-01-01 16:11:40 +0000 |
commit | 614fcd8ea53184b4c794fef58297699b058bebef (patch) | |
tree | 31b4e401b1fd7d628e7534baeab2d6fdc72e553a | |
parent | b24d23c6f54b7a81363c8543c24a5a2ca2534fc2 (diff) | |
download | aur-614fcd8ea53184b4c794fef58297699b058bebef.tar.gz |
Fix nvidia-uvm
-rw-r--r-- | .SRCINFO | 8 | ||||
-rw-r--r-- | PKGBUILD | 43 | ||||
-rw-r--r-- | kernel-5.8.patch | 8 | ||||
-rw-r--r-- | uvm_common-415.18.c | 378 |
4 files changed, 401 insertions, 36 deletions
@@ -1,7 +1,7 @@ pkgbase = nvidia-390xx pkgdesc = NVIDIA drivers for linux, 390xx legacy branch pkgver = 390.138 - pkgrel = 9 + pkgrel = 10 url = https://www.nvidia.com/ arch = x86_64 license = custom @@ -15,13 +15,13 @@ pkgbase = nvidia-390xx source = kernel-5.8.patch source = kernel-5.9.patch source = https://gitlab.com/herecura/packages/nvidia-390xx-dkms/-/raw/db83ed8ac2e0e0097d535a82e2fd4ee0f31873e3/kernel-5.10.patch - source = https://salsa.debian.org/nvidia-team/nvidia-graphics-drivers/-/raw/4ba8f0d0b7fc3e7c2cce19c23930b279c15280e5/debian/module/debian/patches/disable-module-nvidia-uvm.patch + source = uvm_common-415.18.c b2sums = bf56cef38d76accdf547b96cd444b0bd4288f604d44a1d274f3246c13310d6a59050b36f384280edb83938db81fa0544f7a2dc84ff6f440ff90b76ee62749fc1 b2sums = 1d21307640a3844752c92e8344518daf6ad62d846689bebe6eed4dcadbf7b2e742862f5c17c0faee7256662cb75e62e124d59e5a5617e87324e1f0658f2b748d - b2sums = dd3ce18cddc1984deffb94c999b4f086da2fac784fc09dc092efd2fb78b65200fadf90d13f6352226ebbf4aa99b4258aae722403b90ddd64eee1c942ef94114b + b2sums = ce2cfd5a0eab3b01415beb5ebab40baec9b713c52e8a51fab8b144996a581b3e7532fc5ff831f43fcb4167f479cb006924790a4b634190a17fac5a93f83e7953 b2sums = 7358919041a3d5df1cac50f6519b282abe7a344f07b59d52ab95a022ce0af12e743a1c194fd838b5733f3900e68c7f0756a528ac32255775f2ba830a2f052dec b2sums = 8d7c054ff08ed6212aa81f3db6597c1e016609bdddfb19161274e5e75b0ae8b5c5501740ca6a75367d152b16f8350319bd2577561aa796cfe49840c4bd2c2d5d - b2sums = 435120fd87d901f36f4b3ed4d7d2a6a745185feb66506981b231071aec255b2bc91c536685e5c943ce17f07f4c52ca8086c08fa5c6367dddebc4b3c2493c32ae + b2sums = 4f61721cb9f3f76953c552ac8c131a592418078be63f98d43bd7248422cb2d88cfc1341f64b9124c7f102bf17635bb2734bd597b7b1011cc24223a5cc5fbf233 pkgname = nvidia-390xx pkgdesc = NVIDIA drivers for linux, 390xx legacy branch @@ -9,7 +9,7 @@ pkgbase=nvidia-390xx pkgname=(nvidia-390xx nvidia-390xx-dkms) pkgver=390.138 -pkgrel=9 +pkgrel=10 pkgdesc="NVIDIA drivers for linux, 390xx legacy branch" arch=('x86_64') url="https://www.nvidia.com/" @@ -23,23 +23,27 @@ source=("https://us.download.nvidia.com/XFree86/Linux-x86_64/${pkgver}/${_pkg}.r 'kernel-5.8.patch' 'kernel-5.9.patch' 'https://gitlab.com/herecura/packages/nvidia-390xx-dkms/-/raw/db83ed8ac2e0e0097d535a82e2fd4ee0f31873e3/kernel-5.10.patch' - 'https://salsa.debian.org/nvidia-team/nvidia-graphics-drivers/-/raw/4ba8f0d0b7fc3e7c2cce19c23930b279c15280e5/debian/module/debian/patches/disable-module-nvidia-uvm.patch') + 'uvm_common-415.18.c') b2sums=('bf56cef38d76accdf547b96cd444b0bd4288f604d44a1d274f3246c13310d6a59050b36f384280edb83938db81fa0544f7a2dc84ff6f440ff90b76ee62749fc1' '1d21307640a3844752c92e8344518daf6ad62d846689bebe6eed4dcadbf7b2e742862f5c17c0faee7256662cb75e62e124d59e5a5617e87324e1f0658f2b748d' - 'dd3ce18cddc1984deffb94c999b4f086da2fac784fc09dc092efd2fb78b65200fadf90d13f6352226ebbf4aa99b4258aae722403b90ddd64eee1c942ef94114b' + 'c68dc5d3bb659c4e9fc595d6e143677e58a4d564f171490a1cae85b58fb5860240d8dcafb8f314736bb5856a040d7439ce9595cefe61e3dbb7a9166ec7e76ad7' '7358919041a3d5df1cac50f6519b282abe7a344f07b59d52ab95a022ce0af12e743a1c194fd838b5733f3900e68c7f0756a528ac32255775f2ba830a2f052dec' '8d7c054ff08ed6212aa81f3db6597c1e016609bdddfb19161274e5e75b0ae8b5c5501740ca6a75367d152b16f8350319bd2577561aa796cfe49840c4bd2c2d5d' - '435120fd87d901f36f4b3ed4d7d2a6a745185feb66506981b231071aec255b2bc91c536685e5c943ce17f07f4c52ca8086c08fa5c6367dddebc4b3c2493c32ae') + '4f61721cb9f3f76953c552ac8c131a592418078be63f98d43bd7248422cb2d88cfc1341f64b9124c7f102bf17635bb2734bd597b7b1011cc24223a5cc5fbf233') prepare() { sh "${_pkg}.run" --extract-only cd "${_pkg}" + # Use GPL2/MIT code directly from 415.18 release + # https://www.nvidia.com/Download/driverResults.aspx/140282/en-us + install -m644 ../uvm_common-415.18.c kernel/nvidia-uvm/uvm_common.c + # Restore phys_to_dma support (still needed for 396.18) (and still needed for 390.138) # https://bugs.archlinux.org/task/58074 patch -Np1 -i ../kernel-4.16.patch - # 5.8 Patch + # 5.8 Patch, Alberto Milone patch -Np1 -i ../kernel-5.8.patch # 5.9 Patch, from loqs @@ -49,14 +53,6 @@ prepare() { patch -Np1 -i ../kernel-5.10.patch cp -a kernel kernel-dkms - - # 5.10 disable UVM, from Debian - pushd kernel - patch -Np1 -i ../../disable-module-nvidia-uvm.patch - popd - - cp -a kernel kernel-dkms-noUVM - cd kernel-dkms sed -i "s/__VERSION_STRING/${pkgver}/" dkms.conf sed -i 's/__JOBS/`nproc`/' dkms.conf @@ -68,23 +64,7 @@ DEST_MODULE_LOCATION[1]="/kernel/drivers/video"\ BUILT_MODULE_NAME[2]="nvidia-modeset"\ DEST_MODULE_LOCATION[2]="/kernel/drivers/video"\ BUILT_MODULE_NAME[3]="nvidia-drm"\ -DEST_MODULE_LOCATION[3]="/kernel/drivers/video"\ -BUILD_EXCLUSIVE_KERNEL="^(4\\..*|5\\.[0-9]\\.."' dkms.conf - - # Gift for linux-rt guys - sed -i 's/NV_EXCLUDE_BUILD_MODULES/IGNORE_PREEMPT_RT_PRESENCE=1 NV_EXCLUDE_BUILD_MODULES/' dkms.conf - - cd ../kernel-dkms-noUVM - sed -i "s/__VERSION_STRING/${pkgver}/" dkms.conf - sed -i 's/__JOBS/`nproc`/' dkms.conf - sed -i 's/__DKMS_MODULES//' dkms.conf - sed -i '$iBUILT_MODULE_NAME[0]="nvidia"\ -DEST_MODULE_LOCATION[0]="/kernel/drivers/video"\ -BUILT_MODULE_NAME[1]="nvidia-modeset"\ -DEST_MODULE_LOCATION[1]="/kernel/drivers/video"\ -BUILT_MODULE_NAME[2]="nvidia-drm"\ -DEST_MODULE_LOCATION[2]="/kernel/drivers/video"\ -BUILD_EXCLUSIVE_KERNEL="^5\\.10\\..*"' dkms.conf +DEST_MODULE_LOCATION[3]="/kernel/drivers/video"' dkms.conf # Gift for linux-rt guys sed -i 's/NV_EXCLUDE_BUILD_MODULES/IGNORE_PREEMPT_RT_PRESENCE=1 NV_EXCLUDE_BUILD_MODULES/' dkms.conf @@ -101,7 +81,7 @@ package_nvidia-390xx() { _extradir="/usr/lib/modules/$(</usr/src/linux/version)/extramodules" install -Dt "${pkgdir}${_extradir}" -m644 \ - "${srcdir}/${_pkg}/kernel"/nvidia{,-modeset,-drm}.ko + "${srcdir}/${_pkg}/kernel"/nvidia{,-modeset,-drm,-uvm}.ko find "${pkgdir}" -name '*.ko' -exec gzip -n {} + @@ -121,7 +101,6 @@ package_nvidia-390xx-dkms() { install -dm 755 "${pkgdir}"/usr/src cp -dr --no-preserve='ownership' kernel-dkms "${pkgdir}/usr/src/nvidia-${pkgver}" - cp -dr --no-preserve='ownership' kernel-dkms-noUVM "${pkgdir}/usr/src/nvidia-noUVM-${pkgver}" echo "blacklist nouveau" | install -Dm644 /dev/stdin "${pkgdir}/usr/lib/modprobe.d/${pkgname}.conf" diff --git a/kernel-5.8.patch b/kernel-5.8.patch index 31bc0e685baf..b936e274219d 100644 --- a/kernel-5.8.patch +++ b/kernel-5.8.patch @@ -2,6 +2,13 @@ From: Alberto Milone <alberto.milone@canonical.com> Date: Mon, 13 Jul 2020 14:04:41 +0200 Subject: [PATCH 1/1] Add support for Linux 5.8 +--- + kernel/common/inc/nv-linux.h | 4 ++++ + kernel/common/inc/nv-mm.h | 4 ++++ + kernel/conftest.sh | 38 ++++++++++++++++++++++++++++++++++++++ + kernel/nvidia/nvidia.Kbuild | 2 ++ + 4 files changed, 48 insertions(+) + diff --git a/kernel/common/inc/nv-linux.h b/kernel/common/inc/nv-linux.h index ac5bb95..3d2f0b7 100644 --- a/kernel/common/inc/nv-linux.h @@ -98,3 +105,4 @@ index 63e369f..656db7b 100644 NV_CONFTEST_TYPE_COMPILE_TESTS += pci_dev_has_skip_bus_pm -- 2.25.1 + diff --git a/uvm_common-415.18.c b/uvm_common-415.18.c new file mode 100644 index 000000000000..fe227514ca89 --- /dev/null +++ b/uvm_common-415.18.c @@ -0,0 +1,378 @@ +/******************************************************************************* + Copyright (c) 2013-2018 NVIDIA Corporation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*******************************************************************************/ + +/* + * This file contains code that is common to all variants of the (Linux) UVM + * kernel module. + */ + +#include "uvm_common.h" +#include "uvm_linux.h" + +// TODO: Bug 1766109: Remove this when the GPU event stubs are no longer needed +#include "nv_uvm_interface.h" + +#include "uvm8_init.h" +#include "uvm8_forward_decl.h" + +// TODO: Bug 1710855: Tweak this number through benchmarks +#define UVM_SPIN_LOOP_SCHEDULE_TIMEOUT_NS (10*1000ULL) +#define UVM_SPIN_LOOP_PRINT_TIMEOUT_SEC 30ULL + +static dev_t g_uvmBaseDev; +struct UvmOpsUvmEvents g_exportedUvmOps; + +static char* uvm_driver_mode = "8"; + +// There used to be other choices, but now there is only one driver mode: 8. +// If no more choices show up soon, we may just delete this module parameter +// entirely. +module_param(uvm_driver_mode, charp, S_IRUGO); +MODULE_PARM_DESC(uvm_driver_mode, + "Set the uvm kernel driver mode. Choices include: 8"); + +// Default to debug prints being enabled for debug and develop builds and +// disabled for release builds. +static int uvm_debug_prints = UVM_IS_DEBUG() || UVM_IS_DEVELOP(); + +// Make the module param writable so that prints can be enabled or disabled at +// any time by modifying the module parameter. +module_param(uvm_debug_prints, int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(uvm_debug_prints, "Enable uvm debug prints."); + +bool uvm_debug_prints_enabled() +{ + return uvm_debug_prints != 0; +} + +typedef enum +{ + UVM_DRIVER_MODE_8, +} UvmDriverMode; + +static const char * uvm_driver_mode_to_string(UvmDriverMode uvmDriverMode) +{ + switch (uvmDriverMode) + { + case UVM_DRIVER_MODE_8: + return "8"; + } + return "invalid"; +} + +static UvmDriverMode uvm_get_mode(void) +{ + static NvBool bUvmDriverModeChecked = NV_FALSE; + static UvmDriverMode uvmDriverMode; + + if (!bUvmDriverModeChecked) + { + uvmDriverMode = UVM_DRIVER_MODE_8; + + bUvmDriverModeChecked = NV_TRUE; + } + + return uvmDriverMode; +} + +NV_STATUS uvm_api_initialize(UVM_INITIALIZE_PARAMS *params, struct file *filp) +{ + params->rmStatus = uvm8_initialize(params, filp); + return params->rmStatus; +} + +// This function serves to 'stub' out functionality by being a No-Op and +// returning NV_OK early. +NV_STATUS uvm_api_stub(void *pParams, struct file *filp) +{ + return NV_OK; +} + +// This function serves to identify functionality that isn't supported +// in this UVM driver, by returning NV_ERR_NOT_SUPPORTED early. +NV_STATUS uvm_api_unsupported(void *pParams, struct file *filp) +{ + return NV_ERR_NOT_SUPPORTED; +} + +// +// TODO: Bug 1766109: uvm8: delete UVM-Lite files and remove -lite mode +// ...just remove -lite mode, instead of the original to-do: which was: +// +static int __init uvm_init(void) +{ + NvBool allocated_dev = NV_FALSE; + + // The various helper init routines will create their own minor devices, so + // we only need to create space for them here. + int ret = alloc_chrdev_region(&g_uvmBaseDev, + 0, + NVIDIA_UVM_NUM_MINOR_DEVICES, + NVIDIA_UVM_DEVICE_NAME); + if (ret != 0) { + UVM_ERR_PRINT("alloc_chrdev_region failed: %d\n", ret); + goto error; + } + allocated_dev = NV_TRUE; + + ret = uvm8_init(g_uvmBaseDev); + + if (ret != 0) { + UVM_ERR_PRINT("uvm init failed: %d\n", ret); + goto error; + } + + pr_info("Loaded the UVM driver in %s mode, major device number %d\n", + uvm_driver_mode_to_string(uvm_get_mode()), MAJOR(g_uvmBaseDev)); + + if (uvm_enable_builtin_tests) + pr_info("Built-in UVM tests are enabled. This is a security risk.\n"); + + return 0; + +error: + if (allocated_dev) + unregister_chrdev_region(g_uvmBaseDev, NVIDIA_UVM_NUM_MINOR_DEVICES); + + return ret; +} + +static void __exit uvm_exit(void) +{ + uvm8_exit(); + + unregister_chrdev_region(g_uvmBaseDev, NVIDIA_UVM_NUM_MINOR_DEVICES); + + pr_info("Unloaded the UVM driver in %s mode\n", uvm_driver_mode_to_string(uvm_get_mode())); +} + +// +// Convert kernel errno codes to corresponding NV_STATUS +// +NV_STATUS errno_to_nv_status(int errnoCode) +{ + if (errnoCode < 0) + errnoCode = -errnoCode; + + switch (errnoCode) + { + case 0: + return NV_OK; + + case E2BIG: + case EINVAL: + return NV_ERR_INVALID_ARGUMENT; + + case EACCES: + return NV_ERR_INVALID_ACCESS_TYPE; + + case EADDRINUSE: + case EADDRNOTAVAIL: + return NV_ERR_UVM_ADDRESS_IN_USE; + + case EFAULT: + return NV_ERR_INVALID_ADDRESS; + + case EINTR: + case EBUSY: + return NV_ERR_BUSY_RETRY; + + case ENXIO: + case ENODEV: + return NV_ERR_MODULE_LOAD_FAILED; + + case ENOMEM: + return NV_ERR_NO_MEMORY; + + case EPERM: + return NV_ERR_INSUFFICIENT_PERMISSIONS; + + case ESRCH: + return NV_ERR_PID_NOT_FOUND; + + case ETIMEDOUT: + return NV_ERR_TIMEOUT; + + case EEXIST: + return NV_ERR_IN_USE; + + case ENOSYS: + return NV_ERR_NOT_SUPPORTED; + + case ENOENT: + return NV_ERR_NO_VALID_PATH; + + case EIO: + return NV_ERR_RC_ERROR; + + default: + return NV_ERR_GENERIC; + }; +} + +// Returns POSITIVE errno +int nv_status_to_errno(NV_STATUS status) +{ + switch (status) { + case NV_OK: + return 0; + + case NV_ERR_BUSY_RETRY: + return EBUSY; + + case NV_ERR_INSUFFICIENT_PERMISSIONS: + return EPERM; + + case NV_ERR_GPU_UUID_NOT_FOUND: + return ENODEV; + + case NV_ERR_INSUFFICIENT_RESOURCES: + case NV_ERR_NO_MEMORY: + return ENOMEM; + + case NV_ERR_INVALID_ACCESS_TYPE: + return EACCES; + + case NV_ERR_INVALID_ADDRESS: + return EFAULT; + + case NV_ERR_INVALID_ARGUMENT: + case NV_ERR_INVALID_DEVICE: + case NV_ERR_INVALID_PARAMETER: + case NV_ERR_INVALID_REQUEST: + case NV_ERR_INVALID_STATE: + return EINVAL; + + case NV_ERR_NOT_SUPPORTED: + return ENOSYS; + + case NV_ERR_MODULE_LOAD_FAILED: + return ENXIO; + + case NV_ERR_OVERLAPPING_UVM_COMMIT: + case NV_ERR_UVM_ADDRESS_IN_USE: + return EADDRINUSE; + + case NV_ERR_PID_NOT_FOUND: + return ESRCH; + + case NV_ERR_TIMEOUT: + case NV_ERR_TIMEOUT_RETRY: + return ETIMEDOUT; + + case NV_ERR_IN_USE: + return EEXIST; + + case NV_ERR_NO_VALID_PATH: + return ENOENT; + + case NV_ERR_RC_ERROR: + case NV_ERR_ECC_ERROR: + return EIO; + + default: + UVM_ASSERT_MSG(0, "No errno conversion set up for NV_STATUS %s\n", nvstatusToString(status)); + return EINVAL; + } +} + +// +// This routine retrieves the process ID of current, but makes no attempt to +// refcount or lock the pid in place, because that capability is only available +// to GPL-licenses device drivers. +// +// TODO: Bug 1483843: Use the GPL-protected routines if and when we are able to +// change over to a dual MIT/GPL license. +// +unsigned uvm_get_stale_process_id(void) +{ + return (unsigned) current->tgid; +} + +unsigned uvm_get_stale_thread_id(void) +{ + return (unsigned) current->pid; +} + +// +// A simple security rule for allowing access to UVM user space memory: if you +// are the same user as the owner of the memory, or if you are root, then you +// are granted access. The idea is to allow debuggers and profilers to work, but +// without opening up any security holes. +// +NvBool uvm_user_id_security_check(uid_t euidTarget) +{ + return (NV_CURRENT_EUID() == euidTarget) || + (UVM_ROOT_UID == euidTarget); +} + +void on_uvm_assert(void) +{ + (void)NULL; +} + +NV_STATUS uvm_spin_loop(uvm_spin_loop_t *spin) +{ + NvU64 curr = NV_GETTIME(); + + // This schedule() is required for functionality, not just system + // performance. It allows RM to run and unblock the UVM driver: + // + // - UVM must service faults in order for RM to idle/preempt a context + // - RM must service interrupts which stall UVM (SW methods, stalling CE + // interrupts, etc) in order for UVM to service faults + // + // Even though UVM's bottom half is preemptable, we have encountered cases + // in which a user thread running in RM won't preempt the UVM driver's + // thread unless the UVM driver thread gives up its timeslice. This is also + // theoretically possible if the RM thread has a low nice priority. + // + // TODO: Bug 1710855: Look into proper prioritization of these threads as a longer-term + // solution. + if (curr - spin->start_time_ns >= UVM_SPIN_LOOP_SCHEDULE_TIMEOUT_NS && NV_MAY_SLEEP()) { + schedule(); + curr = NV_GETTIME(); + } + + cpu_relax(); + + // TODO: Bug 1710855: Also check fatal_signal_pending() here if the caller can handle it. + + if (curr - spin->print_time_ns >= 1000*1000*1000*UVM_SPIN_LOOP_PRINT_TIMEOUT_SEC) { + spin->print_time_ns = curr; + return NV_ERR_TIMEOUT_RETRY; + } + + return NV_OK; +} + +module_init(uvm_init); +module_exit(uvm_exit); + +// This parameter allows a program in user mode to call the kernel tests +// defined in this module. This parameter should only be used for testing and +// must not be set to true otherwise since it breaks security when it is +// enabled. By default and for safety reasons this parameter is set to false. +int uvm_enable_builtin_tests = 0; +module_param(uvm_enable_builtin_tests, int, S_IRUGO); +MODULE_PARM_DESC(uvm_enable_builtin_tests, + "Enable the UVM built-in tests. (This is a security risk)"); + +MODULE_LICENSE("Dual MIT/GPL"); +MODULE_INFO(supported, "external"); |