mirror of
https://github.com/dockur/macos.git
synced 2026-10-12 02:13:08 +00:00
218 lines
5.3 KiB
Bash
218 lines
5.3 KiB
Bash
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
|
|
# Present the Intel vendor and CPUID behavior expected by macOS while hiding
|
|
# nested VMX and one-gigabyte pages that are problematic for this guest.
|
|
DEFAULT_FLAGS="vendor=GenuineIntel,vmx=off,vmware-cpuid-freq=on,-pdpe1gb"
|
|
|
|
needsAmdCpuProfile() {
|
|
|
|
# AMD hosts and software emulation both require an explicit Intel-compatible
|
|
# CPU profile instead of passing through the host model.
|
|
isAmdCpu || disabled "${KVM:-}"
|
|
|
|
}
|
|
|
|
checkCpuFeatures() {
|
|
|
|
if ! hasFlag "avx2"; then
|
|
warn "This processor does not support AVX2. macOS versions newer than 13 require an Intel Haswell, AMD Zen, or newer processor."
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
selectAmdCpuModel() {
|
|
|
|
if [ -n "${CPU_MODEL:-}" ]; then
|
|
return 0
|
|
fi
|
|
|
|
# Older macOS releases use the conservative Haswell profile; newer releases
|
|
# receive Skylake plus a mitigation flag only when the host can provide it.
|
|
case "${VERSION,,}" in
|
|
"10"* | "11"* | "12"* | "13"* | \
|
|
"catalina" | "bigsur" | "big-sur" | "monterey" | "ventura" )
|
|
CPU_MODEL="Haswell-noTSX"
|
|
;;
|
|
*)
|
|
CPU_MODEL="Skylake-Client-v4"
|
|
if hasFlag "spec-ctrl" && ! disabled "${KVM:-}"; then
|
|
DEFAULT_FLAGS+=",+spec-ctrl"
|
|
else
|
|
DEFAULT_FLAGS+=",-spec-ctrl"
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
return 0
|
|
}
|
|
|
|
appendAmdCpuFlags() {
|
|
|
|
local flag
|
|
|
|
# TCG cannot expose several timing and XSAVE features reliably. Under KVM,
|
|
# mirror each optional feature from the actual host instead.
|
|
if disabled "${KVM:-}"; then
|
|
|
|
DEFAULT_FLAGS+=",-pcid,-invpcid,-tsc-deadline,-xsavec,-xsaves"
|
|
|
|
else
|
|
|
|
for flag in pcid invpcid tsc-deadline xsavec xsaves; do
|
|
if hasFlag "$flag"; then
|
|
DEFAULT_FLAGS+=",+$flag"
|
|
else
|
|
DEFAULT_FLAGS+=",-$flag"
|
|
fi
|
|
done
|
|
|
|
fi
|
|
|
|
# Advertise the instruction set expected by the selected macOS CPU profile;
|
|
# QEMU's check option rejects combinations the accelerator cannot support.
|
|
DEFAULT_FLAGS+=",+ssse3,+sse4.2,+popcnt,+avx,+avx2,+aes,+fma,+bmi1,+bmi2,+smep,+xsave,+xsaveopt,+xgetbv1,+movbe,+rdrand,check"
|
|
|
|
return 0
|
|
}
|
|
|
|
configureAmdCpu() {
|
|
|
|
# Configuration for AMD processors
|
|
selectAmdCpuModel
|
|
appendAmdCpuFlags
|
|
|
|
return 0
|
|
}
|
|
|
|
configureIntelCpu() {
|
|
|
|
# Configuration for Intel processors
|
|
if [ -z "${CPU_MODEL:-}" ]; then
|
|
CPU_MODEL="Skylake-Client-v4"
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
composeCpuFlags() {
|
|
|
|
# Append user flags after the required defaults so explicit feature
|
|
# overrides retain their normal last-value-wins behavior.
|
|
if [ -z "${CPU_FLAGS:-}" ]; then
|
|
CPU_FLAGS="$DEFAULT_FLAGS"
|
|
else
|
|
CPU_FLAGS="$DEFAULT_FLAGS,$CPU_FLAGS"
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
selectClocksource() {
|
|
|
|
SM_BIOS=""
|
|
CLOCKSOURCE="tsc"
|
|
|
|
# Native x86 expects TSC; an ARM host running the x86 guest through
|
|
# emulation is validated against its architectural counter instead.
|
|
[[ "${ARCH,,}" == "arm64" ]] && CLOCKSOURCE="arch_sys_counter"
|
|
|
|
return 0
|
|
}
|
|
|
|
checkClocksource() {
|
|
|
|
local result
|
|
local clock="/sys/devices/system/clocksource/clocksource0/current_clocksource"
|
|
|
|
if [ ! -f "$clock" ]; then
|
|
warn "file \"$clock\" cannot be found?"
|
|
return 0
|
|
fi
|
|
|
|
result=$(<"$clock")
|
|
result="${result//[![:print:]]/}"
|
|
|
|
case "${result,,}" in
|
|
"${CLOCKSOURCE,,}" ) ;;
|
|
"kvm-clock" )
|
|
warn "Nested KVM virtualization detected, this might cause issues running macOS!"
|
|
;;
|
|
"hyperv_clocksource_tsc_page" )
|
|
info "Nested Hyper-V virtualization detected, this might cause issues running macOS!"
|
|
;;
|
|
"hpet" )
|
|
warn "unsupported clock source detected: '$result'. Please set host clock source to '$CLOCKSOURCE', otherwise it will cause issues running macOS!"
|
|
;;
|
|
* )
|
|
warn "unexpected clock source detected: '$result'. Please set host clock source to '$CLOCKSOURCE', otherwise it will cause issues running macOS!"
|
|
;;
|
|
esac
|
|
|
|
return 0
|
|
}
|
|
|
|
normalizeCpuCores() {
|
|
|
|
# Round unsupported near-power-of-two requests down to the closest stable
|
|
# topology before the stricter SMP layout selection below.
|
|
case "$CPU_CORES" in
|
|
"" | "0" | "3" ) CPU_CORES="2" ;;
|
|
"5" ) CPU_CORES="4" ;;
|
|
"9" ) CPU_CORES="8" ;;
|
|
esac
|
|
|
|
return 0
|
|
}
|
|
|
|
configureSmp() {
|
|
|
|
# Describe larger counts using socket/core combinations accepted by macOS
|
|
# instead of exposing every requested vCPU as an arbitrary topology.
|
|
case "$CPU_CORES" in
|
|
"1" | "2" | "4" | "8" ) SMP="$CPU_CORES,sockets=1,dies=1,cores=$CPU_CORES,threads=1" ;;
|
|
"6" | "7" ) SMP="$CPU_CORES,sockets=3,dies=1,cores=2,threads=1" ;;
|
|
"10" | "11" ) SMP="$CPU_CORES,sockets=5,dies=1,cores=2,threads=1" ;;
|
|
"12" | "13" ) SMP="$CPU_CORES,sockets=3,dies=1,cores=4,threads=1" ;;
|
|
"14" | "15" ) SMP="$CPU_CORES,sockets=7,dies=1,cores=2,threads=1" ;;
|
|
"16" | "24" | "32" | "64" ) SMP="$CPU_CORES,sockets=1,dies=1,cores=$CPU_CORES,threads=1" ;;
|
|
*)
|
|
error "Invalid amount of CPU_CORES, value \"${CPU_CORES}\" is not a power of 2!" && exit 35
|
|
;;
|
|
esac
|
|
|
|
return 0
|
|
}
|
|
|
|
configureUsb() {
|
|
|
|
# macOS has broad compatibility with the NEC xHCI model, but MSI must be
|
|
# disabled for reliable keyboard and controller initialization.
|
|
USB="nec-usb-xhci,id=xhci"
|
|
USB+=" -device usb-kbd,bus=xhci.0"
|
|
USB+=" -global nec-usb-xhci.msi=off"
|
|
|
|
return 0
|
|
}
|
|
|
|
checkCpuFeatures
|
|
|
|
if needsAmdCpuProfile; then
|
|
configureAmdCpu
|
|
else
|
|
configureIntelCpu
|
|
fi
|
|
|
|
composeCpuFlags
|
|
|
|
selectClocksource
|
|
checkClocksource
|
|
|
|
normalizeCpuCores
|
|
|
|
configureSmp
|
|
configureUsb
|
|
|
|
return 0
|