From fee7a4b77465393950372b1badd401ba9c4b225d Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 22 Mar 2022 15:01:22 -0700 Subject: [PATCH] kern: enforce end of dram == end of partitions (move our probably outdated KTraceBuffer to new location) --- .../include/mesosphere/kern_k_trace.hpp | 1 + ...kern_k_memory_layout.board.nintendo_nx.cpp | 21 +++++++------------ .../kern_k_memory_layout.board.qemu_virt.cpp | 21 +++++++------------ .../source/kern_k_system_control_base.cpp | 2 +- .../libmesosphere/source/kern_kernel.cpp | 8 +++---- .../source/arch/arm64/init/kern_init_core.cpp | 7 +++++++ 6 files changed, 29 insertions(+), 31 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_trace.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_trace.hpp index 3e757bb70..d8b414977 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_trace.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_trace.hpp @@ -28,6 +28,7 @@ namespace ams::kern { constexpr inline size_t KTraceBufferSize = IsKTraceEnabled ? 16_MB : 0; static_assert(IsKTraceEnabled || !IsKTraceEnabled); + static_assert((IsKTraceEnabled) ^ (KTraceBufferSize == 0)); class KTrace { public: diff --git a/libraries/libmesosphere/source/kern_k_memory_layout.board.nintendo_nx.cpp b/libraries/libmesosphere/source/kern_k_memory_layout.board.nintendo_nx.cpp index 0f551fe95..b2d4a09b0 100644 --- a/libraries/libmesosphere/source/kern_k_memory_layout.board.nintendo_nx.cpp +++ b/libraries/libmesosphere/source/kern_k_memory_layout.board.nintendo_nx.cpp @@ -104,13 +104,6 @@ namespace ams::kern { /* Insert blocks into the tree. */ MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(physical_memory_base_address), intended_memory_size, KMemoryRegionType_Dram)); MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(physical_memory_base_address), ReservedEarlyDramSize, KMemoryRegionType_DramReservedEarly)); - - /* Insert the KTrace block at the end of Dram, if KTrace is enabled. */ - static_assert(!IsKTraceEnabled || KTraceBufferSize > 0); - if constexpr (IsKTraceEnabled) { - const KPhysicalAddress ktrace_buffer_phys_addr = physical_memory_base_address + intended_memory_size - KTraceBufferSize; - MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(ktrace_buffer_phys_addr), KTraceBufferSize, KMemoryRegionType_KernelTraceBuffer)); - } } void SetupPoolPartitionMemoryRegions() { @@ -118,8 +111,15 @@ namespace ams::kern { const auto dram_extents = KMemoryLayout::GetMainMemoryPhysicalExtents(); MESOSPHERE_INIT_ABORT_UNLESS(dram_extents.GetEndAddress() != 0); + /* Find the pool partitions region. */ + const KMemoryRegion *pool_partitions_region = KMemoryLayout::GetPhysicalMemoryRegionTree().FindByTypeAndAttribute(KMemoryRegionType_DramPoolPartition, 0); + MESOSPHERE_INIT_ABORT_UNLESS(pool_partitions_region != nullptr); + + const uintptr_t pool_partitions_start = pool_partitions_region->GetAddress(); + /* Determine the end of the pool region. */ - const uintptr_t pool_end = dram_extents.GetEndAddress() - KTraceBufferSize; + const uintptr_t pool_end = pool_partitions_region->GetEndAddress(); + MESOSPHERE_INIT_ABORT_UNLESS(pool_end == dram_extents.GetEndAddress()); /* Find the start of the kernel DRAM region. */ const KMemoryRegion *kernel_dram_region = KMemoryLayout::GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_DramKernelBase); @@ -128,11 +128,6 @@ namespace ams::kern { const uintptr_t kernel_dram_start = kernel_dram_region->GetAddress(); MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(kernel_dram_start, CarveoutAlignment)); - /* Find the start of the pool partitions region. */ - const KMemoryRegion *pool_partitions_region = KMemoryLayout::GetPhysicalMemoryRegionTree().FindByTypeAndAttribute(KMemoryRegionType_DramPoolPartition, 0); - MESOSPHERE_INIT_ABORT_UNLESS(pool_partitions_region != nullptr); - const uintptr_t pool_partitions_start = pool_partitions_region->GetAddress(); - /* Setup the pool partition layouts. */ if (GetTargetFirmware() >= TargetFirmware_5_0_0) { /* On 5.0.0+, setup modern 4-pool-partition layout. */ diff --git a/libraries/libmesosphere/source/kern_k_memory_layout.board.qemu_virt.cpp b/libraries/libmesosphere/source/kern_k_memory_layout.board.qemu_virt.cpp index 34631169a..5637a771d 100644 --- a/libraries/libmesosphere/source/kern_k_memory_layout.board.qemu_virt.cpp +++ b/libraries/libmesosphere/source/kern_k_memory_layout.board.qemu_virt.cpp @@ -52,13 +52,6 @@ namespace ams::kern { /* Insert blocks into the tree. */ MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(physical_memory_base_address), intended_memory_size, KMemoryRegionType_Dram)); MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(physical_memory_base_address), ReservedEarlyDramSize, KMemoryRegionType_DramReservedEarly)); - - /* Insert the KTrace block at the end of Dram, if KTrace is enabled. */ - static_assert(!IsKTraceEnabled || KTraceBufferSize > 0); - if constexpr (IsKTraceEnabled) { - const KPhysicalAddress ktrace_buffer_phys_addr = physical_memory_base_address + intended_memory_size - KTraceBufferSize; - MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(ktrace_buffer_phys_addr), KTraceBufferSize, KMemoryRegionType_KernelTraceBuffer)); - } } void SetupPoolPartitionMemoryRegions() { @@ -66,18 +59,20 @@ namespace ams::kern { const auto dram_extents = KMemoryLayout::GetMainMemoryPhysicalExtents(); MESOSPHERE_INIT_ABORT_UNLESS(dram_extents.GetEndAddress() != 0); + /* Find the pool partitions region. */ + const KMemoryRegion *pool_partitions_region = KMemoryLayout::GetPhysicalMemoryRegionTree().FindByTypeAndAttribute(KMemoryRegionType_DramPoolPartition, 0); + MESOSPHERE_INIT_ABORT_UNLESS(pool_partitions_region != nullptr); + + const uintptr_t pool_partitions_start = pool_partitions_region->GetAddress(); + /* Determine the end of the pool region. */ - const uintptr_t pool_end = dram_extents.GetEndAddress() - KTraceBufferSize; + const uintptr_t pool_end = pool_partitions_region->GetEndAddress(); + MESOSPHERE_INIT_ABORT_UNLESS(pool_end == dram_extents.GetEndAddress()); /* Find the start of the kernel DRAM region. */ const KMemoryRegion *kernel_dram_region = KMemoryLayout::GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_DramKernelBase); MESOSPHERE_INIT_ABORT_UNLESS(kernel_dram_region != nullptr); - /* Find the start of the pool partitions region. */ - const KMemoryRegion *pool_partitions_region = KMemoryLayout::GetPhysicalMemoryRegionTree().FindByTypeAndAttribute(KMemoryRegionType_DramPoolPartition, 0); - MESOSPHERE_INIT_ABORT_UNLESS(pool_partitions_region != nullptr); - const uintptr_t pool_partitions_start = pool_partitions_region->GetAddress(); - /* Setup the pool partition layouts. */ /* Get Application and Applet pool sizes. */ const size_t application_pool_size = KSystemControl::Init::GetApplicationPoolSize(); diff --git a/libraries/libmesosphere/source/kern_k_system_control_base.cpp b/libraries/libmesosphere/source/kern_k_system_control_base.cpp index f08c34ca7..e6f6e8eb0 100644 --- a/libraries/libmesosphere/source/kern_k_system_control_base.cpp +++ b/libraries/libmesosphere/source/kern_k_system_control_base.cpp @@ -41,7 +41,7 @@ namespace ams::kern { void KSystemControlBase::Init::GetInitialProcessBinaryLayout(InitialProcessBinaryLayout *out) { *out = { - .address = GetInteger(KSystemControl::Init::GetKernelPhysicalBaseAddress(ams::kern::MainMemoryAddress)) + KSystemControl::Init::GetIntendedMemorySize() - KTraceBufferSize - InitialProcessBinarySizeMax, + .address = GetInteger(KSystemControl::Init::GetKernelPhysicalBaseAddress(ams::kern::MainMemoryAddress)) + KSystemControl::Init::GetIntendedMemorySize() - InitialProcessBinarySizeMax, ._08 = 0, }; } diff --git a/libraries/libmesosphere/source/kern_kernel.cpp b/libraries/libmesosphere/source/kern_kernel.cpp index a6e9b15a5..ed6f238e8 100644 --- a/libraries/libmesosphere/source/kern_kernel.cpp +++ b/libraries/libmesosphere/source/kern_kernel.cpp @@ -137,6 +137,10 @@ namespace ams::kern { PrintMemoryRegion(" Slab", KMemoryLayout::GetKernelSlabRegionPhysicalExtents()); PrintMemoryRegion(" PageTableHeap", KMemoryLayout::GetKernelPageTableHeapRegionPhysicalExtents()); PrintMemoryRegion(" InitPageTable", KMemoryLayout::GetKernelInitPageTableRegionPhysicalExtents()); + if constexpr (IsKTraceEnabled) { + MESOSPHERE_LOG(" DebugRegion\n"); + PrintMemoryRegion(" Trace Buffer", KMemoryLayout::GetKernelTraceBufferRegionPhysicalExtents()); + } PrintMemoryRegion(" MemoryPoolRegion", KMemoryLayout::GetKernelPoolPartitionRegionPhysicalExtents()); if (GetTargetFirmware() >= TargetFirmware_5_0_0) { PrintMemoryRegion(" Management", KMemoryLayout::GetKernelPoolManagementRegionPhysicalExtents()); @@ -155,10 +159,6 @@ namespace ams::kern { PrintMemoryRegion(" Secure", KMemoryLayout::GetKernelSystemPoolRegionPhysicalExtents()); PrintMemoryRegion(" Unsafe", KMemoryLayout::GetKernelApplicationPoolRegionPhysicalExtents()); } - if constexpr (IsKTraceEnabled) { - MESOSPHERE_LOG(" Debug\n"); - PrintMemoryRegion(" Trace Buffer", KMemoryLayout::GetKernelTraceBufferRegionPhysicalExtents()); - } MESOSPHERE_LOG("\n"); } diff --git a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp index c8f2cda22..f983f7ce1 100644 --- a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp +++ b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp @@ -513,6 +513,13 @@ namespace ams::kern::init { MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(resource_end_phys_addr), init_page_table_region_size, KMemoryRegionType_DramKernelInitPt)); MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetVirtualMemoryRegionTree().Insert(GetInteger(resource_end_phys_addr) + linear_region_phys_to_virt_diff, init_page_table_region_size, KMemoryRegionType_VirtualDramKernelInitPt)); + /* Insert a physical region for the kernel trace buffer */ + if constexpr (IsKTraceEnabled) { + const KPhysicalAddress ktrace_buffer_phys_addr = GetInteger(resource_end_phys_addr) + init_page_table_region_size; + MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(ktrace_buffer_phys_addr), KTraceBufferSize, KMemoryRegionType_KernelTraceBuffer)); + MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(ktrace_buffer_phys_addr) + linear_region_phys_to_virt_diff, KTraceBufferSize, GetTypeForVirtualLinearMapping(KMemoryRegionType_KernelTraceBuffer))); + } + /* All linear-mapped DRAM regions that we haven't tagged by this point will be allocated to some pool partition. Tag them. */ for (auto ®ion : KMemoryLayout::GetPhysicalMemoryRegionTree()) { constexpr auto UntaggedLinearDram = util::FromUnderlying(util::ToUnderlying(KMemoryRegionType_Dram) | util::ToUnderlying(KMemoryRegionAttr_LinearMapped));