kernel: default flexible memory to 448 MiB and charge loaded modules' segments to it

This commit is contained in:
Claxten authored and nmzik committed 2026-10-27 04:23:00 +01:00
1 parent 2483573651
commit 0a140911ad
5 files changed
+84 -3

No files matched your search

+20 -2
View File
@@ -1636,6 +1636,8 @@ void RuntimeLinker::DeleteTls(Program* program, int thread_id) {
}
}
constexpr uint64_t GUEST_PAGE_SIZE = 0x4000;
static uint64_t CalcBaseSize(const Elf64_Ehdr* ehdr, const Elf64_Phdr* phdr) {
uint64_t base_size = 0;
for (Elf64_Half i = 0; i < ehdr->e_phnum; i++) {
@@ -1649,6 +1651,20 @@ static uint64_t CalcBaseSize(const Elf64_Ehdr* ehdr, const Elf64_Phdr* phdr) {
return base_size;
}
// A module's E, R and RW LOAD segments use flexible memory in 16 KiB pages; GNU_RELRO adds none
// since it lies inside an RW LOAD.
uint64_t CalcFlexibleMemorySize(const Elf64_Phdr* phdr, Elf64_Half phnum) {
uint64_t size = 0;
for (Elf64_Half i = 0; i < phnum; i++) {
const auto flags = phdr[i].p_flags;
if (phdr[i].p_type == PT_LOAD &&
(flags == PF_X || flags == PF_R || flags == (PF_R | PF_W))) {
size += AlignUp(phdr[i].p_memsz, GUEST_PAGE_SIZE);
}
}
return size;
}
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
void RuntimeLinker::LoadProgramToMemory(Program* program) {
KYTY_PROFILER_FUNCTION();
@@ -1668,8 +1684,7 @@ void RuntimeLinker::LoadProgramToMemory(Program* program) {
EXIT_IF(phdr == nullptr || ehdr == nullptr);
program->base_size = CalcBaseSize(ehdr, phdr);
constexpr uint64_t GUEST_PAGE_SIZE = 0x4000;
program->base_size = CalcBaseSize(ehdr, phdr);
EXIT_IF(program->base_size > UINT64_MAX - (GUEST_PAGE_SIZE - 1));
program->base_size_aligned = AlignUp(program->base_size, GUEST_PAGE_SIZE);
@@ -1694,6 +1709,8 @@ void RuntimeLinker::LoadProgramToMemory(Program* program) {
g_desired_base_addr, program->mapped_size, Common::VirtualMemory::Mode::ExecuteReadWrite,
Common::PathToString(program->file_name.filename()).c_str());
EXIT_IF(program->base_vaddr == 0);
program->flexible_size = CalcFlexibleMemorySize(phdr, ehdr->e_phnum);
Libs::LibKernel::Memory::ChargeFlexibleMemory(program->flexible_size);
if (patch_guest_instructions) {
const auto trampoline_addr = program->base_vaddr + program->base_size_aligned;
@@ -1879,6 +1896,7 @@ void RuntimeLinker::DeleteProgram(Program* p) {
}
EXIT_IF(
!Libs::LibKernel::Memory::FreeGuestMemory(program->base_vaddr, program->mapped_size));
Libs::LibKernel::Memory::ReleaseFlexibleMemory(program->flexible_size);
}
}