Skip to content

Instantly share code, notes, and snippets.

@FalconIA
Last active September 11, 2025 09:21
Show Gist options
  • Select an option

  • Save FalconIA/e808e23bc740e208c441f7222c48394a to your computer and use it in GitHub Desktop.

Select an option

Save FalconIA/e808e23bc740e208c441f7222c48394a to your computer and use it in GitHub Desktop.
Ubuntu 24.04 Enable Hyper-V vGPU

Ubuntu 24.04 Enable Hyper-V vGPU

Install Ubuntu 24.04 by ISO

Download ubuntu-24.04.2-live-server-amd64.iso.

Setup VM

Enable GPU Virtualization

Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All

Add GPUs

.\ubuntu-vgpu-vm-setup.ps1

Change Linux Kernel

Downgrade Kernel to 6.6.87

wget https://kernel.ubuntu.com/mainline/v6.6.87/amd64/linux-headers-6.6.87-060687_6.6.87-060687.202504101344_all.deb
wget https://kernel.ubuntu.com/mainline/v6.6.87/amd64/linux-headers-6.6.87-060687-generic_6.6.87-060687.202504101344_amd64.deb
wget https://kernel.ubuntu.com/mainline/v6.6.87/amd64/linux-image-unsigned-6.6.87-060687-generic_6.6.87-060687.202504101344_amd64.deb
wget https://kernel.ubuntu.com/mainline/v6.6.87/amd64/linux-modules-6.6.87-060687-generic_6.6.87-060687.202504101344_amd64.deb
sudo dpkg -i *.deb

sudo update-grub

sudo reboot now

Insatall dxgkrnl

sudo ./dxgkrnl-dkms-install.sh

sudo reboot now
dkms status
# dxgkrnl/6.6.87.2.r427645e, 6.6.87-060687-generic, x86_64: installed

Copy GPU drivers

Copy GPU drivers from host system by WSL2

rsync -P -r /usr/lib/wsl/lib/* root@<VM_IP:VM_PORT>:/usr/lib/wsl/lib/
rsync -P -r /usr/lib/wsl/drivers/nv_dispsi.inf_amd64_* root@<VM_IP:VM_PORT>:/usr/lib/wsl/drivers/

Update libraries config in VM

sudo chmod -R -w /usr/lib/wsl
sudo chmod +x /usr/lib/wsl/lib/nvidia-*

echo 'export PATH="$PATH:/usr/lib/wsl/lib"' | sudo tee /etc/profile.d/wsl.sh > /dev/null
echo '/usr/lib/wsl/lib' | sudo tee /etc/ld.so.conf.d/ld.wsl.conf > /dev/null
sudo ldconfig  # If you get 'libcuda.so.1 is not a symbolic link', just ignore it.

Reboot VM

sudo lspci -v  # should list the vGPU and the dxgkrnl driver

ls -l /dev/dxg  # should exist if the dxgkrnl

nvidia-smi  # should be able to not fail :P
PACKAGE_NAME="@_PKGBASE@"
PACKAGE_VERSION="@PKGVER@"
MAKE[0]="CONFIG_DXGKRNL=m make -C $kernel_source_dir M=$dkms_tree/$module/$module_version/build EXTRA_CFLAGS='-DCONFIG_DXGKRNL=m -include $dkms_tree/$module/$module_version/build/extra-defines.h' modules"
CLEAN="CONFIG_DXGKRNL=m make -C $kernel_source_dir M=$dkms_tree/$module/$module_version/build EXTRA_CFLAGS='-DCONFIG_DXGKRNL=m -include $dkms_tree/$module/$module_version/build/extra-defines.h' clean"
BUILT_MODULE_NAME[0]="@_PKGBASE@"
DEST_MODULE_LOCATION[0]="/kernel/drivers/hv"
AUTOINSTALL="yes"
!#/bin/bash
export tagver=6.6.87.2
export tagrev=427645e
export tag=linux-msft-wsl-${tagver}
wget https://github.com/microsoft/WSL2-Linux-Kernel/archive/refs/tags/${tag}.zip
unzip ${tag}.zip
rm ${tag}.zip
mv WSL2-Linux-Kernel-${tag} WSL2-Linux-Kernel
sudo apt update
export _pkgbase=dxgkrnl
export pkgver=${tagver}.r${tagrev}
export pkgdir=""
mkdir -p "${pkgdir}"/usr/src/${_pkgbase}-${pkgver}/
cp -r WSL2-Linux-Kernel/drivers/hv/dxgkrnl/* "${pkgdir}"/usr/src/${_pkgbase}-${pkgver}/
cp WSL2-Linux-Kernel/include/uapi/misc/d3dkmthk.h "${pkgdir}"/usr/src/${_pkgbase}-${pkgver}/
sed -e "s/<uapi\/misc\/d3dkmthk.h>/\"d3dkmthk.h\"/" \
-i "${pkgdir}"/usr/src/${_pkgbase}-${pkgver}/dxgkrnl.h
# patch --ignore-whitespace -d "${pkgdir}"/usr/src/${_pkgbase}-${pkgver} < fix_recv.patch
install -Dm644 dkms.conf "${pkgdir}"/usr/src/${_pkgbase}-${pkgver}/dkms.conf
sed -e "s/@_PKGBASE@/${_pkgbase}/" \
-e "s/@PKGVER@/${pkgver}/" \
-i "${pkgdir}"/usr/src/${_pkgbase}-${pkgver}/dkms.conf
install -Dm644 extra-defines.h "${pkgdir}"/usr/src/${_pkgbase}-${pkgver}/extra-defines.h
sudo apt install -y dkms
cd /usr/src
dkms build ./${_pkgbase}-${pkgver}
krnl_ver=`uname -r`
dkms install ${_pkgbase}/${pkgver}
modprobe dxgkrnl
#sudo add-apt-repository ppa:kisak/kisak-mesa
#sudo apt install -y mesa-utils
#echo "export LIBVA_DRIVER_NAME=d3d12" > /etc/profile.d/d3d.sh
#echo "export MESA_LOADER_DRIVER_OVERRIDE=vgem" >> /etc/profile.d/d3d.sh
echo "DONE"
// Extracted from
// https://www.mail-archive.com/[email protected]/msg2165538.html
/*
* GPU paravirtualization global DXGK channel
* {DDE9CBC0-5060-4436-9448-EA1254A5D177}
*/
#define HV_GPUP_DXGK_GLOBAL_GUID \
.guid = GUID_INIT(0xdde9cbc0, 0x5060, 0x4436, 0x94, 0x48, 0xea, 0x12, 0x54, \
0xa5, 0xd1, 0x77)
/*
* GPU paravirtualization per virtual GPU DXGK channel
* {6E382D18-3336-4F4B-ACC4-2B7703D4DF4A}
*/
#define HV_GPUP_DXGK_VGPU_GUID \
.guid = GUID_INIT(0x6e382d18, 0x3336, 0x4f4b, 0xac, 0xc4, 0x2b, 0x77, 0x3, \
0xd4, 0xdf, 0x4a)
$VMName = "ubuntu-vgpu"
# 停止虚拟机
Stop-VM -Name $VMName
# 基础VM配置
Set-VMFirmware -VMName $VMName -EnableSecureBoot Off
#Set-VMProcessor -VMName $VMName -ExposeVirtualizationExtensions $true
Set-VM -Name $VMName -GuestControlledCacheTypes $true
Set-VM -Name $VMName -LowMemoryMappedIoSpace 3GB
Set-VM -Name $VMName -HighMemoryMappedIoSpace 96GB
# 设置静态内存
Set-VMMemory -VMName $VMName -DynamicMemoryEnabled $false -StartupBytes 32GB
Write-Host "基础VM配置完成"
# 获取所有GPU适配器
$hostGPUs = Get-VMHostPartitionableGpu
$currentAdapters = Get-VMGpuPartitionAdapter -VMName $VMName
Write-Host "检测到 $($hostGPUs.Count) 张主机GPU"
Write-Host "当前虚拟机有 $($currentAdapters.Count) 个GPU适配器"
# 确保有两个GPU适配器
if ($currentAdapters.Count -eq 0) {
Write-Host "添加第一张GPU适配器..."
Add-VMGpuPartitionAdapter -VMName $VMName -InstancePath $hostGPUs[0].Name
Write-Host "添加第二张GPU适配器..."
Add-VMGpuPartitionAdapter -VMName $VMName -InstancePath $hostGPUs[1].Name
} elseif ($currentAdapters.Count -eq 1) {
Write-Host "添加第二张GPU适配器..."
$usedGPU = $currentAdapters[0].InstancePath
$unusedGPU = $hostGPUs | Where-Object { $_.Name -ne $usedGPU } | Select-Object -First 1
Add-VMGpuPartitionAdapter -VMName $VMName -InstancePath $unusedGPU.Name
}
# 等待适配器添加完成
Start-Sleep -Seconds 5
$adapters = Get-VMGpuPartitionAdapter -VMName $VMName | Sort-Object InstancePath
Write-Host "当前已添加 $($adapters.Count) 个GPU适配器"
Write-Host "配置GPU资源分配..."
if ($adapters.Count -eq 2) {
# 获取每个适配器的ID
$gpu1 = $adapters[0]
$gpu2 = $adapters[1]
Write-Host "第一张GPU ID: $($gpu1.Id)"
Write-Host "第二张GPU ID: $($gpu2.Id)"
# 第一张GPU:80%显存 + 100%计算
Write-Host "配置第一张GPU (80%显存 + 100%计算)..."
Set-VMGpuPartitionAdapter -VMName $VMName -AdapterId $gpu1.Id `
-MinPartitionVRAM 1000000000 `
-MaxPartitionVRAM 19.2GB `
-OptimalPartitionVRAM 19.2GB `
-MinPartitionCompute 80000000 `
-MaxPartitionCompute 100000000 `
-OptimalPartitionCompute 100000000 `
-MinPartitionEncode 50000000 `
-MaxPartitionEncode 80000000 `
-OptimalPartitionEncode 100000000 `
-MinPartitionDecode 50000000 `
-MaxPartitionDecode 80000000 `
-OptimalPartitionDecode 100000000
Write-Host "第一张GPU配置完成"
# 第二张GPU:100%显存 + 100%计算
Write-Host "配置第二张GPU (100%显存 + 100%计算)..."
Set-VMGpuPartitionAdapter -VMName $VMName -AdapterId $gpu2.Id `
-MinPartitionVRAM 1000000000 `
-MaxPartitionVRAM 24GB `
-OptimalPartitionVRAM 24GB `
-MinPartitionCompute 80000000 `
-MaxPartitionCompute 100000000 `
-OptimalPartitionCompute 100000000 `
-MinPartitionEncode 50000000 `
-MaxPartitionEncode 100000000 `
-OptimalPartitionEncode 100000000 `
-MinPartitionDecode 50000000 `
-MaxPartitionDecode 100000000 `
-OptimalPartitionDecode 100000000
Write-Host "第二张GPU配置完成"
} else {
Write-Host "错误:GPU适配器数量不正确,当前数量: $($adapters.Count)"
Write-Host "请检查GPU适配器添加是否成功"
}
# 验证配置
Write-Host "`n=== 验证GPU配置 ==="
$finalAdapters = Get-VMGpuPartitionAdapter -VMName $VMName
for ($i = 0; $i -lt $finalAdapters.Count; $i++) {
$adapter = $finalAdapters[$i]
Write-Host "GPU $($i+1) (ID: $($adapter.Id)):"
Write-Host " 实例路径: $($adapter.InstancePath.Substring(0,60))..."
Write-Host " 显存配置: Min=$([math]::Round($adapter.MinPartitionVRAM/1GB,1))GB, Max=$([math]::Round($adapter.MaxPartitionVRAM/1GB,1))GB, Optimal=$([math]::Round($adapter.OptimalPartitionVRAM/1GB,1))GB"
Write-Host " 计算资源: Min=$($adapter.MinPartitionCompute/1000000)%, Max=$($adapter.MaxPartitionCompute/1000000)%, Optimal=$($adapter.OptimalPartitionCompute/1000000)%"
Write-Host " 编码资源: Min=$($adapter.MinPartitionEncode/1000000)%, Max=$($adapter.MaxPartitionEncode/1000000)%, Optimal=$($adapter.OptimalPartitionEncode/1000000)%"
Write-Host " 解码资源: Min=$($adapter.MinPartitionDecode/1000000)%, Max=$($adapter.MaxPartitionDecode/1000000)%, Optimal=$($adapter.OptimalPartitionDecode/1000000)%"
Write-Host ""
}
Write-Host "=== 配置总结 ==="
Write-Host "第一张GPU: 19.2GB显存 (80%) + 100%计算"
Write-Host "第二张GPU: 24.0GB显存 (100%) + 100%计算"
Write-Host "总可用显存: 43.2GB"
Write-Host "双GPU精确资源配置完成!"
# 启动虚拟机
#Write-Host "启动虚拟机..."
#Start-VM -Name $VMName
#Write-Host "虚拟机已启动!请在虚拟机内使用 'nvidia-smi' 验证GPU配置"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment