Commit graph

67 commits

Author SHA1 Message Date
Daniel Leung
3032b58f52 xtensa: mmu: support memory domain de-initialization
This supports de-initialization of memory domains to release
allocated page tables back to the pool.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2026-02-24 10:39:59 +01:00
Daniel Leung
6db2a0fd71 xtensa: mmu: clear L2 table when usage counter reaches zero
When a L2 table is no longer being used, we should set all PTEs
in the table to be illegal PTEs. This is simply a precautious
so that any stray references to the L2 table would not result
in incorrect permissions being applied.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2026-02-24 10:39:59 +01:00
Daniel Leung
ee54baf126 Revert "xtensa: move MMU init functions to mmu.c"
This reverts commit 8c02dde437.

For some unknown reasons, xt-clang emits two copies of
z_xt_init_pc if xtensa_mmu_init_paging() is in the same file
as xtensa_mmu_init() and xtensa_mmu_reinit(). So had to
revert the change.

Fixes #103055

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2026-02-04 13:50:54 +01:00
Daniel Leung
a5a9ff4c28 xtensa: handle instruction TLB multi-hit exception
When using LLEXT, instruction TLB multi-hit becomes a reality
as the same memory space can be occupied by different modules
with different permissions. The ITLB cache may still contain
entries of the unloaded module. So we need to manually
invalidate any cached ITLB corresponding to the exception
address so the TLB associated with the newly loaded module
can be used.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2026-02-03 09:38:03 +01:00
Daniel Leung
9b9e9ebde7 xtensa: mmu: data TLB multi-hit only handle exception address
There is no need to invalidate the whole auto-refilled data TLB
cache when DTLB multi-hit exception is raised. Now it only
invalidates the TLB entries corresponding to the one causing
the DTLB multi-hit. This allows other non-related TLB entries
to remain in the cache so they don't need to be reloaded.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2026-02-03 09:38:03 +01:00
Daniel Leung
8c02dde437 xtensa: move MMU init functions to mmu.c
Since we have split source files for page table related stuff
and MMU related stuff, move the MMU initialization functions
from the page table source file into MMU source file.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2026-01-24 08:48:54 -06:00
Daniel Leung
ed4cec2d22 xtensa: ptables: doxygen doc
This adds doxygen doc to the page table source file as
we are missing quite a bit of documentation there.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2026-01-24 08:48:54 -06:00
Daniel Leung
50e980d9a8 xtensa: mmu: halt system if not enough L2 tables during boot
If there are not enough free L2 tables to map all predefined
memory regions at boot, halt the system in case assertion is
not enabled. Without all the needed memory regions mapped,
it is very unlikely that anything will run properly.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2026-01-22 08:39:30 +00:00
Daniel Leung
82b7d94d45 xtensa: mmu: add debug logs on page table allocations
Adds some debug logs when we are allocating page tables.
This provides a more visible way of seeing whether
we need to have more free tables.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2026-01-22 08:39:30 +00:00
Daniel Leung
0777dbea02 xtensa: mmu: assert when L2 table allocation fails during dup
Add an assertions to halt the system if L2 table allocation
fails when we need to duplicate an existing L2 table, as it is
a must-have and must-success operation.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2026-01-22 08:39:30 +00:00
Guennadi Liakhovetski
8c200c0f2f xtensa: mmu: (cosmetic) clean up pointer types
Use void * cleanly: avoid needless type-casts and use void * for
generic pointers instead of uint8_t *.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
2025-12-19 07:53:07 -06:00
Daniel Leung
701cbfbc23 xtensa: mmu: may need to copy entries during L2 table dup
During L2 page table duplication, there are cases where we
should copy the table over instead of restoring the PTEs.
Add the ability to copy the table over.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-12-09 09:25:33 +01:00
Daniel Leung
8d0103b4ad xtensa: mmu: spin lock for counter manipulation
This adds a spinlock to guard page table counter updates.
For some reasons, without this, xt-clang generated code would
result in incorrect counter update possibly due to memory
access ordering (though GCC generated code works fine without
the spin lock).

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-12-09 09:25:33 +01:00
Daniel Leung
0540d274c0 xtensa: remove CONFIG_XTENSA_RPO_CACHE
This removes the following kconfigs:

() CONFIG_XTENSA_RPO_CACHE
() CONFIG_XTENSA_CACHED_REGION
() CONFIG_XTENSA_UNCACHED_REGION

The associated feature is actually SoC specific and not general
architecture feature. Since the only user of these have its own
implementation, we can now safely remove these.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-12-09 09:25:33 +01:00
Daniel Leung
27b1c3138f xtensa: mmu: remove CONFIG_XTENSA_MMU_DOUBLE_MAP
This removes CONFIG_XTENSA_MMU_DOUBLE_MAP and its associated
code. The double mapping of a page into both cached and
uncached memory regions should be done in SoC and application,
as it gives finer control on what actually is being mapped.
For example, if a page only needs to mapped in cached region,
there is no need to map it in the uncached region. This may
save the need to allocate a L2 page table for it, and saves
some memory.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-12-09 09:25:33 +01:00
Daniel Leung
1bc72e68c6 xtensa: mmu: allow SoC to override default mappings
Adds kconfig CONFIG_XTENSA_MMU_USE_DEFAULT_MAPPINGS for arch
code to initialize the page tables with a few default mappings
covering text, data, BSS and RODATA. Disabling this allows
the SoC to customize and fine-tune the mappings if needed.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-12-09 09:25:33 +01:00
Adrian Warecki
6cd7cfa104 xtensa: mmu: ptables: Set PPN in region_map_update to fix memory mapping
Set PPN (Physical Page Number) in L2 entry in the region_map_update
function to ensure correct mapping for memory that was not previously
mapped based on xtensa_soc_mmu_ranges.

When a new memory domain is created, the arch_mem_domain_init function
allocates new ptables using the dup_table function. This function only
copies original L2 entries created from xtensa_soc_mmu_ranges with
OPTION_SAVE_ATTRS. Entries added later by arch_mem_map are replaced with
XTENSA_MMU_PTE_L2_ILLEGAL and have PPN (Physical Page Number) set to zero.

When adding a new partition to a memory domain, the update_region function
is used. It sets new access attributes in the L2 table without setting the
PPN value. As a result, it does not work correctly for memory that was not
previously mapped based on xtensa_soc_mmu_ranges.

Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
2025-12-01 11:09:09 +01:00
Adrian Warecki
942b1e8571 xtensa: mmu: ptables: Introduce PTE_PPN_SET macro
Add macro PTE_PPN_SET to simplify setting the physical page
number assigned in the page table entry.

Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
2025-12-01 11:09:09 +01:00
Adrian Warecki
f5f56113fe xtensa: mmu: ptables: Introduce PTE_PPN_GET macro
Add macro PTE_PPN_GET to simplify retrieval of the physical page
number assigned to a page table entry.

Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
2025-12-01 11:09:09 +01:00
Daniel Leung
a6fe6a8f7d xtensa: fix unused func warning on l2_page_tables_counter_inc
xt-clang complains about l2_page_tables_counter_inc() being
unused but not GCC. So fix that by using it somewhere else.

Fixes #99753

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-11-25 20:22:54 -05:00
Daniel Leung
e45808b9cd xtensa: mmu: add page table usage statistics
Adds function for app to obtain page table usage statistics,
allowing fine tuning of numbers of L1 and L2 page table
array.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-11-14 09:21:44 +01:00
Daniel Leung
a48345fccf xtensa: mmu/ptables: conserve memory by using COW on L2 tables
When adding new memory domains, we need to start from kernel
page tables by duplicating them. However, there is no need to
duplicate all in-use page tables as some memory regions remain
unchanged. Fror example, hardware register region where only
kernel has access does not need to be duplicated across all
memory domains. The same L2 table can be used among them.
This changes the L2 page table allocation to be copy-on-write
where we only need to duplicate a L2 table if changes need to
be made on it.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-11-14 09:21:44 +01:00
Daniel Leung
1e41db3ddd xtensa: mmu: no need for cache ops if page tables are not cached
If the page tables are not cached, there is no need to do any
cache ops to flush or invalidate the data in cache. So skip them
if the page tables are not cached. Saves a few CPU cycles.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-11-14 09:21:44 +01:00
Daniel Leung
501368601d xtensa: mmu/ptables: rework TLB invalidation on L2 unmap
In l2_page_table_unmap(), invalidating TLBs should be limited to
the address and not the whole auto-refill TLBs. Also fix a bug
where the EXEC bit should be determined from the L2 PTE and not
the L1 PTE.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-11-14 09:21:44 +01:00
Daniel Leung
259be3d559 xtensa: mmu: remove XTENSA_ prefix for page table array macros
Some macros for the page tables array are local to the file so
there is no need to prefix them with XTENSA_. Simplify by
removing the XTENSA_ prefix, and clairfy if needed.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-11-14 09:21:44 +01:00
Daniel Leung
1470d9ef74 xtensa: mmu: move PTE macros into source file
Almost all page table entry (PTE) related macros are only used
in one source file. These macros are considered the internal
working of MMU. There is no need to expose them in header file
for other to reference. So move them into the source file where
it is only place they are used. Bonus is that we can shorten
the macro names as they are now local to the file. Makes it
easier to read, and few keystrokes to input.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-11-14 09:21:44 +01:00
Daniel Leung
b6713c0145 xtensa: mmu: skip PTE SW field redirection
This skips the redirection of backup attributes and ring via
some SW field macros, and use the PTE bits directly. Should
make it easier to decode what's going on.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-11-14 09:21:44 +01:00
Daniel Leung
95d260e77e xtensa: mmu/ptables: rename flags to attrs under arch_mem_map()
arch_mem_map() takes in some flags to describe the to-be mapped
memory regions' permissions and cache status. When the flags are
translated, they become attributes in PTEs. So for functions
being called by arch_mem_map() and beyond, rename flags to
attrs to better describe its purpose.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-10-15 11:47:25 -04:00
Daniel Leung
84ade183ed xtensa: mmu: cosmetic changes to page table variable names
In functions which manipulate both L1 and L2 tables, make
the variable names obvious by prefixing them with l1_ or l2_.
This is mainly done to avoid confusion when reading through
those functions.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-10-15 11:47:25 -04:00
Daniel Leung
e709cbe3c8 xtensa: mmu: fix __arch_mem_map assert message
The assert error messages when l2_page_table_map() fails are not
correct. It returns false when it cannot allocate new L2 table,
and it is not able the address having already mapped. So correct
the error message.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-10-15 11:47:25 -04:00
Daniel Leung
6877bc8644 xtensa: userspace: handle DTLB multihit exception
This adds a function to handle DTLB multihit exception when
userspace is enabled, as this exception may be raised due to
the same page being able to accessed by both kernel and user
threads. The auto-refill DTLBs may contain entries for same
page, one for kernel and one for user under some situations.
We need to invalidate those existing DTLB entries so that
hardware can reload from the page table.

This is an alternative to the kconfig invalidating DTLBs on
every swap: CONFIG_XTENSA_MMU_FLUSH_AUTOREFILL_DTLBS_ON_SWAP.
Although this does not have extra processing per context
switching, exception handling itself has a high cost. So
care needs to be taken on whether to enable that kconfig.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-10-15 11:47:25 -04:00
Daniel Leung
d3a126cb5d xtensa: userspace: handle load/store ring exception
When a page can be accessed by both kernel and user threads,
the autofill DTLB may contain an entry for kernel thread.
This will result in load/store ring exception when it is
accessed by user thread later. In this case, we need to
invalidate all associated TLBs related to kernel access so
hardware can reload the page table the correct permission
for user thread.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-10-15 11:47:25 -04:00
Daniel Leung
c76b338ec4 xtensa: mmu: properly restore PTE attributes via reset_region()
The software bits inside PTE are used to store original PTE
attributes and ring value, and those bits are used to
restore PTE to previous state.

This modifies reset_region() to properly restore attributes
and ring value when resetting memory regions to the same as
when the system boots.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-10-15 11:47:25 -04:00
Guennadi Liakhovetski
c6b6c62c21 arch: xtensa: (cosmetic) simplify function prototypes
Several static functions in ptables.c always return 0, make them void
to improve readability.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
2025-09-17 19:01:35 +02:00
Peter Mitsis
dde9462666 arch: tweak xtensa_mem_kernel_has_access() API
Adds 'const' to address pointer as its memory contents
do not change.

Signed-off-by: Peter Mitsis <peter.mitsis@intel.com>
2025-06-19 00:03:00 +02:00
Daniel Leung
d31ee53b60 xtensa: allow flushing auto-refill DTLBs on page table swap
This adds a new kconfig and corresponding code to allow flushing
auto-refill data TLBs when page tables are swapped (e.g. during
context switching). This is mainly used to avoid multi-hit TLB
exception raised by certain memory access pattern. If memory is
only marked for user mode access but not inside a memory domain,
accessing that page in kernel mode would result in a TLB being
filled with kernel ASID. When going back into user mode, access
to the memory would result in another TLB being filled with
the user mode ASID. Now there are two entries on the same memory
page, and the multi-hit TLB exception will be raised if that
memory page is accessed. This type of access is better served
using memory partition and memory domain to share data. However,
this type of access is not prohibited but highly discouraged.
Wrapping the code in kconfig is simply because of the execution
penalty as there will be unnecessary TLB refilling being done.
So only enable this if necessary.

Fixes #88772

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-05-28 20:01:58 +02:00
Daniel Leung
277fa9e8ac xtensa: userspace: swap page tables via assembly code
Since the necessary register values are now pre-computed and
stored in the memory domain struct, we can use them directly
in various assembly locations, thus replacing the function
call to xtensa_swap_update_page_tables().

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-04-17 00:57:19 +02:00
Daniel Leung
0dce0bdc0b xtensa: userspace: pre-compute MMU registers at domain init
Instead of computing all the needed register values when
swapping page tables, we can pre-compute those values when
the memory domain is first initialized. Should save some
time during context switching.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-04-17 00:57:19 +02:00
Daniel Leung
a4367eb514 xtensa: remove CONFIG_XTENSA_INVALIDATE_MEM_DOMAIN_TLB_ON_SWAP
Remove CONFIG_XTENSA_INVALIDATE_MEM_DOMAIN_TLB_ON_SWAP as it is
remnant from early MMU enabling work which is not needed as
the page table code is different from early version where
the PTEVADDR would be the same for all memory domains.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-04-17 00:57:19 +02:00
Daniel Leung
833bb667b2 xtensa: fix thread_page_tables_get being unused
thread_page_tables_get() is only used when userspace is
enabled. So move it with userspace #ifdef, or else
compiler would complain about it being unused.

Fixes #88421

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-04-15 19:09:52 +02:00
Daniel Leung
c925b0ecd5 xtensa: mmu: fix incorrect caching attrs on double mapping
Inside map_memory() with double mapping enabled, we should not
be mapping the memory with the incoming attributes as-is since
the incoming address may be on un-cached region but with
caching attribute. So we need to sanitize the attributes
according to the incoming address.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2025-03-14 01:01:32 +01:00
Nicolas Pitre
46aa6717ff Revert "arch: deprecate _current"
Mostly a revert of commit b1def7145f ("arch: deprecate `_current`").

This commit was part of PR #80716 whose initial purpose was about providing
an architecture specific optimization for _current. The actual deprecation
was sneaked in later on without proper discussion.

The Zephyr core always used _current before and that was fine. It is quite
prevalent as well and the alternative is proving rather verbose.
Furthermore, as a concept, the "current thread" is not something that is
necessarily architecture specific. Therefore the primary abstraction
should not carry the arch_ prefix.

Hence this revert.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2025-01-10 07:49:08 +01:00
Yong Cong Sin
b1def7145f arch: deprecate _current
`_current` is now functionally equals to `arch_curr_thread()`, remove
its usage in-tree and deprecate it instead of removing it outright,
as it has been with us since forever.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
Signed-off-by: Yong Cong Sin <yongcong.sin@gmail.com>
2024-11-23 20:12:24 -05:00
Daniel Leung
b0185189ad xtensa: mmu: fix page table initialization
xtensa_mmu_init() is called really early in the boot process
where the _kernel struct has not yet been initialized, and
thus we cannot use it to determine if the current CPU is
the boot CPU. In some cases, this may skip the call to
initialize the page tables which leaves us with incorrect
page table entries. Fix it by using a static variable to
determine whether the page tables have been initialized so
we only do it once per boot.

Fixes #76909

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2024-08-14 09:36:19 +02:00
Daniel Leung
8c10964435 xtensa: mmu: clear ZSR_DEPC_SAVE at boot
ZSR_DEPC_SAVE is being used to determine whether we are faulting
inside double exception if this is not zero. It is possible that
the boot ROM or custom startup code leaves this non-zero, which
would result in a fake triple fault. So clear it at boot. Note
that the zeroing is done in MMU init code as these triple
faults are not actual hardware ones but only semantics, and will
occur once MMU is enabled.

Fixes #75194

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2024-06-28 20:53:37 -04:00
Daniel Leung
79939e3279 xtensa: mmu: mpu: add xtensa_mem_kernel_has_access()
This adds a new function xtensa_mem_kernel_has_access() to
determine if a memory region can be accessed by kernel threads.
This allows checking for valid mapped memory before accessing
them to avoid relying on page faults to detect invalid access.

Also fixed an issue with arch_buffer_validate() on MPU where
it may return okay even if the incoming memory region has no
corresponding entry in the MPU table.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2024-06-15 04:44:48 -04:00
Daniel Leung
61ec0d15d5 xtensa: mmu: arch_buffer_validate is only for user thread
arch_buffer_validate() is only to verify that user threads have
access to the memory region. It should not be used to verify
if kernel thread has access (which they should anyway). So
change the logic.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2024-06-15 04:44:48 -04:00
Daniel Leung
54af5dda84 kernel: mm: rename z_page_frame_* to k_mem_page_frame_*
Also any demand paging and page frame related bits are
renamed.

This is part of a series to move memory management related
stuff out of the Z_ namespace into its own namespace.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2024-06-12 21:13:26 -04:00
Flavio Ceolin
f74a84b251 xtensa: mmu: MMU re-initialization API
With power managment is enabled, depending on the SoC power state
used when idle, the MMU may lose context and may need to be re-initialized.
When re-initializing the MMU, we must not re-create the page table
because it may overwrite changes done during the execution, but we still
need to set the asid and page table for the current context.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
2024-06-04 16:27:55 -05:00
Flavio Ceolin
d6d3c1098d xtensa: mmu: dup_table does not need parameter
The only page table duplicated is the kernel page table. This function
does not need a parameter.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
2024-05-14 15:54:55 +02:00