構成#
Host:Windows 11
VM:Ubuntu22.04LTS
GPU:Intel ARC A770 16GB
kernelは6.5.0-14-generic
前置き#
WSL2で使用されているGPU-PVという技術をHyperVの仮想マシンで使ってVMでもGPUを使おうというお話らしいです。ダラダラ書き綴っておいてなんですがXeKMDで遊んでた頃はできたのが現在思い出しながらやってみたもののうまく行かず、そこまでやる必要もなかったので今後の参考になるようにやったことだけ書き残した形になります。
できたので色々書き直しました。
参考文献#
・Hyper-VでGPU(GPU-PV)を利用する方法 (Ubuntu編)
・Ubuntu 21.04 VM with GPU acceleration under Hyper-V…?
・Windows 11 の Hyper-V マシンに GPU を割り当てる(GPU-PV)
・wsl2如何更新linux内核? - 雾魂泉守-曌鵷鶵的回答 - 知乎
GPUアダプタを追加する#
まずはGPUのパスを確認する。
Get-VMHostPartitionableGpu | Format-Table Name
以下のような感じでデバイスのパスが返ってくる。(複数GPUがあると複数返ってくるらしい)
Name
----
\\?\PCI#VEN_8086&DEV_56A0&SUBSYS_10208086&REV_08#6&17410126&0&00080008#{064092b3-625e-43bf-9eb5-dc845897dd59}\GPUPARAV
帰ってきた値を元にコマンドを実行してアダプタを追加する。
Add-VMGpuPartitionAdapter -VMName "VM Name" -InstancePath "Device Path"
この場合だとAdd-VMGpuPartitionAdapter -VMName "server" -InstancePath "\\?\PCI#VEN_8086&DEV_56A0&SUBSYS_10208086&REV_08#6&17410126&0&00080008#{064092b3-625e-43bf-9eb5-dc845897dd59}\GPUPARAV"
となる。
GPUリソースを割り当てたりメモリの設定をしたりでホストでの作業はおしまい。
Set-VMGpuPartitionAdapter -VMName "VM Name" -Passthru
Set-VM -VMName "VM Name" -GuestControlledCacheTypes $true -LowMemoryMappedIoSpace 1GB -HighMemoryMappedIoSpace 32GB
ドライバをインストールする#
WSL2 Kernelからdxgkrnlドライバをぶっこ抜いてインストールする。
dkmsを扱うので事前にインストールすること。
以下のコマンドでgithubからwsl2 kernelをクローンする。
git clone -b linux-msft-wsl-6.1.y --depth=1 https://github.com/microsoft/WSL2-Linux-Kernel
cd WSL2-Linux-Kernel
drivers/hv/dxgkrnl/dxgmodule.cのInterface from dxgglobal
の部分の上に以下を追記する。
static inline int uuid_le_cmp(const guid_t u1,const guid_t u2)
{
return memcmp(&u1, &u2,sizeof(guid_t));
}
以下のコマンドでdkms.confを作成する。
sudo su
VERSION=$(git rev-parse --short HEAD)
cp -r drivers/hv/dxgkrnl /usr/src/dxgkrnl-$VERSION
mkdir -p /usr/src/dxgkrnl-$VERSION/inc/{uapi/misc,linux}
cp include/uapi/misc/d3dkmthk.h /usr/src/dxgkrnl-$VERSION/inc/uapi/misc/d3dkmthk.h
cp include/linux/hyperv.h /usr/src/dxgkrnl-$VERSION/inc/linux/hyperv_dxgkrnl.h
sed -i 's/\$(CONFIG_DXGKRNL)/m/' /usr/src/dxgkrnl-$VERSION/Makefile
sed -i 's#linux/hyperv.h#linux/hyperv_dxgkrnl.h#' /usr/src/dxgkrnl-$VERSION/dxgmodule.c
echo "EXTRA_CFLAGS=-I\$(PWD)/inc" >> /usr/src/dxgkrnl-$VERSION/Makefile
cat > /usr/src/dxgkrnl-$VERSION/dkms.conf <<EOF
PACKAGE_NAME="dxgkrnl"
PACKAGE_VERSION="$VERSION"
BUILT_MODULE_NAME="dxgkrnl"
DEST_MODULE_LOCATION="/kernel/drivers/hv/dxgkrnl/"
AUTOINSTALL="yes"
EOF
dkmsを使ってインストール。
dkms add dxgkrnl/$VERSION
dkms build dxgkrnl/$VERSION
dkms install dxgkrnl/$VERSION
ホストからGPUドライバをコピーする#
自分は面倒なのでwsl2から直接ぶっこ抜いたものをホストを経由してゲストに入れてます。
sudo cp -r /usr/lib/wsl/ .
以下のコマンドでコピーしたりロードしたり…
cp -r wsl /usr/lib
echo "/usr/lib/wsl/lib" > /etc/ld.so.conf.d/ld.wsl.conf
ldconfig
再起動したらグラフィックがD3D12になってます。
このタイミングから、hypervの仮想マシン接続のウィンドウからGUIの操作ができなくなります。
自分は事前にRustdeskを導入してそれで操作しています。
事前にopenssh-serverを入れるとかして何かあったときに操作できるようにすると良いでしょう。
あとがき#
WSL2と同じように入れるもん入れたらoneAPIなりcudaなり使える。