├── nvidia-merged ├── nvidia-utils.sysusers ├── .gitignore ├── vgpu_unlock-rs.conf ├── nv-kernel.patch ├── nvidia-vgpu.conf ├── nvidia-smi ├── nvidia-drm-outputclass.conf ├── disable-nvidia-blob-version-check.patch ├── nvidia.rules ├── README.md ├── nvidia-510.73.05-vgpu-5.18.patch ├── .SRCINFO ├── PKGBUILD └── vgpu_unlock.patch ├── rider-projector ├── .gitignore ├── rider-projector.service ├── .SRCINFO ├── run.sh.patch └── PKGBUILD ├── melvor-mod-manager ├── .gitignore ├── melvor-mod-manager.png ├── melvor-mod-manager.desktop ├── .SRCINFO └── PKGBUILD ├── nvidia-vgpu ├── .gitignore ├── vgpu_unlock-rs.conf ├── nv-kernel.patch ├── nvidia-vgpu.conf ├── nvidia-smi ├── .SRCINFO ├── nvidia-510.73.05-vgpu-5.18.patch ├── PKGBUILD └── vgpu_unlock.patch └── README.md /nvidia-merged/nvidia-utils.sysusers: -------------------------------------------------------------------------------- 1 | u nvidia-persistenced 143 'NVIDIA Persistence Daemon' 2 | -------------------------------------------------------------------------------- /rider-projector/.gitignore: -------------------------------------------------------------------------------- 1 | pkg 2 | src 3 | projector-installer 4 | *.tar.zst 5 | *.tar.gz 6 | -------------------------------------------------------------------------------- /melvor-mod-manager/.gitignore: -------------------------------------------------------------------------------- 1 | pkg 2 | src 3 | melvor-mod-manager/ 4 | *.tar.zst 5 | *.tar.gz 6 | -------------------------------------------------------------------------------- /nvidia-merged/.gitignore: -------------------------------------------------------------------------------- 1 | pkg 2 | src 3 | vgpu_unlock-rs 4 | *.run 5 | *.tar.zst 6 | *.tar.gz 7 | -------------------------------------------------------------------------------- /nvidia-vgpu/.gitignore: -------------------------------------------------------------------------------- 1 | pkg 2 | src 3 | vgpu_unlock-rs 4 | *.run 5 | *.tar.zst 6 | *.tar.gz 7 | -------------------------------------------------------------------------------- /nvidia-merged/vgpu_unlock-rs.conf: -------------------------------------------------------------------------------- 1 | [Service] 2 | Environment=LD_PRELOAD=/usr/lib/nvidia/libvgpu_unlock_rs.so 3 | -------------------------------------------------------------------------------- /nvidia-vgpu/vgpu_unlock-rs.conf: -------------------------------------------------------------------------------- 1 | [Service] 2 | Environment=LD_PRELOAD=/usr/lib/nvidia/libvgpu_unlock_rs.so 3 | -------------------------------------------------------------------------------- /nvidia-vgpu/nv-kernel.patch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erin-allison/aur-packages/HEAD/nvidia-vgpu/nv-kernel.patch -------------------------------------------------------------------------------- /nvidia-merged/nv-kernel.patch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erin-allison/aur-packages/HEAD/nvidia-merged/nv-kernel.patch -------------------------------------------------------------------------------- /melvor-mod-manager/melvor-mod-manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erin-allison/aur-packages/HEAD/melvor-mod-manager/melvor-mod-manager.png -------------------------------------------------------------------------------- /nvidia-merged/nvidia-vgpu.conf: -------------------------------------------------------------------------------- 1 | [Unit] 2 | After=nvidia-vgpud.service 3 | After=nvidia-vgpu-mgr.service 4 | Wants=nvidia-vgpud.service 5 | Wants=nvidia-vgpu-mgr.service -------------------------------------------------------------------------------- /nvidia-vgpu/nvidia-vgpu.conf: -------------------------------------------------------------------------------- 1 | [Unit] 2 | After=nvidia-vgpud.service 3 | After=nvidia-vgpu-mgr.service 4 | Wants=nvidia-vgpud.service 5 | Wants=nvidia-vgpu-mgr.service 6 | -------------------------------------------------------------------------------- /nvidia-vgpu/nvidia-smi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | 3 | for a in $* 4 | do 5 | case $a in 6 | vgpu) 7 | export LD_PRELOAD="/usr/lib/nvidia/libvgpu_unlock_rs.so" 8 | ;; 9 | esac 10 | done 11 | 12 | exec /usr/lib/nvidia/nvidia-smi.orig $@ 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Erin's AUR Packages 2 | 3 | Package sources for all the AUR packages I [maintain](https://aur.archlinux.org/packages/?SeB=m&K=Erin-Allison). 4 | 5 | ## Credits 6 | 7 | Maintained using [aurpublish](https://github.com/eli-schwartz/aurpublish). 8 | 9 | -------------------------------------------------------------------------------- /nvidia-merged/nvidia-smi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | 3 | for a in $* 4 | do 5 | case $a in 6 | vgpu) 7 | export LD_PRELOAD="/usr/lib/nvidia/libvgpu_unlock_rs.so" 8 | ;; 9 | esac 10 | done 11 | 12 | exec /usr/lib/nvidia/nvidia-smi.orig $@ 13 | -------------------------------------------------------------------------------- /rider-projector/rider-projector.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=JetBrains Projector host for Rider .NET IDE 3 | 4 | [Service] 5 | Type=simple 6 | ExecStart=/usr/bin/rider-projector 7 | Restart=always 8 | RestartSec=1 9 | 10 | [Install] 11 | WantedBy=default.target 12 | -------------------------------------------------------------------------------- /melvor-mod-manager/melvor-mod-manager.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.4 3 | Type=Application 4 | Name=Melvor Mod Manager 5 | Icon=melvor-mod-manager 6 | Exec=/usr/bin/melvor-mod-manager 7 | Comment= 8 | Categories=Utility; 9 | Terminal=false 10 | StartupWMClass=melvor-mod-manager 11 | -------------------------------------------------------------------------------- /nvidia-merged/nvidia-drm-outputclass.conf: -------------------------------------------------------------------------------- 1 | Section "OutputClass" 2 | Identifier "nvidia" 3 | MatchDriver "nvidia-drm" 4 | Driver "nvidia" 5 | Option "AllowEmptyInitialConfiguration" 6 | ModulePath "/usr/lib/nvidia/xorg" 7 | ModulePath "/usr/lib/xorg/modules" 8 | EndSection 9 | -------------------------------------------------------------------------------- /nvidia-merged/disable-nvidia-blob-version-check.patch: -------------------------------------------------------------------------------- 1 | diff --git a/kernel/nvidia/nv.c b/kernel/nvidia/nv.c 2 | index 74ad0aa..38c9a1d 100644 3 | --- a/kernel/nvidia/nv.c 4 | +++ b/kernel/nvidia/nv.c 5 | @@ -2193,7 +2193,7 @@ nvidia_ioctl( 6 | { 7 | NV_CTL_DEVICE_ONLY(nv); 8 | 9 | - rmStatus = rm_perform_version_check(sp, arg_copy, arg_size); 10 | + rmStatus = NV_OK; //rm_perform_version_check(sp, arg_copy, arg_size); 11 | status = ((rmStatus == NV_OK) ? 0 : -EINVAL); 12 | break; 13 | } 14 | -------------------------------------------------------------------------------- /melvor-mod-manager/.SRCINFO: -------------------------------------------------------------------------------- 1 | pkgbase = melvor-mod-manager 2 | pkgdesc = Melvor Mod Manager (M3) allows you to quickly add userscripts and browser extensions as mods to the Steam edition of Melvor Idle. 3 | pkgver = 0.4.2 4 | pkgrel = 1 5 | url = https://github.com/CherryMace/melvor-mod-manager 6 | arch = x86_64 7 | license = MIT 8 | makedepends = npm 9 | makedepends = nodejs 10 | source = melvor-mod-manager.desktop 11 | source = melvor-mod-manager.png 12 | source = git+https://github.com/CherryMace/melvor-mod-manager#tag=v0.4.2 13 | sha256sums = 5384e70639166be6834632e66b0f45dddb1421cb1ec25be4b0706a482f047c75 14 | sha256sums = 793cbb7b7f09e82d04fffe6fd23a4089d712d8d5aec2be71b183e9c1a4e18310 15 | sha256sums = SKIP 16 | 17 | pkgname = melvor-mod-manager 18 | -------------------------------------------------------------------------------- /nvidia-merged/nvidia.rules: -------------------------------------------------------------------------------- 1 | # Make sure device nodes are present even when the DDX is not started for the Wayland/EGLStream case 2 | KERNEL=="nvidia", RUN+="/usr/bin/bash -c '/usr/bin/mknod -Z -m 666 /dev/nvidiactl c $$(grep nvidia-frontend /proc/devices | cut -d \ -f 1) 255'" 3 | KERNEL=="nvidia", RUN+="/usr/bin/bash -c 'for i in $$(cat /proc/driver/nvidia/gpus/*/information | grep Minor | cut -d \ -f 4); do /usr/bin/mknod -Z -m 666 /dev/nvidia$${i} c $$(grep nvidia-frontend /proc/devices | cut -d \ -f 1) $${i}; done'" 4 | KERNEL=="nvidia_modeset", RUN+="/usr/bin/bash -c '/usr/bin/mknod -Z -m 666 /dev/nvidia-modeset c $$(grep nvidia-frontend /proc/devices | cut -d \ -f 1) 254'" 5 | KERNEL=="nvidia_uvm", RUN+="/usr/bin/bash -c '/usr/bin/mknod -Z -m 666 /dev/nvidia-uvm c $$(grep nvidia-uvm /proc/devices | cut -d \ -f 1) 0'" 6 | KERNEL=="nvidia_uvm", RUN+="/usr/bin/bash -c '/usr/bin/mknod -Z -m 666 /dev/nvidia-uvm-tools c $$(grep nvidia-uvm /proc/devices | cut -d \ -f 1) 1'" 7 | -------------------------------------------------------------------------------- /rider-projector/.SRCINFO: -------------------------------------------------------------------------------- 1 | pkgbase = rider-projector 2 | pkgdesc = Run JetBrains Rider as a headless service for use with Projector. 3 | pkgver = 2021.3.2 4 | pkgrel = 1 5 | url = https://www.jetbrains.com/rider/ 6 | arch = x86_64 7 | license = custom 8 | makedepends = python>=3 9 | makedepends = python-pip 10 | makedepends = python-cryptography 11 | makedepends = python-pyopenssl 12 | depends = libxext 13 | depends = libxrender 14 | depends = libxtst 15 | depends = freetype2 16 | depends = libxi 17 | depends = jre-jetbrains 18 | optdepends = projector-bin: Native client for JetBrains Projector 19 | options = !strip 20 | source = rider-projector.service 21 | source = run.sh.patch 22 | source = git+https://github.com/JetBrains/projector-installer/#tag=v1.5.2 23 | sha256sums = 101e4ea3a22c83cbe6e6ff257b2b79350f45c428dcb349903fa9dc773abd4efc 24 | sha256sums = a36da8b7467ff4687410d3d032e4df8f0abe005e347f27ae9ebb4f38ff85d5b1 25 | sha256sums = SKIP 26 | 27 | pkgname = rider-projector 28 | -------------------------------------------------------------------------------- /melvor-mod-manager/PKGBUILD: -------------------------------------------------------------------------------- 1 | # Maintainer: Erin Allison 2 | 3 | pkgname=melvor-mod-manager 4 | pkgver=0.4.2 5 | pkgrel=1 6 | pkgdesc='Melvor Mod Manager (M3) allows you to quickly add userscripts and browser extensions as mods to the Steam edition of Melvor Idle.' 7 | arch=('x86_64') 8 | license=('MIT') 9 | url="https://github.com/CherryMace/${pkgname}" 10 | makedepends=('npm' 'nodejs') 11 | source=( 12 | "${pkgname}.desktop" 13 | "${pkgname}.png" 14 | "git+https://github.com/CherryMace/${pkgname}#tag=v${pkgver}") 15 | sha256sums=( 16 | '5384e70639166be6834632e66b0f45dddb1421cb1ec25be4b0706a482f047c75' 17 | '793cbb7b7f09e82d04fffe6fd23a4089d712d8d5aec2be71b183e9c1a4e18310' 18 | 'SKIP') 19 | 20 | build() { 21 | cd "${srcdir}/${pkgname}" 22 | 23 | npm install 24 | npm run electron:build 25 | } 26 | 27 | package() { 28 | install -dm755 "${pkgdir}/usr/lib" 29 | cp -r "${srcdir}/${pkgname}/dist_electron/linux-unpacked/" "${pkgdir}/usr/lib/${pkgname}" 30 | 31 | install -dm755 "${pkgdir}/usr/bin" 32 | ln -sf "../lib/${pkgname}/${pkgname}" "${pkgdir}/usr/bin/${pkgname}" 33 | 34 | install -Dm644 "${srcdir}/${pkgname}.desktop" "${pkgdir}/usr/share/applications/${pkgname}.desktop" 35 | install -Dm644 "${srcdir}/${pkgname}.png" "${pkgdir}/usr/share/icons/hicolor/96x96/apps/${pkgname}.png" 36 | } 37 | -------------------------------------------------------------------------------- /nvidia-vgpu/.SRCINFO: -------------------------------------------------------------------------------- 1 | pkgbase = nvidia-vgpu 2 | pkgver = 510.73.06 3 | pkgrel = 1 4 | url = https://krutavshah.github.io/GPU_Virtualization-Wiki/ 5 | arch = x86_64 6 | groups = nvidia-vgpu 7 | license = custom 8 | makedepends = git 9 | makedepends = rust 10 | options = !strip 11 | source = nvidia-smi 12 | source = nvidia-vgpu.conf 13 | source = vgpu_unlock-rs.conf 14 | source = nv-kernel.patch 15 | source = nvidia-510.73.05-vgpu-5.18.patch 16 | source = vgpu_unlock.patch 17 | source = file://NVIDIA-Linux-x86_64-510.73.06-vgpu-kvm.run 18 | source = git+https://github.com/mbilker/vgpu_unlock-rs.git#commit=3858f2c 19 | sha256sums = 20676096714ac00d9fc993901ab275e4b0fa3f2eddc937dae395c8f4e8cb543e 20 | sha256sums = 9c23ae9e0ef3b9b927608079ccc5f787e7e351a780f2369479c2e75dfd0470fe 21 | sha256sums = c85ae100a6c87c12906fd0057b77c0c4190f68434de4bc3bc89348ffc19aed61 22 | sha256sums = 36325e26243429e1e55c8500bcac850fea6e6a8975a657984c0979042a001c7b 23 | sha256sums = 79b09682f9c3cfa32d219a14b3c956d8f05340addd5a43e7063c3d96175a56f4 24 | sha256sums = f77f26f609bb6f1eb69d3dc7e84ba704e5c065e424a619ab1460accb8247143f 25 | sha256sums = b7d076bee270e779b7c1eb512c9325794be2e8cbd7cd37c0f62fc72d87654a82 26 | sha256sums = SKIP 27 | 28 | pkgname = nvidia-vgpu-dkms 29 | pkgdesc = NVIDIA drivers - module sources; patched for consumer vGPU support w/ Rust unlock 30 | depends = dkms 31 | depends = nvidia-vgpu-utils=510.73.06 32 | conflicts = nvidia-dkms 33 | 34 | pkgname = nvidia-vgpu-utils 35 | pkgdesc = NVIDIA drivers utilities; patched for consumer vGPU support w/ Rust unlock 36 | optdepends = mdevctl: mediated device contfiguration tool 37 | optdepends = libvirt: virtualization engine control interface 38 | provides = vgpu_unlock 39 | conflicts = nvidia-utils 40 | replaces = vgpu_unlock 41 | -------------------------------------------------------------------------------- /rider-projector/run.sh.patch: -------------------------------------------------------------------------------- 1 | --- ./config/configs/rider/run.sh 2 | +++ ./config/configs/rider/run.sh 3 | @@ -47,7 +47,7 @@ 4 | # Locate a JRE installation directory command -v will be used to run the IDE. 5 | # Try (in order): $RIDER_JDK, .../rider.jdk, .../jbr, $JDK_HOME, $JAVA_HOME, "java" in $PATH. 6 | # --------------------------------------------------------------------- 7 | -JRE="" 8 | +JRE="/usr/lib/jvm/jre-jetbrains" 9 | 10 | # shellcheck disable=SC2154 11 | if [ -n "$RIDER_JDK" ] && [ -x "$RIDER_JDK/bin/java" ]; then 12 | @@ -142,6 +142,16 @@ 13 | CLASSPATH="$CLASSPATH:$RIDER_CLASSPATH" 14 | fi 15 | 16 | +if [ -z "$ORG_JETBRAINS_PROJECTOR_SERVER_PORT" ] 17 | +then 18 | + ORG_JETBRAINS_PROJECTOR_SERVER_PORT=8887 19 | + while true 20 | + do 21 | + fuser -i "$ORG_JETBRAINS_PROJECTOR_SERVER_PORT/tcp" >/dev/null 2>/dev/null || break 22 | + ORG_JETBRAINS_PROJECTOR_SERVER_PORT=$(($ORG_JETBRAINS_PROJECTOR_SERVER_PORT + 1)) 23 | + done 24 | +fi 25 | + 26 | # --------------------------------------------------------------------- 27 | # Run the IDE. 28 | # --------------------------------------------------------------------- 29 | @@ -155,7 +165,7 @@ 30 | "-Djb.vmOptionsFile=${USER_VM_OPTIONS_FILE:-${VM_OPTIONS_FILE}}" \ 31 | ${IDE_PROPERTIES_PROPERTY} \ 32 | -Djava.system.class.loader=com.intellij.util.lang.PathClassLoader -Didea.vendor.name=JetBrains -Didea.paths.selector=Rider2021.3 -Didea.platform.prefix=Rider -Dide.native.launcher=true -Didea.class.before.app=com.jetbrains.rider.protocol.EarlyBackendStarter -Didea.log.config.file=log.xml -Didea.show.customize.ide.wizard=true -Didea.jre.check=true -Dsplash=true \ 33 | - -DORG_JETBRAINS_PROJECTOR_SERVER_PORT=9999 \ 34 | + -DORG_JETBRAINS_PROJECTOR_SERVER_PORT=$ORG_JETBRAINS_PROJECTOR_SERVER_PORT \ 35 | -Dorg.jetbrains.projector.server.classToLaunch=com.intellij.idea.Main \ 36 | org.jetbrains.projector.server.ProjectorLauncher\ 37 | "$@" 38 | -------------------------------------------------------------------------------- /nvidia-merged/README.md: -------------------------------------------------------------------------------- 1 | # Nvidia vGPU-Merged Packages for Arch Linux 2 | Use Nvidia vGPU _and_ GeForce functions of consumer-grade NVIDIA GPUs. 3 | 4 | This repository contains scripts for building all components of the "merged" driver package into drop-in replacements for the Arch Linux NVIDIA packages. It adds the following additional functions by means of scripts/drop-ins: 5 | - Wrapper for `nvidia-smi` to support recognizing consumer GPUs as vGPU-capable 6 | - Dependency re-ordering to ensure `libvirtd`, if installed, will start _after_ the NVIDIA vGPU services. 7 | 8 | Compatible Linux Versions: 9 | - Various 5.11 or older releases 10 | - 5.12 11 | - 5.14 except for some of the earlier 5.14 releases 12 | - 5.15 13 | 14 | ## Important 15 | These packages are not guaranteed to work out of the box (or at all), so use it at your own risk. Backups should be taken before attempting to replace stock NVIDIA drivers on any system. 16 | 17 | ## Installation 18 | 1. Build and install desired packages 19 | 2. Edit `/etc/vgpu_unlock/profile_override.toml` and set desired overrides. 20 | 3. Enable `nvidia-vgpu-mgr.service` and `nvidia-vgpud.service` 21 | 4. Reboot. 22 | 23 | It is recommended to at least install `nvidia-merged` and `nvidia-merged-settings`, which will include the required services/kernel module sources by dependency. 24 | 25 | ## Credits 26 | This project would not be possible without all those who came before me that wrote the software and figured out how to implement it: 27 | - [DualCoder - vgpu_unlock](https://github.com/DualCoder/vgpu_unlock) 28 | - [rupansh - twelve.patch](https://github.com/rupansh/vgpu_unlock_5.12) 29 | - [HiFiPhile - cvgpu.c](https://gist.github.com/HiFiPhile/b3267ce1e93f15642ce3943db6e60776/) 30 | - [Krutav Shah - vGPU_Unlock Wiki](https://docs.google.com/document/d/1pzrWJ9h-zANCtyqRgS7Vzla0Y8Ea2-5z2HEi4X75d2Q) 31 | - [tuh8888 - libvirt_win10_vm](https://github.com/tuh8888/libvirt_win10_vm) 32 | - [mbilker - vgpu_unlock-rs](https://github.com/mbilker/vgpu_unlock-rs) 33 | -------------------------------------------------------------------------------- /rider-projector/PKGBUILD: -------------------------------------------------------------------------------- 1 | # Maintainer: Erin Allison 2 | 3 | pkgname=rider-projector 4 | pkgver=2021.3.2 5 | _projectorver=1.5.2 6 | pkgrel=1 7 | pkgdesc='Run JetBrains Rider as a headless service for use with Projector.' 8 | arch=('x86_64') 9 | license=('custom') 10 | url="https://www.jetbrains.com/rider/" 11 | options=('!strip') 12 | 13 | optdepends=( 14 | 'projector-bin: Native client for JetBrains Projector') 15 | makedepends=( 16 | 'python>=3' 17 | 'python-pip' 18 | 'python-cryptography' 19 | 'python-pyopenssl') 20 | depends=( 21 | 'libxext' 22 | 'libxrender' 23 | 'libxtst' 24 | 'freetype2' 25 | 'libxi' 26 | 'jre-jetbrains') 27 | 28 | source=( 29 | 'rider-projector.service' 30 | 'run.sh.patch' 31 | "git+https://github.com/JetBrains/projector-installer/#tag=v${_projectorver}") 32 | sha256sums=( 33 | '101e4ea3a22c83cbe6e6ff257b2b79350f45c428dcb349903fa9dc773abd4efc' 34 | 'a36da8b7467ff4687410d3d032e4df8f0abe005e347f27ae9ebb4f38ff85d5b1' 35 | 'SKIP') 36 | 37 | build() { 38 | cd "${srcdir}" 39 | 40 | python -m venv env 41 | source env/bin/activate 42 | 43 | python -m pip install --upgrade pip 44 | 45 | cd projector-installer 46 | 47 | python -m pip install -r requirements.txt 48 | python setup.py install 49 | 50 | cd .. 51 | 52 | rm -rf ./config ./cache 53 | 54 | projector --accept-license \ 55 | --config-directory ./config \ 56 | --cache-directory ./cache \ 57 | autoinstall \ 58 | --config-name rider \ 59 | --ide-name "Rider $pkgver" 60 | 61 | mv "${srcdir}/config/apps/JetBrains Rider-${pkgver}/license" "${srcdir}/license" 62 | 63 | # Remove bundled JRE (provided by dependency jre-jetbrains) 64 | rm -rf "./config/apps/JetBrains Rider-${pkgver}/jbr/" 65 | 66 | # Update Rider installation path 67 | sed -Ei 's|(IDE_BIN_HOME)=.+|\1="/usr/lib/jetbrains/rider-projector/rider/bin"|' './config/configs/rider/run.sh' 68 | 69 | # Update Projector installation path 70 | sed -Ei "s|${srcdir}/env/.+/server/|/usr/lib/jetbrains/rider-projector/projector/|" './config/configs/rider/run.sh' 71 | 72 | patch -p1 < ./run.sh.patch 73 | } 74 | 75 | package() { 76 | projectorserver="$(find "${srcdir}/env/lib/" -name projector_installer)/bundled/server" 77 | install -dm755 "${pkgdir}/usr/lib/jetbrains/rider-projector" 78 | install -dm755 "${pkgdir}/usr/share/licenses/" 79 | 80 | cp -dr "${srcdir}/license" "${pkgdir}/usr/share/licenses/rider-projector" 81 | cp -dr "${projectorserver}" "${pkgdir}/usr/lib/jetbrains/rider-projector/projector" 82 | cp -dr "${srcdir}/config/apps/JetBrains Rider-${pkgver}" "${pkgdir}/usr/lib/jetbrains/rider-projector/rider" 83 | 84 | install -Dm755 "${srcdir}/config/configs/rider/run.sh" "${pkgdir}/usr/bin/rider-projector" 85 | install -Dm644 "${srcdir}/rider-projector.service" "${pkgdir}/usr/lib/systemd/user/rider-projector.service" 86 | } 87 | -------------------------------------------------------------------------------- /nvidia-merged/nvidia-510.73.05-vgpu-5.18.patch: -------------------------------------------------------------------------------- 1 | diff --git a/kernel/nvidia-vgpu-vfio/nvidia-vgpu-vfio.c b/kernel/nvidia-vgpu-vfio/nvidia-vgpu-vfio.c 2 | index acb8fb2..a300b73 100644 3 | --- a/kernel/nvidia-vgpu-vfio/nvidia-vgpu-vfio.c 4 | +++ b/kernel/nvidia-vgpu-vfio/nvidia-vgpu-vfio.c 5 | @@ -1058,6 +1058,14 @@ static int nv_vgpu_vfio_region_info(vgpu_dev_t *vgpu_dev, 6 | struct vfio_region_info_cap_type cap_type = { 7 | .header.id = VFIO_REGION_INFO_CAP_TYPE, 8 | .header.version = 1, 9 | +#if defined(VFIO_REGION_TYPE_MIGRATION_DEPRECATED) 10 | + .type = VFIO_REGION_TYPE_MIGRATION_DEPRECATED, 11 | +#else 12 | .type = VFIO_REGION_TYPE_MIGRATION, 13 | +#endif 14 | +#if defined(VFIO_REGION_SUBTYPE_MIGRATION_DEPRECATED) 15 | + .subtype = VFIO_REGION_SUBTYPE_MIGRATION_DEPRECATED 16 | +#else 17 | .subtype = VFIO_REGION_SUBTYPE_MIGRATION 18 | +#endif 19 | }; 20 | @@ -1261,12 +1261,20 @@ static void vgpu_read_base(vgpu_dev_t *vgpu_dev) 21 | NvU32 nv_translate_device_state(NvU32 device_state, NvU32 nv_state) 22 | { 23 | if (device_state & VFIO_DEVICE_STATE_RUNNING) { 24 | +#if defined(VFIO_DEVICE_STATE_V1_SAVING) 25 | + if (device_state & VFIO_DEVICE_STATE_V1_SAVING) 26 | +#else 27 | if (device_state & VFIO_DEVICE_STATE_SAVING) 28 | +#endif 29 | return NV_VFIO_DEVICE_STATE_MIGRATION_PRECOPY_ACTIVE; 30 | else 31 | return NV_VFIO_DEVICE_STATE_RUNNING; 32 | } else { 33 | +#if defined(VFIO_DEVICE_STATE_V1_SAVING) 34 | + if (device_state & VFIO_DEVICE_STATE_V1_SAVING) 35 | +#else 36 | if (device_state & VFIO_DEVICE_STATE_SAVING) 37 | +#endif 38 | return NV_VFIO_DEVICE_STATE_MIGRATION_STOPNCOPY_ACTIVE; 39 | else if (nv_state == NV_VFIO_DEVICE_STATE_MIGRATION_STOPNCOPY_ACTIVE) 40 | return NV_VFIO_DEVICE_STATE_NONE; 41 | @@ -3262,7 +3262,7 @@ static NV_STATUS nv_create_dma_mappings(vgpu_dev_t *vgpu_dev, 42 | } 43 | 44 | pdev = to_pci_dev(NV_GET_MDEV_PARENT(vgpu_dev->mdev)); 45 | - mapped_count = pci_map_sg(pdev, sgt.sgl, sgt.orig_nents, PCI_DMA_BIDIRECTIONAL); 46 | + mapped_count = dma_map_sg(&pdev->dev, sgt.sgl, sgt.orig_nents, DMA_BIDIRECTIONAL); 47 | if (mapped_count == 0) 48 | { 49 | NV_VGPU_DEV_LOG(VGPU_ERR, vgpu_dev->mdev, 50 | @@ -3341,7 +3341,7 @@ static void nv_destroy_dma_mappings(vgpu_dev_t *vgpu_dev, mapping_node_t *mappin 51 | } 52 | 53 | pdev = to_pci_dev(NV_GET_MDEV_PARENT(vgpu_dev->mdev)); 54 | - pci_unmap_sg(pdev, sgt.sgl, sgt.orig_nents, PCI_DMA_BIDIRECTIONAL); 55 | + dma_unmap_sg(&pdev->dev, sgt.sgl, sgt.orig_nents, DMA_BIDIRECTIONAL); 56 | NV_DMA_FREE_SG_TABLE(sgt); 57 | 58 | destroy_exit: 59 | @@ -4412,8 +4412,14 @@ static NV_STATUS nv_vgpu_probe(struct pci_dev *dev, NvU32 num_vgpu_types, NvU32 60 | pci_set_master(dev); 61 | 62 | pf_dma_mask = dma_get_mask(&dev->physfn->dev); 63 | - pci_set_dma_mask(dev, pf_dma_mask); 64 | - pci_set_consistent_dma_mask (dev, pf_dma_mask); 65 | + dma_set_mask(&dev->dev, pf_dma_mask); 66 | +#if !NV_IS_EXPORT_SYMBOL_GPL_sme_active 67 | +#if defined(NV_DMA_SET_COHERENT_MASK_PRESENT) 68 | + dma_set_coherent_mask(&dev->dev, pf_dma_mask); 69 | +#else 70 | + pci_set_consistent_dma_mask(dev, pf_dma_mask); 71 | +#endif 72 | +#endif 73 | } 74 | -------------------------------------------------------------------------------- /nvidia-vgpu/nvidia-510.73.05-vgpu-5.18.patch: -------------------------------------------------------------------------------- 1 | diff --git a/kernel/nvidia-vgpu-vfio/nvidia-vgpu-vfio.c b/kernel/nvidia-vgpu-vfio/nvidia-vgpu-vfio.c 2 | index acb8fb2..a300b73 100644 3 | --- a/kernel/nvidia-vgpu-vfio/nvidia-vgpu-vfio.c 4 | +++ b/kernel/nvidia-vgpu-vfio/nvidia-vgpu-vfio.c 5 | @@ -1058,6 +1058,14 @@ static int nv_vgpu_vfio_region_info(vgpu_dev_t *vgpu_dev, 6 | struct vfio_region_info_cap_type cap_type = { 7 | .header.id = VFIO_REGION_INFO_CAP_TYPE, 8 | .header.version = 1, 9 | +#if defined(VFIO_REGION_TYPE_MIGRATION_DEPRECATED) 10 | + .type = VFIO_REGION_TYPE_MIGRATION_DEPRECATED, 11 | +#else 12 | .type = VFIO_REGION_TYPE_MIGRATION, 13 | +#endif 14 | +#if defined(VFIO_REGION_SUBTYPE_MIGRATION_DEPRECATED) 15 | + .subtype = VFIO_REGION_SUBTYPE_MIGRATION_DEPRECATED 16 | +#else 17 | .subtype = VFIO_REGION_SUBTYPE_MIGRATION 18 | +#endif 19 | }; 20 | @@ -1261,12 +1261,20 @@ static void vgpu_read_base(vgpu_dev_t *vgpu_dev) 21 | NvU32 nv_translate_device_state(NvU32 device_state, NvU32 nv_state) 22 | { 23 | if (device_state & VFIO_DEVICE_STATE_RUNNING) { 24 | +#if defined(VFIO_DEVICE_STATE_V1_SAVING) 25 | + if (device_state & VFIO_DEVICE_STATE_V1_SAVING) 26 | +#else 27 | if (device_state & VFIO_DEVICE_STATE_SAVING) 28 | +#endif 29 | return NV_VFIO_DEVICE_STATE_MIGRATION_PRECOPY_ACTIVE; 30 | else 31 | return NV_VFIO_DEVICE_STATE_RUNNING; 32 | } else { 33 | +#if defined(VFIO_DEVICE_STATE_V1_SAVING) 34 | + if (device_state & VFIO_DEVICE_STATE_V1_SAVING) 35 | +#else 36 | if (device_state & VFIO_DEVICE_STATE_SAVING) 37 | +#endif 38 | return NV_VFIO_DEVICE_STATE_MIGRATION_STOPNCOPY_ACTIVE; 39 | else if (nv_state == NV_VFIO_DEVICE_STATE_MIGRATION_STOPNCOPY_ACTIVE) 40 | return NV_VFIO_DEVICE_STATE_NONE; 41 | @@ -3262,7 +3262,7 @@ static NV_STATUS nv_create_dma_mappings(vgpu_dev_t *vgpu_dev, 42 | } 43 | 44 | pdev = to_pci_dev(NV_GET_MDEV_PARENT(vgpu_dev->mdev)); 45 | - mapped_count = pci_map_sg(pdev, sgt.sgl, sgt.orig_nents, PCI_DMA_BIDIRECTIONAL); 46 | + mapped_count = dma_map_sg(&pdev->dev, sgt.sgl, sgt.orig_nents, DMA_BIDIRECTIONAL); 47 | if (mapped_count == 0) 48 | { 49 | NV_VGPU_DEV_LOG(VGPU_ERR, vgpu_dev->mdev, 50 | @@ -3341,7 +3341,7 @@ static void nv_destroy_dma_mappings(vgpu_dev_t *vgpu_dev, mapping_node_t *mappin 51 | } 52 | 53 | pdev = to_pci_dev(NV_GET_MDEV_PARENT(vgpu_dev->mdev)); 54 | - pci_unmap_sg(pdev, sgt.sgl, sgt.orig_nents, PCI_DMA_BIDIRECTIONAL); 55 | + dma_unmap_sg(&pdev->dev, sgt.sgl, sgt.orig_nents, DMA_BIDIRECTIONAL); 56 | NV_DMA_FREE_SG_TABLE(sgt); 57 | 58 | destroy_exit: 59 | @@ -4412,8 +4412,14 @@ static NV_STATUS nv_vgpu_probe(struct pci_dev *dev, NvU32 num_vgpu_types, NvU32 60 | pci_set_master(dev); 61 | 62 | pf_dma_mask = dma_get_mask(&dev->physfn->dev); 63 | - pci_set_dma_mask(dev, pf_dma_mask); 64 | - pci_set_consistent_dma_mask (dev, pf_dma_mask); 65 | + dma_set_mask(&dev->dev, pf_dma_mask); 66 | +#if !NV_IS_EXPORT_SYMBOL_GPL_sme_active 67 | +#if defined(NV_DMA_SET_COHERENT_MASK_PRESENT) 68 | + dma_set_coherent_mask(&dev->dev, pf_dma_mask); 69 | +#else 70 | + pci_set_consistent_dma_mask(dev, pf_dma_mask); 71 | +#endif 72 | +#endif 73 | } 74 | -------------------------------------------------------------------------------- /nvidia-merged/.SRCINFO: -------------------------------------------------------------------------------- 1 | pkgbase = nvidia-merged 2 | pkgver = 510.73.06 3 | pkgrel = 2 4 | url = https://krutavshah.github.io/GPU_Virtualization-Wiki/ 5 | arch = x86_64 6 | groups = nvidia-merged 7 | license = custom 8 | makedepends = git 9 | makedepends = rust 10 | options = !strip 11 | source = nvidia-drm-outputclass.conf 12 | source = nvidia-smi 13 | source = nvidia-vgpu.conf 14 | source = vgpu_unlock-rs.conf 15 | source = disable-nvidia-blob-version-check.patch 16 | source = nvidia-510.73.05-vgpu-5.18.patch 17 | source = nv-kernel.patch 18 | source = nvidia.rules 19 | source = nvidia-utils.sysusers 20 | source = vgpu_unlock.patch 21 | source = file://NVIDIA-Linux-x86_64-510.73.08-grid.run 22 | source = file://NVIDIA-Linux-x86_64-510.73.06-vgpu-kvm.run 23 | source = git+https://github.com/mbilker/vgpu_unlock-rs.git#commit=6deede6 24 | sha256sums = be99ff3def641bb900c2486cce96530394c5dc60548fc4642f19d3a4c784134d 25 | sha256sums = 20676096714ac00d9fc993901ab275e4b0fa3f2eddc937dae395c8f4e8cb543e 26 | sha256sums = 5ea0d9edfcf282cea9b204291716a9a4d6d522ba3a6bc28d78edf505b6dc7949 27 | sha256sums = c85ae100a6c87c12906fd0057b77c0c4190f68434de4bc3bc89348ffc19aed61 28 | sha256sums = cc150696cf5b74556fca93cee3b1fc05695bb3a420a4a7bae5090e4b9d9bcfd7 29 | sha256sums = 79b09682f9c3cfa32d219a14b3c956d8f05340addd5a43e7063c3d96175a56f4 30 | sha256sums = 36325e26243429e1e55c8500bcac850fea6e6a8975a657984c0979042a001c7b 31 | sha256sums = 4fbfd461f939f18786e79f8dba5fdb48be9f00f2ff4b1bb2f184dbce42dd6fc3 32 | sha256sums = d8d1caa5d72c71c6430c2a0d9ce1a674787e9272ccce28b9d5898ca24e60a167 33 | sha256sums = f77f26f609bb6f1eb69d3dc7e84ba704e5c065e424a619ab1460accb8247143f 34 | sha256sums = 2affa1e1035a71b17d15d5fa9a16d8b3704d73701f04afaa4b09035a3412e6ce 35 | sha256sums = b7d076bee270e779b7c1eb512c9325794be2e8cbd7cd37c0f62fc72d87654a82 36 | sha256sums = SKIP 37 | 38 | pkgname = lib32-nvidia-merged-utils 39 | pkgdesc = NVIDIA drivers utilities; patched for vGPU support w/ Rust unlock & host DRM output (32-bit) 40 | depends = lib32-zlib 41 | depends = lib32-gcc-libs 42 | depends = lib32-libglvnd 43 | depends = nvidia-merged-utils=510.73.06 44 | optdepends = lib32-opencl-nvidia=510.73.06 45 | provides = lib32-vulkan-driver 46 | provides = lib32-opengl-driver 47 | provides = lib32-nvidia-libgl 48 | provides = lib32-nvidia-utils 49 | conflicts = lib32-nvidia-utils 50 | replaces = lib32-nvidia-libgl 51 | 52 | pkgname = lib32-opencl-nvidia-merged 53 | pkgdesc = OpenCL implemention for NVIDIA (32-bit) 54 | depends = lib32-zlib 55 | depends = lib32-gcc-libs 56 | optdepends = opencl-headers: headers necessary for OpenCL development 57 | provides = lib32-opencl-driver 58 | provides = lib32-opencl-nvidia 59 | conflicts = lib32-opencl-nvidia 60 | 61 | pkgname = nvidia-merged-dkms 62 | pkgdesc = NVIDIA drivers - module sources; patched for vGPU support w/ Rust unlock & host DRM output 63 | depends = dkms 64 | depends = nvidia-merged-utils=510.73.06 65 | depends = libglvnd 66 | provides = NVIDIA-MODULE 67 | provides = nvidia-dkms 68 | conflicts = nvidia-dkms 69 | 70 | pkgname = nvidia-merged-settings 71 | pkgdesc = Tool for configuring the NVIDIA graphics driver 72 | depends = jansson 73 | depends = gtk3 74 | depends = libxv 75 | depends = libvdpau 76 | depends = nvidia-merged-utils=510.73.06 77 | provides = nvidia-settings 78 | conflicts = nvidia-settings 79 | 80 | pkgname = nvidia-merged-utils 81 | pkgdesc = NVIDIA drivers utilities; patched for vGPU support w/ Rust unlock & host DRM output 82 | depends = xorg-server 83 | depends = libglvnd 84 | depends = egl-wayland 85 | optdepends = nvidia-merged-settings=510.73.06: configuration tool 86 | optdepends = xorg-server-devel: nvidia-xconfig 87 | optdepends = opencl-nvidia-merged=510.73.06: OpenCL support 88 | optdepends = mdevctl: mediated device contfiguration tool 89 | optdepends = libvirt: virtualization engine control interface 90 | provides = vulkan-driver 91 | provides = opengl-driver 92 | provides = nvidia-libgl 93 | provides = nvidia-utils 94 | provides = vgpu_unlock 95 | conflicts = nvidia-libgl 96 | conflicts = nvidia-utils 97 | replaces = vgpu_unlock 98 | 99 | pkgname = opencl-nvidia-merged 100 | pkgdesc = OpenCL implemention for NVIDIA 101 | depends = zlib 102 | optdepends = opencl-headers: headers necessary for OpenCL development 103 | provides = opencl-driver 104 | provides = opencl-nvidia 105 | conflicts = opencl-nvidia 106 | -------------------------------------------------------------------------------- /nvidia-vgpu/PKGBUILD: -------------------------------------------------------------------------------- 1 | # Maintainer: Erin Allison 2 | 3 | # BUILD INSTRUCTIONS: 4 | # ------------------- 5 | # 6 | # Please note that distribution of the driver files used in this 7 | # package may be prohibited by NVIDIA's EULA. 8 | # Please consult any applicable license agreements prior to 9 | # usage of this script. 10 | # 11 | # You will need to acquire both NVIDIA-Linux-...-vgpu-kvm.run 12 | # place it in the same directory as this PKGBUILD file, and then run makepkg. 13 | 14 | pkgbase='nvidia-vgpu' 15 | pkgname=('nvidia-vgpu-dkms' 'nvidia-vgpu-utils') 16 | pkgver=510.73.06 17 | pkgrel=1 18 | arch=('x86_64') 19 | makedepends=('git' 'rust') 20 | url='https://krutavshah.github.io/GPU_Virtualization-Wiki/' 21 | license=('custom') 22 | options=('!strip') 23 | groups=('nvidia-vgpu') 24 | _vgpupkg="NVIDIA-Linux-${CARCH}-${pkgver}-vgpu-kvm" 25 | 26 | DLAGENTS=("file::/usr/bin/echo ${BOLD}${RED} Unable to find %u, please read the PKGBUILD ${ALL_OFF}" $DLAGENTS[@]) 27 | 28 | source=( 29 | 'nvidia-smi' 30 | 'nvidia-vgpu.conf' 31 | 'vgpu_unlock-rs.conf' 32 | 'nv-kernel.patch' 33 | 'nvidia-510.73.05-vgpu-5.18.patch' 34 | 'vgpu_unlock.patch' 35 | "file://${_vgpupkg}.run" 36 | 'git+https://github.com/mbilker/vgpu_unlock-rs.git#commit=3858f2c') 37 | sha256sums=('20676096714ac00d9fc993901ab275e4b0fa3f2eddc937dae395c8f4e8cb543e' 38 | '9c23ae9e0ef3b9b927608079ccc5f787e7e351a780f2369479c2e75dfd0470fe' 39 | 'c85ae100a6c87c12906fd0057b77c0c4190f68434de4bc3bc89348ffc19aed61' 40 | '36325e26243429e1e55c8500bcac850fea6e6a8975a657984c0979042a001c7b' 41 | '79b09682f9c3cfa32d219a14b3c956d8f05340addd5a43e7063c3d96175a56f4' 42 | 'f77f26f609bb6f1eb69d3dc7e84ba704e5c065e424a619ab1460accb8247143f' 43 | 'b7d076bee270e779b7c1eb512c9325794be2e8cbd7cd37c0f62fc72d87654a82' 44 | 'SKIP') 45 | 46 | create_links() { 47 | # create soname links 48 | find "$pkgdir" -type f -name '*.so*' ! -path '*xorg/*' -print0 | while read -d $'\0' _lib; do 49 | _soname=$(dirname "${_lib}")/$(readelf -d "${_lib}" | grep -Po 'SONAME.*: \[\K[^]]*' || true) 50 | _base=$(echo ${_soname} | sed -r 's/(.*)\.so.*/\1.so/') 51 | [[ -e "${_soname}" ]] || ln -s $(basename "${_lib}") "${_soname}" 52 | [[ -e "${_base}" ]] || ln -s $(basename "${_soname}") "${_base}" 53 | done 54 | } 55 | 56 | prepare() { 57 | rm -rf "${_vgpupkg}" 58 | sh "${_vgpupkg}.run" -x 59 | 60 | gunzip "${_vgpupkg}"/nvidia-smi.1.gz 61 | 62 | sed \ 63 | -e "s/__VERSION_STRING/${pkgver}/" \ 64 | -e 's/__JOBS/`nproc`/' \ 65 | -e 's/__DKMS_MODULES//' \ 66 | -e '$iBUILT_MODULE_NAME[0]="nvidia"\ 67 | DEST_MODULE_LOCATION[0]="/kernel/drivers/video"\ 68 | BUILT_MODULE_NAME[1]="nvidia-vgpu-vfio"\ 69 | DEST_MODULE_LOCATION[1]="/kernel/drivers/video"' \ 70 | -e 's/NV_EXCLUDE_BUILD_MODULES/IGNORE_PREEMPT_RT_PRESENCE=1 NV_EXCLUDE_BUILD_MODULES/' \ 71 | -i "${_vgpupkg}/kernel/dkms.conf" 72 | 73 | pushd "${_vgpupkg}" 74 | patch -p1 < "${srcdir}/nvidia-510.73.05-vgpu-5.18.patch" 75 | popd 76 | 77 | pushd "${_vgpupkg}" 78 | patch -u kernel/nvidia/nv-kernel.o_binary < "${srcdir}/nv-kernel.patch" 79 | patch -p1 < "${srcdir}/vgpu_unlock.patch" 80 | popd 81 | } 82 | 83 | build() { 84 | cd "${srcdir}/vgpu_unlock-rs" 85 | 86 | cargo build -j `nproc` --release 87 | } 88 | 89 | package_nvidia-vgpu-dkms() { 90 | pkgdesc="NVIDIA drivers - module sources; patched for consumer vGPU support w/ Rust unlock" 91 | depends=('dkms' "nvidia-vgpu-utils=${pkgver}") 92 | conflicts=('nvidia-dkms') 93 | 94 | install -d -m755 "${pkgdir}/usr/src" 95 | cp -dr --no-preserve='ownership' "${_vgpupkg}/kernel" "${pkgdir}/usr/src/nvidia-${pkgver}" 96 | 97 | echo "blacklist nouveau" | install -D -m644 /dev/stdin "${pkgdir}/usr/lib/modprobe.d/${pkgname}.conf" 98 | echo "nvidia-uvm" | install -D -m644 /dev/stdin "${pkgdir}/usr/lib/modules-load.d/${pkgname}.conf" 99 | 100 | install -D -m644 "${_vgpupkg}/LICENSE" "${pkgdir}/usr/share/licenses/$pkgname/LICENSE" 101 | } 102 | 103 | package_nvidia-vgpu-utils() { 104 | pkgdesc="NVIDIA drivers utilities; patched for consumer vGPU support w/ Rust unlock" 105 | optdepends=('mdevctl: mediated device contfiguration tool' 106 | 'libvirt: virtualization engine control interface') 107 | conflicts=('nvidia-utils') 108 | provides=('vgpu_unlock') 109 | replaces=('vgpu_unlock') 110 | 111 | # misc 112 | install -D -m755 "${_vgpupkg}/libnvidia-ml.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-ml.so.${pkgver}" 113 | 114 | # vGPU 115 | install -D -m755 "${_vgpupkg}/libnvidia-vgpu.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-vgpu.so.${pkgver}" 116 | install -D -m755 "${_vgpupkg}/libnvidia-vgxcfg.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-vgxcfg.so.${pkgver}" 117 | 118 | # DEBUG 119 | install -D -m755 "${_vgpupkg}/nvidia-debugdump" "${pkgdir}/usr/bin/nvidia-debugdump" 120 | 121 | # nvidia-bug-report 122 | install -D -m755 "${_vgpupkg}/nvidia-bug-report.sh" "${pkgdir}/usr/bin/nvidia-bug-report.sh" 123 | 124 | # nvidia-smi 125 | install -D -m755 "${_vgpupkg}/nvidia-smi" "${pkgdir}/usr/lib/nvidia/nvidia-smi.orig" 126 | install -D -m644 "${_vgpupkg}/nvidia-smi.1" "${pkgdir}/usr/share/man/man1/nvidia-smi.1" 127 | install -D -m755 "${srcdir}/nvidia-smi" "${pkgdir}/usr/bin/nvidia-smi" 128 | 129 | # nvidia-vgpu 130 | install -D -m755 "${_vgpupkg}/nvidia-vgpud" "${pkgdir}/usr/bin/nvidia-vgpud" 131 | install -D -m755 "${_vgpupkg}/nvidia-vgpu-mgr" "${pkgdir}/usr/bin/nvidia-vgpu-mgr" 132 | install -D -m644 "${_vgpupkg}/vgpuConfig.xml" "${pkgdir}/usr/share/nvidia/vgpu/vgpuConfig.xml" 133 | install -D -m644 "${_vgpupkg}/init-scripts/systemd/nvidia-vgpud.service" "${pkgdir}/usr/lib/systemd/system/nvidia-vgpud.service" 134 | install -D -m644 "${_vgpupkg}/init-scripts/systemd/nvidia-vgpu-mgr.service" "${pkgdir}/usr/lib/systemd/system/nvidia-vgpu-mgr.service" 135 | install -D -m644 "${srcdir}/vgpu_unlock-rs.conf" "${pkgdir}/usr/lib/systemd/system/nvidia-vgpud.service.d/30-vgpu_unlock-rs.conf" 136 | install -D -m644 "${srcdir}/vgpu_unlock-rs.conf" "${pkgdir}/usr/lib/systemd/system/nvidia-vgpu-mgr.service.d/30-vgpu_unlock-rs.conf" 137 | install -D -m644 "${srcdir}/nvidia-vgpu.conf" "${pkgdir}/usr/lib/systemd/system/libvirtd.service.d/20-nvidia-vgpu.conf" 138 | 139 | install -D -m644 "${_vgpupkg}/README.txt" "${pkgdir}/usr/share/doc/nvidia/README" 140 | install -D -m644 "${_vgpupkg}/NVIDIA_Changelog" "${pkgdir}/usr/share/doc/nvidia/NVIDIA_Changelog" 141 | cp -r "${_vgpupkg}/html" "${pkgdir}/usr/share/doc/nvidia/" 142 | ln -s nvidia "${pkgdir}/usr/share/doc/nvidia-utils" 143 | 144 | create_links 145 | 146 | # vgpu_unlock-rs 147 | install -D -m755 "vgpu_unlock-rs/target/release/libvgpu_unlock_rs.so" "${pkgdir}/usr/lib/nvidia/libvgpu_unlock_rs.so" 148 | 149 | install -D -m644 "${_vgpupkg}/LICENSE" "${pkgdir}/usr/share/licenses/$pkgname/VGPU_LICENSE" 150 | install -D -m644 "vgpu_unlock-rs/LICENSE" "${pkgdir}/usr/share/licenses/$pkgname/VGPU_UNLOCK-RS_LICENSE" 151 | } 152 | -------------------------------------------------------------------------------- /nvidia-merged/PKGBUILD: -------------------------------------------------------------------------------- 1 | # Maintainer: Erin Allison 2 | 3 | # BUILD INSTRUCTIONS: 4 | # ------------------- 5 | # 6 | # Please note that distribution of the driver files used in this 7 | # package may be prohibited by NVIDIA's EULA. 8 | # Please consult any applicable license agreements prior to 9 | # usage of this script. 10 | # 11 | # You will need to acquire both NVIDIA-Linux-...-grid.run 12 | # and ...-vgpu-kvm.run, place them in the same directory 13 | # as this PKGBUILD file, and then run makepkg. 14 | 15 | 16 | pkgbase='nvidia-merged' 17 | pkgname=('lib32-nvidia-merged-utils' 'lib32-opencl-nvidia-merged' 'nvidia-merged-dkms' 'nvidia-merged-settings' 'nvidia-merged-utils' 'opencl-nvidia-merged') 18 | pkgver=510.73.06 19 | pkgrel=2 20 | arch=('x86_64') 21 | makedepends=('git' 'rust') 22 | url='https://krutavshah.github.io/GPU_Virtualization-Wiki/' 23 | license=('custom') 24 | options=('!strip') 25 | groups=('nvidia-merged') 26 | _gridpkgver=510.73.08 27 | _gridpkg="NVIDIA-Linux-${CARCH}-${_gridpkgver}-grid" 28 | _vgpupkg="NVIDIA-Linux-${CARCH}-${pkgver}-vgpu-kvm" 29 | 30 | DLAGENTS=("file::/usr/bin/echo ${BOLD}${RED} Unable to find %u, please read the PKGBUILD ${ALL_OFF}" $DLAGENTS[@]) 31 | 32 | source=( 33 | 'nvidia-drm-outputclass.conf' 34 | 'nvidia-smi' 35 | 'nvidia-vgpu.conf' 36 | 'vgpu_unlock-rs.conf' 37 | 'disable-nvidia-blob-version-check.patch' 38 | 'nvidia-510.73.05-vgpu-5.18.patch' 39 | 'nv-kernel.patch' 40 | 'nvidia.rules' 41 | 'nvidia-utils.sysusers' 42 | 'vgpu_unlock.patch' 43 | "file://${_gridpkg}.run" 44 | "file://${_vgpupkg}.run" 45 | 'git+https://github.com/mbilker/vgpu_unlock-rs.git#commit=6deede6') 46 | sha256sums=('be99ff3def641bb900c2486cce96530394c5dc60548fc4642f19d3a4c784134d' 47 | '20676096714ac00d9fc993901ab275e4b0fa3f2eddc937dae395c8f4e8cb543e' 48 | '5ea0d9edfcf282cea9b204291716a9a4d6d522ba3a6bc28d78edf505b6dc7949' 49 | 'c85ae100a6c87c12906fd0057b77c0c4190f68434de4bc3bc89348ffc19aed61' 50 | 'cc150696cf5b74556fca93cee3b1fc05695bb3a420a4a7bae5090e4b9d9bcfd7' 51 | '79b09682f9c3cfa32d219a14b3c956d8f05340addd5a43e7063c3d96175a56f4' 52 | '36325e26243429e1e55c8500bcac850fea6e6a8975a657984c0979042a001c7b' 53 | '4fbfd461f939f18786e79f8dba5fdb48be9f00f2ff4b1bb2f184dbce42dd6fc3' 54 | 'd8d1caa5d72c71c6430c2a0d9ce1a674787e9272ccce28b9d5898ca24e60a167' 55 | 'f77f26f609bb6f1eb69d3dc7e84ba704e5c065e424a619ab1460accb8247143f' 56 | '2affa1e1035a71b17d15d5fa9a16d8b3704d73701f04afaa4b09035a3412e6ce' 57 | 'b7d076bee270e779b7c1eb512c9325794be2e8cbd7cd37c0f62fc72d87654a82' 58 | 'SKIP') 59 | 60 | create_links() { 61 | # create soname links 62 | find "$pkgdir" -type f -name '*.so*' ! -path '*xorg/*' -print0 | while read -d $'\0' _lib; do 63 | _soname=$(dirname "${_lib}")/$(readelf -d "${_lib}" | grep -Po 'SONAME.*: \[\K[^]]*' || true) 64 | _base=$(echo ${_soname} | sed -r 's/(.*)\.so.*/\1.so/') 65 | [[ -e "${_soname}" ]] || ln -s $(basename "${_lib}") "${_soname}" 66 | [[ -e "${_base}" ]] || ln -s $(basename "${_soname}") "${_base}" 67 | done 68 | } 69 | 70 | prepare() { 71 | rm -rf "${_gridpkg}" "${_vgpupkg}" 72 | sh "${_gridpkg}.run" -x 73 | sh "${_vgpupkg}.run" -x 74 | 75 | sed \ 76 | -e 's|__UTILS_PATH__|/usr/bin|' \ 77 | -e 's|Icon=.*|Icon=nvidia-settings|' \ 78 | -i "${_gridpkg}/nvidia-settings.desktop" 79 | 80 | bsdtar -C "${_gridpkg}" -xf "${_gridpkg}/nvidia-persistenced-init.tar.bz2" 81 | gunzip "${_gridpkg}"/nvidia-{cuda-mps-control,modprobe,persistenced,settings,smi,xconfig}.1.gz 82 | 83 | sed \ 84 | -e 's/# VGX_KVM_BUILD parameter.*/\0 \nVGX_KVM_BUILD=1/' \ 85 | -i "${_gridpkg}/kernel/conftest.sh" 86 | 87 | sed \ 88 | -e "s/__VERSION_STRING/${_gridpkgver}/" \ 89 | -e 's/__JOBS/`nproc`/' \ 90 | -e 's/__DKMS_MODULES//' \ 91 | -e '$iBUILT_MODULE_NAME[0]="nvidia"\ 92 | DEST_MODULE_LOCATION[0]="/kernel/drivers/video"\ 93 | BUILT_MODULE_NAME[1]="nvidia-uvm"\ 94 | DEST_MODULE_LOCATION[1]="/kernel/drivers/video"\ 95 | BUILT_MODULE_NAME[2]="nvidia-modeset"\ 96 | DEST_MODULE_LOCATION[2]="/kernel/drivers/video"\ 97 | BUILT_MODULE_NAME[3]="nvidia-drm"\ 98 | DEST_MODULE_LOCATION[3]="/kernel/drivers/video"\ 99 | BUILT_MODULE_NAME[4]="nvidia-vgpu-vfio"\ 100 | DEST_MODULE_LOCATION[4]="/kernel/drivers/video" \ 101 | BUILT_MODULE_NAME[5]="nvidia-peermem"\ 102 | DEST_MODULE_LOCATION[5]="/kernel/drivers/video"' \ 103 | -e 's/NV_EXCLUDE_BUILD_MODULES/IGNORE_PREEMPT_RT_PRESENCE=1 NV_EXCLUDE_BUILD_MODULES/' \ 104 | -i "${_gridpkg}/kernel/dkms.conf" 105 | 106 | pushd "${_vgpupkg}" 107 | patch -p1 < "${srcdir}/nvidia-510.73.05-vgpu-5.18.patch" 108 | popd 109 | 110 | pushd "${_gridpkg}" 111 | patch -p1 < "${srcdir}/disable-nvidia-blob-version-check.patch" 112 | patch -u kernel/nvidia/nv-kernel.o_binary < "${srcdir}/nv-kernel.patch" 113 | patch -p1 < "${srcdir}/vgpu_unlock.patch" 114 | popd 115 | } 116 | 117 | build() { 118 | cd "${srcdir}/vgpu_unlock-rs" 119 | 120 | cargo build -j `nproc` --release 121 | } 122 | 123 | package_opencl-nvidia-merged() { 124 | pkgdesc="OpenCL implemention for NVIDIA" 125 | depends=('zlib') 126 | optdepends=('opencl-headers: headers necessary for OpenCL development') 127 | provides=('opencl-driver' 'opencl-nvidia') 128 | conflicts=('opencl-nvidia') 129 | 130 | # OpenCL 131 | install -D -m644 "${_gridpkg}/nvidia.icd" "${pkgdir}/etc/OpenCL/vendors/nvidia.icd" 132 | install -D -m755 "${_gridpkg}/libnvidia-compiler-next.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-compiler-next.so.${_gridpkgver}" 133 | install -D -m755 "${_gridpkg}/libnvidia-compiler.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-compiler.so.${_gridpkgver}" 134 | install -D -m755 "${_gridpkg}/libnvidia-opencl.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-opencl.so.${_gridpkgver}" 135 | 136 | create_links 137 | 138 | install -D -m644 "${_gridpkg}/LICENSE" "${pkgdir}/usr/share/licenses/$pkgname/LICENSE" 139 | } 140 | 141 | package_nvidia-merged-dkms() { 142 | pkgdesc="NVIDIA drivers - module sources; patched for vGPU support w/ Rust unlock & host DRM output" 143 | depends=('dkms' "nvidia-merged-utils=${pkgver}" 'libglvnd') 144 | provides=('NVIDIA-MODULE' 'nvidia-dkms') 145 | conflicts=('nvidia-dkms') 146 | 147 | install -d -m755 "${pkgdir}/usr/src" 148 | cp -dr --no-preserve='ownership' "${_gridpkg}/kernel" "${pkgdir}/usr/src/nvidia-${_gridpkgver}" 149 | 150 | install -D -m644 "${_vgpupkg}/kernel/common/inc/nv-vgpu-vfio-interface.h" "${pkgdir}/usr/src/nvidia-${_gridpkgver}/common/inc/nv-vgpu-vfio-interface.h" 151 | install -D -m644 "${_vgpupkg}/kernel/nvidia/nv-vgpu-vfio-interface.c" "${pkgdir}/usr/src/nvidia-${_gridpkgver}/nvidia/nv-vgpu-vfio-interface.c" 152 | install -D -m644 "${_vgpupkg}/kernel/nvidia/nvidia-sources.Kbuild" "${pkgdir}/usr/src/nvidia-${_gridpkgver}/nvidia/nvidia-sources.Kbuild" 153 | cp -dr --no-preserve='ownership' "${_vgpupkg}/kernel/nvidia-vgpu-vfio" "${pkgdir}/usr/src/nvidia-${_gridpkgver}/nvidia-vgpu-vfio" 154 | 155 | echo "blacklist nouveau" | install -D -m644 /dev/stdin "${pkgdir}/usr/lib/modprobe.d/${pkgname}.conf" 156 | echo "nvidia-uvm" | install -D -m644 /dev/stdin "${pkgdir}/usr/lib/modules-load.d/${pkgname}.conf" 157 | 158 | install -D -m644 "${_gridpkg}/LICENSE" "${pkgdir}/usr/share/licenses/$pkgname/LICENSE" 159 | install -D -m644 "${_vgpupkg}/LICENSE" "${pkgdir}/usr/share/licenses/$pkgname/VGPU_LICENSE" 160 | } 161 | 162 | package_nvidia-merged-settings() { 163 | pkgdesc='Tool for configuring the NVIDIA graphics driver' 164 | depends=('jansson' 'gtk3' 'libxv' 'libvdpau' "nvidia-merged-utils=${pkgver}") 165 | provides=('nvidia-settings') 166 | conflicts=('nvidia-settings') 167 | 168 | install -D -m755 "${_gridpkg}/nvidia-settings" "${pkgdir}/usr/bin/nvidia-settings" 169 | install -D -m644 "${_gridpkg}/libnvidia-gtk3.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-gtk3.so.${_gridpkgver}" 170 | install -D -m644 "${_gridpkg}/nvidia-settings.1" "${pkgdir}/usr/share/man/man1/nvidia-settings.1" 171 | install -D -m644 "${_gridpkg}/nvidia-settings.png" "${pkgdir}/usr/share/pixmaps/nvidia-settings.png" 172 | install -D -m644 "${_gridpkg}/nvidia-settings.desktop" "${pkgdir}/usr/share/applications/nvidia-settings.desktop" 173 | 174 | create_links 175 | 176 | install -D -m644 "${_gridpkg}/LICENSE" "${pkgdir}/usr/share/licenses/$pkgname/LICENSE" 177 | } 178 | 179 | package_nvidia-merged-utils() { 180 | pkgdesc="NVIDIA drivers utilities; patched for vGPU support w/ Rust unlock & host DRM output" 181 | depends=('xorg-server' 'libglvnd' 'egl-wayland') 182 | optdepends=("nvidia-merged-settings=${pkgver}: configuration tool" 183 | 'xorg-server-devel: nvidia-xconfig' 184 | "opencl-nvidia-merged=${pkgver}: OpenCL support" 185 | 'mdevctl: mediated device contfiguration tool' 186 | 'libvirt: virtualization engine control interface') 187 | conflicts=('nvidia-libgl' 'nvidia-utils') 188 | provides=('vulkan-driver' 'opengl-driver' 'nvidia-libgl' 'nvidia-utils' 'vgpu_unlock') 189 | replaces=('vgpu_unlock') 190 | 191 | # X driver 192 | install -D -m755 "${_gridpkg}/nvidia_drv.so" "${pkgdir}/usr/lib/xorg/modules/drivers/nvidia_drv.so" 193 | 194 | # Wayland/GBM 195 | install -D -m755 "${_gridpkg}/libnvidia-egl-gbm.so.1.1.0" "${pkgdir}/usr/lib/libnvidia-egl-gbm.so.1.1.0" 196 | install -D -m644 "${_gridpkg}/15_nvidia_gbm.json" "${pkgdir}/usr/share/egl/egl_external_platform.d/15_nvidia_gbm.json" 197 | 198 | mkdir -p "${pkgdir}/usr/lib/gbm" 199 | ln -s "/usr/lib/libnvidia-allocator.so.${_gridpkgver}" "${pkgdir}/usr/lib/gbm/nvidia-drm_gbm.so" 200 | 201 | # firmware 202 | install -D -m644 "${_gridpkg}/firmware/gsp.bin" "${pkgdir}/usr/lib/firmware/nvidia/${_gridpkgver}/gsp.bin" 203 | 204 | # GLX extension module for X 205 | install -D -m755 "${_gridpkg}/libglxserver_nvidia.so.${_gridpkgver}" "${pkgdir}/usr/lib/nvidia/xorg/libglxserver_nvidia.so.${_gridpkgver}" 206 | 207 | # Ensure that X finds glx 208 | ln -s "libglxserver_nvidia.so.${_gridpkgver}" "${pkgdir}/usr/lib/nvidia/xorg/libglxserver_nvidia.so.1" 209 | ln -s "libglxserver_nvidia.so.${_gridpkgver}" "${pkgdir}/usr/lib/nvidia/xorg/libglxserver_nvidia.so" 210 | 211 | install -D -m755 "${_gridpkg}/libGLX_nvidia.so.${_gridpkgver}" "${pkgdir}/usr/lib/libGLX_nvidia.so.${_gridpkgver}" 212 | 213 | # OpenGL libraries 214 | install -D -m755 "${_gridpkg}/libEGL_nvidia.so.${_gridpkgver}" "${pkgdir}/usr/lib/libEGL_nvidia.so.${_gridpkgver}" 215 | install -D -m755 "${_gridpkg}/libGLESv1_CM_nvidia.so.${_gridpkgver}" "${pkgdir}/usr/lib/libGLESv1_CM_nvidia.so.${_gridpkgver}" 216 | install -D -m755 "${_gridpkg}/libGLESv2_nvidia.so.${_gridpkgver}" "${pkgdir}/usr/lib/libGLESv2_nvidia.so.${_gridpkgver}" 217 | install -D -m644 "${_gridpkg}/10_nvidia.json" "${pkgdir}/usr/share/glvnd/egl_vendor.d/10_nvidia.json" 218 | 219 | # OpenGL core library 220 | install -D -m755 "${_gridpkg}/libnvidia-glcore.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-glcore.so.${_gridpkgver}" 221 | install -D -m755 "${_gridpkg}/libnvidia-eglcore.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-eglcore.so.${_gridpkgver}" 222 | install -D -m755 "${_gridpkg}/libnvidia-glsi.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-glsi.so.${_gridpkgver}" 223 | 224 | # misc 225 | install -D -m755 "${_gridpkg}/libnvidia-fbc.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-fbc.so.${_gridpkgver}" 226 | install -D -m755 "${_gridpkg}/libnvidia-encode.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-encode.so.${_gridpkgver}" 227 | install -D -m755 "${_gridpkg}/libnvidia-cfg.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-cfg.so.${_gridpkgver}" 228 | install -D -m755 "${_gridpkg}/libnvidia-ml.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-ml.so.${_gridpkgver}" 229 | install -D -m755 "${_gridpkg}/libnvidia-glvkspirv.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-glvkspirv.so.${_gridpkgver}" 230 | install -D -m755 "${_gridpkg}/libnvidia-allocator.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-allocator.so.${_gridpkgver}" 231 | install -D -m755 "${_gridpkg}/libnvidia-vulkan-producer.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-vulkan-producer.so.${_gridpkgver}" 232 | # Sigh libnvidia-vulkan-producer.so has no SONAME set so create_links doesn't catch it. NVIDIA please fix! 233 | ln -s "libnvidia-vulkan-producer.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-vulkan-producer.so.1" 234 | ln -s "libnvidia-vulkan-producer.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-vulkan-producer.so" 235 | 236 | # Vulkan ICD 237 | install -D -m644 "${_gridpkg}/nvidia_icd.json" "${pkgdir}/usr/share/vulkan/icd.d/nvidia_icd.json" 238 | install -D -m644 "${_gridpkg}/nvidia_layers.json" "${pkgdir}/usr/share/vulkan/implicit_layer.d/nvidia_layers.json" 239 | 240 | # VDPAU 241 | install -D -m755 "${_gridpkg}/libvdpau_nvidia.so.${_gridpkgver}" "${pkgdir}/usr/lib/vdpau/libvdpau_nvidia.so.${_gridpkgver}" 242 | 243 | # nvidia-tls library 244 | install -D -m755 "${_gridpkg}/libnvidia-tls.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-tls.so.${_gridpkgver}" 245 | 246 | # CUDA 247 | install -D -m755 "${_gridpkg}/libcuda.so.${_gridpkgver}" "${pkgdir}/usr/lib/libcuda.so.${_gridpkgver}" 248 | install -D -m755 "${_gridpkg}/libnvcuvid.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvcuvid.so.${_gridpkgver}" 249 | 250 | # PTX JIT Compiler (Parallel Thread Execution (PTX) is a pseudo-assembly language for CUDA) 251 | install -D -m755 "${_gridpkg}/libnvidia-ptxjitcompiler.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-ptxjitcompiler.so.${_gridpkgver}" 252 | 253 | # raytracing 254 | install -D -m755 "${_gridpkg}/libnvoptix.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvoptix.so.${_gridpkgver}" 255 | install -D -m755 "${_gridpkg}/libnvidia-rtcore.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-rtcore.so.${_gridpkgver}" 256 | 257 | # NGX 258 | install -D -m755 "${_gridpkg}/libnvidia-ngx.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-ngx.so.${_gridpkgver}" 259 | install -D -m755 "${_gridpkg}/nvidia-ngx-updater" "${pkgdir}/usr/bin/nvidia-ngx-updater" 260 | install -D -m755 "${_gridpkg}/_nvngx.dll" "${pkgdir}/usr/lib/nvidia/wine/_nvngx.dll" 261 | install -D -m755 "${_gridpkg}/nvngx.dll" "${pkgdir}/usr/lib/nvidia/wine/nvngx.dll" 262 | 263 | # Optical flow 264 | install -D -m755 "${_gridpkg}/libnvidia-opticalflow.so.${_gridpkgver}" "${pkgdir}/usr/lib/libnvidia-opticalflow.so.${_gridpkgver}" 265 | 266 | # vGPU 267 | install -D -m755 "${_vgpupkg}/libnvidia-vgpu.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-vgpu.so.${pkgver}" 268 | install -D -m755 "${_vgpupkg}/libnvidia-vgxcfg.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-vgxcfg.so.${pkgver}" 269 | 270 | # DEBUG 271 | install -D -m755 "${_gridpkg}/nvidia-debugdump" "${pkgdir}/usr/bin/nvidia-debugdump" 272 | 273 | # nvidia-xconfig 274 | install -D -m755 "${_gridpkg}/nvidia-xconfig" "${pkgdir}/usr/bin/nvidia-xconfig" 275 | install -D -m644 "${_gridpkg}/nvidia-xconfig.1" "${pkgdir}/usr/share/man/man1/nvidia-xconfig.1" 276 | 277 | # nvidia-bug-report 278 | install -D -m755 "${_vgpupkg}/nvidia-bug-report.sh" "${pkgdir}/usr/bin/nvidia-bug-report.sh" 279 | 280 | # nvidia-smi 281 | install -D -m755 "${_gridpkg}/nvidia-smi" "${pkgdir}/usr/lib/nvidia/nvidia-smi.orig" 282 | install -D -m644 "${_gridpkg}/nvidia-smi.1" "${pkgdir}/usr/share/man/man1/nvidia-smi.1" 283 | install -D -m755 "${srcdir}/nvidia-smi" "${pkgdir}/usr/bin/nvidia-smi" 284 | 285 | # nvidia-vgpu 286 | install -D -m755 "${_vgpupkg}/nvidia-vgpud" "${pkgdir}/usr/bin/nvidia-vgpud" 287 | install -D -m755 "${_vgpupkg}/nvidia-vgpu-mgr" "${pkgdir}/usr/bin/nvidia-vgpu-mgr" 288 | install -D -m644 "${_vgpupkg}/vgpuConfig.xml" "${pkgdir}/usr/share/nvidia/vgpu/vgpuConfig.xml" 289 | install -D -m644 "${_vgpupkg}/init-scripts/systemd/nvidia-vgpud.service" "${pkgdir}/usr/lib/systemd/system/nvidia-vgpud.service" 290 | install -D -m644 "${_vgpupkg}/init-scripts/systemd/nvidia-vgpu-mgr.service" "${pkgdir}/usr/lib/systemd/system/nvidia-vgpu-mgr.service" 291 | install -D -m644 "${srcdir}/vgpu_unlock-rs.conf" "${pkgdir}/usr/lib/systemd/system/nvidia-vgpud.service.d/30-vgpu_unlock-rs.conf" 292 | install -D -m644 "${srcdir}/vgpu_unlock-rs.conf" "${pkgdir}/usr/lib/systemd/system/nvidia-vgpu-mgr.service.d/30-vgpu_unlock-rs.conf" 293 | install -D -m644 "${srcdir}/nvidia-vgpu.conf" "${pkgdir}/usr/lib/systemd/system/libvirtd.service.d/20-nvidia-vgpu.conf" 294 | 295 | # nvidia-cuda-mps 296 | install -D -m755 "${_gridpkg}/nvidia-cuda-mps-server" "${pkgdir}/usr/bin/nvidia-cuda-mps-server" 297 | install -D -m755 "${_gridpkg}/nvidia-cuda-mps-control" "${pkgdir}/usr/bin/nvidia-cuda-mps-control" 298 | install -D -m644 "${_gridpkg}/nvidia-cuda-mps-control.1" "${pkgdir}/usr/share/man/man1/nvidia-cuda-mps-control.1" 299 | 300 | # nvidia-modprobe 301 | # This should be removed if nvidia fixed their uvm module! 302 | install -D -m4755 "${_gridpkg}/nvidia-modprobe" "${pkgdir}/usr/bin/nvidia-modprobe" 303 | install -D -m644 "${_gridpkg}/nvidia-modprobe.1" "${pkgdir}/usr/share/man/man1/nvidia-modprobe.1" 304 | 305 | # nvidia-persistenced 306 | install -D -m755 "${_gridpkg}/nvidia-persistenced" "${pkgdir}/usr/bin/nvidia-persistenced" 307 | install -D -m644 "${_gridpkg}/nvidia-persistenced.1" "${pkgdir}/usr/share/man/man1/nvidia-persistenced.1" 308 | install -D -m644 "${_gridpkg}/nvidia-persistenced-init/systemd/nvidia-persistenced.service.template" "${pkgdir}/usr/lib/systemd/system/nvidia-persistenced.service" 309 | sed -i 's/__USER__/nvidia-persistenced/' "${pkgdir}/usr/lib/systemd/system/nvidia-persistenced.service" 310 | 311 | # application profiles 312 | install -D -m644 "${_gridpkg}/nvidia-application-profiles-${_gridpkgver}-rc" "${pkgdir}/usr/share/nvidia/nvidia-application-profiles-${_gridpkgver}-rc" 313 | install -D -m644 "${_gridpkg}/nvidia-application-profiles-${_gridpkgver}-key-documentation" "${pkgdir}/usr/share/nvidia/nvidia-application-profiles-${_gridpkgver}-key-documentation" 314 | 315 | install -D -m644 "${_gridpkg}/README.txt" "${pkgdir}/usr/share/doc/nvidia/README" 316 | install -D -m644 "${_gridpkg}/NVIDIA_Changelog" "${pkgdir}/usr/share/doc/nvidia/NVIDIA_Changelog" 317 | cp -r "${_gridpkg}/html" "${pkgdir}/usr/share/doc/nvidia/" 318 | ln -s nvidia "${pkgdir}/usr/share/doc/nvidia-utils" 319 | 320 | # distro specific files must be installed in /usr/share/X11/xorg.conf.d 321 | install -D -m644 "${srcdir}/nvidia-drm-outputclass.conf" "${pkgdir}/usr/share/X11/xorg.conf.d/10-nvidia-drm-outputclass.conf" 322 | 323 | create_links 324 | 325 | # vgpu_unlock-rs 326 | install -D -m755 "vgpu_unlock-rs/target/release/libvgpu_unlock_rs.so" "${pkgdir}/usr/lib/nvidia/libvgpu_unlock_rs.so" 327 | 328 | install -D -m644 "${_gridpkg}/LICENSE" "${pkgdir}/usr/share/licenses/$pkgname/LICENSE" 329 | install -D -m644 "${_vgpupkg}/LICENSE" "${pkgdir}/usr/share/licenses/$pkgname/VGPU_LICENSE" 330 | install -D -m644 "vgpu_unlock-rs/LICENSE" "${pkgdir}/usr/share/licenses/$pkgname/VGPU_UNLOCK-RS_LICENSE" 331 | } 332 | 333 | package_lib32-nvidia-merged-utils() { 334 | pkgdesc="NVIDIA drivers utilities; patched for vGPU support w/ Rust unlock & host DRM output (32-bit)" 335 | depends=('lib32-zlib' 'lib32-gcc-libs' 'lib32-libglvnd' "nvidia-merged-utils=${pkgver}") 336 | optdepends=("lib32-opencl-nvidia=${pkgver}") 337 | provides=('lib32-vulkan-driver' 'lib32-opengl-driver' 'lib32-nvidia-libgl' 'lib32-nvidia-utils') 338 | replaces=('lib32-nvidia-libgl') 339 | conflicts=('lib32-nvidia-utils') 340 | 341 | install -D -m755 "${_gridpkg}/32/libGLX_nvidia.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libGLX_nvidia.so.${_gridpkgver}" 342 | 343 | # OpenGL libraries 344 | install -D -m755 "${_gridpkg}/32/libEGL_nvidia.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libEGL_nvidia.so.${_gridpkgver}" 345 | install -D -m755 "${_gridpkg}/32/libGLESv1_CM_nvidia.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libGLESv1_CM_nvidia.so.${_gridpkgver}" 346 | install -D -m755 "${_gridpkg}/32/libGLESv2_nvidia.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libGLESv2_nvidia.so.${_gridpkgver}" 347 | 348 | # OpenGL core library 349 | install -D -m755 "${_gridpkg}/32/libnvidia-glcore.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libnvidia-glcore.so.${_gridpkgver}" 350 | install -D -m755 "${_gridpkg}/32/libnvidia-eglcore.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libnvidia-eglcore.so.${_gridpkgver}" 351 | install -D -m755 "${_gridpkg}/32/libnvidia-glsi.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libnvidia-glsi.so.${_gridpkgver}" 352 | 353 | # misc 354 | install -D -m755 "${_gridpkg}/32/libnvidia-fbc.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libnvidia-fbc.so.${_gridpkgver}" 355 | install -D -m755 "${_gridpkg}/32/libnvidia-encode.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libnvidia-encode.so.${_gridpkgver}" 356 | install -D -m755 "${_gridpkg}/32/libnvidia-ml.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libnvidia-ml.so.${_gridpkgver}" 357 | install -D -m755 "${_gridpkg}/32/libnvidia-glvkspirv.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libnvidia-glvkspirv.so.${_gridpkgver}" 358 | install -D -m755 "${_gridpkg}/32/libnvidia-allocator.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libnvidia-allocator.so.${_gridpkgver}" 359 | 360 | # VDPAU 361 | install -D -m755 "${_gridpkg}/32/libvdpau_nvidia.so.${_gridpkgver}" "${pkgdir}/usr/lib32/vdpau/libvdpau_nvidia.so.${_gridpkgver}" 362 | 363 | # nvidia-tls library 364 | install -D -m755 "${_gridpkg}/32/libnvidia-tls.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libnvidia-tls.so.${_gridpkgver}" 365 | 366 | # CUDA 367 | install -D -m755 "${_gridpkg}/32/libcuda.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libcuda.so.${_gridpkgver}" 368 | install -D -m755 "${_gridpkg}/32/libnvcuvid.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libnvcuvid.so.${_gridpkgver}" 369 | 370 | # PTX JIT Compiler (Parallel Thread Execution (PTX) is a pseudo-assembly language for CUDA) 371 | install -D -m755 "${_gridpkg}/32/libnvidia-ptxjitcompiler.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libnvidia-ptxjitcompiler.so.${_gridpkgver}" 372 | 373 | # Optical flow 374 | install -D -m755 "${_gridpkg}/32/libnvidia-opticalflow.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libnvidia-opticalflow.so.${_gridpkgver}" 375 | 376 | create_links 377 | 378 | install -D -m644 "${_gridpkg}/LICENSE" "${pkgdir}/usr/share/licenses/$pkgname/LICENSE" 379 | } 380 | 381 | package_lib32-opencl-nvidia-merged() { 382 | pkgdesc="OpenCL implemention for NVIDIA (32-bit)" 383 | depends=('lib32-zlib' 'lib32-gcc-libs') 384 | optdepends=('opencl-headers: headers necessary for OpenCL development') 385 | provides=('lib32-opencl-driver' 'lib32-opencl-nvidia') 386 | conflicts=('lib32-opencl-nvidia') 387 | 388 | # OpenCL 389 | install -D -m755 "${_gridpkg}/32/libnvidia-compiler.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libnvidia-compiler.so.${_gridpkgver}" 390 | install -D -m755 "${_gridpkg}/32/libnvidia-opencl.so.${_gridpkgver}" "${pkgdir}/usr/lib32/libnvidia-opencl.so.${_gridpkgver}" 391 | 392 | create_links 393 | 394 | install -D -m644 "${_gridpkg}/LICENSE" "${pkgdir}/usr/share/licenses/$pkgname/LICENSE" 395 | } 396 | -------------------------------------------------------------------------------- /nvidia-vgpu/vgpu_unlock.patch: -------------------------------------------------------------------------------- 1 | --- ./kernel/nvidia/kern.ld 1969-12-31 18:00:00.000000000 -0600 2 | +++ ./kernel/nvidia/kern.ld 2022-03-24 11:51:18.776835647 -0500 3 | @@ -0,0 +1,162 @@ 4 | +/* Script for ld -r: link without relocation */ 5 | +/* Copyright (C) 2014-2018 Free Software Foundation, Inc. 6 | + Copying and distribution of this script, with or without modification, 7 | + are permitted in any medium without royalty provided the copyright 8 | + notice and this notice are preserved. */ 9 | +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", 10 | + "elf64-x86-64") 11 | +OUTPUT_ARCH(i386:x86-64) 12 | + /* For some reason, the Solaris linker makes bad executables 13 | + if gld -r is used and the intermediate file has sections starting 14 | + at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld 15 | + bug. But for now assigning the zero vmas works. */ 16 | +SECTIONS 17 | +{ 18 | + /* Read-only sections, merged into text segment: */ 19 | + .interp 0 : { *(.interp) } 20 | + .note.gnu.build-id : { *(.note.gnu.build-id) } 21 | + .hash 0 : { *(.hash) } 22 | + .gnu.hash 0 : { *(.gnu.hash) } 23 | + .dynsym 0 : { *(.dynsym) } 24 | + .dynstr 0 : { *(.dynstr) } 25 | + .gnu.version 0 : { *(.gnu.version) } 26 | + .gnu.version_d 0: { *(.gnu.version_d) } 27 | + .gnu.version_r 0: { *(.gnu.version_r) } 28 | + .rela.init 0 : { *(.rela.init) } 29 | + .rela.text 0 : { *(.rela.text) } 30 | + .rela.fini 0 : { *(.rela.fini) } 31 | + .rela.rodata 0 : { *(.rela.rodata) } 32 | + .rela.data.rel.ro 0 : { *(.rela.data.rel.ro) } 33 | + .rela.data 0 : { *(.rela.data) } 34 | + .rela.tdata 0 : { *(.rela.tdata) } 35 | + .rela.tbss 0 : { *(.rela.tbss) } 36 | + .rela.ctors 0 : { *(.rela.ctors) } 37 | + .rela.dtors 0 : { *(.rela.dtors) } 38 | + .rela.got 0 : { *(.rela.got) } 39 | + .rela.bss 0 : { *(.rela.bss) } 40 | + .rela.ldata 0 : { *(.rela.ldata) } 41 | + .rela.lbss 0 : { *(.rela.lbss) } 42 | + .rela.lrodata 0 : { *(.rela.lrodata) } 43 | + .rela.ifunc 0 : { *(.rela.ifunc) } 44 | + .rela.plt 0 : 45 | + { 46 | + *(.rela.plt) 47 | + } 48 | + .init 0 : 49 | + { 50 | + KEEP (*(SORT_NONE(.init))) 51 | + } 52 | + .plt 0 : { *(.plt) *(.iplt) } 53 | +.plt.got 0 : { *(.plt.got) } 54 | +.plt.sec 0 : { *(.plt.sec) } 55 | + .text 0 : 56 | + { 57 | + *(.text .stub) 58 | + /* .gnu.warning sections are handled specially by elf32.em. */ 59 | + *(.gnu.warning) 60 | + } 61 | + .fini 0 : 62 | + { 63 | + KEEP (*(SORT_NONE(.fini))) 64 | + } 65 | + .rodata 0 : { *(EXCLUDE_FILE (*nv-kernel.o) .rodata) } 66 | + .rodata1 0 : { *(.rodata1) } 67 | + .eh_frame_hdr : { *(.eh_frame_hdr) } 68 | + .eh_frame 0 : ONLY_IF_RO { KEEP (*(.eh_frame)) } 69 | + .gcc_except_table 0 : ONLY_IF_RO { *(.gcc_except_table 70 | + .gcc_except_table.*) } 71 | + .gnu_extab 0 : ONLY_IF_RO { *(.gnu_extab*) } 72 | + /* These sections are generated by the Sun/Oracle C++ compiler. */ 73 | + .exception_ranges 0 : ONLY_IF_RO { *(.exception_ranges 74 | + .exception_ranges*) } 75 | + /* Adjust the address for the data segment. We want to adjust up to 76 | + the same address within the page on the next page up. */ 77 | + /* Exception handling */ 78 | + .eh_frame 0 : ONLY_IF_RW { KEEP (*(.eh_frame)) } 79 | + .gnu_extab 0 : ONLY_IF_RW { *(.gnu_extab) } 80 | + .gcc_except_table 0 : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } 81 | + .exception_ranges 0 : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } 82 | + /* Thread Local Storage sections */ 83 | + .tdata 0 : 84 | + { 85 | + *(.tdata) 86 | + } 87 | + .tbss 0 : { *(.tbss) } 88 | + .jcr 0 : { KEEP (*(.jcr)) } 89 | + .dynamic 0 : { *(.dynamic) } 90 | + .got 0 : { *(.got) *(.igot) } 91 | + .got.plt 0 : { *(.got.plt) *(.igot.plt) } 92 | + .data 0 : 93 | + { 94 | + *(.data) 95 | + vgpu_unlock_nv_kern_rodata_beg = .; 96 | + *nv-kernel.o(.rodata*) 97 | + vgpu_unlock_nv_kern_rodata_end = .; 98 | + } 99 | + .data1 0 : { *(.data1) } 100 | + .bss 0 : 101 | + { 102 | + *(.bss) 103 | + *(COMMON) 104 | + /* Align here to ensure that the .bss section occupies space up to 105 | + _end. Align after .bss to ensure correct alignment even if the 106 | + .bss section disappears because there are no input sections. 107 | + FIXME: Why do we need it? When there is no .bss section, we don't 108 | + pad the .data section. */ 109 | + } 110 | + .lbss 0 : 111 | + { 112 | + *(.dynlbss) 113 | + *(.lbss) 114 | + *(LARGE_COMMON) 115 | + } 116 | + .lrodata 0 : 117 | + { 118 | + *(.lrodata) 119 | + } 120 | + .ldata 0 : 121 | + { 122 | + *(.ldata) 123 | + } 124 | + /* Stabs debugging sections. */ 125 | + .stab 0 : { *(.stab) } 126 | + .stabstr 0 : { *(.stabstr) } 127 | + .stab.excl 0 : { *(.stab.excl) } 128 | + .stab.exclstr 0 : { *(.stab.exclstr) } 129 | + .stab.index 0 : { *(.stab.index) } 130 | + .stab.indexstr 0 : { *(.stab.indexstr) } 131 | + .comment 0 : { *(.comment) } 132 | + /* DWARF debug sections. 133 | + Symbols in the DWARF debugging sections are relative to the beginning 134 | + of the section so we begin them at 0. */ 135 | + /* DWARF 1 */ 136 | + .debug 0 : { *(.debug) } 137 | + .line 0 : { *(.line) } 138 | + /* GNU DWARF 1 extensions */ 139 | + .debug_srcinfo 0 : { *(.debug_srcinfo) } 140 | + .debug_sfnames 0 : { *(.debug_sfnames) } 141 | + /* DWARF 1.1 and DWARF 2 */ 142 | + .debug_aranges 0 : { *(.debug_aranges) } 143 | + .debug_pubnames 0 : { *(.debug_pubnames) } 144 | + /* DWARF 2 */ 145 | + .debug_info 0 : { *(.debug_info) } 146 | + .debug_abbrev 0 : { *(.debug_abbrev) } 147 | + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } 148 | + .debug_frame 0 : { *(.debug_frame) } 149 | + .debug_str 0 : { *(.debug_str) } 150 | + .debug_loc 0 : { *(.debug_loc) } 151 | + .debug_macinfo 0 : { *(.debug_macinfo) } 152 | + /* SGI/MIPS DWARF 2 extensions */ 153 | + .debug_weaknames 0 : { *(.debug_weaknames) } 154 | + .debug_funcnames 0 : { *(.debug_funcnames) } 155 | + .debug_typenames 0 : { *(.debug_typenames) } 156 | + .debug_varnames 0 : { *(.debug_varnames) } 157 | + /* DWARF 3 */ 158 | + .debug_pubtypes 0 : { *(.debug_pubtypes) } 159 | + .debug_ranges 0 : { *(.debug_ranges) } 160 | + /* DWARF Extension. */ 161 | + .debug_macro 0 : { *(.debug_macro) } 162 | + .debug_addr 0 : { *(.debug_addr) } 163 | + .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } 164 | +} 165 | + 166 | --- ./kernel/nvidia/nvidia.Kbuild 2022-01-24 17:56:29.000000000 -0600 167 | +++ ./kernel/nvidia/nvidia.Kbuild 2022-03-24 17:02:20.143988135 -0500 168 | @@ -245 +245,2 @@ NV_CONFTEST_GENERIC_COMPILE_TESTS += pci 169 | NV_CONFTEST_GENERIC_COMPILE_TESTS += drm_available 170 | +ldflags-y += -T $(src)/nvidia/kern.ld 171 | --- ./kernel/nvidia/os-interface.c 2022-01-24 17:56:29.000000000 -0600 172 | +++ ./kernel/nvidia/os-interface.c 2022-03-24 17:02:36.087708543 -0500 173 | @@ -30,2 +30,3 @@ 174 | 175 | +#include "vgpu_unlock_hooks.c" 176 | 177 | --- ./kernel/nvidia/vgpu_unlock_hooks.c 1969-12-31 18:00:00.000000000 -0600 178 | +++ ./kernel/nvidia/vgpu_unlock_hooks.c 2022-03-24 11:51:18.775835663 -0500 179 | @@ -0,0 +1,1230 @@ 180 | +/* 181 | + * vGPU unlock hooks. 182 | + * 183 | + * This file is designed to be included into a single translation unit of the 184 | + * vGPU driver's kernel module. It hooks the nv_ioremap_* functions and memcpy 185 | + * for that translation unit and applies the vgpu_unlock patch when the magic 186 | + * and key values has been accessed by the driver. 187 | + * 188 | + * Copyright 2021 Jonathan Johansson 189 | + * This file is part of the "vgpu_unlock" project, and is distributed under the 190 | + * MIT License. See the LICENSE file for more details. 191 | + * 192 | + * Contributions from Krutav Shah and the vGPU Unlocking community included :) 193 | + * 194 | + */ 195 | + 196 | +/*------------------------------------------------------------------------------ 197 | + * Implementation of AES128-ECB. 198 | + *------------------------------------------------------------------------------ 199 | + */ 200 | + 201 | +typedef struct 202 | +{ 203 | + uint8_t round_key[176]; 204 | +} 205 | +vgpu_unlock_aes128_ctx; 206 | + 207 | +typedef uint8_t vgpu_unlock_aes128_state[4][4]; 208 | + 209 | +#define Nb 4 210 | +#define Nk 4 211 | +#define Nr 10 212 | +#define getSBoxValue(num) (vgpu_unlock_aes128_sbox[(num)]) 213 | +#define getSBoxInvert(num) (vgpu_unlock_aes128_rsbox[(num)]) 214 | +#define Multiply(x, y) \ 215 | + ( ((y & 1) * x) ^ \ 216 | + ((y>>1 & 1) * vgpu_unlock_aes128_xtime(x)) ^ \ 217 | + ((y>>2 & 1) * vgpu_unlock_aes128_xtime(vgpu_unlock_aes128_xtime(x))) ^ \ 218 | + ((y>>3 & 1) * vgpu_unlock_aes128_xtime(vgpu_unlock_aes128_xtime(vgpu_unlock_aes128_xtime(x)))) ^ \ 219 | + ((y>>4 & 1) * vgpu_unlock_aes128_xtime(vgpu_unlock_aes128_xtime(vgpu_unlock_aes128_xtime(vgpu_unlock_aes128_xtime(x)))))) \ 220 | + 221 | +static const uint8_t vgpu_unlock_aes128_sbox[256] = { 222 | + //0 1 2 3 4 5 6 7 8 9 A B C D E F 223 | + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 224 | + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 225 | + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 226 | + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 227 | + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 228 | + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 229 | + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 230 | + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 231 | + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 232 | + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 233 | + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 234 | + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 235 | + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 236 | + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 237 | + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 238 | + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; 239 | + 240 | +static const uint8_t vgpu_unlock_aes128_rsbox[256] = { 241 | + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 242 | + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 243 | + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 244 | + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 245 | + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 246 | + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 247 | + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 248 | + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 249 | + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 250 | + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 251 | + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 252 | + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 253 | + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 254 | + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 255 | + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 256 | + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; 257 | + 258 | +static const uint8_t vgpu_unlock_aes128_rcon[11] = { 259 | + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; 260 | + 261 | +static void vgpu_unlock_aes128_key_expansion(uint8_t *round_key, 262 | + const uint8_t *Key) 263 | +{ 264 | + unsigned i, j, k; 265 | + uint8_t tempa[4]; 266 | + 267 | + for (i = 0; i < Nk; ++i) 268 | + { 269 | + round_key[(i * 4) + 0] = Key[(i * 4) + 0]; 270 | + round_key[(i * 4) + 1] = Key[(i * 4) + 1]; 271 | + round_key[(i * 4) + 2] = Key[(i * 4) + 2]; 272 | + round_key[(i * 4) + 3] = Key[(i * 4) + 3]; 273 | + } 274 | + 275 | + for (i = Nk; i < Nb * (Nr + 1); ++i) 276 | + { 277 | + k = (i - 1) * 4; 278 | + tempa[0] = round_key[k + 0]; 279 | + tempa[1] = round_key[k + 1]; 280 | + tempa[2] = round_key[k + 2]; 281 | + tempa[3] = round_key[k + 3]; 282 | + 283 | + if (i % Nk == 0) 284 | + { 285 | + const uint8_t u8tmp = tempa[0]; 286 | + tempa[0] = tempa[1]; 287 | + tempa[1] = tempa[2]; 288 | + tempa[2] = tempa[3]; 289 | + tempa[3] = u8tmp; 290 | + tempa[0] = getSBoxValue(tempa[0]); 291 | + tempa[1] = getSBoxValue(tempa[1]); 292 | + tempa[2] = getSBoxValue(tempa[2]); 293 | + tempa[3] = getSBoxValue(tempa[3]); 294 | + tempa[0] = tempa[0] ^ vgpu_unlock_aes128_rcon[i/Nk]; 295 | + } 296 | + 297 | + j = i * 4; k=(i - Nk) * 4; 298 | + round_key[j + 0] = round_key[k + 0] ^ tempa[0]; 299 | + round_key[j + 1] = round_key[k + 1] ^ tempa[1]; 300 | + round_key[j + 2] = round_key[k + 2] ^ tempa[2]; 301 | + round_key[j + 3] = round_key[k + 3] ^ tempa[3]; 302 | + } 303 | +} 304 | + 305 | +static void vgpu_unlock_aes128_add_round_key(uint8_t round, 306 | + vgpu_unlock_aes128_state *state, 307 | + const uint8_t *round_key) 308 | +{ 309 | + uint8_t i,j; 310 | + 311 | + for (i = 0; i < 4; ++i) 312 | + { 313 | + for (j = 0; j < 4; ++j) 314 | + { 315 | + (*state)[i][j] ^= round_key[(round * Nb * 4) + (i * Nb) + j]; 316 | + } 317 | + } 318 | +} 319 | + 320 | +static void vgpu_unlock_aes128_sub_bytes(vgpu_unlock_aes128_state *state) 321 | +{ 322 | + uint8_t i, j; 323 | + 324 | + for (i = 0; i < 4; ++i) 325 | + { 326 | + for (j = 0; j < 4; ++j) 327 | + { 328 | + (*state)[j][i] = getSBoxValue((*state)[j][i]); 329 | + } 330 | + } 331 | +} 332 | + 333 | +static void vgpu_unlock_aes128_shift_rows(vgpu_unlock_aes128_state *state) 334 | +{ 335 | + uint8_t temp; 336 | + 337 | + temp = (*state)[0][1]; 338 | + (*state)[0][1] = (*state)[1][1]; 339 | + (*state)[1][1] = (*state)[2][1]; 340 | + (*state)[2][1] = (*state)[3][1]; 341 | + (*state)[3][1] = temp; 342 | + 343 | + temp = (*state)[0][2]; 344 | + (*state)[0][2] = (*state)[2][2]; 345 | + (*state)[2][2] = temp; 346 | + 347 | + temp = (*state)[1][2]; 348 | + (*state)[1][2] = (*state)[3][2]; 349 | + (*state)[3][2] = temp; 350 | + 351 | + temp = (*state)[0][3]; 352 | + (*state)[0][3] = (*state)[3][3]; 353 | + (*state)[3][3] = (*state)[2][3]; 354 | + (*state)[2][3] = (*state)[1][3]; 355 | + (*state)[1][3] = temp; 356 | +} 357 | + 358 | +static uint8_t vgpu_unlock_aes128_xtime(uint8_t x) 359 | +{ 360 | + return ((x<<1) ^ (((x>>7) & 1) * 0x1b)); 361 | +} 362 | + 363 | +static void vgpu_unlock_aes128_mix_columns(vgpu_unlock_aes128_state *state) 364 | +{ 365 | + uint8_t i; 366 | + uint8_t tmp, tm, t; 367 | + 368 | + for (i = 0; i < 4; ++i) 369 | + { 370 | + t = (*state)[i][0]; 371 | + tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3]; 372 | + tm = (*state)[i][0] ^ (*state)[i][1]; 373 | + tm = vgpu_unlock_aes128_xtime(tm); (*state)[i][0] ^= tm ^ tmp; 374 | + tm = (*state)[i][1] ^ (*state)[i][2]; 375 | + tm = vgpu_unlock_aes128_xtime(tm); (*state)[i][1] ^= tm ^ tmp; 376 | + tm = (*state)[i][2] ^ (*state)[i][3]; 377 | + tm = vgpu_unlock_aes128_xtime(tm); (*state)[i][2] ^= tm ^ tmp; 378 | + tm = (*state)[i][3] ^ t; 379 | + tm = vgpu_unlock_aes128_xtime(tm); (*state)[i][3] ^= tm ^ tmp; 380 | + } 381 | +} 382 | + 383 | +static void vgpu_unlock_aes128_inv_mix_columns(vgpu_unlock_aes128_state *state) 384 | +{ 385 | + int i; 386 | + uint8_t a, b, c, d; 387 | + 388 | + for (i = 0; i < 4; ++i) 389 | + { 390 | + a = (*state)[i][0]; 391 | + b = (*state)[i][1]; 392 | + c = (*state)[i][2]; 393 | + d = (*state)[i][3]; 394 | + 395 | + (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09); 396 | + (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d); 397 | + (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b); 398 | + (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e); 399 | + } 400 | +} 401 | + 402 | +static void vgpu_unlock_aes128_inv_sub_bytes(vgpu_unlock_aes128_state *state) 403 | +{ 404 | + uint8_t i, j; 405 | + 406 | + for (i = 0; i < 4; ++i) 407 | + { 408 | + for (j = 0; j < 4; ++j) 409 | + { 410 | + (*state)[j][i] = getSBoxInvert((*state)[j][i]); 411 | + } 412 | + } 413 | +} 414 | + 415 | +static void vgpu_unlock_aes128_inv_shift_rows(vgpu_unlock_aes128_state *state) 416 | +{ 417 | + uint8_t temp; 418 | + 419 | + temp = (*state)[3][1]; 420 | + (*state)[3][1] = (*state)[2][1]; 421 | + (*state)[2][1] = (*state)[1][1]; 422 | + (*state)[1][1] = (*state)[0][1]; 423 | + (*state)[0][1] = temp; 424 | + 425 | + temp = (*state)[0][2]; 426 | + (*state)[0][2] = (*state)[2][2]; 427 | + (*state)[2][2] = temp; 428 | + 429 | + temp = (*state)[1][2]; 430 | + (*state)[1][2] = (*state)[3][2]; 431 | + (*state)[3][2] = temp; 432 | + 433 | + temp = (*state)[0][3]; 434 | + (*state)[0][3] = (*state)[1][3]; 435 | + (*state)[1][3] = (*state)[2][3]; 436 | + (*state)[2][3] = (*state)[3][3]; 437 | + (*state)[3][3] = temp; 438 | +} 439 | + 440 | +static void vgpu_unlock_aes128_cipher(vgpu_unlock_aes128_state *state, 441 | + const uint8_t* round_key) 442 | +{ 443 | + uint8_t round = 0; 444 | + 445 | + vgpu_unlock_aes128_add_round_key(0, state, round_key); 446 | + 447 | + for (round = 1; ; ++round) 448 | + { 449 | + vgpu_unlock_aes128_sub_bytes(state); 450 | + vgpu_unlock_aes128_shift_rows(state); 451 | + 452 | + if (round == Nr) 453 | + { 454 | + break; 455 | + } 456 | + 457 | + vgpu_unlock_aes128_mix_columns(state); 458 | + vgpu_unlock_aes128_add_round_key(round, state, round_key); 459 | + } 460 | + 461 | + vgpu_unlock_aes128_add_round_key(Nr, state, round_key); 462 | +} 463 | + 464 | +static void vgpu_unlock_aes128_inv_cipher(vgpu_unlock_aes128_state *state, 465 | + const uint8_t* round_key) 466 | +{ 467 | + uint8_t round = 0; 468 | + 469 | + vgpu_unlock_aes128_add_round_key(Nr, state, round_key); 470 | + 471 | + for (round = (Nr - 1); ; --round) 472 | + { 473 | + vgpu_unlock_aes128_inv_shift_rows(state); 474 | + vgpu_unlock_aes128_inv_sub_bytes(state); 475 | + vgpu_unlock_aes128_add_round_key(round, state, round_key); 476 | + 477 | + if (round == 0) 478 | + { 479 | + break; 480 | + } 481 | + 482 | + vgpu_unlock_aes128_inv_mix_columns(state); 483 | + } 484 | +} 485 | + 486 | +static void vgpu_unlock_aes128_init(vgpu_unlock_aes128_ctx *ctx, 487 | + const uint8_t *key) 488 | +{ 489 | + vgpu_unlock_aes128_key_expansion(ctx->round_key, key); 490 | +} 491 | + 492 | +static void vgpu_unlock_aes128_encrypt(const vgpu_unlock_aes128_ctx *ctx, 493 | + uint8_t *buf) 494 | +{ 495 | + vgpu_unlock_aes128_cipher((vgpu_unlock_aes128_state*)buf, 496 | + ctx->round_key); 497 | +} 498 | + 499 | +static void vgpu_unlock_aes128_decrypt(const vgpu_unlock_aes128_ctx *ctx, 500 | + uint8_t* buf) 501 | +{ 502 | + vgpu_unlock_aes128_inv_cipher((vgpu_unlock_aes128_state*)buf, 503 | + ctx->round_key); 504 | +} 505 | + 506 | +#undef Nb 507 | +#undef Nk 508 | +#undef Nr 509 | +#undef getSBoxValue 510 | +#undef getSBoxInvert 511 | +#undef Multiply 512 | + 513 | +/*------------------------------------------------------------------------------ 514 | + * End of AES128-ECB implementation. 515 | + *------------------------------------------------------------------------------ 516 | + */ 517 | + 518 | +/*------------------------------------------------------------------------------ 519 | + * Implementation of SHA256. 520 | + * Original author: Brad Conte (brad AT bradconte.com) 521 | + *------------------------------------------------------------------------------ 522 | + */ 523 | + 524 | +typedef struct { 525 | + uint8_t data[64]; 526 | + uint32_t datalen; 527 | + uint64_t bitlen; 528 | + uint32_t state[8]; 529 | +} 530 | +vgpu_unlock_sha256_ctx; 531 | + 532 | +#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b)))) 533 | +#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b)))) 534 | + 535 | +#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) 536 | +#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 537 | +#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22)) 538 | +#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25)) 539 | +#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3)) 540 | +#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10)) 541 | + 542 | +static void vgpu_unlock_sha256_transform(vgpu_unlock_sha256_ctx *ctx, 543 | + const uint8_t data[]) 544 | +{ 545 | + static const uint32_t k[64] = { 546 | + 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, 547 | + 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, 548 | + 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, 549 | + 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, 550 | + 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, 551 | + 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, 552 | + 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, 553 | + 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 554 | + }; 555 | + 556 | + uint32_t a, b, c, d, e, f, g, h, i, j, t1, t2, m[64]; 557 | + 558 | + for (i = 0, j = 0; i < 16; ++i, j += 4) 559 | + m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]); 560 | + for ( ; i < 64; ++i) 561 | + m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; 562 | + 563 | + a = ctx->state[0]; 564 | + b = ctx->state[1]; 565 | + c = ctx->state[2]; 566 | + d = ctx->state[3]; 567 | + e = ctx->state[4]; 568 | + f = ctx->state[5]; 569 | + g = ctx->state[6]; 570 | + h = ctx->state[7]; 571 | + 572 | + for (i = 0; i < 64; ++i) { 573 | + t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i]; 574 | + t2 = EP0(a) + MAJ(a,b,c); 575 | + h = g; 576 | + g = f; 577 | + f = e; 578 | + e = d + t1; 579 | + d = c; 580 | + c = b; 581 | + b = a; 582 | + a = t1 + t2; 583 | + } 584 | + 585 | + ctx->state[0] += a; 586 | + ctx->state[1] += b; 587 | + ctx->state[2] += c; 588 | + ctx->state[3] += d; 589 | + ctx->state[4] += e; 590 | + ctx->state[5] += f; 591 | + ctx->state[6] += g; 592 | + ctx->state[7] += h; 593 | +} 594 | + 595 | +static void vgpu_unlock_sha256_init(vgpu_unlock_sha256_ctx *ctx) 596 | +{ 597 | + ctx->datalen = 0; 598 | + ctx->bitlen = 0; 599 | + ctx->state[0] = 0x6a09e667; 600 | + ctx->state[1] = 0xbb67ae85; 601 | + ctx->state[2] = 0x3c6ef372; 602 | + ctx->state[3] = 0xa54ff53a; 603 | + ctx->state[4] = 0x510e527f; 604 | + ctx->state[5] = 0x9b05688c; 605 | + ctx->state[6] = 0x1f83d9ab; 606 | + ctx->state[7] = 0x5be0cd19; 607 | +} 608 | + 609 | +static void vgpu_unlock_sha256_update(vgpu_unlock_sha256_ctx *ctx, 610 | + const uint8_t data[], 611 | + size_t len) 612 | +{ 613 | + uint32_t i; 614 | + 615 | + for (i = 0; i < len; ++i) { 616 | + ctx->data[ctx->datalen] = data[i]; 617 | + ctx->datalen++; 618 | + if (ctx->datalen == 64) { 619 | + vgpu_unlock_sha256_transform(ctx, ctx->data); 620 | + ctx->bitlen += 512; 621 | + ctx->datalen = 0; 622 | + } 623 | + } 624 | +} 625 | + 626 | +static void vgpu_unlock_sha256_final(vgpu_unlock_sha256_ctx *ctx, 627 | + uint8_t hash[]) 628 | +{ 629 | + uint32_t i; 630 | + 631 | + i = ctx->datalen; 632 | + 633 | + /* Pad whatever data is left in the buffer. */ 634 | + if (ctx->datalen < 56) { 635 | + ctx->data[i++] = 0x80; 636 | + while (i < 56) 637 | + ctx->data[i++] = 0x00; 638 | + } 639 | + else { 640 | + ctx->data[i++] = 0x80; 641 | + while (i < 64) 642 | + ctx->data[i++] = 0x00; 643 | + vgpu_unlock_sha256_transform(ctx, ctx->data); 644 | + memset(ctx->data, 0, 56); 645 | + } 646 | + 647 | + /* 648 | + * Append to the padding the total message's length in bits and 649 | + * transform. 650 | + */ 651 | + ctx->bitlen += ctx->datalen * 8; 652 | + ctx->data[63] = ctx->bitlen; 653 | + ctx->data[62] = ctx->bitlen >> 8; 654 | + ctx->data[61] = ctx->bitlen >> 16; 655 | + ctx->data[60] = ctx->bitlen >> 24; 656 | + ctx->data[59] = ctx->bitlen >> 32; 657 | + ctx->data[58] = ctx->bitlen >> 40; 658 | + ctx->data[57] = ctx->bitlen >> 48; 659 | + ctx->data[56] = ctx->bitlen >> 56; 660 | + vgpu_unlock_sha256_transform(ctx, ctx->data); 661 | + 662 | + /* 663 | + * Since this implementation uses little endian byte ordering and SHA 664 | + * uses big endian, reverse all the bytes when copying the final state 665 | + * to the output hash. 666 | + */ 667 | + for (i = 0; i < 4; ++i) { 668 | + hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; 669 | + hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; 670 | + hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; 671 | + hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; 672 | + hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; 673 | + hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff; 674 | + hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff; 675 | + hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff; 676 | + } 677 | +} 678 | + 679 | +#undef ROTLEFT 680 | +#undef ROTRIGHT 681 | + 682 | +#undef CH 683 | +#undef MAJ 684 | +#undef EP0 685 | +#undef EP1 686 | +#undef SIG0 687 | +#undef SIG1 688 | + 689 | +/*------------------------------------------------------------------------------ 690 | + * End of SHA256 implementation. 691 | + *------------------------------------------------------------------------------ 692 | + */ 693 | + 694 | + 695 | +/*------------------------------------------------------------------------------ 696 | + * Implementation of HMAC-SHA256. 697 | + *------------------------------------------------------------------------------ 698 | + */ 699 | + 700 | +static void vgpu_unlock_hmac_sha256(void* dst, 701 | + const void *msg, 702 | + size_t msg_size, 703 | + const void *key, 704 | + size_t key_size) 705 | +{ 706 | + vgpu_unlock_sha256_ctx ctx; 707 | + uint8_t o_key[96]; 708 | + uint8_t i_key_pad[64]; 709 | + uint8_t i; 710 | + 711 | + for (i = 0; i < 64; i++) 712 | + { 713 | + if (i < key_size) 714 | + { 715 | + o_key[i] = ((uint8_t*)key)[i] ^ 0x5c; 716 | + i_key_pad[i] = ((uint8_t*)key)[i] ^ 0x36; 717 | + } 718 | + else 719 | + { 720 | + o_key[i] = 0x5c; 721 | + i_key_pad[i] = 0x36; 722 | + } 723 | + } 724 | + 725 | + vgpu_unlock_sha256_init(&ctx); 726 | + vgpu_unlock_sha256_update(&ctx, i_key_pad, sizeof(i_key_pad)); 727 | + vgpu_unlock_sha256_update(&ctx, msg, msg_size); 728 | + vgpu_unlock_sha256_final(&ctx, &o_key[64]); 729 | + 730 | + vgpu_unlock_sha256_init(&ctx); 731 | + vgpu_unlock_sha256_update(&ctx, o_key, sizeof(o_key)); 732 | + vgpu_unlock_sha256_final(&ctx, dst); 733 | +} 734 | + 735 | +/*------------------------------------------------------------------------------ 736 | + * End of HMAC-SHA256 implementation. 737 | + *------------------------------------------------------------------------------ 738 | + */ 739 | + 740 | +/*------------------------------------------------------------------------------ 741 | + * Implementation of vgpu_unlock hooks. 742 | + *------------------------------------------------------------------------------ 743 | + */ 744 | + 745 | +/* Debug logs can be enabled here. To enable it, change 0 to 1. */ 746 | +#if 0 747 | + #define LOG(...) printk(__VA_ARGS__) 748 | +#else 749 | + #define LOG(...) 750 | +#endif 751 | + 752 | +typedef struct { 753 | + uint8_t num_blocks; /* Number of 16 byte blocks up to 'sign'. */ 754 | + uint8_t name1_len; /* Length of first name (unused?) */ 755 | + uint8_t name2_len; /* Length of second name (used by VM) */ 756 | + uint16_t dev_id; 757 | + uint16_t vend_id; /* Check skipped if zero. */ 758 | + uint16_t subsys_id; 759 | + uint16_t subsys_vend_id; /* Check skipped if zero. */ 760 | + char name1_2[38]; /* First and second name, no separation. */ 761 | + uint8_t sign[0x20]; 762 | +} 763 | +__attribute__((packed)) 764 | +vgpu_unlock_vgpu_t; 765 | + 766 | +/* Helper macro to initialize the structure above. */ 767 | +#define VGPU(dev_id, subsys_id, name) \ 768 | + { (10 + 2 * strlen(name) + 15) / 16, /* num_blocks */ \ 769 | + strlen(name), /* name1_len */ \ 770 | + strlen(name), /* name2_len */ \ 771 | + (dev_id), /* dev_id */ \ 772 | + 0, /* vend_id */ \ 773 | + (subsys_id), /* subsys_id */ \ 774 | + 0, /* subsys_vend_id */ \ 775 | + { name name } } /* name1_2 */ 776 | + 777 | +static vgpu_unlock_vgpu_t vgpu_unlock_vgpu[] = 778 | +{ 779 | + /* Tesla M10 (Maxwell) */ 780 | + VGPU(0x13bd, 0x11cc, "GRID M10-0B"), 781 | + VGPU(0x13bd, 0x11cd, "GRID M10-1B"), 782 | + VGPU(0x13bd, 0x1339, "GRID M10-1B4"), 783 | + VGPU(0x13bd, 0x1286, "GRID M10-2B"), 784 | + VGPU(0x13bd, 0x12ee, "GRID M10-2B4"), 785 | + VGPU(0x13bd, 0x11ce, "GRID M10-0Q"), 786 | + VGPU(0x13bd, 0x11cf, "GRID M10-1Q"), 787 | + VGPU(0x13bd, 0x11d0, "GRID M10-2Q"), 788 | + VGPU(0x13bd, 0x11d1, "GRID M10-4Q"), 789 | + VGPU(0x13bd, 0x11d2, "GRID M10-8Q"), 790 | + VGPU(0x13bd, 0x11d3, "GRID M10-1A"), 791 | + VGPU(0x13bd, 0x11d4, "GRID M10-2A"), 792 | + VGPU(0x13bd, 0x11d5, "GRID M10-4A"), 793 | + VGPU(0x13bd, 0x11d6, "GRID M10-8A"), 794 | + 795 | + /* Tesla M60 (Maxwell 2.0) */ 796 | + VGPU(0x13f2, 0x114c, "GRID M60-0Q"), 797 | + VGPU(0x13f2, 0x114d, "GRID M60-1Q"), 798 | + VGPU(0x13f2, 0x114e, "GRID M60-2Q"), 799 | + VGPU(0x13f2, 0x114f, "GRID M60-4Q"), 800 | + VGPU(0x13f2, 0x1150, "GRID M60-8Q"), 801 | + VGPU(0x13f2, 0x1176, "GRID M60-0B"), 802 | + VGPU(0x13f2, 0x1177, "GRID M60-1B"), 803 | + VGPU(0x13f2, 0x117D, "GRID M60-2B"), 804 | + VGPU(0x13f2, 0x1337, "GRID M60-1B4"), 805 | + VGPU(0x13f2, 0x12ec, "GRID M60-2B4"), 806 | + VGPU(0x13f2, 0x11ae, "GRID M60-1A"), 807 | + VGPU(0x13f2, 0x11aF, "GRID M60-2A"), 808 | + VGPU(0x13f2, 0x11b0, "GRID M60-4A"), 809 | + VGPU(0x13f2, 0x11b1, "GRID M60-8A"), 810 | + 811 | + /* Tesla P4 (Pascal) */ 812 | + VGPU(0x1bb3, 0x1203, "GRID P4-1B"), 813 | + VGPU(0x1bb3, 0x1204, "GRID P4-1Q"), 814 | + VGPU(0x1bb3, 0x1205, "GRID P4-2Q"), 815 | + VGPU(0x1bb3, 0x1206, "GRID P4-4Q"), 816 | + VGPU(0x1bb3, 0x1207, "GRID P4-8Q"), 817 | + VGPU(0x1bb3, 0x1208, "GRID P4-1A"), 818 | + VGPU(0x1bb3, 0x1209, "GRID P4-2A"), 819 | + VGPU(0x1bb3, 0x120a, "GRID P4-4A"), 820 | + VGPU(0x1bb3, 0x120b, "GRID P4-8A"), 821 | + VGPU(0x1bb3, 0x1288, "GRID P4-2B"), 822 | + VGPU(0x1bb3, 0x12f1, "GRID P4-2B4"), 823 | + VGPU(0x1bb3, 0x133c, "GRID P4-1B4"), 824 | + VGPU(0x1bb3, 0x1380, "GRID P4-8C"), 825 | + VGPU(0x1bb3, 0x1385, "GRID P4-4C"), 826 | + 827 | + /* Tesla P40 (Pascal) */ 828 | + VGPU(0x1b38, 0x11e7, "GRID P40-1B"), 829 | + VGPU(0x1b38, 0x11e8, "GRID P40-1Q"), 830 | + VGPU(0x1b38, 0x11e9, "GRID P40-2Q"), 831 | + VGPU(0x1b38, 0x11ea, "GRID P40-3Q"), 832 | + VGPU(0x1b38, 0x11eb, "GRID P40-4Q"), 833 | + VGPU(0x1b38, 0x11ec, "GRID P40-6Q"), 834 | + VGPU(0x1b38, 0x11ed, "GRID P40-8Q"), 835 | + VGPU(0x1b38, 0x11ee, "GRID P40-12Q"), 836 | + VGPU(0x1b38, 0x11ef, "GRID P40-24Q"), 837 | + VGPU(0x1b38, 0x11f0, "GRID P40-1A"), 838 | + VGPU(0x1b38, 0x11f1, "GRID P40-2A"), 839 | + VGPU(0x1b38, 0x11f2, "GRID P40-3A"), 840 | + VGPU(0x1b38, 0x11f3, "GRID P40-4A"), 841 | + VGPU(0x1b38, 0x11f4, "GRID P40-6A"), 842 | + VGPU(0x1b38, 0x11f5, "GRID P40-8A"), 843 | + VGPU(0x1b38, 0x11f6, "GRID P40-12A"), 844 | + VGPU(0x1b38, 0x11f7, "GRID P40-24A"), 845 | + VGPU(0x1b38, 0x1287, "GRID P40-2B"), 846 | + VGPU(0x1b38, 0x12ef, "GRID P40-2B4"), 847 | + VGPU(0x1b38, 0x133a, "GRID P40-1B4"), 848 | + VGPU(0x1b38, 0x137e, "GRID P40-24C"), 849 | + VGPU(0x1b38, 0x1381, "GRID P40-4C"), 850 | + VGPU(0x1b38, 0x1382, "GRID P40-6C"), 851 | + VGPU(0x1b38, 0x1383, "GRID P40-8C"), 852 | + VGPU(0x1b38, 0x1384, "GRID P40-12C"), 853 | + 854 | + /* Tesla V100 32GB PCIE (Volta) */ 855 | + VGPU(0x1db6, 0x12bd, "GRID V100D-1B"), 856 | + VGPU(0x1db6, 0x12be, "GRID V100D-2B"), 857 | + VGPU(0x1db6, 0x12f7, "GRID V100D-2B4"), 858 | + VGPU(0x1db6, 0x1342, "GRID V100D-1B4"), 859 | + VGPU(0x1db6, 0x12bf, "GRID V100D-1Q"), 860 | + VGPU(0x1db6, 0x12c0, "GRID V100D-2Q"), 861 | + VGPU(0x1db6, 0x12c1, "GRID V100D-4Q"), 862 | + VGPU(0x1db6, 0x12c2, "GRID V100D-8Q"), 863 | + VGPU(0x1db6, 0x12c3, "GRID V100D-16Q"), 864 | + VGPU(0x1db6, 0x12c4, "GRID V100D-32Q"), 865 | + VGPU(0x1db6, 0x12c5, "GRID V100D-1A"), 866 | + VGPU(0x1db6, 0x12c6, "GRID V100D-2A"), 867 | + VGPU(0x1db6, 0x12c7, "GRID V100D-4A"), 868 | + VGPU(0x1db6, 0x12c8, "GRID V100D-8A"), 869 | + VGPU(0x1db6, 0x12c9, "GRID V100D-16A"), 870 | + VGPU(0x1db6, 0x12ca, "GRID V100D-32A"), 871 | + VGPU(0x1db6, 0x1395, "GRID V100D-4C"), 872 | + VGPU(0x1db6, 0x1396, "GRID V100D-8C"), 873 | + VGPU(0x1db6, 0x1397, "GRID V100D-16C"), 874 | + VGPU(0x1db6, 0x1377, "GRID V100D-32C"), 875 | + 876 | + /* Tesla T4 (Turing) */ 877 | + VGPU(0x1eb8, 0x1309, "GRID T4-1B"), 878 | + VGPU(0x1eb8, 0x130a, "GRID T4-2B"), 879 | + VGPU(0x1eb8, 0x130b, "GRID T4-2B4"), 880 | + VGPU(0x1eb8, 0x130c, "GRID T4-1Q"), 881 | + VGPU(0x1eb8, 0x130d, "GRID T4-2Q"), 882 | + VGPU(0x1eb8, 0x130e, "GRID T4-4Q"), 883 | + VGPU(0x1eb8, 0x130f, "GRID T4-8Q"), 884 | + VGPU(0x1eb8, 0x1310, "GRID T4-16Q"), 885 | + VGPU(0x1eb8, 0x1311, "GRID T4-1A"), 886 | + VGPU(0x1eb8, 0x1312, "GRID T4-2A"), 887 | + VGPU(0x1eb8, 0x1313, "GRID T4-4A"), 888 | + VGPU(0x1eb8, 0x1314, "GRID T4-8A"), 889 | + VGPU(0x1eb8, 0x1315, "GRID T4-16A"), 890 | + VGPU(0x1eb8, 0x1345, "GRID T4-1B4"), 891 | + VGPU(0x1eb8, 0x1375, "GRID T4-16C"), 892 | + VGPU(0x1eb8, 0x139a, "GRID T4-4C"), 893 | + VGPU(0x1eb8, 0x139b, "GRID T4-8C"), 894 | + 895 | + /* Quadro RTX 6000 (Turing) */ 896 | + VGPU(0x1e30, 0x1325, "GRID RTX6000-1Q"), 897 | + VGPU(0x1e30, 0x1326, "GRID RTX6000-2Q"), 898 | + VGPU(0x1e30, 0x1327, "GRID RTX6000-3Q"), 899 | + VGPU(0x1e30, 0x1328, "GRID RTX6000-4Q"), 900 | + VGPU(0x1e30, 0x1329, "GRID RTX6000-6Q"), 901 | + VGPU(0x1e30, 0x132a, "GRID RTX6000-8Q"), 902 | + VGPU(0x1e30, 0x132b, "GRID RTX6000-12Q"), 903 | + VGPU(0x1e30, 0x132c, "GRID RTX6000-24Q"), 904 | + VGPU(0x1e30, 0x13bf, "GRID RTX6000-4C"), 905 | + VGPU(0x1e30, 0x13c0, "GRID RTX6000-6C"), 906 | + VGPU(0x1e30, 0x13c1, "GRID RTX6000-8C"), 907 | + VGPU(0x1e30, 0x13c2, "GRID RTX6000-12C"), 908 | + VGPU(0x1e30, 0x13c3, "GRID RTX6000-24C"), 909 | + VGPU(0x1e30, 0x1437, "GRID RTX6000-1B"), 910 | + VGPU(0x1e30, 0x1438, "GRID RTX6000-2B"), 911 | + VGPU(0x1e30, 0x1439, "GRID RTX6000-1A"), 912 | + VGPU(0x1e30, 0x143a, "GRID RTX6000-2A"), 913 | + VGPU(0x1e30, 0x143b, "GRID RTX6000-3A"), 914 | + VGPU(0x1e30, 0x143c, "GRID RTX6000-4A"), 915 | + VGPU(0x1e30, 0x143d, "GRID RTX6000-6A"), 916 | + VGPU(0x1e30, 0x143e, "GRID RTX6000-8A"), 917 | + VGPU(0x1e30, 0x143f, "GRID RTX6000-12A"), 918 | + VGPU(0x1e30, 0x1440, "GRID RTX6000-24A"), 919 | + 920 | + /* RTX A6000 (Ampere) */ 921 | + VGPU(0x2230, 0x14fa, "NVIDIA RTXA6000-1B"), 922 | + VGPU(0x2230, 0x14fb, "NVIDIA RTXA6000-2B"), 923 | + VGPU(0x2230, 0x14fc, "NVIDIA RTXA6000-1Q"), 924 | + VGPU(0x2230, 0x14fd, "NVIDIA RTXA6000-2Q"), 925 | + VGPU(0x2230, 0x14fe, "NVIDIA RTXA6000-3Q"), 926 | + VGPU(0x2230, 0x14ff, "NVIDIA RTXA6000-4Q"), 927 | + VGPU(0x2230, 0x1500, "NVIDIA RTXA6000-6Q"), 928 | + VGPU(0x2230, 0x1501, "NVIDIA RTXA6000-8Q"), 929 | + VGPU(0x2230, 0x1502, "NVIDIA RTXA6000-12Q"), 930 | + VGPU(0x2230, 0x1503, "NVIDIA RTXA6000-16Q"), 931 | + VGPU(0x2230, 0x1504, "NVIDIA RTXA6000-24Q"), 932 | + VGPU(0x2230, 0x1505, "NVIDIA RTXA6000-48Q"), 933 | + VGPU(0x2230, 0x1506, "NVIDIA RTXA6000-1A"), 934 | + VGPU(0x2230, 0x1507, "NVIDIA RTXA6000-2A"), 935 | + VGPU(0x2230, 0x1508, "NVIDIA RTXA6000-3A"), 936 | + VGPU(0x2230, 0x1509, "NVIDIA RTXA6000-4A"), 937 | + VGPU(0x2230, 0x150a, "NVIDIA RTXA6000-6A"), 938 | + VGPU(0x2230, 0x150b, "NVIDIA RTXA6000-8A"), 939 | + VGPU(0x2230, 0x150c, "NVIDIA RTXA6000-12A"), 940 | + VGPU(0x2230, 0x150d, "NVIDIA RTXA6000-16A"), 941 | + VGPU(0x2230, 0x150e, "NVIDIA RTXA6000-24A"), 942 | + VGPU(0x2230, 0x150f, "NVIDIA RTXA6000-48A"), 943 | + VGPU(0x2230, 0x1514, "NVIDIA RTXA6000-4C"), 944 | + VGPU(0x2230, 0x1515, "NVIDIA RTXA6000-6C"), 945 | + VGPU(0x2230, 0x1516, "NVIDIA RTXA6000-8C"), 946 | + VGPU(0x2230, 0x1517, "NVIDIA RTXA6000-12C"), 947 | + VGPU(0x2230, 0x1518, "NVIDIA RTXA6000-16C"), 948 | + VGPU(0x2230, 0x1519, "NVIDIA RTXA6000-24C"), 949 | + VGPU(0x2230, 0x151a, "NVIDIA RTXA6000-48C"), 950 | + 951 | + { 0 } /* Sentinel */ 952 | +}; 953 | + 954 | +#undef VGPU 955 | + 956 | +static const uint8_t vgpu_unlock_magic_start[0x10] = { 957 | + 0xf3, 0xf5, 0x9e, 0x3d, 0x13, 0x91, 0x75, 0x18, 958 | + 0x6a, 0x7b, 0x55, 0xed, 0xce, 0x5d, 0x84, 0x67 959 | +}; 960 | + 961 | +static const uint8_t vgpu_unlock_magic_sacrifice[0x10] = { 962 | + 0x46, 0x4f, 0x39, 0x49, 0x74, 0x91, 0xd7, 0x0f, 963 | + 0xbc, 0x65, 0xc2, 0x70, 0xdd, 0xdd, 0x11, 0x54 964 | +}; 965 | + 966 | +static bool vgpu_unlock_patch_applied = FALSE; 967 | + 968 | +static bool vgpu_unlock_bar3_mapped = FALSE; 969 | +static uint64_t vgpu_unlock_bar3_beg; 970 | +static uint64_t vgpu_unlock_bar3_end; 971 | + 972 | +static uint8_t vgpu_unlock_magic[0x10]; 973 | +static bool vgpu_unlock_magic_found = FALSE; 974 | + 975 | +static uint8_t vgpu_unlock_key[0x10]; 976 | +static bool vgpu_unlock_key_found = FALSE; 977 | + 978 | +/* These need to be added to the linker script. */ 979 | +extern uint8_t vgpu_unlock_nv_kern_rodata_beg; 980 | +extern uint8_t vgpu_unlock_nv_kern_rodata_end; 981 | + 982 | +static uint16_t vgpu_unlock_pci_devid_to_vgpu_capable(uint16_t pci_devid) 983 | +{ 984 | + switch (pci_devid) 985 | + { 986 | + /* Maxwell */ 987 | + case 0x1340 ... 0x13bd: 988 | + case 0x174d ... 0x179c: 989 | + return 0x13bd; /* Tesla M10 */ 990 | + 991 | + /* Maxwell 2.0 */ 992 | + case 0x13c0 ... 0x1436: 993 | + case 0x1617 ... 0x1667: /* GM204 */ 994 | + case 0x17c2 ... 0x17fd: /* GM200 */ 995 | + return 0x13f2; /* Tesla M60 */ 996 | + 997 | + /* Pascal */ 998 | + case 0x15f0 ... 0x15f1: /* GP100GL */ 999 | + case 0x1b00 ... 0x1d56: 1000 | + case 0x1725 ... 0x172f: /* GP100 */ 1001 | + return 0x1b38; /* Tesla P40 */ 1002 | + 1003 | + /* Volta GV100 */ 1004 | + case 0x1d81: /* Titan V 16GB */ 1005 | + case 0x1dba: /* Quadro GV100 32GB */ 1006 | + return 0x1db6; /* Tesla V100 32GB PCIE */ 1007 | + 1008 | + /* Turing */ 1009 | + case 0x1e02 ... 0x1ff9: 1010 | + case 0x2182 ... 0x21d1: /* TU116 */ 1011 | + return 0x1e30; /* Quadro RTX 6000 */ 1012 | + 1013 | + /* Ampere */ 1014 | + case 0x2200 ... 0x2600: 1015 | + return 0x2230; /* RTX A6000 */ 1016 | + } 1017 | + 1018 | + return pci_devid; 1019 | +} 1020 | + 1021 | +/* Our own memcmp that will bypass buffer overflow checks. */ 1022 | +static int vgpu_unlock_memcmp(const void *a, const void *b, size_t size) 1023 | +{ 1024 | + uint8_t *pa = (uint8_t*)a; 1025 | + uint8_t *pb = (uint8_t*)b; 1026 | + 1027 | + while (size--) 1028 | + { 1029 | + if (*pa != *pb) 1030 | + { 1031 | + return *pa - *pb; 1032 | + } 1033 | + 1034 | + pa++; 1035 | + pb++; 1036 | + } 1037 | + 1038 | + return 0; 1039 | +} 1040 | + 1041 | +/* Search for a certain pattern in the .rodata section of nv-kern.o_binary. */ 1042 | +static void *vgpu_unlock_find_in_rodata(const void *val, size_t size) 1043 | +{ 1044 | + uint8_t *i; 1045 | + 1046 | + for (i = &vgpu_unlock_nv_kern_rodata_beg; 1047 | + i < &vgpu_unlock_nv_kern_rodata_end - size; 1048 | + i++) 1049 | + { 1050 | + if (vgpu_unlock_memcmp(val, i, size) == 0) 1051 | + { 1052 | + return i; 1053 | + } 1054 | + } 1055 | + 1056 | + return NULL; 1057 | +} 1058 | + 1059 | +/* Check if a value is within a range. */ 1060 | +static bool vgpu_unlock_in_range(uint64_t val, uint64_t beg, uint64_t end) 1061 | +{ 1062 | + return (val >= beg) && (val <= end); 1063 | +} 1064 | + 1065 | +/* Check if range a is completely contained within range b. */ 1066 | +static bool vgpu_unlock_range_contained_in(uint64_t a_beg, 1067 | + uint64_t a_end, 1068 | + uint64_t b_beg, 1069 | + uint64_t b_end) 1070 | +{ 1071 | + return vgpu_unlock_in_range(a_beg, b_beg, b_end) && 1072 | + vgpu_unlock_in_range(a_end, b_beg, b_end); 1073 | +} 1074 | + 1075 | +/* Check if an address points into a specific BAR of an NVIDIA GPU. */ 1076 | +static bool vgpu_unlock_in_bar(uint64_t addr, int bar) 1077 | +{ 1078 | + struct pci_dev *dev = NULL; 1079 | + 1080 | + while (1) 1081 | + { 1082 | + dev = pci_get_device(0x10de, PCI_ANY_ID, dev); 1083 | + 1084 | + if (dev) 1085 | + { 1086 | + if (vgpu_unlock_in_range(addr, 1087 | + pci_resource_start(dev, bar), 1088 | + pci_resource_end(dev, bar))) 1089 | + { 1090 | + return TRUE; 1091 | + } 1092 | + } 1093 | + else 1094 | + { 1095 | + return FALSE; 1096 | + } 1097 | + } 1098 | +} 1099 | + 1100 | +/* Check if a potential magic value is valid. */ 1101 | +static bool vgpu_unlock_magic_valid(const uint8_t *magic) 1102 | +{ 1103 | + void **gpu_list_item; 1104 | + 1105 | + static void **gpu_list_start = NULL; 1106 | + 1107 | + if (!gpu_list_start) 1108 | + { 1109 | + void *magic_start = vgpu_unlock_find_in_rodata(vgpu_unlock_magic_start, 1110 | + sizeof(vgpu_unlock_magic_start)); 1111 | + 1112 | + if (!magic_start) 1113 | + { 1114 | + LOG(KERN_ERR "Failed to find start of gpu list in .rodata\n"); 1115 | + return NULL; 1116 | + } 1117 | + 1118 | + gpu_list_start = (void**)vgpu_unlock_find_in_rodata(&magic_start, 1119 | + sizeof(magic_start)); 1120 | + 1121 | + if (!gpu_list_start) 1122 | + { 1123 | + LOG(KERN_ERR "Failed to find pointer to start of gpu list in .rodata\n"); 1124 | + return NULL; 1125 | + } 1126 | + } 1127 | + 1128 | + for (gpu_list_item = gpu_list_start; 1129 | + vgpu_unlock_in_range((uint64_t)*gpu_list_item, 1130 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_beg, 1131 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_end); 1132 | + gpu_list_item += 3) 1133 | + { 1134 | + if (memcmp(magic, *gpu_list_item, 0x10) == 0) 1135 | + { 1136 | + return TRUE; 1137 | + } 1138 | + } 1139 | + 1140 | + return FALSE; 1141 | +} 1142 | + 1143 | +static void vgpu_unlock_apply_patch(void) 1144 | +{ 1145 | + uint8_t i; 1146 | + void *magic; 1147 | + void **magic_ptr; 1148 | + void **blocks_ptr; 1149 | + void **sign_ptr; 1150 | + uint8_t sign[0x20]; 1151 | + uint8_t num_blocks; 1152 | + void *sac_magic; 1153 | + void **sac_magic_ptr; 1154 | + void **sac_blocks_ptr; 1155 | + void **sac_sign_ptr; 1156 | + vgpu_unlock_aes128_ctx aes_ctx; 1157 | + vgpu_unlock_vgpu_t* vgpu; 1158 | + uint8_t first_block[0x10]; 1159 | + uint16_t device_id; 1160 | + 1161 | + magic = vgpu_unlock_find_in_rodata(vgpu_unlock_magic, 1162 | + sizeof(vgpu_unlock_magic)); 1163 | + if (!magic) 1164 | + { 1165 | + LOG(KERN_ERR "Failed to find magic in .rodata.\n"); 1166 | + goto failed; 1167 | + } 1168 | + 1169 | + LOG(KERN_WARNING "Magic is at: %px\n", magic); 1170 | + 1171 | + magic_ptr = (void**)vgpu_unlock_find_in_rodata(&magic, 1172 | + sizeof(magic)); 1173 | + 1174 | + if (!magic_ptr) 1175 | + { 1176 | + LOG(KERN_ERR "Failed to find pointer to magic in .rodata.\n"); 1177 | + goto failed; 1178 | + } 1179 | + 1180 | + blocks_ptr = magic_ptr + 1; 1181 | + sign_ptr = magic_ptr + 2; 1182 | + 1183 | + LOG(KERN_WARNING "Pointers found, magic: %px blocks: %px sign: %px\n", 1184 | + magic_ptr, blocks_ptr, sign_ptr); 1185 | + 1186 | + if (!vgpu_unlock_in_range((uint64_t)*blocks_ptr, 1187 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_beg, 1188 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_end) || 1189 | + !vgpu_unlock_in_range((uint64_t)*sign_ptr, 1190 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_beg, 1191 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_end)) 1192 | + { 1193 | + LOG(KERN_ERR "Invalid sign or blocks pointer.\n"); 1194 | + goto failed; 1195 | + } 1196 | + 1197 | + num_blocks = *(uint8_t*)*blocks_ptr; 1198 | + 1199 | + vgpu_unlock_hmac_sha256(sign, 1200 | + *blocks_ptr, 1201 | + 1 + num_blocks * 0x10, 1202 | + vgpu_unlock_key, 1203 | + sizeof(vgpu_unlock_key)); 1204 | + 1205 | + LOG(KERN_WARNING "Generate signature is: %32ph\n", sign); 1206 | + 1207 | + if (memcmp(sign, *sign_ptr, sizeof(sign)) != 0) 1208 | + { 1209 | + LOG(KERN_ERR "Signatures does not match.\n"); 1210 | + goto failed; 1211 | + } 1212 | + 1213 | + sac_magic = vgpu_unlock_find_in_rodata(vgpu_unlock_magic_sacrifice, 1214 | + sizeof(vgpu_unlock_magic_sacrifice)); 1215 | + 1216 | + if (!sac_magic) 1217 | + { 1218 | + LOG(KERN_ERR "Failed to find sacrificial magic.\n"); 1219 | + goto failed; 1220 | + } 1221 | + 1222 | + LOG(KERN_WARNING "Sacrificial magic is at: %px\n", sac_magic); 1223 | + 1224 | + sac_magic_ptr = (void**) vgpu_unlock_find_in_rodata(&sac_magic, 1225 | + sizeof(sac_magic)); 1226 | + 1227 | + if (!sac_magic_ptr) 1228 | + { 1229 | + LOG(KERN_ERR "Failed to find pointer to sacrificial magic.\n"); 1230 | + goto failed; 1231 | + } 1232 | + 1233 | + sac_blocks_ptr = sac_magic_ptr + 1; 1234 | + sac_sign_ptr = sac_magic_ptr + 2; 1235 | + 1236 | + LOG(KERN_WARNING "Pointers found, sac_magic: %px sac_blocks: %px sac_sign: %px\n", 1237 | + sac_magic_ptr, sac_blocks_ptr, sac_sign_ptr); 1238 | + 1239 | + if (!vgpu_unlock_in_range((uint64_t)*sac_blocks_ptr, 1240 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_beg, 1241 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_end) || 1242 | + !vgpu_unlock_in_range((uint64_t)*sac_sign_ptr, 1243 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_beg, 1244 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_end)) 1245 | + { 1246 | + LOG(KERN_ERR "Invalid sacrificial sign or blocks pointer.\n"); 1247 | + goto failed; 1248 | + } 1249 | + 1250 | + /* Decrypt the first block so we can access the PCI device ID. */ 1251 | + memcpy(first_block, (uint8_t*)*blocks_ptr + 1, sizeof(first_block)); 1252 | + vgpu_unlock_aes128_init(&aes_ctx, vgpu_unlock_key); 1253 | + vgpu_unlock_aes128_decrypt(&aes_ctx, first_block); 1254 | + LOG(KERN_WARNING "Decrypted first block is: %16ph.\n", 1255 | + first_block); 1256 | + 1257 | + device_id = *((uint16_t*)first_block + 1); 1258 | + device_id = vgpu_unlock_pci_devid_to_vgpu_capable(device_id); 1259 | + 1260 | + /* Loop over all vGPUs and add the ones that match our device ID. */ 1261 | + vgpu = vgpu_unlock_vgpu; 1262 | + 1263 | + while (vgpu->num_blocks != 0) 1264 | + { 1265 | + if (vgpu->dev_id != device_id) 1266 | + { 1267 | + vgpu++; 1268 | + continue; 1269 | + } 1270 | + 1271 | + num_blocks = vgpu->num_blocks; 1272 | + 1273 | + *sac_magic_ptr = vgpu_unlock_magic; 1274 | + *sac_blocks_ptr = vgpu; 1275 | + *sac_sign_ptr = &vgpu->sign; 1276 | + 1277 | + vgpu_unlock_aes128_init(&aes_ctx, vgpu_unlock_key); 1278 | + 1279 | + for (i = 0; i < num_blocks; i++) 1280 | + { 1281 | + vgpu_unlock_aes128_encrypt(&aes_ctx, 1282 | + (uint8_t*)vgpu + 1 + i * 0x10); 1283 | + } 1284 | + 1285 | + vgpu_unlock_hmac_sha256(&vgpu->sign, 1286 | + vgpu, 1287 | + 1 + num_blocks * 0x10, 1288 | + vgpu_unlock_key, 1289 | + sizeof(vgpu_unlock_key)); 1290 | + 1291 | + sac_magic_ptr += 3; 1292 | + sac_blocks_ptr = sac_magic_ptr + 1; 1293 | + sac_sign_ptr = sac_magic_ptr + 2; 1294 | + vgpu++; 1295 | + } 1296 | + 1297 | + vgpu_unlock_patch_applied = TRUE; 1298 | + 1299 | + LOG(KERN_WARNING "vGPU unlock patch applied.\n"); 1300 | + 1301 | + return; 1302 | + 1303 | +failed: 1304 | + vgpu_unlock_magic_found = FALSE; 1305 | + vgpu_unlock_key_found = FALSE; 1306 | +} 1307 | + 1308 | +static void *vgpu_unlock_memcpy_hook(void *dst, const void *src, size_t count) 1309 | +{ 1310 | + bool src_in_bar3 = vgpu_unlock_bar3_mapped && 1311 | + vgpu_unlock_in_range((uint64_t)src, 1312 | + vgpu_unlock_bar3_beg, 1313 | + vgpu_unlock_bar3_end); 1314 | + 1315 | + void *result = memcpy(dst, src, count); 1316 | + 1317 | + if (src_in_bar3 && 1318 | + count == sizeof(vgpu_unlock_magic) && 1319 | + !vgpu_unlock_magic_found && 1320 | + vgpu_unlock_magic_valid(dst)) 1321 | + { 1322 | + memcpy(vgpu_unlock_magic, dst, count); 1323 | + vgpu_unlock_magic_found = TRUE; 1324 | + 1325 | + LOG(KERN_WARNING "Magic found: %16ph\n", 1326 | + vgpu_unlock_magic); 1327 | + 1328 | + } 1329 | + else if (src_in_bar3 && 1330 | + count == sizeof(vgpu_unlock_key) && 1331 | + vgpu_unlock_magic_found && 1332 | + !vgpu_unlock_key_found) 1333 | + { 1334 | + memcpy(vgpu_unlock_key, dst, count); 1335 | + vgpu_unlock_key_found = TRUE; 1336 | + 1337 | + LOG(KERN_WARNING "Key found: %16ph\n", 1338 | + vgpu_unlock_key); 1339 | + } 1340 | + 1341 | + if (!vgpu_unlock_patch_applied && 1342 | + vgpu_unlock_magic_found && 1343 | + vgpu_unlock_key_found) 1344 | + { 1345 | + vgpu_unlock_apply_patch(); 1346 | + } 1347 | + 1348 | + return result; 1349 | +} 1350 | + 1351 | +/* Check if the new IO mapping contains the magic or key. */ 1352 | +static void vgpu_unlock_check_map(uint64_t phys_addr, 1353 | + size_t size, 1354 | + void *virt_addr) 1355 | +{ 1356 | + LOG(KERN_WARNING "Remap called.\n"); 1357 | + 1358 | + if (virt_addr && 1359 | + !vgpu_unlock_bar3_mapped && 1360 | + vgpu_unlock_in_bar(phys_addr, 3)) 1361 | + { 1362 | + vgpu_unlock_bar3_beg = (uint64_t)virt_addr; 1363 | + vgpu_unlock_bar3_end = (uint64_t)virt_addr + size; 1364 | + vgpu_unlock_bar3_mapped = TRUE; 1365 | + LOG(KERN_WARNING "BAR3 mapped at: 0x%llX\n", 1366 | + vgpu_unlock_bar3_beg); 1367 | + } 1368 | +} 1369 | + 1370 | +static void *vgpu_unlock_nv_ioremap_hook(uint64_t phys, 1371 | + uint64_t size) 1372 | +{ 1373 | + void *virt_addr = nv_ioremap(phys, size); 1374 | + vgpu_unlock_check_map(phys, size, virt_addr); 1375 | + return virt_addr; 1376 | +} 1377 | + 1378 | +static void *vgpu_unlock_nv_ioremap_nocache_hook(uint64_t phys, 1379 | + uint64_t size) 1380 | +{ 1381 | + void *virt_addr = nv_ioremap_nocache(phys, size); 1382 | + vgpu_unlock_check_map(phys, size, virt_addr); 1383 | + return virt_addr; 1384 | +} 1385 | + 1386 | +static void *vgpu_unlock_nv_ioremap_cache_hook(uint64_t phys, 1387 | + uint64_t size) 1388 | +{ 1389 | + void *virt_addr = nv_ioremap_cache(phys, size); 1390 | + vgpu_unlock_check_map(phys, size, virt_addr); 1391 | + return virt_addr; 1392 | +} 1393 | + 1394 | +static void *vgpu_unlock_nv_ioremap_wc_hook(uint64_t phys, 1395 | + uint64_t size) 1396 | +{ 1397 | + void *virt_addr = nv_ioremap_wc(phys, size); 1398 | + vgpu_unlock_check_map(phys, size, virt_addr); 1399 | + return virt_addr; 1400 | +} 1401 | + 1402 | +#undef LOG 1403 | + 1404 | +/* Redirect future callers to our hooks. */ 1405 | +#define memcpy vgpu_unlock_memcpy_hook 1406 | +#define nv_ioremap vgpu_unlock_nv_ioremap_hook 1407 | +#define nv_ioremap_nocache vgpu_unlock_nv_ioremap_nocache_hook 1408 | +#define nv_ioremap_cache vgpu_unlock_nv_ioremap_cache_hook 1409 | +#define nv_ioremap_wc vgpu_unlock_nv_ioremap_wc_hook 1410 | -------------------------------------------------------------------------------- /nvidia-merged/vgpu_unlock.patch: -------------------------------------------------------------------------------- 1 | --- ./kernel/nvidia/kern.ld 1969-12-31 18:00:00.000000000 -0600 2 | +++ ./kernel/nvidia/kern.ld 2022-03-24 11:51:18.776835647 -0500 3 | @@ -0,0 +1,162 @@ 4 | +/* Script for ld -r: link without relocation */ 5 | +/* Copyright (C) 2014-2018 Free Software Foundation, Inc. 6 | + Copying and distribution of this script, with or without modification, 7 | + are permitted in any medium without royalty provided the copyright 8 | + notice and this notice are preserved. */ 9 | +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", 10 | + "elf64-x86-64") 11 | +OUTPUT_ARCH(i386:x86-64) 12 | + /* For some reason, the Solaris linker makes bad executables 13 | + if gld -r is used and the intermediate file has sections starting 14 | + at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld 15 | + bug. But for now assigning the zero vmas works. */ 16 | +SECTIONS 17 | +{ 18 | + /* Read-only sections, merged into text segment: */ 19 | + .interp 0 : { *(.interp) } 20 | + .note.gnu.build-id : { *(.note.gnu.build-id) } 21 | + .hash 0 : { *(.hash) } 22 | + .gnu.hash 0 : { *(.gnu.hash) } 23 | + .dynsym 0 : { *(.dynsym) } 24 | + .dynstr 0 : { *(.dynstr) } 25 | + .gnu.version 0 : { *(.gnu.version) } 26 | + .gnu.version_d 0: { *(.gnu.version_d) } 27 | + .gnu.version_r 0: { *(.gnu.version_r) } 28 | + .rela.init 0 : { *(.rela.init) } 29 | + .rela.text 0 : { *(.rela.text) } 30 | + .rela.fini 0 : { *(.rela.fini) } 31 | + .rela.rodata 0 : { *(.rela.rodata) } 32 | + .rela.data.rel.ro 0 : { *(.rela.data.rel.ro) } 33 | + .rela.data 0 : { *(.rela.data) } 34 | + .rela.tdata 0 : { *(.rela.tdata) } 35 | + .rela.tbss 0 : { *(.rela.tbss) } 36 | + .rela.ctors 0 : { *(.rela.ctors) } 37 | + .rela.dtors 0 : { *(.rela.dtors) } 38 | + .rela.got 0 : { *(.rela.got) } 39 | + .rela.bss 0 : { *(.rela.bss) } 40 | + .rela.ldata 0 : { *(.rela.ldata) } 41 | + .rela.lbss 0 : { *(.rela.lbss) } 42 | + .rela.lrodata 0 : { *(.rela.lrodata) } 43 | + .rela.ifunc 0 : { *(.rela.ifunc) } 44 | + .rela.plt 0 : 45 | + { 46 | + *(.rela.plt) 47 | + } 48 | + .init 0 : 49 | + { 50 | + KEEP (*(SORT_NONE(.init))) 51 | + } 52 | + .plt 0 : { *(.plt) *(.iplt) } 53 | +.plt.got 0 : { *(.plt.got) } 54 | +.plt.sec 0 : { *(.plt.sec) } 55 | + .text 0 : 56 | + { 57 | + *(.text .stub) 58 | + /* .gnu.warning sections are handled specially by elf32.em. */ 59 | + *(.gnu.warning) 60 | + } 61 | + .fini 0 : 62 | + { 63 | + KEEP (*(SORT_NONE(.fini))) 64 | + } 65 | + .rodata 0 : { *(EXCLUDE_FILE (*nv-kernel.o) .rodata) } 66 | + .rodata1 0 : { *(.rodata1) } 67 | + .eh_frame_hdr : { *(.eh_frame_hdr) } 68 | + .eh_frame 0 : ONLY_IF_RO { KEEP (*(.eh_frame)) } 69 | + .gcc_except_table 0 : ONLY_IF_RO { *(.gcc_except_table 70 | + .gcc_except_table.*) } 71 | + .gnu_extab 0 : ONLY_IF_RO { *(.gnu_extab*) } 72 | + /* These sections are generated by the Sun/Oracle C++ compiler. */ 73 | + .exception_ranges 0 : ONLY_IF_RO { *(.exception_ranges 74 | + .exception_ranges*) } 75 | + /* Adjust the address for the data segment. We want to adjust up to 76 | + the same address within the page on the next page up. */ 77 | + /* Exception handling */ 78 | + .eh_frame 0 : ONLY_IF_RW { KEEP (*(.eh_frame)) } 79 | + .gnu_extab 0 : ONLY_IF_RW { *(.gnu_extab) } 80 | + .gcc_except_table 0 : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } 81 | + .exception_ranges 0 : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } 82 | + /* Thread Local Storage sections */ 83 | + .tdata 0 : 84 | + { 85 | + *(.tdata) 86 | + } 87 | + .tbss 0 : { *(.tbss) } 88 | + .jcr 0 : { KEEP (*(.jcr)) } 89 | + .dynamic 0 : { *(.dynamic) } 90 | + .got 0 : { *(.got) *(.igot) } 91 | + .got.plt 0 : { *(.got.plt) *(.igot.plt) } 92 | + .data 0 : 93 | + { 94 | + *(.data) 95 | + vgpu_unlock_nv_kern_rodata_beg = .; 96 | + *nv-kernel.o(.rodata*) 97 | + vgpu_unlock_nv_kern_rodata_end = .; 98 | + } 99 | + .data1 0 : { *(.data1) } 100 | + .bss 0 : 101 | + { 102 | + *(.bss) 103 | + *(COMMON) 104 | + /* Align here to ensure that the .bss section occupies space up to 105 | + _end. Align after .bss to ensure correct alignment even if the 106 | + .bss section disappears because there are no input sections. 107 | + FIXME: Why do we need it? When there is no .bss section, we don't 108 | + pad the .data section. */ 109 | + } 110 | + .lbss 0 : 111 | + { 112 | + *(.dynlbss) 113 | + *(.lbss) 114 | + *(LARGE_COMMON) 115 | + } 116 | + .lrodata 0 : 117 | + { 118 | + *(.lrodata) 119 | + } 120 | + .ldata 0 : 121 | + { 122 | + *(.ldata) 123 | + } 124 | + /* Stabs debugging sections. */ 125 | + .stab 0 : { *(.stab) } 126 | + .stabstr 0 : { *(.stabstr) } 127 | + .stab.excl 0 : { *(.stab.excl) } 128 | + .stab.exclstr 0 : { *(.stab.exclstr) } 129 | + .stab.index 0 : { *(.stab.index) } 130 | + .stab.indexstr 0 : { *(.stab.indexstr) } 131 | + .comment 0 : { *(.comment) } 132 | + /* DWARF debug sections. 133 | + Symbols in the DWARF debugging sections are relative to the beginning 134 | + of the section so we begin them at 0. */ 135 | + /* DWARF 1 */ 136 | + .debug 0 : { *(.debug) } 137 | + .line 0 : { *(.line) } 138 | + /* GNU DWARF 1 extensions */ 139 | + .debug_srcinfo 0 : { *(.debug_srcinfo) } 140 | + .debug_sfnames 0 : { *(.debug_sfnames) } 141 | + /* DWARF 1.1 and DWARF 2 */ 142 | + .debug_aranges 0 : { *(.debug_aranges) } 143 | + .debug_pubnames 0 : { *(.debug_pubnames) } 144 | + /* DWARF 2 */ 145 | + .debug_info 0 : { *(.debug_info) } 146 | + .debug_abbrev 0 : { *(.debug_abbrev) } 147 | + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } 148 | + .debug_frame 0 : { *(.debug_frame) } 149 | + .debug_str 0 : { *(.debug_str) } 150 | + .debug_loc 0 : { *(.debug_loc) } 151 | + .debug_macinfo 0 : { *(.debug_macinfo) } 152 | + /* SGI/MIPS DWARF 2 extensions */ 153 | + .debug_weaknames 0 : { *(.debug_weaknames) } 154 | + .debug_funcnames 0 : { *(.debug_funcnames) } 155 | + .debug_typenames 0 : { *(.debug_typenames) } 156 | + .debug_varnames 0 : { *(.debug_varnames) } 157 | + /* DWARF 3 */ 158 | + .debug_pubtypes 0 : { *(.debug_pubtypes) } 159 | + .debug_ranges 0 : { *(.debug_ranges) } 160 | + /* DWARF Extension. */ 161 | + .debug_macro 0 : { *(.debug_macro) } 162 | + .debug_addr 0 : { *(.debug_addr) } 163 | + .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } 164 | +} 165 | + 166 | --- ./kernel/nvidia/nvidia.Kbuild 2022-01-24 17:56:29.000000000 -0600 167 | +++ ./kernel/nvidia/nvidia.Kbuild 2022-03-24 17:02:20.143988135 -0500 168 | @@ -245 +245,2 @@ NV_CONFTEST_GENERIC_COMPILE_TESTS += pci 169 | NV_CONFTEST_GENERIC_COMPILE_TESTS += drm_available 170 | +ldflags-y += -T $(src)/nvidia/kern.ld 171 | --- ./kernel/nvidia/os-interface.c 2022-01-24 17:56:29.000000000 -0600 172 | +++ ./kernel/nvidia/os-interface.c 2022-03-24 17:02:36.087708543 -0500 173 | @@ -30,2 +30,3 @@ 174 | 175 | +#include "vgpu_unlock_hooks.c" 176 | 177 | --- ./kernel/nvidia/vgpu_unlock_hooks.c 1969-12-31 18:00:00.000000000 -0600 178 | +++ ./kernel/nvidia/vgpu_unlock_hooks.c 2022-03-24 11:51:18.775835663 -0500 179 | @@ -0,0 +1,1230 @@ 180 | +/* 181 | + * vGPU unlock hooks. 182 | + * 183 | + * This file is designed to be included into a single translation unit of the 184 | + * vGPU driver's kernel module. It hooks the nv_ioremap_* functions and memcpy 185 | + * for that translation unit and applies the vgpu_unlock patch when the magic 186 | + * and key values has been accessed by the driver. 187 | + * 188 | + * Copyright 2021 Jonathan Johansson 189 | + * This file is part of the "vgpu_unlock" project, and is distributed under the 190 | + * MIT License. See the LICENSE file for more details. 191 | + * 192 | + * Contributions from Krutav Shah and the vGPU Unlocking community included :) 193 | + * 194 | + */ 195 | + 196 | +/*------------------------------------------------------------------------------ 197 | + * Implementation of AES128-ECB. 198 | + *------------------------------------------------------------------------------ 199 | + */ 200 | + 201 | +typedef struct 202 | +{ 203 | + uint8_t round_key[176]; 204 | +} 205 | +vgpu_unlock_aes128_ctx; 206 | + 207 | +typedef uint8_t vgpu_unlock_aes128_state[4][4]; 208 | + 209 | +#define Nb 4 210 | +#define Nk 4 211 | +#define Nr 10 212 | +#define getSBoxValue(num) (vgpu_unlock_aes128_sbox[(num)]) 213 | +#define getSBoxInvert(num) (vgpu_unlock_aes128_rsbox[(num)]) 214 | +#define Multiply(x, y) \ 215 | + ( ((y & 1) * x) ^ \ 216 | + ((y>>1 & 1) * vgpu_unlock_aes128_xtime(x)) ^ \ 217 | + ((y>>2 & 1) * vgpu_unlock_aes128_xtime(vgpu_unlock_aes128_xtime(x))) ^ \ 218 | + ((y>>3 & 1) * vgpu_unlock_aes128_xtime(vgpu_unlock_aes128_xtime(vgpu_unlock_aes128_xtime(x)))) ^ \ 219 | + ((y>>4 & 1) * vgpu_unlock_aes128_xtime(vgpu_unlock_aes128_xtime(vgpu_unlock_aes128_xtime(vgpu_unlock_aes128_xtime(x)))))) \ 220 | + 221 | +static const uint8_t vgpu_unlock_aes128_sbox[256] = { 222 | + //0 1 2 3 4 5 6 7 8 9 A B C D E F 223 | + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 224 | + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 225 | + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 226 | + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 227 | + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 228 | + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 229 | + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 230 | + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 231 | + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 232 | + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 233 | + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 234 | + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 235 | + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 236 | + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 237 | + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 238 | + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; 239 | + 240 | +static const uint8_t vgpu_unlock_aes128_rsbox[256] = { 241 | + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 242 | + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 243 | + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 244 | + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 245 | + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 246 | + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 247 | + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 248 | + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 249 | + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 250 | + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 251 | + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 252 | + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 253 | + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 254 | + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 255 | + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 256 | + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; 257 | + 258 | +static const uint8_t vgpu_unlock_aes128_rcon[11] = { 259 | + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; 260 | + 261 | +static void vgpu_unlock_aes128_key_expansion(uint8_t *round_key, 262 | + const uint8_t *Key) 263 | +{ 264 | + unsigned i, j, k; 265 | + uint8_t tempa[4]; 266 | + 267 | + for (i = 0; i < Nk; ++i) 268 | + { 269 | + round_key[(i * 4) + 0] = Key[(i * 4) + 0]; 270 | + round_key[(i * 4) + 1] = Key[(i * 4) + 1]; 271 | + round_key[(i * 4) + 2] = Key[(i * 4) + 2]; 272 | + round_key[(i * 4) + 3] = Key[(i * 4) + 3]; 273 | + } 274 | + 275 | + for (i = Nk; i < Nb * (Nr + 1); ++i) 276 | + { 277 | + k = (i - 1) * 4; 278 | + tempa[0] = round_key[k + 0]; 279 | + tempa[1] = round_key[k + 1]; 280 | + tempa[2] = round_key[k + 2]; 281 | + tempa[3] = round_key[k + 3]; 282 | + 283 | + if (i % Nk == 0) 284 | + { 285 | + const uint8_t u8tmp = tempa[0]; 286 | + tempa[0] = tempa[1]; 287 | + tempa[1] = tempa[2]; 288 | + tempa[2] = tempa[3]; 289 | + tempa[3] = u8tmp; 290 | + tempa[0] = getSBoxValue(tempa[0]); 291 | + tempa[1] = getSBoxValue(tempa[1]); 292 | + tempa[2] = getSBoxValue(tempa[2]); 293 | + tempa[3] = getSBoxValue(tempa[3]); 294 | + tempa[0] = tempa[0] ^ vgpu_unlock_aes128_rcon[i/Nk]; 295 | + } 296 | + 297 | + j = i * 4; k=(i - Nk) * 4; 298 | + round_key[j + 0] = round_key[k + 0] ^ tempa[0]; 299 | + round_key[j + 1] = round_key[k + 1] ^ tempa[1]; 300 | + round_key[j + 2] = round_key[k + 2] ^ tempa[2]; 301 | + round_key[j + 3] = round_key[k + 3] ^ tempa[3]; 302 | + } 303 | +} 304 | + 305 | +static void vgpu_unlock_aes128_add_round_key(uint8_t round, 306 | + vgpu_unlock_aes128_state *state, 307 | + const uint8_t *round_key) 308 | +{ 309 | + uint8_t i,j; 310 | + 311 | + for (i = 0; i < 4; ++i) 312 | + { 313 | + for (j = 0; j < 4; ++j) 314 | + { 315 | + (*state)[i][j] ^= round_key[(round * Nb * 4) + (i * Nb) + j]; 316 | + } 317 | + } 318 | +} 319 | + 320 | +static void vgpu_unlock_aes128_sub_bytes(vgpu_unlock_aes128_state *state) 321 | +{ 322 | + uint8_t i, j; 323 | + 324 | + for (i = 0; i < 4; ++i) 325 | + { 326 | + for (j = 0; j < 4; ++j) 327 | + { 328 | + (*state)[j][i] = getSBoxValue((*state)[j][i]); 329 | + } 330 | + } 331 | +} 332 | + 333 | +static void vgpu_unlock_aes128_shift_rows(vgpu_unlock_aes128_state *state) 334 | +{ 335 | + uint8_t temp; 336 | + 337 | + temp = (*state)[0][1]; 338 | + (*state)[0][1] = (*state)[1][1]; 339 | + (*state)[1][1] = (*state)[2][1]; 340 | + (*state)[2][1] = (*state)[3][1]; 341 | + (*state)[3][1] = temp; 342 | + 343 | + temp = (*state)[0][2]; 344 | + (*state)[0][2] = (*state)[2][2]; 345 | + (*state)[2][2] = temp; 346 | + 347 | + temp = (*state)[1][2]; 348 | + (*state)[1][2] = (*state)[3][2]; 349 | + (*state)[3][2] = temp; 350 | + 351 | + temp = (*state)[0][3]; 352 | + (*state)[0][3] = (*state)[3][3]; 353 | + (*state)[3][3] = (*state)[2][3]; 354 | + (*state)[2][3] = (*state)[1][3]; 355 | + (*state)[1][3] = temp; 356 | +} 357 | + 358 | +static uint8_t vgpu_unlock_aes128_xtime(uint8_t x) 359 | +{ 360 | + return ((x<<1) ^ (((x>>7) & 1) * 0x1b)); 361 | +} 362 | + 363 | +static void vgpu_unlock_aes128_mix_columns(vgpu_unlock_aes128_state *state) 364 | +{ 365 | + uint8_t i; 366 | + uint8_t tmp, tm, t; 367 | + 368 | + for (i = 0; i < 4; ++i) 369 | + { 370 | + t = (*state)[i][0]; 371 | + tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3]; 372 | + tm = (*state)[i][0] ^ (*state)[i][1]; 373 | + tm = vgpu_unlock_aes128_xtime(tm); (*state)[i][0] ^= tm ^ tmp; 374 | + tm = (*state)[i][1] ^ (*state)[i][2]; 375 | + tm = vgpu_unlock_aes128_xtime(tm); (*state)[i][1] ^= tm ^ tmp; 376 | + tm = (*state)[i][2] ^ (*state)[i][3]; 377 | + tm = vgpu_unlock_aes128_xtime(tm); (*state)[i][2] ^= tm ^ tmp; 378 | + tm = (*state)[i][3] ^ t; 379 | + tm = vgpu_unlock_aes128_xtime(tm); (*state)[i][3] ^= tm ^ tmp; 380 | + } 381 | +} 382 | + 383 | +static void vgpu_unlock_aes128_inv_mix_columns(vgpu_unlock_aes128_state *state) 384 | +{ 385 | + int i; 386 | + uint8_t a, b, c, d; 387 | + 388 | + for (i = 0; i < 4; ++i) 389 | + { 390 | + a = (*state)[i][0]; 391 | + b = (*state)[i][1]; 392 | + c = (*state)[i][2]; 393 | + d = (*state)[i][3]; 394 | + 395 | + (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09); 396 | + (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d); 397 | + (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b); 398 | + (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e); 399 | + } 400 | +} 401 | + 402 | +static void vgpu_unlock_aes128_inv_sub_bytes(vgpu_unlock_aes128_state *state) 403 | +{ 404 | + uint8_t i, j; 405 | + 406 | + for (i = 0; i < 4; ++i) 407 | + { 408 | + for (j = 0; j < 4; ++j) 409 | + { 410 | + (*state)[j][i] = getSBoxInvert((*state)[j][i]); 411 | + } 412 | + } 413 | +} 414 | + 415 | +static void vgpu_unlock_aes128_inv_shift_rows(vgpu_unlock_aes128_state *state) 416 | +{ 417 | + uint8_t temp; 418 | + 419 | + temp = (*state)[3][1]; 420 | + (*state)[3][1] = (*state)[2][1]; 421 | + (*state)[2][1] = (*state)[1][1]; 422 | + (*state)[1][1] = (*state)[0][1]; 423 | + (*state)[0][1] = temp; 424 | + 425 | + temp = (*state)[0][2]; 426 | + (*state)[0][2] = (*state)[2][2]; 427 | + (*state)[2][2] = temp; 428 | + 429 | + temp = (*state)[1][2]; 430 | + (*state)[1][2] = (*state)[3][2]; 431 | + (*state)[3][2] = temp; 432 | + 433 | + temp = (*state)[0][3]; 434 | + (*state)[0][3] = (*state)[1][3]; 435 | + (*state)[1][3] = (*state)[2][3]; 436 | + (*state)[2][3] = (*state)[3][3]; 437 | + (*state)[3][3] = temp; 438 | +} 439 | + 440 | +static void vgpu_unlock_aes128_cipher(vgpu_unlock_aes128_state *state, 441 | + const uint8_t* round_key) 442 | +{ 443 | + uint8_t round = 0; 444 | + 445 | + vgpu_unlock_aes128_add_round_key(0, state, round_key); 446 | + 447 | + for (round = 1; ; ++round) 448 | + { 449 | + vgpu_unlock_aes128_sub_bytes(state); 450 | + vgpu_unlock_aes128_shift_rows(state); 451 | + 452 | + if (round == Nr) 453 | + { 454 | + break; 455 | + } 456 | + 457 | + vgpu_unlock_aes128_mix_columns(state); 458 | + vgpu_unlock_aes128_add_round_key(round, state, round_key); 459 | + } 460 | + 461 | + vgpu_unlock_aes128_add_round_key(Nr, state, round_key); 462 | +} 463 | + 464 | +static void vgpu_unlock_aes128_inv_cipher(vgpu_unlock_aes128_state *state, 465 | + const uint8_t* round_key) 466 | +{ 467 | + uint8_t round = 0; 468 | + 469 | + vgpu_unlock_aes128_add_round_key(Nr, state, round_key); 470 | + 471 | + for (round = (Nr - 1); ; --round) 472 | + { 473 | + vgpu_unlock_aes128_inv_shift_rows(state); 474 | + vgpu_unlock_aes128_inv_sub_bytes(state); 475 | + vgpu_unlock_aes128_add_round_key(round, state, round_key); 476 | + 477 | + if (round == 0) 478 | + { 479 | + break; 480 | + } 481 | + 482 | + vgpu_unlock_aes128_inv_mix_columns(state); 483 | + } 484 | +} 485 | + 486 | +static void vgpu_unlock_aes128_init(vgpu_unlock_aes128_ctx *ctx, 487 | + const uint8_t *key) 488 | +{ 489 | + vgpu_unlock_aes128_key_expansion(ctx->round_key, key); 490 | +} 491 | + 492 | +static void vgpu_unlock_aes128_encrypt(const vgpu_unlock_aes128_ctx *ctx, 493 | + uint8_t *buf) 494 | +{ 495 | + vgpu_unlock_aes128_cipher((vgpu_unlock_aes128_state*)buf, 496 | + ctx->round_key); 497 | +} 498 | + 499 | +static void vgpu_unlock_aes128_decrypt(const vgpu_unlock_aes128_ctx *ctx, 500 | + uint8_t* buf) 501 | +{ 502 | + vgpu_unlock_aes128_inv_cipher((vgpu_unlock_aes128_state*)buf, 503 | + ctx->round_key); 504 | +} 505 | + 506 | +#undef Nb 507 | +#undef Nk 508 | +#undef Nr 509 | +#undef getSBoxValue 510 | +#undef getSBoxInvert 511 | +#undef Multiply 512 | + 513 | +/*------------------------------------------------------------------------------ 514 | + * End of AES128-ECB implementation. 515 | + *------------------------------------------------------------------------------ 516 | + */ 517 | + 518 | +/*------------------------------------------------------------------------------ 519 | + * Implementation of SHA256. 520 | + * Original author: Brad Conte (brad AT bradconte.com) 521 | + *------------------------------------------------------------------------------ 522 | + */ 523 | + 524 | +typedef struct { 525 | + uint8_t data[64]; 526 | + uint32_t datalen; 527 | + uint64_t bitlen; 528 | + uint32_t state[8]; 529 | +} 530 | +vgpu_unlock_sha256_ctx; 531 | + 532 | +#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b)))) 533 | +#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b)))) 534 | + 535 | +#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) 536 | +#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 537 | +#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22)) 538 | +#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25)) 539 | +#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3)) 540 | +#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10)) 541 | + 542 | +static void vgpu_unlock_sha256_transform(vgpu_unlock_sha256_ctx *ctx, 543 | + const uint8_t data[]) 544 | +{ 545 | + static const uint32_t k[64] = { 546 | + 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, 547 | + 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, 548 | + 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, 549 | + 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, 550 | + 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, 551 | + 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, 552 | + 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, 553 | + 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 554 | + }; 555 | + 556 | + uint32_t a, b, c, d, e, f, g, h, i, j, t1, t2, m[64]; 557 | + 558 | + for (i = 0, j = 0; i < 16; ++i, j += 4) 559 | + m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]); 560 | + for ( ; i < 64; ++i) 561 | + m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; 562 | + 563 | + a = ctx->state[0]; 564 | + b = ctx->state[1]; 565 | + c = ctx->state[2]; 566 | + d = ctx->state[3]; 567 | + e = ctx->state[4]; 568 | + f = ctx->state[5]; 569 | + g = ctx->state[6]; 570 | + h = ctx->state[7]; 571 | + 572 | + for (i = 0; i < 64; ++i) { 573 | + t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i]; 574 | + t2 = EP0(a) + MAJ(a,b,c); 575 | + h = g; 576 | + g = f; 577 | + f = e; 578 | + e = d + t1; 579 | + d = c; 580 | + c = b; 581 | + b = a; 582 | + a = t1 + t2; 583 | + } 584 | + 585 | + ctx->state[0] += a; 586 | + ctx->state[1] += b; 587 | + ctx->state[2] += c; 588 | + ctx->state[3] += d; 589 | + ctx->state[4] += e; 590 | + ctx->state[5] += f; 591 | + ctx->state[6] += g; 592 | + ctx->state[7] += h; 593 | +} 594 | + 595 | +static void vgpu_unlock_sha256_init(vgpu_unlock_sha256_ctx *ctx) 596 | +{ 597 | + ctx->datalen = 0; 598 | + ctx->bitlen = 0; 599 | + ctx->state[0] = 0x6a09e667; 600 | + ctx->state[1] = 0xbb67ae85; 601 | + ctx->state[2] = 0x3c6ef372; 602 | + ctx->state[3] = 0xa54ff53a; 603 | + ctx->state[4] = 0x510e527f; 604 | + ctx->state[5] = 0x9b05688c; 605 | + ctx->state[6] = 0x1f83d9ab; 606 | + ctx->state[7] = 0x5be0cd19; 607 | +} 608 | + 609 | +static void vgpu_unlock_sha256_update(vgpu_unlock_sha256_ctx *ctx, 610 | + const uint8_t data[], 611 | + size_t len) 612 | +{ 613 | + uint32_t i; 614 | + 615 | + for (i = 0; i < len; ++i) { 616 | + ctx->data[ctx->datalen] = data[i]; 617 | + ctx->datalen++; 618 | + if (ctx->datalen == 64) { 619 | + vgpu_unlock_sha256_transform(ctx, ctx->data); 620 | + ctx->bitlen += 512; 621 | + ctx->datalen = 0; 622 | + } 623 | + } 624 | +} 625 | + 626 | +static void vgpu_unlock_sha256_final(vgpu_unlock_sha256_ctx *ctx, 627 | + uint8_t hash[]) 628 | +{ 629 | + uint32_t i; 630 | + 631 | + i = ctx->datalen; 632 | + 633 | + /* Pad whatever data is left in the buffer. */ 634 | + if (ctx->datalen < 56) { 635 | + ctx->data[i++] = 0x80; 636 | + while (i < 56) 637 | + ctx->data[i++] = 0x00; 638 | + } 639 | + else { 640 | + ctx->data[i++] = 0x80; 641 | + while (i < 64) 642 | + ctx->data[i++] = 0x00; 643 | + vgpu_unlock_sha256_transform(ctx, ctx->data); 644 | + memset(ctx->data, 0, 56); 645 | + } 646 | + 647 | + /* 648 | + * Append to the padding the total message's length in bits and 649 | + * transform. 650 | + */ 651 | + ctx->bitlen += ctx->datalen * 8; 652 | + ctx->data[63] = ctx->bitlen; 653 | + ctx->data[62] = ctx->bitlen >> 8; 654 | + ctx->data[61] = ctx->bitlen >> 16; 655 | + ctx->data[60] = ctx->bitlen >> 24; 656 | + ctx->data[59] = ctx->bitlen >> 32; 657 | + ctx->data[58] = ctx->bitlen >> 40; 658 | + ctx->data[57] = ctx->bitlen >> 48; 659 | + ctx->data[56] = ctx->bitlen >> 56; 660 | + vgpu_unlock_sha256_transform(ctx, ctx->data); 661 | + 662 | + /* 663 | + * Since this implementation uses little endian byte ordering and SHA 664 | + * uses big endian, reverse all the bytes when copying the final state 665 | + * to the output hash. 666 | + */ 667 | + for (i = 0; i < 4; ++i) { 668 | + hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; 669 | + hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; 670 | + hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; 671 | + hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; 672 | + hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; 673 | + hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff; 674 | + hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff; 675 | + hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff; 676 | + } 677 | +} 678 | + 679 | +#undef ROTLEFT 680 | +#undef ROTRIGHT 681 | + 682 | +#undef CH 683 | +#undef MAJ 684 | +#undef EP0 685 | +#undef EP1 686 | +#undef SIG0 687 | +#undef SIG1 688 | + 689 | +/*------------------------------------------------------------------------------ 690 | + * End of SHA256 implementation. 691 | + *------------------------------------------------------------------------------ 692 | + */ 693 | + 694 | + 695 | +/*------------------------------------------------------------------------------ 696 | + * Implementation of HMAC-SHA256. 697 | + *------------------------------------------------------------------------------ 698 | + */ 699 | + 700 | +static void vgpu_unlock_hmac_sha256(void* dst, 701 | + const void *msg, 702 | + size_t msg_size, 703 | + const void *key, 704 | + size_t key_size) 705 | +{ 706 | + vgpu_unlock_sha256_ctx ctx; 707 | + uint8_t o_key[96]; 708 | + uint8_t i_key_pad[64]; 709 | + uint8_t i; 710 | + 711 | + for (i = 0; i < 64; i++) 712 | + { 713 | + if (i < key_size) 714 | + { 715 | + o_key[i] = ((uint8_t*)key)[i] ^ 0x5c; 716 | + i_key_pad[i] = ((uint8_t*)key)[i] ^ 0x36; 717 | + } 718 | + else 719 | + { 720 | + o_key[i] = 0x5c; 721 | + i_key_pad[i] = 0x36; 722 | + } 723 | + } 724 | + 725 | + vgpu_unlock_sha256_init(&ctx); 726 | + vgpu_unlock_sha256_update(&ctx, i_key_pad, sizeof(i_key_pad)); 727 | + vgpu_unlock_sha256_update(&ctx, msg, msg_size); 728 | + vgpu_unlock_sha256_final(&ctx, &o_key[64]); 729 | + 730 | + vgpu_unlock_sha256_init(&ctx); 731 | + vgpu_unlock_sha256_update(&ctx, o_key, sizeof(o_key)); 732 | + vgpu_unlock_sha256_final(&ctx, dst); 733 | +} 734 | + 735 | +/*------------------------------------------------------------------------------ 736 | + * End of HMAC-SHA256 implementation. 737 | + *------------------------------------------------------------------------------ 738 | + */ 739 | + 740 | +/*------------------------------------------------------------------------------ 741 | + * Implementation of vgpu_unlock hooks. 742 | + *------------------------------------------------------------------------------ 743 | + */ 744 | + 745 | +/* Debug logs can be enabled here. To enable it, change 0 to 1. */ 746 | +#if 0 747 | + #define LOG(...) printk(__VA_ARGS__) 748 | +#else 749 | + #define LOG(...) 750 | +#endif 751 | + 752 | +typedef struct { 753 | + uint8_t num_blocks; /* Number of 16 byte blocks up to 'sign'. */ 754 | + uint8_t name1_len; /* Length of first name (unused?) */ 755 | + uint8_t name2_len; /* Length of second name (used by VM) */ 756 | + uint16_t dev_id; 757 | + uint16_t vend_id; /* Check skipped if zero. */ 758 | + uint16_t subsys_id; 759 | + uint16_t subsys_vend_id; /* Check skipped if zero. */ 760 | + char name1_2[38]; /* First and second name, no separation. */ 761 | + uint8_t sign[0x20]; 762 | +} 763 | +__attribute__((packed)) 764 | +vgpu_unlock_vgpu_t; 765 | + 766 | +/* Helper macro to initialize the structure above. */ 767 | +#define VGPU(dev_id, subsys_id, name) \ 768 | + { (10 + 2 * strlen(name) + 15) / 16, /* num_blocks */ \ 769 | + strlen(name), /* name1_len */ \ 770 | + strlen(name), /* name2_len */ \ 771 | + (dev_id), /* dev_id */ \ 772 | + 0, /* vend_id */ \ 773 | + (subsys_id), /* subsys_id */ \ 774 | + 0, /* subsys_vend_id */ \ 775 | + { name name } } /* name1_2 */ 776 | + 777 | +static vgpu_unlock_vgpu_t vgpu_unlock_vgpu[] = 778 | +{ 779 | + /* Tesla M10 (Maxwell) */ 780 | + VGPU(0x13bd, 0x11cc, "GRID M10-0B"), 781 | + VGPU(0x13bd, 0x11cd, "GRID M10-1B"), 782 | + VGPU(0x13bd, 0x1339, "GRID M10-1B4"), 783 | + VGPU(0x13bd, 0x1286, "GRID M10-2B"), 784 | + VGPU(0x13bd, 0x12ee, "GRID M10-2B4"), 785 | + VGPU(0x13bd, 0x11ce, "GRID M10-0Q"), 786 | + VGPU(0x13bd, 0x11cf, "GRID M10-1Q"), 787 | + VGPU(0x13bd, 0x11d0, "GRID M10-2Q"), 788 | + VGPU(0x13bd, 0x11d1, "GRID M10-4Q"), 789 | + VGPU(0x13bd, 0x11d2, "GRID M10-8Q"), 790 | + VGPU(0x13bd, 0x11d3, "GRID M10-1A"), 791 | + VGPU(0x13bd, 0x11d4, "GRID M10-2A"), 792 | + VGPU(0x13bd, 0x11d5, "GRID M10-4A"), 793 | + VGPU(0x13bd, 0x11d6, "GRID M10-8A"), 794 | + 795 | + /* Tesla M60 (Maxwell 2.0) */ 796 | + VGPU(0x13f2, 0x114c, "GRID M60-0Q"), 797 | + VGPU(0x13f2, 0x114d, "GRID M60-1Q"), 798 | + VGPU(0x13f2, 0x114e, "GRID M60-2Q"), 799 | + VGPU(0x13f2, 0x114f, "GRID M60-4Q"), 800 | + VGPU(0x13f2, 0x1150, "GRID M60-8Q"), 801 | + VGPU(0x13f2, 0x1176, "GRID M60-0B"), 802 | + VGPU(0x13f2, 0x1177, "GRID M60-1B"), 803 | + VGPU(0x13f2, 0x117D, "GRID M60-2B"), 804 | + VGPU(0x13f2, 0x1337, "GRID M60-1B4"), 805 | + VGPU(0x13f2, 0x12ec, "GRID M60-2B4"), 806 | + VGPU(0x13f2, 0x11ae, "GRID M60-1A"), 807 | + VGPU(0x13f2, 0x11aF, "GRID M60-2A"), 808 | + VGPU(0x13f2, 0x11b0, "GRID M60-4A"), 809 | + VGPU(0x13f2, 0x11b1, "GRID M60-8A"), 810 | + 811 | + /* Tesla P4 (Pascal) */ 812 | + VGPU(0x1bb3, 0x1203, "GRID P4-1B"), 813 | + VGPU(0x1bb3, 0x1204, "GRID P4-1Q"), 814 | + VGPU(0x1bb3, 0x1205, "GRID P4-2Q"), 815 | + VGPU(0x1bb3, 0x1206, "GRID P4-4Q"), 816 | + VGPU(0x1bb3, 0x1207, "GRID P4-8Q"), 817 | + VGPU(0x1bb3, 0x1208, "GRID P4-1A"), 818 | + VGPU(0x1bb3, 0x1209, "GRID P4-2A"), 819 | + VGPU(0x1bb3, 0x120a, "GRID P4-4A"), 820 | + VGPU(0x1bb3, 0x120b, "GRID P4-8A"), 821 | + VGPU(0x1bb3, 0x1288, "GRID P4-2B"), 822 | + VGPU(0x1bb3, 0x12f1, "GRID P4-2B4"), 823 | + VGPU(0x1bb3, 0x133c, "GRID P4-1B4"), 824 | + VGPU(0x1bb3, 0x1380, "GRID P4-8C"), 825 | + VGPU(0x1bb3, 0x1385, "GRID P4-4C"), 826 | + 827 | + /* Tesla P40 (Pascal) */ 828 | + VGPU(0x1b38, 0x11e7, "GRID P40-1B"), 829 | + VGPU(0x1b38, 0x11e8, "GRID P40-1Q"), 830 | + VGPU(0x1b38, 0x11e9, "GRID P40-2Q"), 831 | + VGPU(0x1b38, 0x11ea, "GRID P40-3Q"), 832 | + VGPU(0x1b38, 0x11eb, "GRID P40-4Q"), 833 | + VGPU(0x1b38, 0x11ec, "GRID P40-6Q"), 834 | + VGPU(0x1b38, 0x11ed, "GRID P40-8Q"), 835 | + VGPU(0x1b38, 0x11ee, "GRID P40-12Q"), 836 | + VGPU(0x1b38, 0x11ef, "GRID P40-24Q"), 837 | + VGPU(0x1b38, 0x11f0, "GRID P40-1A"), 838 | + VGPU(0x1b38, 0x11f1, "GRID P40-2A"), 839 | + VGPU(0x1b38, 0x11f2, "GRID P40-3A"), 840 | + VGPU(0x1b38, 0x11f3, "GRID P40-4A"), 841 | + VGPU(0x1b38, 0x11f4, "GRID P40-6A"), 842 | + VGPU(0x1b38, 0x11f5, "GRID P40-8A"), 843 | + VGPU(0x1b38, 0x11f6, "GRID P40-12A"), 844 | + VGPU(0x1b38, 0x11f7, "GRID P40-24A"), 845 | + VGPU(0x1b38, 0x1287, "GRID P40-2B"), 846 | + VGPU(0x1b38, 0x12ef, "GRID P40-2B4"), 847 | + VGPU(0x1b38, 0x133a, "GRID P40-1B4"), 848 | + VGPU(0x1b38, 0x137e, "GRID P40-24C"), 849 | + VGPU(0x1b38, 0x1381, "GRID P40-4C"), 850 | + VGPU(0x1b38, 0x1382, "GRID P40-6C"), 851 | + VGPU(0x1b38, 0x1383, "GRID P40-8C"), 852 | + VGPU(0x1b38, 0x1384, "GRID P40-12C"), 853 | + 854 | + /* Tesla V100 32GB PCIE (Volta) */ 855 | + VGPU(0x1db6, 0x12bd, "GRID V100D-1B"), 856 | + VGPU(0x1db6, 0x12be, "GRID V100D-2B"), 857 | + VGPU(0x1db6, 0x12f7, "GRID V100D-2B4"), 858 | + VGPU(0x1db6, 0x1342, "GRID V100D-1B4"), 859 | + VGPU(0x1db6, 0x12bf, "GRID V100D-1Q"), 860 | + VGPU(0x1db6, 0x12c0, "GRID V100D-2Q"), 861 | + VGPU(0x1db6, 0x12c1, "GRID V100D-4Q"), 862 | + VGPU(0x1db6, 0x12c2, "GRID V100D-8Q"), 863 | + VGPU(0x1db6, 0x12c3, "GRID V100D-16Q"), 864 | + VGPU(0x1db6, 0x12c4, "GRID V100D-32Q"), 865 | + VGPU(0x1db6, 0x12c5, "GRID V100D-1A"), 866 | + VGPU(0x1db6, 0x12c6, "GRID V100D-2A"), 867 | + VGPU(0x1db6, 0x12c7, "GRID V100D-4A"), 868 | + VGPU(0x1db6, 0x12c8, "GRID V100D-8A"), 869 | + VGPU(0x1db6, 0x12c9, "GRID V100D-16A"), 870 | + VGPU(0x1db6, 0x12ca, "GRID V100D-32A"), 871 | + VGPU(0x1db6, 0x1395, "GRID V100D-4C"), 872 | + VGPU(0x1db6, 0x1396, "GRID V100D-8C"), 873 | + VGPU(0x1db6, 0x1397, "GRID V100D-16C"), 874 | + VGPU(0x1db6, 0x1377, "GRID V100D-32C"), 875 | + 876 | + /* Tesla T4 (Turing) */ 877 | + VGPU(0x1eb8, 0x1309, "GRID T4-1B"), 878 | + VGPU(0x1eb8, 0x130a, "GRID T4-2B"), 879 | + VGPU(0x1eb8, 0x130b, "GRID T4-2B4"), 880 | + VGPU(0x1eb8, 0x130c, "GRID T4-1Q"), 881 | + VGPU(0x1eb8, 0x130d, "GRID T4-2Q"), 882 | + VGPU(0x1eb8, 0x130e, "GRID T4-4Q"), 883 | + VGPU(0x1eb8, 0x130f, "GRID T4-8Q"), 884 | + VGPU(0x1eb8, 0x1310, "GRID T4-16Q"), 885 | + VGPU(0x1eb8, 0x1311, "GRID T4-1A"), 886 | + VGPU(0x1eb8, 0x1312, "GRID T4-2A"), 887 | + VGPU(0x1eb8, 0x1313, "GRID T4-4A"), 888 | + VGPU(0x1eb8, 0x1314, "GRID T4-8A"), 889 | + VGPU(0x1eb8, 0x1315, "GRID T4-16A"), 890 | + VGPU(0x1eb8, 0x1345, "GRID T4-1B4"), 891 | + VGPU(0x1eb8, 0x1375, "GRID T4-16C"), 892 | + VGPU(0x1eb8, 0x139a, "GRID T4-4C"), 893 | + VGPU(0x1eb8, 0x139b, "GRID T4-8C"), 894 | + 895 | + /* Quadro RTX 6000 (Turing) */ 896 | + VGPU(0x1e30, 0x1325, "GRID RTX6000-1Q"), 897 | + VGPU(0x1e30, 0x1326, "GRID RTX6000-2Q"), 898 | + VGPU(0x1e30, 0x1327, "GRID RTX6000-3Q"), 899 | + VGPU(0x1e30, 0x1328, "GRID RTX6000-4Q"), 900 | + VGPU(0x1e30, 0x1329, "GRID RTX6000-6Q"), 901 | + VGPU(0x1e30, 0x132a, "GRID RTX6000-8Q"), 902 | + VGPU(0x1e30, 0x132b, "GRID RTX6000-12Q"), 903 | + VGPU(0x1e30, 0x132c, "GRID RTX6000-24Q"), 904 | + VGPU(0x1e30, 0x13bf, "GRID RTX6000-4C"), 905 | + VGPU(0x1e30, 0x13c0, "GRID RTX6000-6C"), 906 | + VGPU(0x1e30, 0x13c1, "GRID RTX6000-8C"), 907 | + VGPU(0x1e30, 0x13c2, "GRID RTX6000-12C"), 908 | + VGPU(0x1e30, 0x13c3, "GRID RTX6000-24C"), 909 | + VGPU(0x1e30, 0x1437, "GRID RTX6000-1B"), 910 | + VGPU(0x1e30, 0x1438, "GRID RTX6000-2B"), 911 | + VGPU(0x1e30, 0x1439, "GRID RTX6000-1A"), 912 | + VGPU(0x1e30, 0x143a, "GRID RTX6000-2A"), 913 | + VGPU(0x1e30, 0x143b, "GRID RTX6000-3A"), 914 | + VGPU(0x1e30, 0x143c, "GRID RTX6000-4A"), 915 | + VGPU(0x1e30, 0x143d, "GRID RTX6000-6A"), 916 | + VGPU(0x1e30, 0x143e, "GRID RTX6000-8A"), 917 | + VGPU(0x1e30, 0x143f, "GRID RTX6000-12A"), 918 | + VGPU(0x1e30, 0x1440, "GRID RTX6000-24A"), 919 | + 920 | + /* RTX A6000 (Ampere) */ 921 | + VGPU(0x2230, 0x14fa, "NVIDIA RTXA6000-1B"), 922 | + VGPU(0x2230, 0x14fb, "NVIDIA RTXA6000-2B"), 923 | + VGPU(0x2230, 0x14fc, "NVIDIA RTXA6000-1Q"), 924 | + VGPU(0x2230, 0x14fd, "NVIDIA RTXA6000-2Q"), 925 | + VGPU(0x2230, 0x14fe, "NVIDIA RTXA6000-3Q"), 926 | + VGPU(0x2230, 0x14ff, "NVIDIA RTXA6000-4Q"), 927 | + VGPU(0x2230, 0x1500, "NVIDIA RTXA6000-6Q"), 928 | + VGPU(0x2230, 0x1501, "NVIDIA RTXA6000-8Q"), 929 | + VGPU(0x2230, 0x1502, "NVIDIA RTXA6000-12Q"), 930 | + VGPU(0x2230, 0x1503, "NVIDIA RTXA6000-16Q"), 931 | + VGPU(0x2230, 0x1504, "NVIDIA RTXA6000-24Q"), 932 | + VGPU(0x2230, 0x1505, "NVIDIA RTXA6000-48Q"), 933 | + VGPU(0x2230, 0x1506, "NVIDIA RTXA6000-1A"), 934 | + VGPU(0x2230, 0x1507, "NVIDIA RTXA6000-2A"), 935 | + VGPU(0x2230, 0x1508, "NVIDIA RTXA6000-3A"), 936 | + VGPU(0x2230, 0x1509, "NVIDIA RTXA6000-4A"), 937 | + VGPU(0x2230, 0x150a, "NVIDIA RTXA6000-6A"), 938 | + VGPU(0x2230, 0x150b, "NVIDIA RTXA6000-8A"), 939 | + VGPU(0x2230, 0x150c, "NVIDIA RTXA6000-12A"), 940 | + VGPU(0x2230, 0x150d, "NVIDIA RTXA6000-16A"), 941 | + VGPU(0x2230, 0x150e, "NVIDIA RTXA6000-24A"), 942 | + VGPU(0x2230, 0x150f, "NVIDIA RTXA6000-48A"), 943 | + VGPU(0x2230, 0x1514, "NVIDIA RTXA6000-4C"), 944 | + VGPU(0x2230, 0x1515, "NVIDIA RTXA6000-6C"), 945 | + VGPU(0x2230, 0x1516, "NVIDIA RTXA6000-8C"), 946 | + VGPU(0x2230, 0x1517, "NVIDIA RTXA6000-12C"), 947 | + VGPU(0x2230, 0x1518, "NVIDIA RTXA6000-16C"), 948 | + VGPU(0x2230, 0x1519, "NVIDIA RTXA6000-24C"), 949 | + VGPU(0x2230, 0x151a, "NVIDIA RTXA6000-48C"), 950 | + 951 | + { 0 } /* Sentinel */ 952 | +}; 953 | + 954 | +#undef VGPU 955 | + 956 | +static const uint8_t vgpu_unlock_magic_start[0x10] = { 957 | + 0xf3, 0xf5, 0x9e, 0x3d, 0x13, 0x91, 0x75, 0x18, 958 | + 0x6a, 0x7b, 0x55, 0xed, 0xce, 0x5d, 0x84, 0x67 959 | +}; 960 | + 961 | +static const uint8_t vgpu_unlock_magic_sacrifice[0x10] = { 962 | + 0x46, 0x4f, 0x39, 0x49, 0x74, 0x91, 0xd7, 0x0f, 963 | + 0xbc, 0x65, 0xc2, 0x70, 0xdd, 0xdd, 0x11, 0x54 964 | +}; 965 | + 966 | +static bool vgpu_unlock_patch_applied = FALSE; 967 | + 968 | +static bool vgpu_unlock_bar3_mapped = FALSE; 969 | +static uint64_t vgpu_unlock_bar3_beg; 970 | +static uint64_t vgpu_unlock_bar3_end; 971 | + 972 | +static uint8_t vgpu_unlock_magic[0x10]; 973 | +static bool vgpu_unlock_magic_found = FALSE; 974 | + 975 | +static uint8_t vgpu_unlock_key[0x10]; 976 | +static bool vgpu_unlock_key_found = FALSE; 977 | + 978 | +/* These need to be added to the linker script. */ 979 | +extern uint8_t vgpu_unlock_nv_kern_rodata_beg; 980 | +extern uint8_t vgpu_unlock_nv_kern_rodata_end; 981 | + 982 | +static uint16_t vgpu_unlock_pci_devid_to_vgpu_capable(uint16_t pci_devid) 983 | +{ 984 | + switch (pci_devid) 985 | + { 986 | + /* Maxwell */ 987 | + case 0x1340 ... 0x13bd: 988 | + case 0x174d ... 0x179c: 989 | + return 0x13bd; /* Tesla M10 */ 990 | + 991 | + /* Maxwell 2.0 */ 992 | + case 0x13c0 ... 0x1436: 993 | + case 0x1617 ... 0x1667: /* GM204 */ 994 | + case 0x17c2 ... 0x17fd: /* GM200 */ 995 | + return 0x13f2; /* Tesla M60 */ 996 | + 997 | + /* Pascal */ 998 | + case 0x15f0 ... 0x15f1: /* GP100GL */ 999 | + case 0x1b00 ... 0x1d56: 1000 | + case 0x1725 ... 0x172f: /* GP100 */ 1001 | + return 0x1b38; /* Tesla P40 */ 1002 | + 1003 | + /* Volta GV100 */ 1004 | + case 0x1d81: /* Titan V 16GB */ 1005 | + case 0x1dba: /* Quadro GV100 32GB */ 1006 | + return 0x1db6; /* Tesla V100 32GB PCIE */ 1007 | + 1008 | + /* Turing */ 1009 | + case 0x1e02 ... 0x1ff9: 1010 | + case 0x2182 ... 0x21d1: /* TU116 */ 1011 | + return 0x1e30; /* Quadro RTX 6000 */ 1012 | + 1013 | + /* Ampere */ 1014 | + case 0x2200 ... 0x2600: 1015 | + return 0x2230; /* RTX A6000 */ 1016 | + } 1017 | + 1018 | + return pci_devid; 1019 | +} 1020 | + 1021 | +/* Our own memcmp that will bypass buffer overflow checks. */ 1022 | +static int vgpu_unlock_memcmp(const void *a, const void *b, size_t size) 1023 | +{ 1024 | + uint8_t *pa = (uint8_t*)a; 1025 | + uint8_t *pb = (uint8_t*)b; 1026 | + 1027 | + while (size--) 1028 | + { 1029 | + if (*pa != *pb) 1030 | + { 1031 | + return *pa - *pb; 1032 | + } 1033 | + 1034 | + pa++; 1035 | + pb++; 1036 | + } 1037 | + 1038 | + return 0; 1039 | +} 1040 | + 1041 | +/* Search for a certain pattern in the .rodata section of nv-kern.o_binary. */ 1042 | +static void *vgpu_unlock_find_in_rodata(const void *val, size_t size) 1043 | +{ 1044 | + uint8_t *i; 1045 | + 1046 | + for (i = &vgpu_unlock_nv_kern_rodata_beg; 1047 | + i < &vgpu_unlock_nv_kern_rodata_end - size; 1048 | + i++) 1049 | + { 1050 | + if (vgpu_unlock_memcmp(val, i, size) == 0) 1051 | + { 1052 | + return i; 1053 | + } 1054 | + } 1055 | + 1056 | + return NULL; 1057 | +} 1058 | + 1059 | +/* Check if a value is within a range. */ 1060 | +static bool vgpu_unlock_in_range(uint64_t val, uint64_t beg, uint64_t end) 1061 | +{ 1062 | + return (val >= beg) && (val <= end); 1063 | +} 1064 | + 1065 | +/* Check if range a is completely contained within range b. */ 1066 | +static bool vgpu_unlock_range_contained_in(uint64_t a_beg, 1067 | + uint64_t a_end, 1068 | + uint64_t b_beg, 1069 | + uint64_t b_end) 1070 | +{ 1071 | + return vgpu_unlock_in_range(a_beg, b_beg, b_end) && 1072 | + vgpu_unlock_in_range(a_end, b_beg, b_end); 1073 | +} 1074 | + 1075 | +/* Check if an address points into a specific BAR of an NVIDIA GPU. */ 1076 | +static bool vgpu_unlock_in_bar(uint64_t addr, int bar) 1077 | +{ 1078 | + struct pci_dev *dev = NULL; 1079 | + 1080 | + while (1) 1081 | + { 1082 | + dev = pci_get_device(0x10de, PCI_ANY_ID, dev); 1083 | + 1084 | + if (dev) 1085 | + { 1086 | + if (vgpu_unlock_in_range(addr, 1087 | + pci_resource_start(dev, bar), 1088 | + pci_resource_end(dev, bar))) 1089 | + { 1090 | + return TRUE; 1091 | + } 1092 | + } 1093 | + else 1094 | + { 1095 | + return FALSE; 1096 | + } 1097 | + } 1098 | +} 1099 | + 1100 | +/* Check if a potential magic value is valid. */ 1101 | +static bool vgpu_unlock_magic_valid(const uint8_t *magic) 1102 | +{ 1103 | + void **gpu_list_item; 1104 | + 1105 | + static void **gpu_list_start = NULL; 1106 | + 1107 | + if (!gpu_list_start) 1108 | + { 1109 | + void *magic_start = vgpu_unlock_find_in_rodata(vgpu_unlock_magic_start, 1110 | + sizeof(vgpu_unlock_magic_start)); 1111 | + 1112 | + if (!magic_start) 1113 | + { 1114 | + LOG(KERN_ERR "Failed to find start of gpu list in .rodata\n"); 1115 | + return NULL; 1116 | + } 1117 | + 1118 | + gpu_list_start = (void**)vgpu_unlock_find_in_rodata(&magic_start, 1119 | + sizeof(magic_start)); 1120 | + 1121 | + if (!gpu_list_start) 1122 | + { 1123 | + LOG(KERN_ERR "Failed to find pointer to start of gpu list in .rodata\n"); 1124 | + return NULL; 1125 | + } 1126 | + } 1127 | + 1128 | + for (gpu_list_item = gpu_list_start; 1129 | + vgpu_unlock_in_range((uint64_t)*gpu_list_item, 1130 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_beg, 1131 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_end); 1132 | + gpu_list_item += 3) 1133 | + { 1134 | + if (memcmp(magic, *gpu_list_item, 0x10) == 0) 1135 | + { 1136 | + return TRUE; 1137 | + } 1138 | + } 1139 | + 1140 | + return FALSE; 1141 | +} 1142 | + 1143 | +static void vgpu_unlock_apply_patch(void) 1144 | +{ 1145 | + uint8_t i; 1146 | + void *magic; 1147 | + void **magic_ptr; 1148 | + void **blocks_ptr; 1149 | + void **sign_ptr; 1150 | + uint8_t sign[0x20]; 1151 | + uint8_t num_blocks; 1152 | + void *sac_magic; 1153 | + void **sac_magic_ptr; 1154 | + void **sac_blocks_ptr; 1155 | + void **sac_sign_ptr; 1156 | + vgpu_unlock_aes128_ctx aes_ctx; 1157 | + vgpu_unlock_vgpu_t* vgpu; 1158 | + uint8_t first_block[0x10]; 1159 | + uint16_t device_id; 1160 | + 1161 | + magic = vgpu_unlock_find_in_rodata(vgpu_unlock_magic, 1162 | + sizeof(vgpu_unlock_magic)); 1163 | + if (!magic) 1164 | + { 1165 | + LOG(KERN_ERR "Failed to find magic in .rodata.\n"); 1166 | + goto failed; 1167 | + } 1168 | + 1169 | + LOG(KERN_WARNING "Magic is at: %px\n", magic); 1170 | + 1171 | + magic_ptr = (void**)vgpu_unlock_find_in_rodata(&magic, 1172 | + sizeof(magic)); 1173 | + 1174 | + if (!magic_ptr) 1175 | + { 1176 | + LOG(KERN_ERR "Failed to find pointer to magic in .rodata.\n"); 1177 | + goto failed; 1178 | + } 1179 | + 1180 | + blocks_ptr = magic_ptr + 1; 1181 | + sign_ptr = magic_ptr + 2; 1182 | + 1183 | + LOG(KERN_WARNING "Pointers found, magic: %px blocks: %px sign: %px\n", 1184 | + magic_ptr, blocks_ptr, sign_ptr); 1185 | + 1186 | + if (!vgpu_unlock_in_range((uint64_t)*blocks_ptr, 1187 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_beg, 1188 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_end) || 1189 | + !vgpu_unlock_in_range((uint64_t)*sign_ptr, 1190 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_beg, 1191 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_end)) 1192 | + { 1193 | + LOG(KERN_ERR "Invalid sign or blocks pointer.\n"); 1194 | + goto failed; 1195 | + } 1196 | + 1197 | + num_blocks = *(uint8_t*)*blocks_ptr; 1198 | + 1199 | + vgpu_unlock_hmac_sha256(sign, 1200 | + *blocks_ptr, 1201 | + 1 + num_blocks * 0x10, 1202 | + vgpu_unlock_key, 1203 | + sizeof(vgpu_unlock_key)); 1204 | + 1205 | + LOG(KERN_WARNING "Generate signature is: %32ph\n", sign); 1206 | + 1207 | + if (memcmp(sign, *sign_ptr, sizeof(sign)) != 0) 1208 | + { 1209 | + LOG(KERN_ERR "Signatures does not match.\n"); 1210 | + goto failed; 1211 | + } 1212 | + 1213 | + sac_magic = vgpu_unlock_find_in_rodata(vgpu_unlock_magic_sacrifice, 1214 | + sizeof(vgpu_unlock_magic_sacrifice)); 1215 | + 1216 | + if (!sac_magic) 1217 | + { 1218 | + LOG(KERN_ERR "Failed to find sacrificial magic.\n"); 1219 | + goto failed; 1220 | + } 1221 | + 1222 | + LOG(KERN_WARNING "Sacrificial magic is at: %px\n", sac_magic); 1223 | + 1224 | + sac_magic_ptr = (void**) vgpu_unlock_find_in_rodata(&sac_magic, 1225 | + sizeof(sac_magic)); 1226 | + 1227 | + if (!sac_magic_ptr) 1228 | + { 1229 | + LOG(KERN_ERR "Failed to find pointer to sacrificial magic.\n"); 1230 | + goto failed; 1231 | + } 1232 | + 1233 | + sac_blocks_ptr = sac_magic_ptr + 1; 1234 | + sac_sign_ptr = sac_magic_ptr + 2; 1235 | + 1236 | + LOG(KERN_WARNING "Pointers found, sac_magic: %px sac_blocks: %px sac_sign: %px\n", 1237 | + sac_magic_ptr, sac_blocks_ptr, sac_sign_ptr); 1238 | + 1239 | + if (!vgpu_unlock_in_range((uint64_t)*sac_blocks_ptr, 1240 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_beg, 1241 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_end) || 1242 | + !vgpu_unlock_in_range((uint64_t)*sac_sign_ptr, 1243 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_beg, 1244 | + (uint64_t)&vgpu_unlock_nv_kern_rodata_end)) 1245 | + { 1246 | + LOG(KERN_ERR "Invalid sacrificial sign or blocks pointer.\n"); 1247 | + goto failed; 1248 | + } 1249 | + 1250 | + /* Decrypt the first block so we can access the PCI device ID. */ 1251 | + memcpy(first_block, (uint8_t*)*blocks_ptr + 1, sizeof(first_block)); 1252 | + vgpu_unlock_aes128_init(&aes_ctx, vgpu_unlock_key); 1253 | + vgpu_unlock_aes128_decrypt(&aes_ctx, first_block); 1254 | + LOG(KERN_WARNING "Decrypted first block is: %16ph.\n", 1255 | + first_block); 1256 | + 1257 | + device_id = *((uint16_t*)first_block + 1); 1258 | + device_id = vgpu_unlock_pci_devid_to_vgpu_capable(device_id); 1259 | + 1260 | + /* Loop over all vGPUs and add the ones that match our device ID. */ 1261 | + vgpu = vgpu_unlock_vgpu; 1262 | + 1263 | + while (vgpu->num_blocks != 0) 1264 | + { 1265 | + if (vgpu->dev_id != device_id) 1266 | + { 1267 | + vgpu++; 1268 | + continue; 1269 | + } 1270 | + 1271 | + num_blocks = vgpu->num_blocks; 1272 | + 1273 | + *sac_magic_ptr = vgpu_unlock_magic; 1274 | + *sac_blocks_ptr = vgpu; 1275 | + *sac_sign_ptr = &vgpu->sign; 1276 | + 1277 | + vgpu_unlock_aes128_init(&aes_ctx, vgpu_unlock_key); 1278 | + 1279 | + for (i = 0; i < num_blocks; i++) 1280 | + { 1281 | + vgpu_unlock_aes128_encrypt(&aes_ctx, 1282 | + (uint8_t*)vgpu + 1 + i * 0x10); 1283 | + } 1284 | + 1285 | + vgpu_unlock_hmac_sha256(&vgpu->sign, 1286 | + vgpu, 1287 | + 1 + num_blocks * 0x10, 1288 | + vgpu_unlock_key, 1289 | + sizeof(vgpu_unlock_key)); 1290 | + 1291 | + sac_magic_ptr += 3; 1292 | + sac_blocks_ptr = sac_magic_ptr + 1; 1293 | + sac_sign_ptr = sac_magic_ptr + 2; 1294 | + vgpu++; 1295 | + } 1296 | + 1297 | + vgpu_unlock_patch_applied = TRUE; 1298 | + 1299 | + LOG(KERN_WARNING "vGPU unlock patch applied.\n"); 1300 | + 1301 | + return; 1302 | + 1303 | +failed: 1304 | + vgpu_unlock_magic_found = FALSE; 1305 | + vgpu_unlock_key_found = FALSE; 1306 | +} 1307 | + 1308 | +static void *vgpu_unlock_memcpy_hook(void *dst, const void *src, size_t count) 1309 | +{ 1310 | + bool src_in_bar3 = vgpu_unlock_bar3_mapped && 1311 | + vgpu_unlock_in_range((uint64_t)src, 1312 | + vgpu_unlock_bar3_beg, 1313 | + vgpu_unlock_bar3_end); 1314 | + 1315 | + void *result = memcpy(dst, src, count); 1316 | + 1317 | + if (src_in_bar3 && 1318 | + count == sizeof(vgpu_unlock_magic) && 1319 | + !vgpu_unlock_magic_found && 1320 | + vgpu_unlock_magic_valid(dst)) 1321 | + { 1322 | + memcpy(vgpu_unlock_magic, dst, count); 1323 | + vgpu_unlock_magic_found = TRUE; 1324 | + 1325 | + LOG(KERN_WARNING "Magic found: %16ph\n", 1326 | + vgpu_unlock_magic); 1327 | + 1328 | + } 1329 | + else if (src_in_bar3 && 1330 | + count == sizeof(vgpu_unlock_key) && 1331 | + vgpu_unlock_magic_found && 1332 | + !vgpu_unlock_key_found) 1333 | + { 1334 | + memcpy(vgpu_unlock_key, dst, count); 1335 | + vgpu_unlock_key_found = TRUE; 1336 | + 1337 | + LOG(KERN_WARNING "Key found: %16ph\n", 1338 | + vgpu_unlock_key); 1339 | + } 1340 | + 1341 | + if (!vgpu_unlock_patch_applied && 1342 | + vgpu_unlock_magic_found && 1343 | + vgpu_unlock_key_found) 1344 | + { 1345 | + vgpu_unlock_apply_patch(); 1346 | + } 1347 | + 1348 | + return result; 1349 | +} 1350 | + 1351 | +/* Check if the new IO mapping contains the magic or key. */ 1352 | +static void vgpu_unlock_check_map(uint64_t phys_addr, 1353 | + size_t size, 1354 | + void *virt_addr) 1355 | +{ 1356 | + LOG(KERN_WARNING "Remap called.\n"); 1357 | + 1358 | + if (virt_addr && 1359 | + !vgpu_unlock_bar3_mapped && 1360 | + vgpu_unlock_in_bar(phys_addr, 3)) 1361 | + { 1362 | + vgpu_unlock_bar3_beg = (uint64_t)virt_addr; 1363 | + vgpu_unlock_bar3_end = (uint64_t)virt_addr + size; 1364 | + vgpu_unlock_bar3_mapped = TRUE; 1365 | + LOG(KERN_WARNING "BAR3 mapped at: 0x%llX\n", 1366 | + vgpu_unlock_bar3_beg); 1367 | + } 1368 | +} 1369 | + 1370 | +static void *vgpu_unlock_nv_ioremap_hook(uint64_t phys, 1371 | + uint64_t size) 1372 | +{ 1373 | + void *virt_addr = nv_ioremap(phys, size); 1374 | + vgpu_unlock_check_map(phys, size, virt_addr); 1375 | + return virt_addr; 1376 | +} 1377 | + 1378 | +static void *vgpu_unlock_nv_ioremap_nocache_hook(uint64_t phys, 1379 | + uint64_t size) 1380 | +{ 1381 | + void *virt_addr = nv_ioremap_nocache(phys, size); 1382 | + vgpu_unlock_check_map(phys, size, virt_addr); 1383 | + return virt_addr; 1384 | +} 1385 | + 1386 | +static void *vgpu_unlock_nv_ioremap_cache_hook(uint64_t phys, 1387 | + uint64_t size) 1388 | +{ 1389 | + void *virt_addr = nv_ioremap_cache(phys, size); 1390 | + vgpu_unlock_check_map(phys, size, virt_addr); 1391 | + return virt_addr; 1392 | +} 1393 | + 1394 | +static void *vgpu_unlock_nv_ioremap_wc_hook(uint64_t phys, 1395 | + uint64_t size) 1396 | +{ 1397 | + void *virt_addr = nv_ioremap_wc(phys, size); 1398 | + vgpu_unlock_check_map(phys, size, virt_addr); 1399 | + return virt_addr; 1400 | +} 1401 | + 1402 | +#undef LOG 1403 | + 1404 | +/* Redirect future callers to our hooks. */ 1405 | +#define memcpy vgpu_unlock_memcpy_hook 1406 | +#define nv_ioremap vgpu_unlock_nv_ioremap_hook 1407 | +#define nv_ioremap_nocache vgpu_unlock_nv_ioremap_nocache_hook 1408 | +#define nv_ioremap_cache vgpu_unlock_nv_ioremap_cache_hook 1409 | +#define nv_ioremap_wc vgpu_unlock_nv_ioremap_wc_hook 1410 | --------------------------------------------------------------------------------