feat(cpuid): automate the passthrough toggle around enabled guests
This commit is contained in:
41
scripts/cpuid-passthrough-watch
Executable file
41
scripts/cpuid-passthrough-watch
Executable file
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
# Waits for a just-started guest's network to actually come up, then turns
|
||||
# kvm_amd cpuid_passthrough on.
|
||||
#
|
||||
# The readiness signal is the guest's own tap RX counter: it is fresh every boot,
|
||||
# it needs nothing enabled inside the guest (no SSH, no RDP, no agent), and it only
|
||||
# moves once the guest's NIC driver has really loaded - which is well past the CPU
|
||||
# enumeration that the switch must not change under. A DHCP lease left over from a
|
||||
# previous boot cannot trip it early.
|
||||
#
|
||||
# Launched as a transient systemd unit by the cpuid-passthrough hook, so it is free
|
||||
# to call virsh (the hook itself must not - that deadlocks libvirtd).
|
||||
|
||||
DOMAIN=$1
|
||||
BRAND=$2
|
||||
PARAM=/sys/module/kvm_amd/parameters
|
||||
V="virsh -c qemu:///system"
|
||||
|
||||
running() { [ "$($V domstate "$DOMAIN" 2>/dev/null)" = running ]; }
|
||||
|
||||
tap=""
|
||||
i=0
|
||||
for _ in $(seq 1 65); do # ~195 s cap, then flip anyway if still up
|
||||
i=$((i + 1))
|
||||
running || { sleep 3; continue; } # not "running" yet at prepare time - wait
|
||||
[ -z "$tap" ] && tap=$($V domiflist "$DOMAIN" 2>/dev/null |
|
||||
awk '$1 ~ /^(vnet|tap|macvtap)/ {print $1; exit}')
|
||||
rx="/sys/class/net/$tap/statistics/rx_packets"
|
||||
# the iteration floor keeps a stray pre-OS packet (a UEFI netboot attempt) from
|
||||
# tripping the flip before the guest is even past its interrupt and timer setup
|
||||
if [ "$i" -ge 4 ] && [ -n "$tap" ] && [ -r "$rx" ] &&
|
||||
[ "$(cat "$rx" 2>/dev/null || echo 0)" -ge 4 ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
|
||||
running || exit 0 # guest went away before it came up
|
||||
printf '%s' "$BRAND" > "$PARAM/brand_string"
|
||||
echo Y > "$PARAM/cpuid_passthrough"
|
||||
logger -t vfio-cpuid "$DOMAIN network up: cpuid_passthrough=Y"
|
||||
Reference in New Issue
Block a user