04
11

 

 

DualCoder/vgpu_unlock

Unlock vGPU functionality for consumer grade GPUs. - DualCoder/vgpu_unlock

github.com

원래 테슬라랑 쿼드로 일부 모델만 지원하는 기능인데

드라이버가 다른 디바이스 ID를 읽게 해서 뚫어버렸다고 함

리눅스랑 KVM에서만 작동하는 듯

 

 

vgpu_unlock

 

소비자 등급 GPU를 위한 vGPU 기능을 잠금 해제하십시오.

 

중대한!
이 도구는 테스트되지 않았으므로 사용자의 책임하에 사용하십시오.

 

 

기술
이 도구를 사용하면 NVIDIA vGPU 소프트웨어와 함께 Geforce 및 Quadro GPU를 사용할 수 있습니다. NVIDIA vGPU는 일반적으로 몇 개의 Tesla GPU 만 지원하지만 일부 Geforce 및 Quadro GPU는 Tesla와 동일한 물리적 칩을 공유하므로 이러한 GPU에 대한 소프트웨어 제한 일뿐입니다. 이 도구는 이러한 제한을 제거하는 것을 목표로 합니다.

 

종속성 :
이 도구에는 Python3가 필요하며 최신 버전이 권장됩니다.
파이썬 패키지 "frida"가 필요합니다. pip3 install frida.
이 도구에는 NVIDIA GRID vGPU 드라이버가 필요합니다.
"dkms"는 드라이버를 많이 재 구축하는 과정을 단순화하므로 필요합니다. OS의 패키지 관리자를 사용하여 DKMS를 설치합니다.

 

 

설치:
다음 지침에서 대상 시스템의 이 저장소 경로로 교체해야 하며 NVIDIA GRID vGPU 드라이버 버전으로 교체해야 합니다.

NVIDIA GRID vGPU 드라이버를 설치하고 dkms 모듈로 설치해야 합니다.

./nvidia-installer --dkms
와 라인 태초 수정 ExecStart=에 /lib/systemd/system/nvidia-vgpud.service 하고 /lib/systemd/system/nvidia-vgpu-mgr.service 사용하는 vgpu_unlock실행 파일과 첫 번째 인수로 원래의 실행 파일을 전달합니다. 전의:

ExecStart=/vgpu_unlock /usr/bin/nvidia-vgpud
systemd 데몬을 다시 로드합니다.

systemctl daemon-reload
파일을 수정하고 파일 시작 부분에서로 /usr/src/nvidia-/nvidia/os-interface.c 시작하는 줄 뒤에 다음 줄을 추가 #include 합니다.

#include "/vgpu_unlock_hooks.c"
파일을 수정하고 파일 /usr/src/nvidia-/nvidia/nvidia.Kbuild맨 아래에 다음 행을 추가하십시오.

ldflags-y += -T /kern.ld
dkms를 사용하여 nvidia 커널 모듈을 제거합니다.

dkms remove -m nvidia -v --all
dkms를 사용하여 nvidia 커널 모듈을 다시 빌드하고 다시 설치합니다.

dkms install -m nvidia -v
재부팅하십시오.

 

노트

이 스크립트는 사용 중인 실제 GPU와 동일한 물리적 칩을 사용하는 vGPU 호환 Tesla GPU가 있는 경우에만 작동합니다.

 

작동 원리
vGPU가 지원됩니까?
특정 GPU가 vGPU 기능을 지원하는지 확인하기 위해 드라이버는 PCI 장치 ID를 확인합니다. PCI 공급 업체 ID와 함께 이 식별자는 각 PCI 장치 유형에 대해 고유합니다. vGPU 지원을 활성화하려면 설치된 GPU의 PCI 장치 ID가 vGPU 지원 GPU에서 사용하는 장치 ID 중 하나임을 드라이버에 알려야 합니다.

 

사용자 공간 스크립트 : vgpu_unlock
사용자 공간 서비스 nvidia-vgpud 및 nvidia-vgpu-mgr은 ioctl syscall을 사용하여 커널 모듈과 통신합니다. 특히 PCI 장치 ID를 읽고 설치된 GPU가 vGPU를 지원하는지 확인합니다.

파이썬 스크립트 vgpu_unlock은 첫 번째 인수로 지정된 실행 파일과 커널 사이의 모든 ioctl syscall을 가로챕니다. 그런 다음 스크립트는 vGPU 지원 및 vGPU 지원 GPU가 있는 PCI 장치 ID를 나타내도록 커널 응답을 수정합니다.

 

커널 모듈 후크 : vgpu_unlock_hooks.c
GPU와 데이터를 교환하기 위해 커널 모듈은 PCI 버스의 물리적 주소 공간을 자체 가상 주소 공간에 매핑합니다. 이것은 ioremap * 커널 함수를 사용하여 수행됩니다. 그런 다음 커널 모듈은 매핑된 주소 공간에 데이터를 읽고 씁니다. 이것은 memcpy 커널 함수를 사용하여 수행됩니다.

vgpu_unlock_hooks.c 파일을 os-interface.c 파일에 포함하면 C 전 처리기 매크로를 사용하여 iormeap 및 memcpy 함수에 대한 호출을 대체하고 가로챌 수 있습니다. 이렇게 하면 매핑된 위치와 액세스 중인 데이터에 대한 보기를 유지할 수 있습니다.

 

커널 모듈 링커 스크립트 : kern.ld
이것은 gcc에서 제공하는 기본 링커 스크립트의 수정된 버전입니다. 스크립트는 nv-kernel.o의. rodata 섹션을. rodata 대신. data 섹션에 배치하여 쓰기 가능하도록 수정되었습니다. 스크립트는 또한 기호를 제공 vgpu_unlock_nv_kern_rodata_beg 하고 vgpu_unlock_nv_kern_rodata_end 해당 섹션이 시작하고 끝나는 위치를 알려 할 수 있습니다.

 

모든 것이 하나로 결합되는 방법
부팅 후 nvidia-vgpud 서비스는 커널에 설치된 모든 GPU를 쿼리하고 vGPU 기능을 확인합니다. 이 호출은 vgpu_unlock python 스크립트에 의해 차단되며 GPU는 vGPU를 지원합니다. vGPU 지원 GPU가 발견되면 nvidia-vgpu가 MDEV 장치를 생성하고 시스템에서 / sys / class / mdev_bus 디렉토리를 생성합니다.

이제 createmdev 버스 표현의 파일에 UUID를 에코 하여 vGPU 장치를 만들 수 있습니다. 이렇게 하면 MDEV 버스에서 새 vGPU 장치를 나타내는 추가 구조가 생성됩니다. 그런 다음 이러한 장치를 VM에 할당할 수 있으며 VM이 시작되면 MDEV 장치가 열립니다. 이렇게 하면 nvidia-vgpu-mgr이 ioctl을 사용하여 커널과 통신을 시작합니다. 다시 이러한 호출은 vgpu_unlock python 스크립트에 의해 가로채고 nvidia-vgpu-mgr이 GPU가 vGPU를 지원하는지 물어보면 대답이 yes로 변경됩니다. 그 후 vGPU 장치 인스턴스 초기화를 시도합니다.

vGPU 장치의 초기화는 커널 모듈에 의해 처리되며 자체적으로 vGPU 기능 검사를 수행합니다. 이것은 좀 더 복잡합니다.

커널 모듈은 물리적 PCI 주소 범위 0 xf0000000-0 xf1000000을 가상 주소 공간에 매핑 한 다음 우리가 실제로 무엇을 하는지 알지 못하는 마법 같은 작업을 수행합니다. 우리가 아는 것은 이러한 작업 후에 물리적 주소 0 xf0029624에서 128 비트 값에 액세스 한다는 것입니다. 이를 매직 값이라고 합니다. 커널 모듈은 또한 키 값이라고 하는 물리적 주소 0 xf0029634에서 128 비트 값에 액세스 합니다.

그런 다음 커널 모듈에는 매직 값에 대한 두 개의 조회 테이블이 있습니다. 하나는 vGPU 지원 GPU 용이고 다른 하나는 다른 하나입니다. 따라서 커널 모듈은 이 두 룩업 테이블에서 매직 값을 찾고 테이블 항목에 AES-128 암호화 데이터 블록 세트와 HMAC-SHA256 서명도 포함되어있는 것으로 확인됩니다.

그런 다음 암호화된 데이터 블록에 대한 HMAC-SHA256 서명을 계산하기 위해 앞서 언급 한 키 값을 사용하여 서명의 유효성을 검사합니다. 서명이 정확하면 블록은 AES-128과 동일한 키를 사용하여 해독됩니다.

복호화된 데이터 내부에는 다시 한번 PCI 장치 ID가 있습니다.

따라서 커널 모듈이 GPU를 vGPU 지원으로 받아들이려면 매직 값이 vGPU 지원 매직 값 테이블에 있어야 하며 키는 유효한 HMAC-SHA256 서명을 생성해야 하며 AES-128 해독된 데이터 블록은 vGPU 지원 PCI 장치 ID를 포함합니다. 이러한 검사 중 하나라도 실패하면 오류 코드 0x56 "Call not supported"가 반환됩니다.

이러한 검사를 통과하기 위해 vgpu_unlock_hooks.c의 후크는 매직 및 키 값을 포함하는 물리적 주소 범위를 매핑하는 ioremap 호출을 찾고 해당 값의 주소를 커널 모듈의 가상 주소 공간으로 다시 계산하고 모니터링합니다. memcpy 작업은 해당 주소에서 읽습니다. 이러한 작업이 발생하면 둘 다 알 수 있을 때까지 값의 복사본을 보관하고 nv-kernel.o의. rodata 섹션에서 조회 테이블을 찾고 서명과 데이터 블록을 찾고 서명, 블록 해독, 해독된 데이터의 PCI 장치 ID 편집, 블록 재 암호화, 서명 재생성 및 매직, 블록 및 서명을 vGPU 가능 매직 값 테이블에 삽입합니다. 그리고 그것이 그들 이하는 일입니다.

COMMENT
 

인기 글


최근 글