Skip to content

Darwin/ARM64: integrate native GIC and EL2 timers for nested KVM - #916

Draft
trikesh32 wants to merge 1 commit into
VirtualBox:mainfrom
trikesh32:915-darwin-arm64-nested-kvm
Draft

trikesh32 wants to merge 1 commit into
VirtualBox:mainfrom
trikesh32:915-darwin-arm64-nested-kvm

Conversation

@trikesh32

Copy link
Copy Markdown

Enabling --nested-hw-virt on on an Apple M3 Pro with stock VirtualBox 7.2.20 fails at PC=0 with VERR_NOT_SUPPORTED while synchronizing CNTHP registers. With these integration changes, a source-built headless VirtualBox and ARM64 firmware boot Debian at EL2, initialize KVM, and boot and power off an ARM64 Linux L2 using explicit -accel kvm.

Refs #915, which contains the source-build QMP result, nested console output, L1 KVM initialization, and nested-off evidence.

This draft connects the existing native Apple GIC backend to nested EL2:

  • Select native GIC for Darwin/ARM64 nested configurations, create it before vCPUs, require available EL2/native-GIC support, and reject the unsupported GIC ITS combination.
  • Avoid the software IRQ/FIQ pending-interrupt API when native GIC owns delivery. Correct the old-SDK GIC INTID enum.
  • Add separate stored mappings for CNTHCTL_EL2 and MDCCINT_EL1, with write-ignore masks of zero, plus a RAZ/WI LORC_EL1 entry. Existing debug-register mappings remain intact.
  • Select SMC PSCI and describe maintenance INTID 25 in DT and ACPI for Darwin nested configurations. Correct the swapped ACPI physical/hypervisor timer IDs to 30/26, matching DT.
  • Add a VirtualBox firmware timer library using CNTHP/CNTPCT at EL2 and CNTV/CNTVCT at EL1, selected through the existing VBOX integration point. Document the host requirements in the command reference.

Validation completed on the official 7.2.20 source release, Apple M3 Pro, macOS 26.7:

  • Full headless host and ARM64 EDK2 firmware builds; the rebuilt firmware was embedded in VBoxDD2.
  • Debian 13 L1, kernel 6.12.111+deb13-arm64, two vCPUs at EL2; KVM initialization and /dev/kvm.
  • QEMU 10.0.13, one-vCPU/256 MB Linux/BusyBox L2: QMP query-kvm returned {"enabled":true,"present":true}, both NESTED_KVM_LINUX_BOOT_OK and NESTED_KVM_TEST_COMPLETE appeared, and QEMU exited 0 after poweroff.
  • A cold nested-off boot also passed with software GIC, both L1 CPUs at EL1, and HYP mode not available.

The patch applies to this PR's base a85a9b457af490dade7671c2c99de1db899804e1; that main revision has not been built or runtime-tested. Preparing this branch added only comments and whitespace changes to the tested patch. git diff --check passes. The scm attempt could not establish a style pass because SVN is unavailable in this checkout.

To validate manually:

  1. Build the host and build-efi-arm64 target. Ensure the newly built QEMU_EFI.fd is embedded in VBoxDD2; the ordinary host build can otherwise use the prebuilt firmware.
  2. Sign the experimental host binaries with the Hypervisor.framework entitlement and use an isolated VirtualBox profile and a disposable ARM64 Debian VM.
  3. Enable --nested-hw-virt on, boot Debian, and check EL2/KVM initialization and /dev/kvm.
  4. Boot an ARM64 Linux kernel and BusyBox initramfs with qemu-system-aarch64 -accel kvm -machine virt,gic-version=3 -cpu host -smp 1 -m 256, a serial console, and QMP. Require query-kvm enabled/present, actual L2 execution, and normal shutdown. The complete tested command and output are in [Req]: Darwin/ARM64 nested KVM: source-built proof and integration fixes #915.
  5. Power off, disable nested virtualization, and cold-boot again to check the EL1/software-GIC path.

Build/runtime qualifications: the tested local macOS build required separate build-tool adaptations and two XPCOM fixes from Roberto Nibali's #747 (cc84c586c87ca34b2ac0a7ce6bad147a83afb0aa, d10be7f8f93339c744aaf6c52527990024958ef7). Those changes are excluded from this PR and are not attributed to this contribution. Successful source runtime tests used VBoxInternal/PDM/AsyncCompletion/File/IoMgr=Simple after an async-I/O stall. The installed VBoxManage served only as the guest-control IPC client because source CLI password-file authentication failed; the executing Headless, VBoxC, VMM, and embedded firmware were all source-built.

Review is still needed for register masks/feature exposure, timer/PPI ownership, compatibility gating, and saved-state handling. An L1 warning concerning PPI INTID 30 remains. Individual necessity of the native-GIC IRQ/FIQ guard was not isolated by an ablation test. No L2 SMP, stress, save/restore, snapshot, migration, or other host/OS coverage is claimed. The ACPI timer correction also affects ARM configurations outside Darwin nested mode and needs broader validation. No public API or .xidl changes.

OCA status: formal signing/verification is pending; the OCA portal returned a technical error. This is a draft for technical review, not ready for acceptance under CONTRIBUTING.md.

Select native Apple GIC and SMC PSCI for nested configurations, supply
trapped register mappings, and align DT/ACPI interrupt descriptions.
Use CNTHP and the physical counter in EL2 firmware while preserving
the EL1 virtual timer path. Document host and GIC ITS requirements.

Validated with a source-built 7.2.20 headless host and ARM64 firmware:
Debian initializes KVM, and an explicit -accel kvm Linux L2 boots and
powers off. A cold nested-off boot also succeeds.

Refs VirtualBox#915
@oracle-contributor-agreement

Copy link
Copy Markdown

Thank you for your pull request and welcome to our community! To contribute, please sign the Oracle Contributor Agreement (OCA).
The following contributors of this PR have not signed the OCA:

To sign the OCA, please create an Oracle account and sign the OCA in Oracle's Contributor Agreement Application.

When signing the OCA, please provide your GitHub username. After signing the OCA and getting an OCA approval from Oracle, this PR will be automatically updated.

If you are an Oracle employee, please make sure that you are a member of the main Oracle GitHub organization, and your membership in this organization is public.

@oracle-contributor-agreement oracle-contributor-agreement Bot added the OCA Required At least one contributor does not have an approved Oracle Contributor Agreement. label Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OCA Required At least one contributor does not have an approved Oracle Contributor Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant