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
|
||||
}
|
||||
|
||||
# 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() {
|
||||
local SHORTCUT_DIR="${HOME}/.local/share/applications"
|
||||
if [ -e "${SHORTCUT_DIR}/${VMNAME}.desktop" ]; then
|
||||
|
|
@ -1364,6 +1452,7 @@ function vm_boot() {
|
|||
|
||||
configure_cpu
|
||||
configure_ram
|
||||
check_macos_tsc_stability
|
||||
configure_bios
|
||||
configure_os_quirks
|
||||
configure_storage
|
||||
|
|
@ -1848,6 +1937,7 @@ function usage() {
|
|||
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 " --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 " --offline : Override all network settings and start the VM offline"
|
||||
echo " --shortcut : Create a desktop shortcut"
|
||||
|
|
@ -2110,6 +2200,7 @@ sound_duplex="${sound_duplex:-hda-micro}"
|
|||
ACCESS=""
|
||||
ACTIONS=()
|
||||
BRAILLE=""
|
||||
IGNORE_TSC_WARNING=""
|
||||
CPU_PINNING=""
|
||||
FULLSCREEN=""
|
||||
MONITOR_CMD=""
|
||||
|
|
@ -2202,6 +2293,9 @@ else
|
|||
-ignore-msrs-always|--ignore-msrs-always)
|
||||
ignore_msrs_always
|
||||
exit;;
|
||||
-ignore-tsc-warning|--ignore-tsc-warning)
|
||||
IGNORE_TSC_WARNING="1"
|
||||
shift;;
|
||||
-kill|--kill)
|
||||
ACTIONS+=(kill_vm)
|
||||
shift;;
|
||||
|
|
|
|||
Loading…
Reference in New Issue