kern: pass ini1 size from loader to kernel, remove slab memset from init0

This commit is contained in:
Michael Scire 2023-10-11 02:02:49 -07:00
parent 937ae17f19
commit 2a060d2645
6 changed files with 62 additions and 31 deletions

View file

@ -34,8 +34,14 @@ namespace ams::kern {
uintptr_t _08;
};
struct InitialProcessBinaryLayoutWithSize {
InitialProcessBinaryLayout layout;
size_t size;
};
KPhysicalAddress GetInitialProcessBinaryPhysicalAddress();
void SetInitialProcessBinaryPhysicalAddress(KPhysicalAddress phys_addr);
size_t GetInitialProcessBinarySize();
void SetInitialProcessBinaryPhysicalAddress(KPhysicalAddress phys_addr, size_t size);
u64 GetInitialProcessIdMin();
u64 GetInitialProcessIdMax();

View file

@ -171,6 +171,9 @@ namespace ams::kern::init {
const KMemoryRegion &slab_region = KMemoryLayout::GetSlabRegion();
KVirtualAddress address = slab_region.GetAddress();
/* Clear the slab region. */
std::memset(GetVoidPointer(address), 0, slab_region.GetSize());
/* Initialize slab type array to be in sorted order. */
KSlabType slab_types[KSlabType_Count];
for (size_t i = 0; i < util::size(slab_types); i++) { slab_types[i] = static_cast<KSlabType>(i); }

View file

@ -27,6 +27,7 @@ namespace ams::kern {
constinit KPhysicalAddress g_initial_process_binary_phys_addr = Null<KPhysicalAddress>;
constinit KVirtualAddress g_initial_process_binary_address = Null<KVirtualAddress>;
constinit size_t g_initial_process_binary_size = 0;
constinit InitialProcessBinaryHeader g_initial_process_binary_header = {};
constinit size_t g_initial_process_secure_memory_size = 0;
constinit u64 g_initial_process_id_min = std::numeric_limits<u64>::max();
@ -275,10 +276,11 @@ namespace ams::kern {
}
void SetInitialProcessBinaryPhysicalAddress(KPhysicalAddress phys_addr) {
void SetInitialProcessBinaryPhysicalAddress(KPhysicalAddress phys_addr, size_t size) {
MESOSPHERE_INIT_ABORT_UNLESS(g_initial_process_binary_phys_addr == Null<KPhysicalAddress>);
g_initial_process_binary_phys_addr = phys_addr;
g_initial_process_binary_size = size;
}
KPhysicalAddress GetInitialProcessBinaryPhysicalAddress() {
@ -287,6 +289,12 @@ namespace ams::kern {
return g_initial_process_binary_phys_addr;
}
size_t GetInitialProcessBinarySize() {
MESOSPHERE_INIT_ABORT_UNLESS(g_initial_process_binary_phys_addr != Null<KPhysicalAddress>);
return g_initial_process_binary_size;
}
u64 GetInitialProcessIdMin() {
return g_initial_process_id_min;
}
@ -305,14 +313,17 @@ namespace ams::kern {
LoadInitialProcessBinaryHeader();
if (g_initial_process_binary_header.num_processes > 0) {
/* Reserve pages for the initial process binary from the system resource limit. */
const size_t total_size = util::AlignUp(g_initial_process_binary_header.size, PageSize);
MESOSPHERE_ABORT_UNLESS(Kernel::GetSystemResourceLimit().Reserve(ams::svc::LimitableResource_PhysicalMemoryMax, total_size));
/* Ensure that we have a non-zero size. */
const size_t expected_size = g_initial_process_binary_size;
MESOSPHERE_INIT_ABORT_UNLESS(expected_size != 0);
/* The initial process binary is potentially over-allocated, so free any extra pages. */
if (total_size < InitialProcessBinarySizeMax) {
Kernel::GetMemoryManager().Close(KMemoryLayout::GetLinearPhysicalAddress(g_initial_process_binary_address + total_size), (InitialProcessBinarySizeMax - total_size) / PageSize);
}
/* Ensure that the size we need to reserve is as we expect it to be. */
const size_t total_size = util::AlignUp(g_initial_process_binary_header.size, PageSize);
MESOSPHERE_ABORT_UNLESS(total_size == expected_size);
MESOSPHERE_ABORT_UNLESS(total_size <= InitialProcessBinarySizeMax);
/* Reserve pages for the initial process binary from the system resource limit. */
MESOSPHERE_ABORT_UNLESS(Kernel::GetSystemResourceLimit().Reserve(ams::svc::LimitableResource_PhysicalMemoryMax, total_size));
return total_size;
} else {

View file

@ -108,7 +108,8 @@ namespace ams::kern {
/* Free each region to its corresponding heap. */
size_t reserved_sizes[MaxManagerCount] = {};
const KPhysicalAddress ini_start = GetInitialProcessBinaryPhysicalAddress();
const KPhysicalAddress ini_end = ini_start + InitialProcessBinarySizeMax;
const size_t ini_size = GetInitialProcessBinarySize();
const KPhysicalAddress ini_end = ini_start + ini_size;
const KPhysicalAddress ini_last = ini_end - 1;
for (const auto &it : KMemoryLayout::GetPhysicalMemoryRegionTree()) {
if (it.IsDerivedFrom(KMemoryRegionType_DramUserPool)) {
@ -126,13 +127,13 @@ namespace ams::kern {
}
/* Open/reserve the ini memory. */
manager.OpenFirst(ini_start, InitialProcessBinarySizeMax / PageSize);
reserved_sizes[it.GetAttributes()] += InitialProcessBinarySizeMax;
manager.OpenFirst(ini_start, ini_size / PageSize);
reserved_sizes[it.GetAttributes()] += ini_size;
/* Free memory after the ini to the heap. */
if (ini_last != cur_last) {
MESOSPHERE_ABORT_UNLESS(cur_end != Null<KPhysicalAddress>);
manager.Free(ini_end, cur_end - ini_end);
manager.Free(ini_end, (cur_end - ini_end) / PageSize);
}
} else {
/* Ensure there's no partial overlap with the ini image. */