From e63ed72f55f7b68b6f54423297dfc37035747609 Mon Sep 17 00:00:00 2001 From: osy <50960678+osy@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:51:15 -0800 Subject: [PATCH] config(qemu): default x86_64 CPU to highest supported by host We cannot use "-cpu max" because it causes BSOD issues (see #2368). QEMU documentation suggests choosing a CPU model that matches the generation of the host. Luckily for us, XNU already did the difficult work of mapping the CPUID to the generation. Note that Rosetta returns Westmere but AMD based Hackintoshes will still be unsupported and will default to the old CPU model. This change is needed to both improve performance of virtualized CPUs on Intel Macs as well as enable Windows 11 24H2 to be booted as it now requires SSE4.2 support. Fixes #6325 Fixes #6772 --- .../UTMQemuConfiguration+Arguments.swift | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/Configuration/UTMQemuConfiguration+Arguments.swift b/Configuration/UTMQemuConfiguration+Arguments.swift index 8d104a7c1..c2ebd0afb 100644 --- a/Configuration/UTMQemuConfiguration+Arguments.swift +++ b/Configuration/UTMQemuConfiguration+Arguments.swift @@ -294,7 +294,12 @@ import Virtualization // for getting network interfaces if system.cpu.rawValue == system.architecture.cpuType.default.rawValue { // if default and not hypervisor, we don't pass any -cpu argument for x86 and use host for ARM if isHypervisorUsed { - #if !arch(x86_64) + #if arch(x86_64) + if let cpu = highestIntelCPUConfigurationForHost() { + f("-cpu") + f(cpu) + } + #else f("-cpu") f("host") #endif @@ -306,6 +311,9 @@ import Virtualization // for getting network interfaces // ARM64 QEMU does not support "-cpu default" so we hard code a sensible default f("-cpu") f("cortex-a15") + } else if system.architecture == .x86_64, let cpu = highestIntelCPUConfigurationForHost() { + f("-cpu") + f(cpu) } } else { f("-cpu") @@ -1064,6 +1072,32 @@ import Virtualization // for getting network interfaces } } +@MainActor +private extension UTMQemuConfiguration { + #if arch(x86_64) + func highestIntelCPUConfigurationForHost() -> String? { + let cpufamily = Self.sysctlIntRead("hw.cpufamily") + // source: https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/mach/machine.h + switch cpufamily { + case 0x78ea4fbc: return "Penryn" + case 0x6b5a4cd2: return "Nehalem" + case 0x573b5eec: return "Westmere" + case 0x5490b78c: return "SandyBridge" + case 0x1f65e835: return "IvyBridge" + case 0x10b282dc: return "Haswell" + case 0x582ed09c: return "Broadwell" + case 0x37fc219f /* Skylake */, 0x0f817246 /* Kabylake */, 0x1cf8a03e /* Cometlake */: return "Skylake-Client" + case 0x38435547 /* Icelake */: return "Icelake-Server" // client doesn't exist + default: return nil + } + } + #else + func highestIntelCPUConfigurationForHost() -> String? { + return "Skylake-Client" + } + #endif +} + private extension String { func appendingDefaultPropertyName(_ name: String, value: String) -> String { if !self.contains(name + "=") {