53 lines
1.9 KiB
Bash
Executable File
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"
|