Skip to content

arm64, KVM, irqchip/apple-aic: KVM guests on the J813 (M5 MacBook Air) at EL2 - #1728

Merged
DjDeveloperr merged 3 commits into
aurora-silicon:integration/aurorafrom
sithglan:thomas/j813-kvm-el2
Nov 12, 2026
Merged

DjDeveloperr merged 3 commits into
aurora-silicon:integration/aurorafrom
sithglan:thomas/j813-kvm-el2

Conversation

@sithglan

Copy link
Copy Markdown
Contributor

Base: integration/aurora (028d762). Branch thomas/j813-kvm-el2, three commits.

With aura main's padded CTXR execute window (aura#77, docs/macho-boot-object.md "Running the OS"), the J813 (T8142) under the macOS 27.2 stub runs Linux at EL2 on all ten CPUs, and CONFIG_ARM64_CTXR_EXECMEM confines its code to the window. KVM initializes in VHE mode, but no guest got far. These three changes make KVM guests boot.

arm64: errata: treat the T8142 vGIC SEIS as broken, like T6040 and T8140

ICH_VTR_EL2 reads 0x90580007 on all ten J813 CPUs: E cores (part 0x062) and P cores (0x063), at EL2, read with a small module. That's eight list registers with SEIS set, the same value as the T6040, Tahiti and T6050 cores. The two T8142 parts go into apple_broken_seis_cpus. Jens Axboe found the T6050 needs the same, or SMP guests livelock.

KVM: arm64: Fix up ID_AA64PFR1_EL1.MTE_frac only for a VM with MTE

QEMU 11.1 failed to start any KVM guest on the J813, whatever -cpu it was given:
Could not set register ... op0:3 op1:0 crn:0 crm:4 op2:1 to 1 (is 1). That's ID_AA64PFR1_EL1. On this host the sanitised PFR1 is 0x00000f0002000201, which has MTE == MTE2 and MTE_frac == NI. For a VM without MTE, sanitise_id_aa64pfr1_el1() hides both fields, so the vCPU reads 0x1. When userspace writes that back, set_id_aa64pfr1_el1() treats MTE_frac 0 as MTE_ASYNC and replaces it with the host's NI. The result no longer matches the limit, and arm64_check_features() refuses the value KVM itself handed out; KVM_SET_ONE_REG fails with EINVAL even for 0x1. The fix-up is meant for VMs with MTE, so it now applies only to those. This is generic arm64 KVM and would apply to any MTE2-without-ASYM host.

irqchip/apple-aic: Mask T8142 guest timers through VM_TMR_FIQ_ENA_EL2 at EL2 without SPTM

aic3_t8142_info.vm_timer_fiq_readonly (95caa2c) masks the guest timer FIQs by setting IMASK in CNTP_CTL_EL02 and CNTV_CTL_EL02. It was added because the first J813 bring-up, under SPTM, trapped writes to VM_TMR_FIQ_ENA_EL2. But those EL02 registers are the guest's own timer controls: once KVM masks the FIQ, the guest's timer keeps IMASK as guest state, and the guest never gets another timer interrupt. On the J813, UEFI (AAVMF) stalled right after its banner, and Linux guests stalled in their initramfs, with nohlt too.

Without SPTM, at EL2, VM_TMR_FIQ_ENA_EL2 reads 0xf, and a write back succeeds on all ten CPUs. aura publishes /chosen/aurora,ctxr-exec-window exactly when it runs the OS that way. In that case the driver now uses the register; every other boot keeps the EL02 masking.

Testing

On the J813 under 27.2, with aura main + aurora-silicon/aura#192 enrolled as a padded object. The kernel is integration with #1683 and #1696, plus these three, CONFIG_ARM64_CTXR_EXECMEM=y and CONFIG_KVM=y:

  • Boot: "CPU: All CPU(s) started at EL2", execmem-confine boot verify 616 mappings with 0 violations, ten CPUs, "kvm [1]: VHE mode initialized successfully". DCP, GPU, sound and ISP work as at EL1.
  • libvirt/QEMU 11.1.3, -accel kvm -cpu host -M virt,gic-version=3, Debian 13 arm64 nocloud with UEFI:
    • 4 vCPUs: login prompt in about 18 s (35 s under TCG); systemd startup 2.1 s; network up.
    • A CPU-bound shell loop takes 2.62 s in the guest against 2.24 s on the host.
    • 10 vCPUs: login prompt in about 16 s, with the 4-vCPU guest still running.
  • Each of the three commits builds with CONFIG_KVM=y (Image.gz, modules, dtbs; LLVM 22).

cc @Acelogic @DjDeveloperr @RyanTheTide @LiamRay10

ICH_VTR_EL2 on the J813 (MacBook Air M5, T8142, macOS 27.2 stub) reads
0x90580007 at EL2 on all ten CPUs, E (part 0x062) and P (0x063) cores
alike: eight list registers and SEIS set, the value of the other Apple
cores in apple_broken_seis_cpus. Add the two T8142 parts so that KVM
does not trust the locally generated SError the vGIC claims to support,
as for those cores.

With it the kernel reports "Known broken GICv3 SEIS implementation" and
KVM guests with 4 and 10 vCPUs boot on the J813.

Signed-off-by: Thomas Glanzmann <thomas@glanzmann.de>
On a host whose sanitised ID_AA64PFR1_EL1 has MTE == MTE2 and
MTE_frac == NI (0xf), the M5 MacBook Air (T8142) for one, every VMM that
writes the ID registers back after vCPU init fails. QEMU 11.1 reports
"Could not set register ... op0:3 op1:0 crn:0 crm:4 op2:1 to 1 (is 1)",
whatever -cpu it is given.

A VM without MTE sees MTE and MTE_frac as 0: sanitise_id_aa64pfr1_el1()
hides both. Writing that value back, set_id_aa64pfr1_el1() takes the
MTE_frac of 0 for MTE_ASYNC and replaces it with the host's NI. The
result no longer matches the limit, which has MTE_frac cleared, so
arm64_check_features() rejects the value KVM itself provided.

The fix-up exists so that a VM that has MTE can be given back the value
older kernels reported. Apply it only to such a VM.

On the J813 at EL2 (sanitised PFR1 0x00000f0002000201): before, KVM
refused KVM_SET_ONE_REG of the ID_AA64PFR1_EL1 value it had just
returned (0x1); after, QEMU starts KVM guests.

Signed-off-by: Thomas Glanzmann <thomas@glanzmann.de>
… at EL2 without SPTM

T8142 has vm_timer_fiq_readonly: under the SPTM boot of the first J813
bring-up, writes to VM_TMR_FIQ_ENA_EL2 trapped, so the guest timer FIQs
are masked by setting IMASK in CNTP_CTL_EL02 and CNTV_CTL_EL02. Those
are the guest's own timer controls. When KVM masks the guest timer FIQ
around a vCPU load or after the timer fires, the guest's CNTV_CTL keeps
IMASK, KVM saves it as guest state, and the guest gets no timer
interrupt again. On the J813 at EL2 every KVM guest stalls the first
time it waits for a timer: UEFI right after its banner, Linux in its
initramfs.

aura runs the OS at EL2 in a CTXR execute window without SPTM, and says
so with /chosen/aurora,ctxr-exec-window. There VM_TMR_FIQ_ENA_EL2 takes
writes: it reads 0xf and a write back succeeds on all ten J813 CPUs. Use
the register in that case and keep the EL02 masking for the others.

With it, guests boot to a login prompt on the J813 under 27.2: UEFI with
4 vCPUs (libvirt) in about 18 s and 10 vCPUs in about 16 s; the guest
vtimer FIQ is delivered (thousands per CPU, where it had stayed at 2).

Signed-off-by: Thomas Glanzmann <thomas@glanzmann.de>

@DjDeveloperr DjDeveloperr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@DjDeveloperr
DjDeveloperr merged commit f3c5c98 into aurora-silicon:integration/aurora Nov 12, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants