feat(quickemu): warn on unstable TSC for macOS Ventura+ on AMD
- Add check_macos_tsc_stability() to detect unstable TSC on Linux hosts with AuthenticAMD CPUs when launching macOS Ventura+ guests - Log a clear warning to the VM log and prompt interactively to continue or abort to avoid guest freezes - Abort by default in non-interactive mode to prevent unattended VM hangs - Add --ignore-tsc-warning to bypass the check and invoke the check during vm_boot so it runs early in startup Closes #1273 Signed-off-by: Martin Wimpress <martin@wimpress.org>
This commit is contained in:
parent
086128530f
commit
b0e643d1c3
94
quickemu
94
quickemu
|
|
@ -38,6 +38,94 @@ function ignore_msrs_alert() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check for TSC instability that can cause macOS Ventura+ to freeze on AMD Ryzen mobile CPUs.
|
||||||
|
# Returns 0 if check passes or user acknowledges warning, exits with 1 if user aborts.
|
||||||
|
# Reference: https://github.com/quickemu-project/quickemu/issues/1273
|
||||||
|
function check_macos_tsc_stability() {
|
||||||
|
# Gate 1: Only on Linux hosts
|
||||||
|
if [ "${OS_KERNEL}" != "Linux" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Gate 2: Only for AMD CPUs
|
||||||
|
if [ "${HOST_CPU_VENDOR}" != "AuthenticAMD" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Gate 3: Only for macOS guests
|
||||||
|
if [ "${guest_os}" != "macos" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Gate 4: Only for macOS Ventura (13) and newer
|
||||||
|
case ${macos_release} in
|
||||||
|
ventura|sonoma|sequoia|tahoe) ;;
|
||||||
|
*) return 0 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Gate 5: Skip if user has already set tsc=reliable in kernel cmdline
|
||||||
|
local cmdline=""
|
||||||
|
if [ -r /proc/cmdline ]; then
|
||||||
|
cmdline=$(cat /proc/cmdline)
|
||||||
|
if [[ "${cmdline}" == *"tsc=reliable"* ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Gate 6: Check if TSC is the current clocksource (indicates stable TSC)
|
||||||
|
local clocksource_path="/sys/devices/system/clocksource/clocksource0/current_clocksource"
|
||||||
|
local current_clocksource=""
|
||||||
|
if [ -r "${clocksource_path}" ]; then
|
||||||
|
current_clocksource=$(cat "${clocksource_path}")
|
||||||
|
if [ "${current_clocksource}" == "tsc" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Cannot determine clocksource - assume OK and let user discover issues
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# All gates failed - this system is at risk
|
||||||
|
# Check if warning should be skipped
|
||||||
|
if [ "${IGNORE_TSC_WARNING}" == "1" ]; then
|
||||||
|
echo " - TSC: WARNING! Unstable TSC detected (clocksource: ${current_clocksource})"
|
||||||
|
echo " Proceeding anyway due to --ignore-tsc-warning flag."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Display warning and prompt user
|
||||||
|
echo " - TSC: WARNING! Unstable TSC detected (clocksource: ${current_clocksource})"
|
||||||
|
echo " macOS ${macos_release^} may freeze on AMD Ryzen mobile CPUs."
|
||||||
|
echo
|
||||||
|
echo " Fix: Add 'tsc=reliable' to kernel boot parameters and reboot."
|
||||||
|
echo " Or: Use macOS Big Sur (11) or Monterey (12) instead."
|
||||||
|
echo " See: https://github.com/quickemu-project/quickemu/wiki/03-Create-macOS-virtual-machines#tsc-instability-on-amd-ryzen-mobile-cpus"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Log the warning
|
||||||
|
echo "TSC_WARNING: clocksource=${current_clocksource} macos_release=${macos_release} cpu_vendor=${HOST_CPU_VENDOR}" >> "${VMDIR}/${VMNAME}.log"
|
||||||
|
|
||||||
|
# Interactive prompt - check if stdin is a terminal
|
||||||
|
if [ -t 0 ]; then
|
||||||
|
echo -n "Do you want to continue anyway? [y/N] "
|
||||||
|
read -r response
|
||||||
|
case "${response}" in
|
||||||
|
[yY]|[yY][eE][sS])
|
||||||
|
echo " - TSC: Proceeding despite unstable TSC warning."
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo " - TSC: Aborting. Please apply one of the solutions above."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
# Non-interactive mode - abort by default for safety
|
||||||
|
echo "ERROR! Non-interactive mode detected. Use --ignore-tsc-warning to bypass this check."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
function delete_shortcut() {
|
function delete_shortcut() {
|
||||||
local SHORTCUT_DIR="${HOME}/.local/share/applications"
|
local SHORTCUT_DIR="${HOME}/.local/share/applications"
|
||||||
if [ -e "${SHORTCUT_DIR}/${VMNAME}.desktop" ]; then
|
if [ -e "${SHORTCUT_DIR}/${VMNAME}.desktop" ]; then
|
||||||
|
|
@ -1364,6 +1452,7 @@ function vm_boot() {
|
||||||
|
|
||||||
configure_cpu
|
configure_cpu
|
||||||
configure_ram
|
configure_ram
|
||||||
|
check_macos_tsc_stability
|
||||||
configure_bios
|
configure_bios
|
||||||
configure_os_quirks
|
configure_os_quirks
|
||||||
configure_storage
|
configure_storage
|
||||||
|
|
@ -1848,6 +1937,7 @@ function usage() {
|
||||||
echo " --display : Select display backend. 'sdl' (default), 'cocoa', 'gtk', 'none', 'spice' or 'spice-app'"
|
echo " --display : Select display backend. 'sdl' (default), 'cocoa', 'gtk', 'none', 'spice' or 'spice-app'"
|
||||||
echo " --fullscreen : Starts VM in full screen mode (Ctl+Alt+f to exit)"
|
echo " --fullscreen : Starts VM in full screen mode (Ctl+Alt+f to exit)"
|
||||||
echo " --ignore-msrs-always : Configure KVM to always ignore unhandled machine-specific registers"
|
echo " --ignore-msrs-always : Configure KVM to always ignore unhandled machine-specific registers"
|
||||||
|
echo " --ignore-tsc-warning : Skip TSC stability warning for macOS VMs on AMD"
|
||||||
echo " --kill : Kill the VM process if it is running"
|
echo " --kill : Kill the VM process if it is running"
|
||||||
echo " --offline : Override all network settings and start the VM offline"
|
echo " --offline : Override all network settings and start the VM offline"
|
||||||
echo " --shortcut : Create a desktop shortcut"
|
echo " --shortcut : Create a desktop shortcut"
|
||||||
|
|
@ -2110,6 +2200,7 @@ sound_duplex="${sound_duplex:-hda-micro}"
|
||||||
ACCESS=""
|
ACCESS=""
|
||||||
ACTIONS=()
|
ACTIONS=()
|
||||||
BRAILLE=""
|
BRAILLE=""
|
||||||
|
IGNORE_TSC_WARNING=""
|
||||||
CPU_PINNING=""
|
CPU_PINNING=""
|
||||||
FULLSCREEN=""
|
FULLSCREEN=""
|
||||||
MONITOR_CMD=""
|
MONITOR_CMD=""
|
||||||
|
|
@ -2202,6 +2293,9 @@ else
|
||||||
-ignore-msrs-always|--ignore-msrs-always)
|
-ignore-msrs-always|--ignore-msrs-always)
|
||||||
ignore_msrs_always
|
ignore_msrs_always
|
||||||
exit;;
|
exit;;
|
||||||
|
-ignore-tsc-warning|--ignore-tsc-warning)
|
||||||
|
IGNORE_TSC_WARNING="1"
|
||||||
|
shift;;
|
||||||
-kill|--kill)
|
-kill|--kill)
|
||||||
ACTIONS+=(kill_vm)
|
ACTIONS+=(kill_vm)
|
||||||
shift;;
|
shift;;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue