blob: c4685dac058fc915f476542ddc0732005bd0e29d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
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:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
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 "$@"
|