Skip to content

runtime: aarch64: do not use DC ZVA while the MMU is off - #2183

Merged
francescolavra merged 1 commit into
nanovms:masterfrom
AngeloRubens:aarch64-zva-mmu
Oct 10, 2026
Merged

francescolavra merged 1 commit into
nanovms:masterfrom
AngeloRubens:aarch64-zva-mmu

Conversation

@AngeloRubens

Copy link
Copy Markdown
Contributor

DC ZVA requires Normal memory. While the MMU is off every access is Device
memory, where the instruction faults whatever DCZID_EL0.DZP reports.

The kernel runs in exactly that state between the UEFI loader clearing
SCTLR_EL1 and enable_mmu() turning translation back on, so any zero() call in
that window takes a synchronous exception on real hardware. QEMU does not
enforce the restriction, so the same image boots there either way.

Observed on a VM.Standard.A1.Flex instance in eu-milan-1:

Synchronous Exception at 0x0000000040488E54

which the disassembly of the running kernel resolves to the dc zva instruction
in zero(). With the check added, the same image boots and serves requests.

The change adds SCTLR_EL1.M to the condition that already tests DZP, and leaves
the body of the fast path untouched.

Console of the instance, captured with oci compute console-history, before the
change:

Starting Boot0002 "UEFI ORACLE BlockVolume " from PciRoot(0x0)/Pci(0x5,0x7)/Pci(0x0,0x0)/Scsi(0x0,0x1)
EFI ExitBootServices: Called.

Synchronous Exception at 0x0000000040488E54
PC 0x000040488E54

Recursive exception occurred while dumping the CPU state

Disassembly of the kernel that produced it, at that address:

40488e54:  d50b7424   dc   zva, x4
40488e58:  8b070084   add  x4, x4, x7
40488e5c:  b5ffffa0   cbnz x0, 40488e50

addr2line places it in zero() at src/runtime/memops.c.

After the change, the same image on the same shape reaches userspace:

EFI ExitBootServices: Called.
[4.179006] en1: assigned 10.0.0.113

and an application server on top of it starts and serves requests.

Comment thread src/runtime/memops.c Outdated
Comment thread src/runtime/memops.c Outdated
Comment thread src/runtime/memops.c
@AngeloRubens
AngeloRubens force-pushed the aarch64-zva-mmu branch 2 times, most recently from 1ff1525 to 932d6a2 Compare October 10, 2026 17:35
DC ZVA requires Normal memory. While the MMU is off every access is
Device memory, where the instruction faults whatever DCZID_EL0.DZP
reports, and the kernel can run in that state during early boot: zero()
called there takes a synchronous exception on real hardware. An emulator
that does not enforce the restriction boots either way, which is why
this has gone unnoticed.

In a kernel build, check SCTLR_EL1.M alongside the DZP check that is
already there. SCTLR_EL1 cannot be read from EL0, and zero() also runs
in runtime test programs, so outside the kernel the MMU is taken as on.
@francescolavra
francescolavra merged commit 7ae67d4 into nanovms:master Oct 10, 2026
6 checks 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