構成
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-Kerneldrivers/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"
EOFdkmsを使ってインストール。
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なり使える。