Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions quickemu
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1364,6 +1452,7 @@ function vm_boot() {

configure_cpu
configure_ram
check_macos_tsc_stability
configure_bios
configure_os_quirks
configure_storage
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -2110,6 +2200,7 @@ sound_duplex="${sound_duplex:-hda-micro}"
ACCESS=""
ACTIONS=()
BRAILLE=""
IGNORE_TSC_WARNING=""
CPU_PINNING=""
FULLSCREEN=""
MONITOR_CMD=""
Expand Down Expand Up @@ -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;;
Expand Down
Loading