summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/kernel/k_memory_block.h2
-rw-r--r--src/core/hle/kernel/k_page_table.cpp167
-rw-r--r--src/core/hle/kernel/k_page_table.h19
-rw-r--r--src/core/hle/kernel/k_process.cpp8
-rw-r--r--src/core/hle/kernel/svc.cpp23
-rw-r--r--src/core/hle/kernel/svc_common.h5
6 files changed, 141 insertions, 83 deletions
diff --git a/src/core/hle/kernel/k_memory_block.h b/src/core/hle/kernel/k_memory_block.h
index fd491146f..9e51c33ce 100644
--- a/src/core/hle/kernel/k_memory_block.h
+++ b/src/core/hle/kernel/k_memory_block.h
@@ -120,7 +120,7 @@ static_assert(static_cast<u32>(KMemoryState::CodeOut) == 0x00402015);
120 120
121enum class KMemoryPermission : u8 { 121enum class KMemoryPermission : u8 {
122 None = 0, 122 None = 0,
123 Mask = static_cast<u8>(~None), 123 All = static_cast<u8>(~None),
124 124
125 Read = 1 << 0, 125 Read = 1 << 0,
126 Write = 1 << 1, 126 Write = 1 << 1,
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp
index f2f88c147..4da509224 100644
--- a/src/core/hle/kernel/k_page_table.cpp
+++ b/src/core/hle/kernel/k_page_table.cpp
@@ -264,9 +264,9 @@ ResultCode KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_
264 ASSERT(heap_last < stack_start || stack_last < heap_start); 264 ASSERT(heap_last < stack_start || stack_last < heap_start);
265 ASSERT(heap_last < kmap_start || kmap_last < heap_start); 265 ASSERT(heap_last < kmap_start || kmap_last < heap_start);
266 266
267 current_heap_addr = heap_region_start; 267 current_heap_end = heap_region_start;
268 heap_capacity = 0; 268 max_heap_size = 0;
269 physical_memory_usage = 0; 269 mapped_physical_memory_size = 0;
270 memory_pool = pool; 270 memory_pool = pool;
271 271
272 page_table_impl.Resize(address_space_width, PageBits); 272 page_table_impl.Resize(address_space_width, PageBits);
@@ -306,7 +306,7 @@ ResultCode KPageTable::MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std:
306 KMemoryState state{}; 306 KMemoryState state{};
307 KMemoryPermission perm{}; 307 KMemoryPermission perm{};
308 CASCADE_CODE(CheckMemoryState(&state, &perm, nullptr, src_addr, size, KMemoryState::All, 308 CASCADE_CODE(CheckMemoryState(&state, &perm, nullptr, src_addr, size, KMemoryState::All,
309 KMemoryState::Normal, KMemoryPermission::Mask, 309 KMemoryState::Normal, KMemoryPermission::All,
310 KMemoryPermission::ReadAndWrite, KMemoryAttribute::Mask, 310 KMemoryPermission::ReadAndWrite, KMemoryAttribute::Mask,
311 KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); 311 KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped));
312 312
@@ -465,7 +465,7 @@ ResultCode KPageTable::MapPhysicalMemory(VAddr addr, std::size_t size) {
465 465
466 MapPhysicalMemory(page_linked_list, addr, end_addr); 466 MapPhysicalMemory(page_linked_list, addr, end_addr);
467 467
468 physical_memory_usage += remaining_size; 468 mapped_physical_memory_size += remaining_size;
469 469
470 const std::size_t num_pages{size / PageSize}; 470 const std::size_t num_pages{size / PageSize};
471 block_manager->Update(addr, num_pages, KMemoryState::Free, KMemoryPermission::None, 471 block_manager->Update(addr, num_pages, KMemoryState::Free, KMemoryPermission::None,
@@ -507,7 +507,7 @@ ResultCode KPageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) {
507 507
508 auto process{system.Kernel().CurrentProcess()}; 508 auto process{system.Kernel().CurrentProcess()};
509 process->GetResourceLimit()->Release(LimitableResource::PhysicalMemory, mapped_size); 509 process->GetResourceLimit()->Release(LimitableResource::PhysicalMemory, mapped_size);
510 physical_memory_usage -= mapped_size; 510 mapped_physical_memory_size -= mapped_size;
511 511
512 return ResultSuccess; 512 return ResultSuccess;
513} 513}
@@ -554,7 +554,7 @@ ResultCode KPageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) {
554 KMemoryState src_state{}; 554 KMemoryState src_state{};
555 CASCADE_CODE(CheckMemoryState( 555 CASCADE_CODE(CheckMemoryState(
556 &src_state, nullptr, nullptr, src_addr, size, KMemoryState::FlagCanAlias, 556 &src_state, nullptr, nullptr, src_addr, size, KMemoryState::FlagCanAlias,
557 KMemoryState::FlagCanAlias, KMemoryPermission::Mask, KMemoryPermission::ReadAndWrite, 557 KMemoryState::FlagCanAlias, KMemoryPermission::All, KMemoryPermission::ReadAndWrite,
558 KMemoryAttribute::Mask, KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)); 558 KMemoryAttribute::Mask, KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped));
559 559
560 if (IsRegionMapped(dst_addr, size)) { 560 if (IsRegionMapped(dst_addr, size)) {
@@ -593,7 +593,7 @@ ResultCode KPageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) {
593 KMemoryState src_state{}; 593 KMemoryState src_state{};
594 CASCADE_CODE(CheckMemoryState( 594 CASCADE_CODE(CheckMemoryState(
595 &src_state, nullptr, nullptr, src_addr, size, KMemoryState::FlagCanAlias, 595 &src_state, nullptr, nullptr, src_addr, size, KMemoryState::FlagCanAlias,
596 KMemoryState::FlagCanAlias, KMemoryPermission::Mask, KMemoryPermission::None, 596 KMemoryState::FlagCanAlias, KMemoryPermission::All, KMemoryPermission::None,
597 KMemoryAttribute::Mask, KMemoryAttribute::Locked, KMemoryAttribute::IpcAndDeviceMapped)); 597 KMemoryAttribute::Mask, KMemoryAttribute::Locked, KMemoryAttribute::IpcAndDeviceMapped));
598 598
599 KMemoryPermission dst_perm{}; 599 KMemoryPermission dst_perm{};
@@ -784,7 +784,7 @@ ResultCode KPageTable::ReserveTransferMemory(VAddr addr, std::size_t size, KMemo
784 CASCADE_CODE(CheckMemoryState( 784 CASCADE_CODE(CheckMemoryState(
785 &state, nullptr, &attribute, addr, size, 785 &state, nullptr, &attribute, addr, size,
786 KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted, 786 KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted,
787 KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted, KMemoryPermission::Mask, 787 KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted, KMemoryPermission::All,
788 KMemoryPermission::ReadAndWrite, KMemoryAttribute::Mask, KMemoryAttribute::None, 788 KMemoryPermission::ReadAndWrite, KMemoryAttribute::Mask, KMemoryAttribute::None,
789 KMemoryAttribute::IpcAndDeviceMapped)); 789 KMemoryAttribute::IpcAndDeviceMapped));
790 790
@@ -859,61 +859,125 @@ ResultCode KPageTable::SetMemoryAttribute(VAddr addr, std::size_t size, KMemoryA
859 return ResultSuccess; 859 return ResultSuccess;
860} 860}
861 861
862ResultCode KPageTable::SetHeapCapacity(std::size_t new_heap_capacity) { 862ResultCode KPageTable::SetMaxHeapSize(std::size_t size) {
863 // Lock the table.
863 std::lock_guard lock{page_table_lock}; 864 std::lock_guard lock{page_table_lock};
864 heap_capacity = new_heap_capacity;
865 return ResultSuccess;
866}
867 865
868ResultVal<VAddr> KPageTable::SetHeapSize(std::size_t size) { 866 // Only process page tables are allowed to set heap size.
867 ASSERT(!this->IsKernel());
869 868
870 if (size > heap_region_end - heap_region_start) { 869 max_heap_size = size;
871 return ResultOutOfMemory;
872 }
873 870
874 const u64 previous_heap_size{GetHeapSize()}; 871 return ResultSuccess;
875 872}
876 UNIMPLEMENTED_IF_MSG(previous_heap_size > size, "Heap shrink is unimplemented");
877 873
878 // Increase the heap size 874ResultCode KPageTable::SetHeapSize(VAddr* out, std::size_t size) {
875 // Try to perform a reduction in heap, instead of an extension.
876 VAddr cur_address{};
877 std::size_t allocation_size{};
879 { 878 {
880 std::lock_guard lock{page_table_lock}; 879 // Lock the table.
881 880 std::lock_guard lk(page_table_lock);
882 const u64 delta{size - previous_heap_size}; 881
883 882 // Validate that setting heap size is possible at all.
884 // Reserve memory for the heap extension. 883 R_UNLESS(!is_kernel, ResultOutOfMemory);
885 KScopedResourceReservation memory_reservation( 884 R_UNLESS(size <= static_cast<std::size_t>(heap_region_end - heap_region_start),
886 system.Kernel().CurrentProcess()->GetResourceLimit(), LimitableResource::PhysicalMemory, 885 ResultOutOfMemory);
887 delta); 886 R_UNLESS(size <= max_heap_size, ResultOutOfMemory);
888 887
889 if (!memory_reservation.Succeeded()) { 888 if (size < GetHeapSize()) {
890 LOG_ERROR(Kernel, "Could not reserve heap extension of size {:X} bytes", delta); 889 // The size being requested is less than the current size, so we need to free the end of
891 return ResultLimitReached; 890 // the heap.
891
892 // Validate memory state.
893 std::size_t num_allocator_blocks;
894 R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks),
895 heap_region_start + size, GetHeapSize() - size,
896 KMemoryState::All, KMemoryState::Normal,
897 KMemoryPermission::All, KMemoryPermission::ReadAndWrite,
898 KMemoryAttribute::All, KMemoryAttribute::None));
899
900 // Unmap the end of the heap.
901 const auto num_pages = (GetHeapSize() - size) / PageSize;
902 R_TRY(Operate(heap_region_start + size, num_pages, KMemoryPermission::None,
903 OperationType::Unmap));
904
905 // Release the memory from the resource limit.
906 system.Kernel().CurrentProcess()->GetResourceLimit()->Release(
907 LimitableResource::PhysicalMemory, num_pages * PageSize);
908
909 // Apply the memory block update.
910 block_manager->Update(heap_region_start + size, num_pages, KMemoryState::Free,
911 KMemoryPermission::None, KMemoryAttribute::None);
912
913 // Update the current heap end.
914 current_heap_end = heap_region_start + size;
915
916 // Set the output.
917 *out = heap_region_start;
918 return ResultSuccess;
919 } else if (size == GetHeapSize()) {
920 // The size requested is exactly the current size.
921 *out = heap_region_start;
922 return ResultSuccess;
923 } else {
924 // We have to allocate memory. Determine how much to allocate and where while the table
925 // is locked.
926 cur_address = current_heap_end;
927 allocation_size = size - GetHeapSize();
892 } 928 }
929 }
893 930
894 KPageLinkedList page_linked_list; 931 // Reserve memory for the heap extension.
895 const std::size_t num_pages{delta / PageSize}; 932 KScopedResourceReservation memory_reservation(
933 system.Kernel().CurrentProcess()->GetResourceLimit(), LimitableResource::PhysicalMemory,
934 allocation_size);
935 R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
896 936
897 CASCADE_CODE( 937 // Allocate pages for the heap extension.
898 system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)); 938 KPageLinkedList page_linked_list;
939 R_TRY(system.Kernel().MemoryManager().Allocate(page_linked_list, allocation_size / PageSize,
940 memory_pool));
899 941
900 if (IsRegionMapped(current_heap_addr, delta)) { 942 // Map the pages.
901 return ResultInvalidCurrentMemory; 943 {
944 // Lock the table.
945 std::lock_guard lk(page_table_lock);
946
947 // Ensure that the heap hasn't changed since we began executing.
948 ASSERT(cur_address == current_heap_end);
949
950 // Check the memory state.
951 std::size_t num_allocator_blocks{};
952 R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), current_heap_end,
953 allocation_size, KMemoryState::All, KMemoryState::Free,
954 KMemoryPermission::None, KMemoryPermission::None,
955 KMemoryAttribute::None, KMemoryAttribute::None));
956
957 // Map the pages.
958 const auto num_pages = allocation_size / PageSize;
959 R_TRY(Operate(current_heap_end, num_pages, page_linked_list, OperationType::MapGroup));
960
961 // Clear all the newly allocated pages.
962 for (std::size_t cur_page = 0; cur_page < num_pages; ++cur_page) {
963 std::memset(system.Memory().GetPointer(current_heap_end + (cur_page * PageSize)), 0,
964 PageSize);
902 } 965 }
903 966
904 CASCADE_CODE( 967 // We succeeded, so commit our memory reservation.
905 Operate(current_heap_addr, num_pages, page_linked_list, OperationType::MapGroup));
906
907 // Succeeded in allocation, commit the resource reservation
908 memory_reservation.Commit(); 968 memory_reservation.Commit();
909 969
910 block_manager->Update(current_heap_addr, num_pages, KMemoryState::Normal, 970 // Apply the memory block update.
911 KMemoryPermission::ReadAndWrite); 971 block_manager->Update(current_heap_end, num_pages, KMemoryState::Normal,
972 KMemoryPermission::ReadAndWrite, KMemoryAttribute::None);
912 973
913 current_heap_addr = heap_region_start + size; 974 // Update the current heap end.
914 } 975 current_heap_end = heap_region_start + size;
915 976
916 return heap_region_start; 977 // Set the output.
978 *out = heap_region_start;
979 return ResultSuccess;
980 }
917} 981}
918 982
919ResultVal<VAddr> KPageTable::AllocateAndMapMemory(std::size_t needed_num_pages, std::size_t align, 983ResultVal<VAddr> KPageTable::AllocateAndMapMemory(std::size_t needed_num_pages, std::size_t align,
@@ -1005,7 +1069,7 @@ ResultCode KPageTable::LockForCodeMemory(VAddr addr, std::size_t size) {
1005 1069
1006 if (const ResultCode result{CheckMemoryState( 1070 if (const ResultCode result{CheckMemoryState(
1007 nullptr, &old_perm, nullptr, addr, size, KMemoryState::FlagCanCodeMemory, 1071 nullptr, &old_perm, nullptr, addr, size, KMemoryState::FlagCanCodeMemory,
1008 KMemoryState::FlagCanCodeMemory, KMemoryPermission::Mask, 1072 KMemoryState::FlagCanCodeMemory, KMemoryPermission::All,
1009 KMemoryPermission::UserReadWrite, KMemoryAttribute::All, KMemoryAttribute::None)}; 1073 KMemoryPermission::UserReadWrite, KMemoryAttribute::All, KMemoryAttribute::None)};
1010 result.IsError()) { 1074 result.IsError()) {
1011 return result; 1075 return result;
@@ -1058,9 +1122,8 @@ ResultCode KPageTable::InitializeMemoryLayout(VAddr start, VAddr end) {
1058 1122
1059bool KPageTable::IsRegionMapped(VAddr address, u64 size) { 1123bool KPageTable::IsRegionMapped(VAddr address, u64 size) {
1060 return CheckMemoryState(address, size, KMemoryState::All, KMemoryState::Free, 1124 return CheckMemoryState(address, size, KMemoryState::All, KMemoryState::Free,
1061 KMemoryPermission::Mask, KMemoryPermission::None, 1125 KMemoryPermission::All, KMemoryPermission::None, KMemoryAttribute::Mask,
1062 KMemoryAttribute::Mask, KMemoryAttribute::None, 1126 KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)
1063 KMemoryAttribute::IpcAndDeviceMapped)
1064 .IsError(); 1127 .IsError();
1065} 1128}
1066 1129
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h
index db08ea8ce..564410dca 100644
--- a/src/core/hle/kernel/k_page_table.h
+++ b/src/core/hle/kernel/k_page_table.h
@@ -50,8 +50,8 @@ public:
50 ResultCode SetMemoryPermission(VAddr addr, std::size_t size, Svc::MemoryPermission perm); 50 ResultCode SetMemoryPermission(VAddr addr, std::size_t size, Svc::MemoryPermission perm);
51 ResultCode SetMemoryAttribute(VAddr addr, std::size_t size, KMemoryAttribute mask, 51 ResultCode SetMemoryAttribute(VAddr addr, std::size_t size, KMemoryAttribute mask,
52 KMemoryAttribute value); 52 KMemoryAttribute value);
53 ResultCode SetHeapCapacity(std::size_t new_heap_capacity); 53 ResultCode SetMaxHeapSize(std::size_t size);
54 ResultVal<VAddr> SetHeapSize(std::size_t size); 54 ResultCode SetHeapSize(VAddr* out, std::size_t size);
55 ResultVal<VAddr> AllocateAndMapMemory(std::size_t needed_num_pages, std::size_t align, 55 ResultVal<VAddr> AllocateAndMapMemory(std::size_t needed_num_pages, std::size_t align,
56 bool is_map_only, VAddr region_start, 56 bool is_map_only, VAddr region_start,
57 std::size_t region_num_pages, KMemoryState state, 57 std::size_t region_num_pages, KMemoryState state,
@@ -183,14 +183,15 @@ public:
183 constexpr VAddr GetAliasCodeRegionSize() const { 183 constexpr VAddr GetAliasCodeRegionSize() const {
184 return alias_code_region_end - alias_code_region_start; 184 return alias_code_region_end - alias_code_region_start;
185 } 185 }
186 size_t GetNormalMemorySize() {
187 std::lock_guard lk(page_table_lock);
188 return GetHeapSize() + mapped_physical_memory_size;
189 }
186 constexpr std::size_t GetAddressSpaceWidth() const { 190 constexpr std::size_t GetAddressSpaceWidth() const {
187 return address_space_width; 191 return address_space_width;
188 } 192 }
189 constexpr std::size_t GetHeapSize() { 193 constexpr std::size_t GetHeapSize() const {
190 return current_heap_addr - heap_region_start; 194 return current_heap_end - heap_region_start;
191 }
192 constexpr std::size_t GetTotalHeapSize() {
193 return GetHeapSize() + physical_memory_usage;
194 } 195 }
195 constexpr bool IsInsideAddressSpace(VAddr address, std::size_t size) const { 196 constexpr bool IsInsideAddressSpace(VAddr address, std::size_t size) const {
196 return address_space_start <= address && address + size - 1 <= address_space_end - 1; 197 return address_space_start <= address && address + size - 1 <= address_space_end - 1;
@@ -270,10 +271,8 @@ private:
270 VAddr code_region_end{}; 271 VAddr code_region_end{};
271 VAddr alias_code_region_start{}; 272 VAddr alias_code_region_start{};
272 VAddr alias_code_region_end{}; 273 VAddr alias_code_region_end{};
273 VAddr current_heap_addr{};
274 274
275 std::size_t heap_capacity{}; 275 std::size_t mapped_physical_memory_size{};
276 std::size_t physical_memory_usage{};
277 std::size_t max_heap_size{}; 276 std::size_t max_heap_size{};
278 std::size_t max_physical_memory_size{}; 277 std::size_t max_physical_memory_size{};
279 std::size_t address_space_width{}; 278 std::size_t address_space_width{};
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index aee313995..73f8bc4fe 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -172,7 +172,7 @@ void KProcess::DecrementThreadCount() {
172 172
173u64 KProcess::GetTotalPhysicalMemoryAvailable() const { 173u64 KProcess::GetTotalPhysicalMemoryAvailable() const {
174 const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) + 174 const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) +
175 page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + 175 page_table->GetNormalMemorySize() + GetSystemResourceSize() + image_size +
176 main_thread_stack_size}; 176 main_thread_stack_size};
177 if (const auto pool_size = kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application); 177 if (const auto pool_size = kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application);
178 capacity != pool_size) { 178 capacity != pool_size) {
@@ -189,7 +189,7 @@ u64 KProcess::GetTotalPhysicalMemoryAvailableWithoutSystemResource() const {
189} 189}
190 190
191u64 KProcess::GetTotalPhysicalMemoryUsed() const { 191u64 KProcess::GetTotalPhysicalMemoryUsed() const {
192 return image_size + main_thread_stack_size + page_table->GetTotalHeapSize() + 192 return image_size + main_thread_stack_size + page_table->GetNormalMemorySize() +
193 GetSystemResourceSize(); 193 GetSystemResourceSize();
194} 194}
195 195
@@ -410,8 +410,8 @@ void KProcess::Run(s32 main_thread_priority, u64 stack_size) {
410 resource_limit->Reserve(LimitableResource::Threads, 1); 410 resource_limit->Reserve(LimitableResource::Threads, 1);
411 resource_limit->Reserve(LimitableResource::PhysicalMemory, main_thread_stack_size); 411 resource_limit->Reserve(LimitableResource::PhysicalMemory, main_thread_stack_size);
412 412
413 const std::size_t heap_capacity{memory_usage_capacity - main_thread_stack_size - image_size}; 413 const std::size_t heap_capacity{memory_usage_capacity - (main_thread_stack_size + image_size)};
414 ASSERT(!page_table->SetHeapCapacity(heap_capacity).IsError()); 414 ASSERT(!page_table->SetMaxHeapSize(heap_capacity).IsError());
415 415
416 ChangeStatus(ProcessStatus::Running); 416 ChangeStatus(ProcessStatus::Running);
417 417
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 68cb47211..63e2dff19 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -135,24 +135,15 @@ enum class ResourceLimitValueType {
135} // Anonymous namespace 135} // Anonymous namespace
136 136
137/// Set the process heap to a given Size. It can both extend and shrink the heap. 137/// Set the process heap to a given Size. It can both extend and shrink the heap.
138static ResultCode SetHeapSize(Core::System& system, VAddr* heap_addr, u64 heap_size) { 138static ResultCode SetHeapSize(Core::System& system, VAddr* out_address, u64 size) {
139 LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size); 139 LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", size);
140 140
141 // Size must be a multiple of 0x200000 (2MB) and be equal to or less than 8GB. 141 // Validate size.
142 if ((heap_size % 0x200000) != 0) { 142 R_UNLESS(Common::IsAligned(size, HeapSizeAlignment), ResultInvalidSize);
143 LOG_ERROR(Kernel_SVC, "The heap size is not a multiple of 2MB, heap_size=0x{:016X}", 143 R_UNLESS(size < MainMemorySizeMax, ResultInvalidSize);
144 heap_size);
145 return ResultInvalidSize;
146 }
147
148 if (heap_size >= 0x200000000) {
149 LOG_ERROR(Kernel_SVC, "The heap size is not less than 8GB, heap_size=0x{:016X}", heap_size);
150 return ResultInvalidSize;
151 }
152
153 auto& page_table{system.Kernel().CurrentProcess()->PageTable()};
154 144
155 CASCADE_RESULT(*heap_addr, page_table.SetHeapSize(heap_size)); 145 // Set the heap size.
146 R_TRY(system.Kernel().CurrentProcess()->PageTable().SetHeapSize(out_address, size));
156 147
157 return ResultSuccess; 148 return ResultSuccess;
158} 149}
diff --git a/src/core/hle/kernel/svc_common.h b/src/core/hle/kernel/svc_common.h
index 60ea2c405..25de6e437 100644
--- a/src/core/hle/kernel/svc_common.h
+++ b/src/core/hle/kernel/svc_common.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "common/literals.h"
8 9
9namespace Kernel { 10namespace Kernel {
10using Handle = u32; 11using Handle = u32;
@@ -12,9 +13,13 @@ using Handle = u32;
12 13
13namespace Kernel::Svc { 14namespace Kernel::Svc {
14 15
16using namespace Common::Literals;
17
15constexpr s32 ArgumentHandleCountMax = 0x40; 18constexpr s32 ArgumentHandleCountMax = 0x40;
16constexpr u32 HandleWaitMask{1u << 30}; 19constexpr u32 HandleWaitMask{1u << 30};
17 20
21constexpr inline std::size_t HeapSizeAlignment = 2_MiB;
22
18constexpr inline Handle InvalidHandle = Handle(0); 23constexpr inline Handle InvalidHandle = Handle(0);
19 24
20enum PseudoHandle : Handle { 25enum PseudoHandle : Handle {