Skip to content

Commit 1e4fd23

Browse files
Nicolas Pitrenashif
Nicolas Pitre
authored andcommittedSep 10, 2024
kernel: mmu: install demand mappings for the on-demand linker sections
This sets initial unpaged mappings for __ondemand_func code and __ondemand_rodata variables. To achieve this, we have to augment the backing store API. Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
1 parent cbbd857 commit 1e4fd23

File tree

4 files changed

+55
-0
lines changed

4 files changed

+55
-0
lines changed
 

‎Kconfig.zephyr

+1
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ config LINKER_USE_PINNED_SECTION
262262

263263
config LINKER_USE_ONDEMAND_SECTION
264264
bool "Use Evictable Linker Section"
265+
depends on DEMAND_MAPPING
265266
depends on !LINKER_USE_PINNED_SECTION
266267
depends on !ARCH_MAPS_ALL_RAM
267268
help

‎doc/kernel/memory_management/demand_paging.rst

+5
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,11 @@ which must be implemented:
179179
free a backing store location (the ``location`` token) which can
180180
then be used for subsequent page out operation.
181181

182+
* :c:func:`k_mem_paging_backing_store_location_query()` is called to obtain
183+
the ``location`` token corresponding to storage content to be virtually
184+
mapped and paged-in on demand. Most useful with
185+
:kconfig:option:`CONFIG_DEMAND_MAPPING`.
186+
182187
* :c:func:`k_mem_paging_backing_store_page_in()` copies a data page
183188
from the backing store location associated with the provided
184189
``location`` token to the page pointed by ``K_MEM_SCRATCH_PAGE``.

‎include/zephyr/kernel/mm/demand_paging.h

+16
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,22 @@ int k_mem_paging_backing_store_location_get(struct k_mem_page_frame *pf,
349349
*/
350350
void k_mem_paging_backing_store_location_free(uintptr_t location);
351351

352+
/**
353+
* Obtain persistent location token for on-demand content
354+
*
355+
* Unlike k_mem_paging_backing_store_location_get() this does not allocate
356+
* any backing store space. Instead, it returns a location token corresponding
357+
* to some fixed storage content to be paged in on demand. This is expected
358+
* to be used in conjonction with CONFIG_LINKER_USE_ONDEMAND_SECTION and the
359+
* K_MEM_MAP_UNPAGED flag to create demand mappings at boot time. This may
360+
* also be used e.g. to implement file-based mmap().
361+
*
362+
* @param addr Virtual address to obtain a location token for
363+
* @param [out] location storage location token
364+
* @return 0 for success or negative error code
365+
*/
366+
int k_mem_paging_backing_store_location_query(void *addr, uintptr_t *location);
367+
352368
/**
353369
* Copy a data page from K_MEM_SCRATCH_PAGE to the specified location
354370
*

‎kernel/mmu.c

+33
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,34 @@ static void mark_linker_section_pinned(void *start_addr, void *end_addr,
10501050
}
10511051
#endif /* CONFIG_LINKER_USE_BOOT_SECTION) || CONFIG_LINKER_USE_PINNED_SECTION */
10521052

1053+
#ifdef CONFIG_LINKER_USE_ONDEMAND_SECTION
1054+
static void z_paging_ondemand_section_map(void)
1055+
{
1056+
uint8_t *addr;
1057+
size_t size;
1058+
uintptr_t location;
1059+
uint32_t flags;
1060+
1061+
size = (uintptr_t)lnkr_ondemand_text_size;
1062+
flags = K_MEM_MAP_UNPAGED | K_MEM_PERM_EXEC | K_MEM_CACHE_WB;
1063+
VIRT_FOREACH(lnkr_ondemand_text_start, size, addr) {
1064+
k_mem_paging_backing_store_location_query(addr, &location);
1065+
arch_mem_map(addr, location, CONFIG_MMU_PAGE_SIZE, flags);
1066+
sys_bitarray_set_region(&virt_region_bitmap, 1,
1067+
virt_to_bitmap_offset(addr, CONFIG_MMU_PAGE_SIZE));
1068+
}
1069+
1070+
size = (uintptr_t)lnkr_ondemand_rodata_size;
1071+
flags = K_MEM_MAP_UNPAGED | K_MEM_CACHE_WB;
1072+
VIRT_FOREACH(lnkr_ondemand_rodata_start, size, addr) {
1073+
k_mem_paging_backing_store_location_query(addr, &location);
1074+
arch_mem_map(addr, location, CONFIG_MMU_PAGE_SIZE, flags);
1075+
sys_bitarray_set_region(&virt_region_bitmap, 1,
1076+
virt_to_bitmap_offset(addr, CONFIG_MMU_PAGE_SIZE));
1077+
}
1078+
}
1079+
#endif /* CONFIG_LINKER_USE_ONDEMAND_SECTION */
1080+
10531081
void z_mem_manage_init(void)
10541082
{
10551083
uintptr_t phys;
@@ -1126,6 +1154,11 @@ void z_mem_manage_init(void)
11261154
}
11271155
}
11281156
#endif /* CONFIG_DEMAND_PAGING */
1157+
1158+
#ifdef CONFIG_LINKER_USE_ONDEMAND_SECTION
1159+
z_paging_ondemand_section_map();
1160+
#endif
1161+
11291162
#if __ASSERT_ON
11301163
page_frames_initialized = true;
11311164
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.