summaryrefslogtreecommitdiffstats
path: root/scripts/stack_manager.sh
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/stack_manager.sh')
-rwxr-xr-xscripts/stack_manager.sh393
1 files changed, 393 insertions, 0 deletions
diff --git a/scripts/stack_manager.sh b/scripts/stack_manager.sh
new file mode 100755
index 0000000..fe0a73a
--- /dev/null
+++ b/scripts/stack_manager.sh
@@ -0,0 +1,393 @@
+#!/bin/bash
+# stack_manager.sh - Complete vGPU stack management (load, unload, test, debug)
+# Usage: ./stack_manager.sh <command> [options]
+
+set -euo pipefail
+
+BASE_DIR="$OPEN_IOV_ROOT"
+NVIDIA_KO="$BASE_DIR/nvidia-open-gpu-kernel-modules/kernel-open/nvidia.ko"
+VFIO_KO="$BASE_DIR/kernel/open-iov-vfio.ko"
+FIRMWARE_PATH="$BASE_DIR/firmware/57X-GSP/570.144/gsp-570.144.fwimage.bin"
+FIRMWARE_DEST="/lib/firmware/gsp-570.144.fwimage.bin"
+
+MDEV_SCRIPT="$BASE_DIR/scripts/create_mdev.sh"
+QEMU_SCRIPT="$BASE_DIR/scripts/launch_qemu_vgpu.sh"
+TEST_SCRIPT="$BASE_DIR/scripts/test_vgpu_stack.sh"
+
+color_red='\033[0;31m'
+color_green='\033[0;32m'
+color_yellow='\033[1;33m'
+color_blue='\033[0;34m'
+color_nc='\033[0m'
+
+log_info() { echo -e "${color_blue}[INFO]${color_nc} $*"; }
+log_ok() { echo -e "${color_green}[OK]${color_nc} $*"; }
+log_warn() { echo -e "${color_yellow}[WARN]${color_nc} $*"; }
+log_err() { echo -e "${color_red}[ERROR]${color_nc} $*"; }
+
+# ============================================================
+# BUILD COMMANDS (correct order matters!)
+# ============================================================
+
+cmd_build_kernel() {
+ log_info "Building open-iov-vfio.ko (kernel module)..."
+ cd "$BASE_DIR"
+ make kernel
+ log_ok "open-iov-vfio.ko built"
+}
+
+cmd_build_nvidia() {
+ log_info "Building NVIDIA OpenRM with vGPU symbols (KBUILD_EXTRA_SYMBOLS)..."
+ cd "$BASE_DIR"
+
+ # Step 1: Build nvidia kernel module (nv-kernel.o)
+ log_info "Building nvidia kernel module (nv-kernel.o)..."
+ cd "$BASE_DIR/nvidia-open-gpu-kernel-modules/src/nvidia"
+ make -j$(nproc)
+ log_ok "nvidia kernel module built"
+
+ # Step 2: Build nvidia-modeset kernel module (nv-modeset-kernel.o)
+ log_info "Building nvidia-modeset kernel module (nv-modeset-kernel.o)..."
+ cd "$BASE_DIR/nvidia-open-gpu-kernel-modules/src/nvidia-modeset"
+ make -j$(nproc)
+ log_ok "nvidia-modeset kernel module built"
+
+ # Step 3: Build kernel-open modules with KBUILD_EXTRA_SYMBOLS
+ log_info "Building kernel-open modules with KBUILD_EXTRA_SYMBOLS..."
+ cd "$BASE_DIR/nvidia-open-gpu-kernel-modules/kernel-open"
+ KBUILD_EXTRA_SYMBOLS="$BASE_DIR/kernel/Module.symvers" make -j$(nproc) modules
+ log_ok "NVIDIA OpenRM built"
+}
+
+cmd_build_userspace() {
+ log_info "Building userspace (libiov.so + examples)..."
+ cd "$BASE_DIR"
+ make userspace
+ make examples
+ log_ok "Userspace built"
+}
+
+cmd_build_all() {
+ log_info "=== BUILD ALL (correct order) ==="
+ cmd_build_kernel
+ cmd_build_nvidia
+ cmd_build_userspace
+ log_ok "=== ALL BUILDS COMPLETE ==="
+}
+
+# ============================================================
+# LOAD COMMANDS (correct order matters!)
+# ============================================================
+
+cmd_load_prereqs() {
+ log_info "Loading kernel prerequisites (vfio, mdev)..."
+ sudo modprobe vfio vfio_iommu_type1 vfio_pci mdev vfio_mdev 2>/dev/null || true
+ lsmod | grep -E "vfio|mdev"
+}
+
+cmd_load_open_iov() {
+ if [[ ! -f "$VFIO_KO" ]]; then
+ log_err "Missing $VFIO_KO - run 'build' first"
+ return 1
+ fi
+ if ! lsmod | grep -q "^open_iov_vfio "; then
+ log_info "Loading open-iov-vfio.ko..."
+ sudo insmod "$VFIO_KO" || { log_err "Failed to load open-iov-vfio.ko"; return 1; }
+ log_ok "open-iov-vfio.ko loaded"
+ else
+ log_ok "open-iov-vfio.ko already loaded"
+ fi
+}
+
+cmd_load_nvidia() {
+ if [[ ! -f "$NVIDIA_KO" ]]; then
+ log_err "Missing $NVIDIA_KO - run 'build-nvidia' first"
+ return 1
+ fi
+ if ! lsmod | grep -q "^nvidia "; then
+ log_info "Loading nvidia.ko (OpenRM)..."
+ sudo insmod "$NVIDIA_KO" || { log_err "Failed to load nvidia.ko"; return 1; }
+ log_ok "nvidia.ko loaded"
+ else
+ log_ok "nvidia.ko already loaded"
+ fi
+}
+
+cmd_install_firmware() {
+ if [[ ! -f "$FIRMWARE_PATH" ]]; then
+ log_err "Missing firmware at $FIRMWARE_PATH"
+ return 1
+ fi
+ if [[ ! -f "$FIRMWARE_DEST" ]] || ! cmp -s "$FIRMWARE_PATH" "$FIRMWARE_DEST"; then
+ log_info "Installing firmware to $FIRMWARE_DEST..."
+ sudo cp "$FIRMWARE_PATH" "$FIRMWARE_DEST"
+ log_ok "Firmware installed"
+ else
+ log_ok "Firmware already installed"
+ fi
+}
+
+cmd_load_stack() {
+ log_info "=== LOAD STACK (correct order) ==="
+ cmd_load_prereqs
+ cmd_load_open_iov
+ cmd_load_nvidia
+ cmd_install_firmware
+ log_ok "=== DRIVER STACK LOADED ==="
+ lsmod | grep -E "nvidia|open_iov|vfio|mdev"
+}
+
+# Full cycle: build all + load stack + create mdev
+cmd_up() {
+ log_info "=== FULL STARTUP: build + load + mdev ==="
+ cmd_build_all
+ cmd_load_stack
+ cmd_create_mdev
+ log_ok "=== SYSTEM READY FOR QEMU ==="
+ echo "Run: ./stack_manager.sh qemu"
+}
+
+# ============================================================
+# UNLOAD COMMANDS
+# ============================================================
+
+cmd_unload_stack() {
+ log_info "=== UNLOAD STACK ==="
+
+ if [[ -e /sys/bus/mdev/devices/* ]]; then
+ log_warn "MDEV devices exist - removing them first..."
+ for mdev in /sys/bus/mdev/devices/*; do
+ uuid=$(basename "$mdev")
+ log_info "Removing mdev $uuid..."
+ echo 1 | sudo tee "$mdev/remove" >/dev/null
+ done
+ sleep 2
+ fi
+
+ # CRITICAL: nvidia.ko holds a reference to open_iov_vfio, so unload nvidia FIRST
+ for mod in nvidia_uvm nvidia_modeset nvidia_drm nvidia_peermem nvidia; do
+ if lsmod | grep -qE "^$mod\>"; then
+ log_info "Unloading $mod..."
+ sudo rmmod "$mod" || { log_err "Failed to unload $mod"; return 1; }
+ log_ok "$mod unloaded"
+ fi
+ done
+
+ if lsmod | grep -qE "^open_iov_vfio\>"; then
+ log_info "Unloading open-iov-vfio.ko..."
+ sudo rmmod open_iov_vfio || { log_err "Failed to unload open-iov-vfio.ko"; return 1; }
+ log_ok "open-iov-vfio.ko unloaded"
+ fi
+
+ sudo modprobe -r vfio_mdev vfio_pci vfio_iommu_type1 vfio mdev 2>/dev/null || true
+ log_ok "=== DRIVER STACK UNLOADED ==="
+}
+
+# ============================================================
+# MDEV COMMANDS
+# ============================================================
+
+cmd_create_mdev() {
+ log_info "Creating mdev device..."
+ if [[ ! -f "$MDEV_SCRIPT" ]]; then
+ log_err "create_mdev.sh not found"
+ return 1
+ fi
+ "$MDEV_SCRIPT" "$@"
+}
+
+cmd_list_mdev() {
+ log_info "MDEV devices:"
+ ls -la /sys/bus/mdev/devices/ 2>/dev/null || log_warn "No mdev devices"
+}
+
+# ============================================================
+# QEMU COMMANDS
+# ============================================================
+
+cmd_launch_qemu() {
+ log_info "Launching QEMU with vGPU..."
+ if [[ ! -f "$QEMU_SCRIPT" ]]; then
+ log_err "launch_qemu_vgpu.sh not found"
+ return 1
+ fi
+ "$QEMU_SCRIPT" "$@"
+}
+
+# ============================================================
+# TEST COMMANDS
+# ============================================================
+
+cmd_test_stack() {
+ log_info "Running comprehensive test suite..."
+ if [[ ! -f "$TEST_SCRIPT" ]]; then
+ log_err "test_vgpu_stack.sh not found"
+ return 1
+ fi
+ "$TEST_SCRIPT" "$@"
+}
+
+# ============================================================
+# STATUS / DEBUG
+# ============================================================
+
+cmd_status() {
+ echo "=== Kernel Modules ==="
+ lsmod | grep -E "nvidia|open_iov|vfio|mdev" || echo " (none)"
+ echo ""
+ echo "=== MDEV Devices ==="
+ ls -la /sys/bus/mdev/devices/ 2>/dev/null || echo " (none)"
+ echo ""
+ echo "=== VFIO Devices ==="
+ ls -la /dev/vfio/ 2>/dev/null || echo " (none)"
+ echo ""
+ echo "=== Firmware ==="
+ ls -la "$FIRMWARE_DEST" 2>/dev/null || echo " Not installed"
+ echo ""
+ echo "=== dmesg (last 20) ==="
+ sudo dmesg -T | grep -i -e nvidia -e gsp -e vgpu -e open-iov -e mdev | tail -20
+}
+
+cmd_dmesg() {
+ sudo dmesg -T -w | grep -i -e nvidia -e gsp -e vgpu -e open-iov -e mdev
+}
+
+cmd_debug_qemu() {
+ log_info "Starting debug QEMU session..."
+ if [[ ! -f "$BASE_DIR/scripts/debug_guest_init.sh" ]]; then
+ log_err "debug_guest_init.sh not found"
+ return 1
+ fi
+ "$BASE_DIR/scripts/debug_guest_init.sh" "$@"
+}
+
+cmd_cleanup_crash() {
+ log_info "Cleaning up after crash..."
+ cmd_unload_stack
+ log_info "Clearing any stuck mdev devices..."
+ for mdev in /sys/bus/mdev/devices/*; do
+ [[ -e "$mdev" ]] || continue
+ uuid=$(basename "$mdev")
+ echo 1 | sudo tee "$mdev/remove" >/dev/null 2>&1 || true
+ done
+ log_ok "Cleanup complete"
+}
+
+# ============================================================
+# HELP
+# ============================================================
+
+cmd_help() {
+ cat <<EOF
+stack_manager.sh - Complete vGPU Stack Management
+
+USAGE:
+ ./stack_manager.sh <command> [options]
+
+BUILD COMMANDS (run in order):
+ build-kernel Build open-iov-vfio.ko (generates Module.symvers)
+ build-nvidia Build NVIDIA OpenRM with KBUILD_EXTRA_SYMBOLS
+ build-userspace Build libiov.so + examples
+ build-all Run all three build steps in correct order
+
+LOAD COMMANDS (run in order):
+ load-prereqs Load vfio, vfio_iommu_type1, vfio_pci, mdev, vfio_mdev
+ load-open-iov Load open-iov-vfio.ko
+ load-nvidia Load nvidia.ko (OpenRM)
+ install-firmware Copy GSP firmware to /lib/firmware/
+ load-stack Run all four load steps in correct order
+
+FULL CYCLE:
+ up Build all + load stack + create mdev (one command!)
+
+MDEV COMMANDS:
+ mdev-create Create mdev device
+ mdev-list List mdev devices
+
+QEMU COMMANDS:
+ qemu Launch QEMU with vGPU
+ qemu-debug Launch QEMU with GDB + guest monitor
+
+TEST COMMANDS:
+ test Run comprehensive test suite
+
+STATUS / DEBUG:
+ status Show current stack status
+ dmesg Follow filtered dmesg output
+ cleanup-crash Emergency cleanup after crash/hang
+ help Show this help
+
+EXAMPLES:
+ # Full startup from clean state:
+ ./stack_manager.sh up
+
+ # Step by step:
+ ./stack_manager.sh build-all
+ ./stack_manager.sh load-stack
+ ./stack_manager.sh mdev-create
+ ./stack_manager.sh qemu
+
+ # Or just load (if already built):
+ ./stack_manager.sh load-stack
+ ./stack_manager.sh mdev-create
+ ./stack_manager.sh qemu
+
+ # Testing:
+ ./stack_manager.sh test
+
+ # Cleanup:
+ ./stack_manager.sh unload
+ # Or force cleanup after crash:
+ ./stack_manager.sh cleanup-crash
+
+NOTE:
+ - Requires root for module operations
+ - BUILD ORDER: open-iov-vfio.ko FIRST (generates Module.symvers),
+ THEN nvidia.ko with KBUILD_EXTRA_SYMBOLS
+ - LOAD ORDER: vfio/mdev prerequisites -> open-iov-vfio.ko -> nvidia.ko
+ - UNLOAD ORDER: remove mdevs -> open-iov-vfio.ko -> nvidia.ko
+ - NEVER REBOOT without explicit approval
+EOF
+}
+
+main() {
+ case "${1:-help}" in
+ # Build
+ build-kernel) cmd_build_kernel ;;
+ build-nvidia) cmd_build_nvidia ;;
+ build-userspace) cmd_build_userspace ;;
+ build-all) cmd_build_all ;;
+
+ # Load
+ load-prereqs) cmd_load_prereqs ;;
+ load-open-iov) cmd_load_open_iov ;;
+ load-nvidia) cmd_load_nvidia ;;
+ install-firmware) cmd_install_firmware ;;
+ load-stack) cmd_load_stack ;;
+
+ # Full cycle
+ up) cmd_up ;;
+
+ # Unload
+ unload) cmd_unload_stack ;;
+
+ # MDEV
+ mdev-create) shift; cmd_create_mdev "$@" ;;
+ mdev-list) cmd_list_mdev ;;
+
+ # QEMU
+ qemu) shift; cmd_launch_qemu "$@" ;;
+ qemu-debug) shift; cmd_debug_qemu "$@" ;;
+
+ # Test
+ test) shift; cmd_test_stack "$@" ;;
+
+ # Status/Debug
+ status) cmd_status ;;
+ dmesg) cmd_dmesg ;;
+ cleanup-crash) cmd_cleanup_crash ;;
+ help|*) cmd_help ;;
+ esac
+}
+
+main "$@" \ No newline at end of file