Files
vfio-native/scripts/install-modules.sh

53 lines
1.9 KiB
Bash
Executable File

#!/bin/bash
# Install patched KVM modules for the RUNNING kernel and prove they went live.
#
# install-modules.sh [dir] dir holds the built kvm*.ko, default arch/x86/kvm
#
# Modules land in updates/, which modprobe prefers over kernel/. On Arch the
# vfio-native-kvm package does all of this; this script is the manual path.
# Back out with restore-stock-kvm.sh.
set -euo pipefail
SRC=${1:-arch/x86/kvm}
KVER=$(uname -r)
DEST=/usr/lib/modules/$KVER/updates
[ "$EUID" -eq 0 ] || { echo "run as root"; exit 1; }
if virsh -c qemu:///system list --state-running --name 2>/dev/null | grep -q .; then
echo "a domain is running; modprobe -r kvm needs the refcount at zero"; exit 1
fi
VENDOR=$(lsmod | grep -oE '^kvm_(amd|intel)' | head -1)
[ -n "$VENDOR" ] || { echo "neither kvm_amd nor kvm_intel is loaded"; exit 1; }
# vermagic must match the running kernel exactly or the module will silently not load
want="$KVER SMP preempt mod_unload"
found=0
for m in kvm kvm-amd kvm-intel; do
[ -f "$SRC/$m.ko" ] || continue
got=$(modinfo -F vermagic "$SRC/$m.ko" | tr -s ' ' | sed 's/ *$//')
[ "$got" = "$want" ] || { echo "vermagic mismatch on $m: '$got' != '$want'"; exit 1; }
found=1
done
[ "$found" = 1 ] || { echo "no kvm modules found in $SRC"; exit 1; }
install -d "$DEST"
for m in kvm kvm-amd kvm-intel; do
[ -f "$SRC/$m.ko" ] || continue
zstd -q -f -19 "$SRC/$m.ko" -o "$DEST/$m.ko.zst"
echo "installed $DEST/$m.ko.zst"
done
depmod -a "$KVER"
modprobe -r "$VENDOR" kvm
modprobe "$VENDOR"
# Check BOTH. The #GP fix lands in svm.c (kvm-amd.ko) and the hypercall fixes in
# emulate.c/x86.c (kvm.ko), so verifying one passes on a stale build of the other.
for m in kvm "$VENDOR"; do
built=$(modinfo -F srcversion "$SRC/${m//_/-}.ko")
live=$(cat "/sys/module/$m/srcversion")
echo "$m built=$built live=$live"
[ "$built" = "$live" ] || { echo "FATAL: patched $m is NOT live"; exit 1; }
done
echo "OK - patched modules are live"