Skip to content

Commit f942e01

Browse files
pncclaude
andcommitted
Add HVF→TCG fallback on macOS, force TCG in CI
GitHub-hosted macOS runners don't support HVF (QEMU aborts with HV_UNSUPPORTED). DarwinBackend now auto-detects HVF via sysctl and falls back to TCG, matching LinuxBackend's KVM detection pattern. QEMU_ACCEL env var overrides detection for CI or debugging. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a6558f5 commit f942e01

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
5454
e2e-macos:
5555
runs-on: macos-latest
56-
timeout-minutes: 15
56+
timeout-minutes: 20
5757
steps:
5858
- uses: actions/checkout@v4
5959
- name: Install uv
@@ -68,6 +68,7 @@ jobs:
6868
run: uv run pytest tests/test_e2e.py -v -s
6969
env:
7070
VM_STATE_DIR: ${{ runner.temp }}/vm-state
71+
QEMU_ACCEL: tcg # HVF is unavailable on GitHub-hosted macOS runners
7172

7273
- name: Upload logs on failure
7374
if: failure()

vm.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,18 +147,27 @@ def launch_qemu(self, qemu_args: list[str]) -> subprocess.Popen:
147147
# ---------------------------------------------------------------------------
148148

149149
class DarwinBackend(Backend):
150-
"""macOS backend: HVF acceleration, Homebrew firmware paths."""
150+
"""macOS backend: HVF acceleration (with TCG fallback), Homebrew firmware paths."""
151151

152152
def __init__(self, brew: Path, arch: Arch, proxy_port: int = PROXY_PORT,
153153
ssh_host_port: int = SSH_HOST_PORT) -> None:
154154
super().__init__(arch, proxy_port, ssh_host_port)
155155
self._brew = brew
156+
override = os.environ.get("QEMU_ACCEL")
157+
if override:
158+
self._accel = override
159+
else:
160+
r = subprocess.run(["sysctl", "-n", "kern.hv_support"],
161+
capture_output=True, text=True)
162+
self._accel = "hvf" if r.returncode == 0 and r.stdout.strip() == "1" else "tcg"
156163

157164
@property
158165
def machine_args(self) -> list[str]:
159166
if self.arch == Arch.ARM64:
160-
return ["-machine", "virt,accel=hvf", "-cpu", "host"]
161-
return ["-machine", "q35,accel=hvf", "-cpu", "host"]
167+
cpu = "host" if self._accel == "hvf" else "cortex-a57"
168+
return ["-machine", f"virt,accel={self._accel}", "-cpu", cpu]
169+
cpu = "host" if self._accel == "hvf" else "qemu64"
170+
return ["-machine", f"q35,accel={self._accel}", "-cpu", cpu]
162171

163172
def prepare_efi(self, state_dir: Path) -> tuple[Path, Path]:
164173
code_src = self._brew / "share/qemu/edk2-aarch64-code.fd"

0 commit comments

Comments
 (0)