Skip to content

arch/arm64/imx9: give the ELE a physical address and the cache a virtual one - #20196

Draft
royzah wants to merge 2 commits into
apache:masterfrom
royzah:imx9-ele-va
Draft

royzah wants to merge 2 commits into
apache:masterfrom
royzah:imx9-ele-va

Conversation

@royzah

@royzah royzah commented Sep 19, 2026

Copy link
Copy Markdown

Summary

The ELE addresses memory physically. Cache maintenance takes a virtual address. The two buffer calls each supply one of them and use it for both purposes, in opposite directions.

cache maintenance address given to the enclave
imx9_ele_get_random() a physical address correct
imx9_ele_get_key() correct a virtual address

up_flush_dcache() and up_invalidate_dcache() document their arguments as virtual. So imx9_ele_get_random() maintains whatever lines its physical values happen to name, and a caller can read back what its own dirty line still holds rather than what the ELE wrote, with nothing reported anywhere.

Both are correct only while the virtual and physical addresses are equal. That holds for the configurations in tree today. It does not hold for a kernel build with address environments.

Change

Both take the virtual address, maintain the cache on it, and translate for the message. imx9_ele_get_random() also gains the cache line alignment check imx9_ele_get_key() already has, because invalidating a partial line discards whatever shares it.

imx9_ele_get_random() changes prototype. Neither function has an in-tree caller, so nothing else moves.

Depends on

The arm64 up_addrenv_va_to_pa() in #20192, which is approved.

Testing

Compiles for imx93-evk:nsh. Not yet run on hardware, which is why this is a draft.

up_addrenv_va_to_pa() is declared in include/nuttx/arch.h but implemented
only by armv7-a, so no arm64 port can map a virtual address to a physical
one. A driver whose device addresses memory physically has nothing to call.

The translation is asked of the MMU with AT S1E1R rather than walked in
software, so it answers for whatever is actually mapped: any granule size,
block or page, at any level, and it cannot drift from the tables in use.

PAR_EL1 is one register per CPU, so nothing may run between the translation
and reading the result. Interrupts are banked with it, so masking them
locally is sufficient and SMP needs nothing further.

Returns zero for an address that is not mapped for a privileged read, which
is what the declaration in arch.h specifies. Note this differs from the
armv7-a implementation, which returns the virtual address unchanged.

Signed-off-by: Royyan Zahir <royzah@gmail.com>
…ual one.

The ELE addresses memory physically; cache maintenance takes a virtual
address. Both buffer calls supply one and use it for both, in opposite
directions: get_random() runs up_flush_dcache() on a physical address,
get_key() hands the enclave a virtual one. Both fail silently, and both
are correct only while the two are equal.

Take the virtual address in both, maintain the cache on it, and translate
for the message. get_random() also gains the alignment check get_key()
already has.

Signed-off-by: Royyan Zahir <royzah@gmail.com>
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.

1 participant