장애-그래픽카드 패스스루
이번 글에서는 아래 내용을 정리한다.
- 2025년 6월, GTX 1060을 Windows 11 VM에 넣었을 때 무슨 일이 있었나
- 1년이 지난 뒤 같은 카드가 왜 한 번에 됐나
- 남아 있는 로그로 당시 상황을 되짚는 방법 (setupapi, 이벤트 로그, 드라이버 저장소)
- 진짜 원인: NVIDIA GeForce 드라이버의 VM 차단(코드 43)과 465 이전 드라이버
- “멈춤"은 카드 문제가 아니었다는 근거
- 패스스루 GPU에서 MSI 인터럽트를 확인하는 법
- 이번 교체에서 실제로 한 절차
배경
집에 XCP-ng 호스트가 한 대 있다. Ryzen 7 5700X, 램 80GB, 그 위에 Windows 서버 VM 몇 대와 Unity 작업용 Windows 11 VM이 돈다. Windows 11 VM에는 그래픽카드 한 장을 PCI 패스스루로 통째로 넘겨 준다.
2025년 6월에 남는 GTX 1060 6GB를 이 VM에 넣었다. 결과는 극심한 렉, 그리고 멈춤이었다. 카드를 GTX 1050으로 바꿔 봐도 같았다. 결국 10월에 Quadro P400(VRAM 2GB)으로 바꾸고 나서야 안정됐고, 그 뒤로 1년 가까이 P400을 썼다. 당시의 결론은 “GeForce는 이 서버에서 안 되고 Quadro는 된다” 정도였다.
2026년 9월, Unity 3D 작업을 준비하면서 VRAM 2GB가 벽에 부딪혔다. 그래서 창고에 있던 그 1060을 다시 꺼냈다. 다른 PC에서 스트레스 테스트를 돌려 카드가 멀쩡한 것을 확인하고, 호스트를 끄고, 같은 슬롯에 꽂고, 드라이버를 설치했다. 그런데 이번에는 아무 문제 없이 한 번에 됐다.
같은 카드, 같은 슬롯, 같은 VM이다. 그러면 2025년에는 왜 안 됐을까. 그때는 원인을 못 찾고 카드만 바꿨으니, 이번에는 남아 있는 로그로 끝까지 파 보기로 했다.
무엇이 남아 있었나
1년 전 일이라 남은 자료가 많지는 않다. 호스트(dom0)의 로그는 30일만 보관되어 전부 사라졌다. 그래서 VM 안의 Windows에 남은 것만으로 추적했다.
| 자료 | 위치 | 남은 범위 | 알 수 있는 것 |
|---|---|---|---|
| setupapi.dev.log (+ 보관본 5개) | C:\Windows\INF\ |
2025-06 ~ 현재 | 드라이버 설치·교체·제거 시각, 드라이버 버전, 설치 직후 장치 상태 코드 |
| 시스템 이벤트 로그 | 이벤트 뷰어 | 2025-06-11 ~ 현재 (20MB 순환) | 강제 리셋(Kernel-Power 41, EventLog 6008), 정상 재부팅(109), GPU 드라이버 오류(Display 4101, nvlddmkm) |
| 응용 프로그램 로그 | 이벤트 뷰어 | 2026-04 ~ | 2025년 것은 이미 밀려나서 없음 |
| 드라이버 저장소 | pnputil /enum-drivers |
현재 | 당시 설치했던 패키지의 잔재 |
| 설치 파일 압축 해제 폴더 | C:\NVIDIA\DisplayDriver\ |
2025-06-08 생성 | 당시 어떤 설치 파일을 썼는지, 그 INF의 내용 |
| 호스트에 남은 파일 | dom0 홈 디렉터리 | 2025-06-11 생성 | 1060의 VBIOS ROM 덤프 (128KB) |
이 중에서 결정적이었던 것은 setupapi.dev.log다. Windows는 장치 드라이버가 설치되거나 바뀔 때마다 이 로그에 섹션을 남기는데, 어떤 INF의 어떤 버전이 선택됐는지, 설치가 끝난 직후 장치 상태 코드가 무엇이었는지까지 적혀 있다. 로그가 20MB 단위로 보관본(setupapi.dev.YYYYMMDD_HHMMSS.log)으로 넘어가면서 1년 전 기록이 그대로 남아 있었다.
타임라인
로그를 시간순으로 붙이면 이렇게 된다.
| 시각 | 기록 | 출처 |
|---|---|---|
| 2025-06-08 14:22 | GeForce 399.24(2018년 9월 릴리스) 설치 파일을 C:\NVIDIA\DisplayDriver\399.24에 압축 해제 |
폴더 생성 시각 |
| 2025-06-08 14:24 | GTX 1060에 399.24 설치. 설치 직후 상태 코드 14(재시작 필요) | setupapi |
| 2025-06-08 14:43 | Windows Update가 드라이버를 456.71(2020년 9월)로 자동 교체. 장치 상태 코드 43 | setupapi [Device Install (Install Windows Update driver)] |
| 2025-06-11 01:16 | VM 강제 리셋 (Kernel-Power 41) | 시스템 로그 |
| 2025-06-11 23:33 | 호스트에 1060의 VBIOS ROM 덤프 파일 생성 | dom0 파일 시각 |
| 2025-06-19 10:45 | 재부팅 직후 18초 만에 다시 강제 리셋 | 시스템 로그 |
| 2025-06 ~ 08 | 정상 재부팅 여러 번. 465 이상 드라이버를 설치한 기록은 없음 | setupapi |
| 2025-08-17 20:17 | GTX 1050으로 교체. Windows Update가 또 456.71을 선택, 장치 상태 코드 43 | setupapi |
| 2025-09-06, 09-07 | 강제 리셋 2회 | 시스템 로그 |
| 2025-10-04 19:49 | Quadro P400으로 교체. 20:10 Quadro 드라이버 581.42 설치, 장치 상태 정상 | setupapi |
| 2025-10-04 ~ 2026-08 | 그래도 강제 리셋이 간간이 이어짐 (아래 참고) | 시스템 로그 |
| 2026-09-24 14:52 | 1060 재장착, GeForce 582.66 무인 설치. 설치 직후 장치 상태 정상, 재부팅 후 nvidia-smi 정상 | setupapi, nvidia-smi |
원인: 465 이전 GeForce 드라이버는 VM 안에서 코드 43을 낸다
NVIDIA는 오랫동안 GeForce(소비자용) 드라이버가 가상머신 안에서 실행되는 것을 막아 왔다. 드라이버가 하이퍼바이저를 감지하면 장치를 시작하지 않고 장치 관리자에 코드 43(“문제가 보고되어 Windows가 이 장치를 중지했습니다”)을 띄운다. Xen HVM 게스트도 하이퍼바이저 신호를 그대로 노출하니 여기에 걸린다. 이 차단은 2021년 3월 465.89부터 풀렸다. Quadro 같은 전문가용 드라이버에는 처음부터 이 차단이 없었다.
2025년에 1060에 들어간 드라이버는 둘 다 465 이전이다.
- 직접 설치한 399.24 (2018년 9월)
- Windows Update가 바꿔 넣은 456.71 (2020년 9월)
setupapi 로그는 456.71로 교체된 직후의 장치 상태를 [0x2b], 즉 코드 43으로 기록하고 있다. 8월의 1050도 마찬가지로 456.71에 코드 43이다. 그리고 10월의 P400에는 Quadro 드라이버 581.42가 들어갔고 상태는 정상이었다. “GeForce는 안 되고 Quadro는 된다"의 정체가 이것이다.
코드 43이면 GPU 가속이 전혀 없다. Windows는 Microsoft 기본 디스플레이 어댑터로 떨어지고 모든 화면을 CPU가 그린다. 당시 이 VM은 vCPU 4개에 CPU 가중치도 다른 VM보다 낮게 잡혀 있었다. 그 위에서 Unity 에디터와 원격 화면 스트리밍을 돌렸으니 “극심한 렉"은 카드가 느린 게 아니라 카드가 아예 안 쓰이고 있던 것이다.
왜 2018년 드라이버를 골랐는지는 기록이 없다. 예전에 받아 둔 설치 파일을 그대로 썼을 가능성이 크다. 어느 쪽이든, 19분 뒤 Windows Update가 456.71로 바꿔 놓았으니 처음 고른 버전은 결과에 영향이 없었다. Windows Update가 주는 NVIDIA 드라이버는 대체로 오래된 WHQL 버전이라, 이것도 465 이전이었다.
코드 43과 싸운 흔적
당시의 나는 코드 43이라고 기억하지 못했는데, 로그를 보면 분명히 싸운 흔적이 있다.
- 호스트에 남은 VBIOS ROM 덤프: KVM/Proxmox 쪽 가이드에 나오는 “romfile로 코드 43 우회” 트릭이다. XCP-ng에는 적용할 방법이 없다. 그래도 시도해 본 것이다.
- 레지스트리의 TdrDelay=10, TdrDdiDelay=20: 기본값(2, 5)보다 늘려 놓았다. “디스플레이 드라이버가 응답하지 않습니다"를 피하려는 흔한 처방인데, 코드 43에는 아무 효과가 없다.
이런 걸 만졌다면 십중팔구 코드 43과 싸우고 있던 것이다. 그리고 진짜 해법은 단 하나, 465 이상 드라이버였다. 이번에 넣은 582.66은 설치 직후부터 장치 상태가 정상이었다.
“멈춤"은 카드 탓이 아니었다
렉은 설명이 됐다. 그러면 멈춤은? 시스템 로그의 강제 리셋 기록(Kernel-Power 41 + EventLog 6008)을 카드별로 세어 봤다.
| 기간 | 카드 | 강제 리셋 |
|---|---|---|
| 2025-06-08 ~ 08-17 | GTX 1060 | 2회 (06-11, 06-19) |
| 2025-08-17 ~ 10-04 | GTX 1050 | 2회 (09-06, 09-07) |
| 2025-10-04 ~ 2026-09 | Quadro P400 | 교체 당일 4회 + 이튿날 블루스크린 1회 + 이후 7회 (10-11, 11-07, 12-09, 01-04 ×3, 08-22) |
P400으로 바꾼 뒤에도 멈춤은 이어졌다. 세 카드 모두에서 일어났으니 GPU가 원인이 아니다. 2025년 시스템 로그에는 GPU 드라이버 오류(Display 4101, nvlddmkm)가 한 건도 없다. 멈춤 직전 기록도 특별한 게 없다. 그냥 어느 순간 응답이 없어져서 호스트에서 강제로 껐다 켠 것이다.
지금 와서 짚이는 것은 세 가지다. 당시의 작은 VM 크기(vCPU 4개, 16GB, 낮은 CPU 가중치), 소프트웨어 렌더링이 CPU를 다 먹어 버린 상태, 그리고 같은 시기에 호스트에서 벌이던 다른 실험들. 이 중 어느 것인지는 로그로 확정할 수 없다. 다만 2026년 들어 VM을 8 vCPU/32GB로 키우고 호스트를 XCP-ng 8.3(Xen 4.17)으로 올린 뒤로는 빈도가 크게 줄었다.
부수 확인: MSI 인터럽트
Xen 패스스루에서 GPU가 예전 방식(line-based, INTx) 인터럽트를 쓰면 인터럽트 하나하나가 하이퍼바이저를 거쳐야 해서 느리고, 심하면 인터럽트 폭풍으로 게스트가 굳는다. 그래서 패스스루 GPU는 MSI 모드인지 확인해야 한다.
- 399.24의 INF를 열어 보니 GTX 1060 설치 섹션에는 MSI를 켜는 항목이 없다. 그 시절에는 신형 GPU에만 넣어 줬다. 설령 코드 43을 넘겼더라도 line-based로 돌았을 것이다.
- 582.66의 INF는 설치와 동시에
MSISupported=1을 넣는다. 설치 직후 확인하니 GPU 인터럽트가 이미 MSI였다. - 카드의 HDMI 오디오 기능은 지금도 line-based가 기본이라 레지스트리로 따로 켰다.
확인 방법은 간단하다. 장치 관리자에서 장치의 리소스 탭을 보거나 아래 명령으로 IRQ 번호를 보면 된다. 음수면 MSI, 양수면 line-based다.
Get-CimInstance Win32_PnPAllocatedResource |
Where-Object { $_.Dependent.DeviceID -like 'PCI\VEN_10DE*' -and
$_.Antecedent.CimClass.CimClassName -eq 'Win32_IRQResource' } |
ForEach-Object { "$($_.Dependent.DeviceID) IRQ=$([int64]$_.Antecedent.IRQNumber - 4294967296)" }켜는 위치는 HKLM\SYSTEM\CurrentControlSet\Enum\PCI\<장치>\Device Parameters\Interrupt Management\MessageSignaledInterruptProperties의 MSISupported(DWORD) = 1이다. 재부팅해야 적용된다. 이번에는 GPU는 -10, 오디오는 -11로 둘 다 MSI다.
이번 교체에서 한 것
교체 자체는 단순했다. 기록으로 남긴다.
- 롤백용으로 VM 스냅샷을 찍고, 호스트 설정(pool DB, VM 메타데이터, 패스스루 설정)을 따로 백업했다.
- VM 전부 정상 종료 → 호스트 종료 → 카드 교체(같은 x16 슬롯, 6핀 보조 전원 연결) → 부팅.
- 호스트에서
lspci로 새 카드의 PCI 주소를 확인했다. 같은 슬롯이라 주소가 그대로여서xen-pciback.hide와 VM의other-config:pci는 손댈 것이 없었다. - VM을 켜니 1060이 “Microsoft 기본 디스플레이 어댑터, 코드 10"으로 보였다. 드라이버가 없으니 정상이다.
- GeForce 582.66을 무인 설치했다. GUI 없이 원격에서 돌리려면 PowerShell로 이렇게 한다.
Start-Process -FilePath '.\582.66-desktop-win10-win11-64bit-international-dch-whql.exe' `
-ArgumentList '-s','-clean','-noreboot','-noeula','-nofinish' -Wait -PassThru-clean이 GUI의 “완전 설치"에 해당한다. 4분 걸렸고 종료 코드 0. 다만 무인 설치는 NVIDIA App까지 같이 깔아 버리니, 원격 데스크톱으로만 쓰는 VM이면 나중에 지워도 된다.
6. HDMI 오디오의 MSI를 켜고 재부팅했다.
7. 결과: nvidia-smi에서 GeForce GTX 1060 6GB, 드라이버 582.66, 6144MiB, 유휴 30W. 이벤트 로그에 GPU 오류 없음. 예전 P400의 유령 장치 항목과 Quadro 드라이버 패키지는 정리했다.
꼭 기억할 것 ① GeForce 패스스루는 465.89 이상 드라이버가 전제 조건이다
VM 안에서 GeForce가 코드 43을 내면 카드나 슬롯이나 호스트를 의심하기 전에 드라이버 버전부터 본다. 2021년 3월 이전 드라이버는 하이퍼바이저를 감지하면 무조건 코드 43이다. ROM 덤프, TDR 레지스트리, 별의별 트릭을 다 써 봐야 소용없다.
꼭 기억할 것 ② Windows Update가 드라이버를 바꿔치기한다
직접 설치한 드라이버가 19분 뒤에 Windows Update의 옛 버전으로 교체됐다. 설치가 끝났다고 끝이 아니다. 재부팅 후
nvidia-smi나 장치 관리자에서 버전을 다시 본다. setupapi.dev.log에Install Windows Update driver섹션이 있으면 그것이 범인이다.
꼭 기억할 것 ③ “렉 + 멈춤"을 GPU 탓으로 묶지 않는다
렉은 드라이버(소프트웨어 렌더링), 멈춤은 다른 원인이었다. 둘을 한 덩어리로 보고 카드를 세 번 바꿨다. setupapi.dev.log와 시스템 로그의 Kernel-Power 41, Display 4101, nvlddmkm 항목만 먼저 봤어도 한 시간이면 갈렸을 일이다.
꼭 기억할 것 ④ 패스스루 GPU는 IRQ가 음수인지 본다
요즘 GeForce 드라이버는 GPU에는 MSI를 알아서 켜 주지만 오디오 기능에는 안 켜 준다. Xen에서 line-based 인터럽트는 느리고 위험하다. 설치 후 IRQ 번호를 확인하고 양수면
MSISupported=1을 넣는다.
마치며
1년 동안 “이 서버는 GeForce가 안 된다"고 믿었다. 실제로는 2018년, 2020년 드라이버가 VM을 거부한 것이었고, 그 사이 NVIDIA는 이미 차단을 풀어 놓은 상태였다. 원인을 안 찾고 부품만 바꾸면 이렇게 된다. 이번에는 로그가 남아 있어서 다행이었다. setupapi.dev.log는 지우지 말자.