From 5dd8165f1754e156a0f9fb16c7a6bfa90e99ed60 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Mon, 14 Sep 2026 06:43:11 -0400 Subject: VFIO device registration fix + IOMMUFD callbacks + VFIO ioctl handlers - Removed IOMMU group addition before vfio_register_emulated_iommu_dev() in nv_vgpu_mdev_create() - Added IOMMUFD callbacks (bind_iommufd, unbind_iommufd, attach_ioas, detach_ioas) using kernel's vfio_iommufd_emulated_* functions - Implemented VFIO ioctl handlers: GET_INFO, GET_REGION_INFO, GET_IRQ_INFO, SET_IRQS, MMAP - Added config space read/write handlers at offset 0x70000000000 - Mmap handler for config space, BAR0 (emulation shadow), BAR1-5 (physical VRAM/registers) - Interrupt handler for VFIO_DEVICE_SET_IRQS (DATA_EVENTFD, DATA_NONE, DATA_BOOL) - Added udev rules for vfio group permissions - Created stack_manager.sh unified tool - Fixed mdev remove crash with deferred cleanup in vfio_device_release callback - Kernel 6.8+ IOMMUFD compatibility - QEMU launches successfully with vGPU passthrough --- scripts/windows_guest_automation.sh | 220 ++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100755 scripts/windows_guest_automation.sh (limited to 'scripts/windows_guest_automation.sh') diff --git a/scripts/windows_guest_automation.sh b/scripts/windows_guest_automation.sh new file mode 100755 index 0000000..f95471e --- /dev/null +++ b/scripts/windows_guest_automation.sh @@ -0,0 +1,220 @@ +#!/bin/bash +# windows_guest_automation.sh - Windows guest test automation via WinRM/SSH + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BASE_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" + +RESULTS_DIR="/tmp/gsp_emu_windows/$(date +%Y%m%d_%H%M%S)" +mkdir -p "$RESULTS_DIR" + +log_info() { echo -e "\033[0;34m[INFO]\033[0m $1"; } +log_ok() { echo -e "\033[0;32m[OK]\033[0m $1"; } +log_error() { echo -e "\033[0;31m[ERROR]\033[0m $1"; } + +# Configuration +WIN_USER="${WIN_USER:-Administrator}" +WIN_IP="${WIN_IP:-192.168.122.100}" +WIN_PASSWORD="${WIN_PASSWORD:-}" +WINRM_PORT="${WINRM_PORT:-5985}" +SSH_PORT="${SSH_PORT:-22}" + +check_winrm() { + log_info "Checking WinRM connectivity to $WIN_IP..." + if command -v winrm &>/dev/null; then + winrm identify -r:"http://$WIN_IP:$WINRM_PORT/wsman" -u:"$WIN_USER" -p:"$WIN_PASSWORD" -auth:basic 2>/dev/null + elif command -v python3 &>/dev/null; then + python3 -c " +import winrm +session = winrm.Session('$WIN_IP:$WINRM_PORT', auth=('$WIN_USER', '$WIN_PASSWORD'), transport='ntlm') +result = session.run_cmd('echo test') +print('WinRM OK' if result.status_code == 0 else 'WinRM FAILED') +" + else + log_error "No WinRM client found. Install winrm or python3 with pywinrm" + return 1 + fi +} + +run_winrm_cmd() { + local cmd="$1" + local output_file="$2" + + if command -v winrm &>/dev/null; then + winrm invoke -r:"http://$WIN_IP:$WINRM_PORT/wsman" -u:"$WIN_USER" -p:"$WIN_PASSWORD" \ + -auth:basic Create "http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Command" \ + "Command=cmd.exe" "Arguments=/c $cmd" > "$output_file" 2>&1 + else + python3 -c " +import winrm, sys +session = winrm.Session('$WIN_IP:$WINRM_PORT', auth=('$WIN_USER', '$WIN_PASSWORD'), transport='ntlm') +result = session.run_cmd('$cmd') +with open('$output_file', 'w') as f: + f.write(result.std_out.decode() + result.std_err.decode()) +sys.exit(result.status_code) +" + fi +} + +run_ssh_cmd() { + local cmd="$1" + local output_file="$2" + sshpass -p "$WIN_PASSWORD" ssh -o StrictHostKeyChecking=no -p "$SSH_PORT" "$WIN_USER@$WIN_IP" "$cmd" > "$output_file" 2>&1 +} + +test_nvidia_smi() { + log_info "Testing nvidia-smi..." + run_winrm_cmd "nvidia-smi" "$RESULTS_DIR/nvidia_smi.txt" + if grep -q "NVIDIA" "$RESULTS_DIR/nvidia_smi.txt"; then + log_ok "nvidia-smi: PASS" + return 0 + else + log_error "nvidia-smi: FAIL" + cat "$RESULTS_DIR/nvidia_smi.txt" + return 1 + fi +} + +test_cuda_vectoradd() { + log_info "Testing CUDA vectorAdd..." + run_winrm_cmd "cd C:\\cuda_samples\\1_Utilities\\vectorAdd && .\\vectorAdd.exe" "$RESULTS_DIR/cuda_vectoradd.txt" + if grep -q "Test passed" "$RESULTS_DIR/cuda_vectoradd.txt"; then + log_ok "CUDA vectorAdd: PASS" + return 0 + else + log_error "CUDA vectorAdd: FAIL" + cat "$RESULTS_DIR/cuda_vectoradd.txt" + return 1 + fi +} + +test_cuda_devquery() { + log_info "Testing CUDA deviceQuery..." + run_winrm_cmd "cd C:\\cuda_samples\\1_Utilities\\deviceQuery && .\\deviceQuery.exe" "$RESULTS_DIR/cuda_devquery.txt" + if grep -q "Result = PASS" "$RESULTS_DIR/cuda_devquery.txt"; then + log_ok "CUDA deviceQuery: PASS" + return 0 + else + log_error "CUDA deviceQuery: FAIL" + cat "$RESULTS_DIR/cuda_devquery.txt" + return 1 + fi +} + +test_vulkan() { + log_info "Testing Vulkan..." + run_winrm_cmd "vulkaninfo.exe" "$RESULTS_DIR/vulkaninfo.txt" + if grep -q "GPU id" "$RESULTS_DIR/vulkaninfo.txt"; then + log_ok "Vulkan: PASS" + return 0 + else + log_error "Vulkan: FAIL" + cat "$RESULTS_DIR/vulkaninfo.txt" + return 1 + fi +} + +test_dx12() { + log_info "Testing DirectX 12..." + run_winrm_cmd "dxdiag /t $RESULTS_DIR/dxdiag.txt" "$RESULTS_DIR/dxdiag_cmd.txt" + # Parse dxdiag output + if grep -q "Feature Level" "$RESULTS_DIR/dxdiag.txt"; then + log_ok "DirectX 12: PASS" + return 0 + else + log_error "DirectX 12: FAIL" + return 1 + fi +} + +test_ffmpeg_nvenc() { + log_info "Testing FFmpeg NVENC..." + run_winrm_cmd "ffmpeg -encoders" "$RESULTS_DIR/ffmpeg_encoders.txt" + if grep -q "h264_nvenc\|hevc_nvenc" "$RESULTS_DIR/ffmpeg_encoders.txt"; then + log_ok "FFmpeg NVENC: PASS" + return 0 + else + log_error "FFmpeg NVENC: FAIL" + return 1 + fi +} + +test_pytorch() { + log_info "Testing PyTorch..." + run_winrm_cmd "python -c \"import torch; print('CUDA:', torch.cuda.is_available()); print('Device:', torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'N/A')\"" "$RESULTS_DIR/pytorch.txt" + if grep -q "CUDA: True" "$RESULTS_DIR/pytorch.txt"; then + log_ok "PyTorch: PASS" + return 0 + else + log_error "PyTorch: FAIL" + cat "$RESULTS_DIR/pytorch.txt" + return 1 + fi +} + +test_windows_driver_signature() { + log_info "Checking driver signature status..." + run_winrm_cmd "pnputil /enum-drivers | findstr nvidia" "$RESULTS_DIR/driver_signature.txt" + cat "$RESULTS_DIR/driver_signature.txt" +} + +collect_event_logs() { + log_info "Collecting Windows event logs..." + run_winrm_cmd "wevtutil qe System /q:\"*[System[Provider[@Name='NVIDIA']]]\" /f:text /c:50" "$RESULTS_DIR/nvidia_events.txt" + run_winrm_cmd "wevtutil qe System /q:\"*[System[Provider[@Name='Display']]]\" /f:text /c:50" "$RESULTS_DIR/display_events.txt" +} + +run_full_suite() { + log_info "=== Windows Guest Test Suite ===" + local failed=0 + + test_nvidia_smi || ((failed++)) + test_cuda_devquery || ((failed++)) + test_cuda_vectoradd || ((failed++)) + test_vulkan || ((failed++)) + test_dx12 || ((failed++)) + test_ffmpeg_nvenc || ((failed++)) + test_pytorch || ((failed++)) + test_windows_driver_signature + collect_event_logs + + log_info "=== Results ===" + log_info "Failed tests: $failed" + + # Generate summary + cat > "$RESULTS_DIR/summary.json" <