summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ameerj2021-02-12 19:05:24 -0500
committerGravatar ameerj2021-02-12 19:05:24 -0500
commitec9b6641b12aa04ae3d7782b0423037dbc1400ac (patch)
treefc563f28673dfe851cfaf665951423e0ad759025 /src
parentkernel: KScopedReservation implementation (diff)
downloadyuzu-ec9b6641b12aa04ae3d7782b0423037dbc1400ac.tar.gz
yuzu-ec9b6641b12aa04ae3d7782b0423037dbc1400ac.tar.xz
yuzu-ec9b6641b12aa04ae3d7782b0423037dbc1400ac.zip
kernel: More accurately reserve and release resources
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/kernel.cpp15
-rw-r--r--src/core/hle/kernel/process.cpp3
-rw-r--r--src/core/hle/kernel/session.cpp11
-rw-r--r--src/core/hle/kernel/shared_memory.cpp4
-rw-r--r--src/core/hle/kernel/svc.cpp21
-rw-r--r--src/core/hle/kernel/transfer_memory.cpp2
6 files changed, 42 insertions, 14 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 8da5a5c86..b6e6f115e 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -141,11 +141,17 @@ struct KernelCore::Impl {
141 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 700).IsSuccess()); 141 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 700).IsSuccess());
142 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200) 142 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200)
143 .IsSuccess()); 143 .IsSuccess());
144 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 900).IsSuccess()); 144 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 933).IsSuccess());
145 145
146 if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemory, 0x60000)) { 146 // Derived from recent software updates. The kernel reserves 27MB
147 constexpr u64 kernel_size{0x1b00000};
148 if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemory, kernel_size)) {
147 UNREACHABLE(); 149 UNREACHABLE();
148 } 150 }
151 // Reserve secure applet memory, introduced in firmware 5.0.0
152 constexpr u64 secure_applet_memory_size{0x400000};
153 ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory,
154 secure_applet_memory_size));
149 } 155 }
150 156
151 void InitializePreemption(KernelCore& kernel) { 157 void InitializePreemption(KernelCore& kernel) {
@@ -302,8 +308,11 @@ struct KernelCore::Impl {
302 // Allocate slab heaps 308 // Allocate slab heaps
303 user_slab_heap_pages = std::make_unique<Memory::SlabHeap<Memory::Page>>(); 309 user_slab_heap_pages = std::make_unique<Memory::SlabHeap<Memory::Page>>();
304 310
311 constexpr u64 user_slab_heap_size{0x1ef000};
312 // Reserve slab heaps
313 ASSERT(
314 system_resource_limit->Reserve(LimitableResource::PhysicalMemory, user_slab_heap_size));
305 // Initialize slab heaps 315 // Initialize slab heaps
306 constexpr u64 user_slab_heap_size{0x3de000};
307 user_slab_heap_pages->Initialize( 316 user_slab_heap_pages->Initialize(
308 system.DeviceMemory().GetPointer(Core::DramMemoryMap::SlabHeapBase), 317 system.DeviceMemory().GetPointer(Core::DramMemoryMap::SlabHeapBase),
309 user_slab_heap_size); 318 user_slab_heap_size);
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 05e21830c..47b3ac57b 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -39,6 +39,7 @@ namespace {
39 */ 39 */
40void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, VAddr stack_top) { 40void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, VAddr stack_top) {
41 const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart(); 41 const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart();
42 ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::Threads, 1));
42 auto thread_res = KThread::Create(system, ThreadType::User, "main", entry_point, priority, 0, 43 auto thread_res = KThread::Create(system, ThreadType::User, "main", entry_point, priority, 0,
43 owner_process.GetIdealCoreId(), stack_top, &owner_process); 44 owner_process.GetIdealCoreId(), stack_top, &owner_process);
44 45
@@ -279,7 +280,7 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
279 if (!memory_reservation.Succeeded()) { 280 if (!memory_reservation.Succeeded()) {
280 LOG_ERROR(Kernel, "Could not reserve process memory requirements of size {:X} bytes", 281 LOG_ERROR(Kernel, "Could not reserve process memory requirements of size {:X} bytes",
281 code_size + system_resource_size); 282 code_size + system_resource_size);
282 return ERR_RESOURCE_LIMIT_EXCEEDED; 283 return ResultResourceLimitedExceeded;
283 } 284 }
284 // Initialize proces address space 285 // Initialize proces address space
285 if (const ResultCode result{ 286 if (const ResultCode result{
diff --git a/src/core/hle/kernel/session.cpp b/src/core/hle/kernel/session.cpp
index 75304b961..8830d4e91 100644
--- a/src/core/hle/kernel/session.cpp
+++ b/src/core/hle/kernel/session.cpp
@@ -4,15 +4,23 @@
4 4
5#include "common/assert.h" 5#include "common/assert.h"
6#include "core/hle/kernel/client_session.h" 6#include "core/hle/kernel/client_session.h"
7#include "core/hle/kernel/k_scoped_resource_reservation.h"
7#include "core/hle/kernel/server_session.h" 8#include "core/hle/kernel/server_session.h"
8#include "core/hle/kernel/session.h" 9#include "core/hle/kernel/session.h"
9 10
10namespace Kernel { 11namespace Kernel {
11 12
12Session::Session(KernelCore& kernel) : KSynchronizationObject{kernel} {} 13Session::Session(KernelCore& kernel) : KSynchronizationObject{kernel} {}
13Session::~Session() = default; 14Session::~Session() {
15 // Release reserved resource when the Session pair was created.
16 kernel.GetSystemResourceLimit()->Release(LimitableResource::Sessions, 1);
17}
14 18
15Session::SessionPair Session::Create(KernelCore& kernel, std::string name) { 19Session::SessionPair Session::Create(KernelCore& kernel, std::string name) {
20 // Reserve a new session from the resource limit.
21 KScopedResourceReservation session_reservation(kernel.GetSystemResourceLimit(),
22 LimitableResource::Sessions);
23 ASSERT(session_reservation.Succeeded());
16 auto session{std::make_shared<Session>(kernel)}; 24 auto session{std::make_shared<Session>(kernel)};
17 auto client_session{Kernel::ClientSession::Create(kernel, session, name + "_Client").Unwrap()}; 25 auto client_session{Kernel::ClientSession::Create(kernel, session, name + "_Client").Unwrap()};
18 auto server_session{Kernel::ServerSession::Create(kernel, session, name + "_Server").Unwrap()}; 26 auto server_session{Kernel::ServerSession::Create(kernel, session, name + "_Server").Unwrap()};
@@ -21,6 +29,7 @@ Session::SessionPair Session::Create(KernelCore& kernel, std::string name) {
21 session->client = client_session; 29 session->client = client_session;
22 session->server = server_session; 30 session->server = server_session;
23 31
32 session_reservation.Commit();
24 return std::make_pair(std::move(client_session), std::move(server_session)); 33 return std::make_pair(std::move(client_session), std::move(server_session));
25} 34}
26 35
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index 67d748561..2eadd51d7 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -14,7 +14,9 @@ namespace Kernel {
14SharedMemory::SharedMemory(KernelCore& kernel, Core::DeviceMemory& device_memory) 14SharedMemory::SharedMemory(KernelCore& kernel, Core::DeviceMemory& device_memory)
15 : Object{kernel}, device_memory{device_memory} {} 15 : Object{kernel}, device_memory{device_memory} {}
16 16
17SharedMemory::~SharedMemory() = default; 17SharedMemory::~SharedMemory() {
18 kernel.GetSystemResourceLimit()->Release(LimitableResource::PhysicalMemory, size);
19}
18 20
19std::shared_ptr<SharedMemory> SharedMemory::Create( 21std::shared_ptr<SharedMemory> SharedMemory::Create(
20 KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process, 22 KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process,
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 1d377ffe6..31d899e06 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -138,6 +138,7 @@ ResultCode MapUnmapMemorySanityChecks(const Memory::PageTable& manager, VAddr ds
138enum class ResourceLimitValueType { 138enum class ResourceLimitValueType {
139 CurrentValue, 139 CurrentValue,
140 LimitValue, 140 LimitValue,
141 PeakValue,
141}; 142};
142 143
143ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit, 144ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit,
@@ -160,11 +161,17 @@ ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_
160 return ResultInvalidHandle; 161 return ResultInvalidHandle;
161 } 162 }
162 163
163 if (value_type == ResourceLimitValueType::CurrentValue) { 164 switch (value_type) {
165 case ResourceLimitValueType::CurrentValue:
164 return MakeResult(resource_limit_object->GetCurrentValue(type)); 166 return MakeResult(resource_limit_object->GetCurrentValue(type));
167 case ResourceLimitValueType::LimitValue:
168 return MakeResult(resource_limit_object->GetLimitValue(type));
169 case ResourceLimitValueType::PeakValue:
170 return MakeResult(resource_limit_object->GetPeakValue(type));
171 default:
172 LOG_ERROR(Kernel_SVC, "Invalid resource value_type: '{}'", value_type);
173 return ResultInvalidEnumValue;
165 } 174 }
166
167 return MakeResult(resource_limit_object->GetLimitValue(type));
168} 175}
169} // Anonymous namespace 176} // Anonymous namespace
170 177
@@ -314,8 +321,6 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle,
314 return ResultNotFound; 321 return ResultNotFound;
315 } 322 }
316 323
317 ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(LimitableResource::Sessions, 1));
318
319 auto client_port = it->second; 324 auto client_port = it->second;
320 325
321 std::shared_ptr<ClientSession> client_session; 326 std::shared_ptr<ClientSession> client_session;
@@ -1522,7 +1527,7 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
1522 system.CoreTiming().GetGlobalTimeNs().count() + 100000000); 1527 system.CoreTiming().GetGlobalTimeNs().count() + 100000000);
1523 if (!thread_reservation.Succeeded()) { 1528 if (!thread_reservation.Succeeded()) {
1524 LOG_ERROR(Kernel_SVC, "Could not reserve a new thread"); 1529 LOG_ERROR(Kernel_SVC, "Could not reserve a new thread");
1525 return ERR_RESOURCE_LIMIT_EXCEEDED; 1530 return ResultResourceLimitedExceeded;
1526 } 1531 }
1527 1532
1528 std::shared_ptr<KThread> thread; 1533 std::shared_ptr<KThread> thread;
@@ -1896,7 +1901,7 @@ static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAd
1896 LimitableResource::TransferMemory); 1901 LimitableResource::TransferMemory);
1897 if (!trmem_reservation.Succeeded()) { 1902 if (!trmem_reservation.Succeeded()) {
1898 LOG_ERROR(Kernel_SVC, "Could not reserve a new transfer memory"); 1903 LOG_ERROR(Kernel_SVC, "Could not reserve a new transfer memory");
1899 return ERR_RESOURCE_LIMIT_EXCEEDED; 1904 return ResultResourceLimitedExceeded;
1900 } 1905 }
1901 auto transfer_mem_handle = TransferMemory::Create(kernel, system.Memory(), addr, size, perms); 1906 auto transfer_mem_handle = TransferMemory::Create(kernel, system.Memory(), addr, size, perms);
1902 1907
@@ -2026,7 +2031,7 @@ static ResultCode SignalEvent(Core::System& system, Handle event_handle) {
2026 LimitableResource::Events); 2031 LimitableResource::Events);
2027 if (!event_reservation.Succeeded()) { 2032 if (!event_reservation.Succeeded()) {
2028 LOG_ERROR(Kernel, "Could not reserve a new event"); 2033 LOG_ERROR(Kernel, "Could not reserve a new event");
2029 return ERR_RESOURCE_LIMIT_EXCEEDED; 2034 return ResultResourceLimitedExceeded;
2030 } 2035 }
2031 2036
2032 // Get the writable event. 2037 // Get the writable event.
diff --git a/src/core/hle/kernel/transfer_memory.cpp b/src/core/hle/kernel/transfer_memory.cpp
index 765f408c3..6b0fc1591 100644
--- a/src/core/hle/kernel/transfer_memory.cpp
+++ b/src/core/hle/kernel/transfer_memory.cpp
@@ -2,6 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/kernel/k_resource_limit.h"
5#include "core/hle/kernel/kernel.h" 6#include "core/hle/kernel/kernel.h"
6#include "core/hle/kernel/memory/page_table.h" 7#include "core/hle/kernel/memory/page_table.h"
7#include "core/hle/kernel/process.h" 8#include "core/hle/kernel/process.h"
@@ -17,6 +18,7 @@ TransferMemory::TransferMemory(KernelCore& kernel, Core::Memory::Memory& memory)
17TransferMemory::~TransferMemory() { 18TransferMemory::~TransferMemory() {
18 // Release memory region when transfer memory is destroyed 19 // Release memory region when transfer memory is destroyed
19 Reset(); 20 Reset();
21 owner_process->GetResourceLimit()->Release(LimitableResource::TransferMemory, 1);
20} 22}
21 23
22std::shared_ptr<TransferMemory> TransferMemory::Create(KernelCore& kernel, 24std::shared_ptr<TransferMemory> TransferMemory::Create(KernelCore& kernel,