mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-22 20:06:40 +00:00
kern: implement new default application system resource field in KProcess
This commit is contained in:
parent
2c5002ce50
commit
39a95d4023
2 changed files with 70 additions and 26 deletions
|
@ -76,6 +76,7 @@ namespace ams::kern {
|
||||||
bool m_is_signaled;
|
bool m_is_signaled;
|
||||||
bool m_is_initialized;
|
bool m_is_initialized;
|
||||||
bool m_is_application;
|
bool m_is_application;
|
||||||
|
bool m_is_default_application_system_resource;
|
||||||
char m_name[13];
|
char m_name[13];
|
||||||
util::Atomic<u16> m_num_running_threads;
|
util::Atomic<u16> m_num_running_threads;
|
||||||
u32 m_flags;
|
u32 m_flags;
|
||||||
|
@ -178,6 +179,8 @@ namespace ams::kern {
|
||||||
|
|
||||||
constexpr bool IsApplication() const { return m_is_application; }
|
constexpr bool IsApplication() const { return m_is_application; }
|
||||||
|
|
||||||
|
constexpr bool IsDefaultApplicationSystemResource() const { return m_is_default_application_system_resource; }
|
||||||
|
|
||||||
constexpr bool IsSuspended() const { return m_is_suspended; }
|
constexpr bool IsSuspended() const { return m_is_suspended; }
|
||||||
constexpr void SetSuspended(bool suspended) { m_is_suspended = suspended; }
|
constexpr void SetSuspended(bool suspended) { m_is_suspended = suspended; }
|
||||||
|
|
||||||
|
@ -280,12 +283,20 @@ namespace ams::kern {
|
||||||
void IncrementRunningThreadCount();
|
void IncrementRunningThreadCount();
|
||||||
void DecrementRunningThreadCount();
|
void DecrementRunningThreadCount();
|
||||||
|
|
||||||
|
size_t GetRequiredSecureMemorySizeNonDefault() const {
|
||||||
|
return (!this->IsDefaultApplicationSystemResource() && m_system_resource->IsSecureResource()) ? static_cast<KSecureSystemResource *>(m_system_resource)->CalculateRequiredSecureMemorySize() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetRequiredSecureMemorySize() const {
|
||||||
|
return m_system_resource->IsSecureResource() ? static_cast<KSecureSystemResource *>(m_system_resource)->CalculateRequiredSecureMemorySize() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
size_t GetTotalSystemResourceSize() const {
|
size_t GetTotalSystemResourceSize() const {
|
||||||
return m_system_resource->IsSecureResource() ? static_cast<KSecureSystemResource *>(m_system_resource)->GetSize() : 0;
|
return (!this->IsDefaultApplicationSystemResource() && m_system_resource->IsSecureResource()) ? static_cast<KSecureSystemResource *>(m_system_resource)->GetSize() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GetUsedSystemResourceSize() const {
|
size_t GetUsedSystemResourceSize() const {
|
||||||
return m_system_resource->IsSecureResource() ? static_cast<KSecureSystemResource *>(m_system_resource)->GetUsedSize() : 0;
|
return (!this->IsDefaultApplicationSystemResource() && m_system_resource->IsSecureResource()) ? static_cast<KSecureSystemResource *>(m_system_resource)->GetUsedSize() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetRunningThread(s32 core, KThread *thread, u64 idle_count, u64 switch_count) {
|
void SetRunningThread(s32 core, KThread *thread, u64 idle_count, u64 switch_count) {
|
||||||
|
|
|
@ -263,28 +263,47 @@ namespace ams::kern {
|
||||||
MESOSPHERE_ASSERT(res_limit != nullptr);
|
MESOSPHERE_ASSERT(res_limit != nullptr);
|
||||||
MESOSPHERE_ABORT_UNLESS((params.code_num_pages * PageSize) / PageSize == static_cast<size_t>(params.code_num_pages));
|
MESOSPHERE_ABORT_UNLESS((params.code_num_pages * PageSize) / PageSize == static_cast<size_t>(params.code_num_pages));
|
||||||
|
|
||||||
/* Determine is application. */
|
|
||||||
const bool is_app = (params.flags & ams::svc::CreateProcessFlag_IsApplication) != 0;
|
|
||||||
|
|
||||||
/* Set members. */
|
/* Set members. */
|
||||||
m_memory_pool = pool;
|
m_memory_pool = pool;
|
||||||
m_resource_limit = res_limit;
|
m_resource_limit = res_limit;
|
||||||
m_system_resource = std::addressof(is_app ? Kernel::GetApplicationSystemResource() : Kernel::GetSystemSystemResource());
|
m_is_default_application_system_resource = false;
|
||||||
m_is_immortal = immortal;
|
m_is_immortal = immortal;
|
||||||
|
|
||||||
/* Open reference to our system resource. */
|
/* Setup our system resource. */
|
||||||
m_system_resource->Open();
|
if (const size_t system_resource_num_pages = params.system_resource_num_pages; system_resource_num_pages != 0) {
|
||||||
|
/* Create a secure system resource. */
|
||||||
|
KSecureSystemResource *secure_resource = KSecureSystemResource::Create();
|
||||||
|
R_UNLESS(secure_resource != nullptr, svc::ResultOutOfResource());
|
||||||
|
|
||||||
|
ON_RESULT_FAILURE { secure_resource->Close(); };
|
||||||
|
|
||||||
|
/* Initialize the secure resource. */
|
||||||
|
R_TRY(secure_resource->Initialize(system_resource_num_pages * PageSize, m_resource_limit, m_memory_pool));
|
||||||
|
|
||||||
|
/* Set our system resource. */
|
||||||
|
m_system_resource = secure_resource;
|
||||||
|
} else {
|
||||||
|
/* Use the system-wide system resource. */
|
||||||
|
const bool is_app = (params.flags & ams::svc::CreateProcessFlag_IsApplication);
|
||||||
|
m_system_resource = std::addressof(is_app ? Kernel::GetApplicationSystemResource() : Kernel::GetSystemSystemResource());
|
||||||
|
|
||||||
|
m_is_default_application_system_resource = is_app;
|
||||||
|
|
||||||
|
/* Open reference to the system resource. */
|
||||||
|
m_system_resource->Open();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure we clean up our secure resource, if we fail. */
|
||||||
|
ON_RESULT_FAILURE { m_system_resource->Close(); };
|
||||||
|
|
||||||
/* Setup page table. */
|
/* Setup page table. */
|
||||||
/* NOTE: Nintendo passes process ID despite not having set it yet. */
|
|
||||||
/* This goes completely unused, but even so... */
|
|
||||||
{
|
{
|
||||||
const auto as_type = static_cast<ams::svc::CreateProcessFlag>(params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask);
|
const auto as_type = static_cast<ams::svc::CreateProcessFlag>(params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask);
|
||||||
const bool enable_aslr = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) != 0;
|
const bool enable_aslr = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) != 0;
|
||||||
const bool enable_das_merge = (params.flags & ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge) == 0;
|
const bool enable_das_merge = (params.flags & ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge) == 0;
|
||||||
R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, params.code_address, params.code_num_pages * PageSize, m_system_resource, res_limit));
|
R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, params.code_address, params.code_num_pages * PageSize, m_system_resource, res_limit));
|
||||||
}
|
}
|
||||||
ON_RESULT_FAILURE { m_page_table.Finalize(); };
|
ON_RESULT_FAILURE_2 { m_page_table.Finalize(); };
|
||||||
|
|
||||||
/* Ensure we can insert the code region. */
|
/* Ensure we can insert the code region. */
|
||||||
R_UNLESS(m_page_table.CanContain(params.code_address, params.code_num_pages * PageSize, KMemoryState_Code), svc::ResultInvalidMemoryRegion());
|
R_UNLESS(m_page_table.CanContain(params.code_address, params.code_num_pages * PageSize, KMemoryState_Code), svc::ResultInvalidMemoryRegion());
|
||||||
|
@ -315,9 +334,10 @@ namespace ams::kern {
|
||||||
MESOSPHERE_ASSERT(res_limit != nullptr);
|
MESOSPHERE_ASSERT(res_limit != nullptr);
|
||||||
|
|
||||||
/* Set pool and resource limit. */
|
/* Set pool and resource limit. */
|
||||||
m_memory_pool = pool;
|
m_memory_pool = pool;
|
||||||
m_resource_limit = res_limit;
|
m_resource_limit = res_limit;
|
||||||
m_is_immortal = false;
|
m_is_default_application_system_resource = false;
|
||||||
|
m_is_immortal = false;
|
||||||
|
|
||||||
/* Get the memory sizes. */
|
/* Get the memory sizes. */
|
||||||
const size_t code_num_pages = params.code_num_pages;
|
const size_t code_num_pages = params.code_num_pages;
|
||||||
|
@ -348,6 +368,8 @@ namespace ams::kern {
|
||||||
const bool is_app = (params.flags & ams::svc::CreateProcessFlag_IsApplication);
|
const bool is_app = (params.flags & ams::svc::CreateProcessFlag_IsApplication);
|
||||||
m_system_resource = std::addressof(is_app ? Kernel::GetApplicationSystemResource() : Kernel::GetSystemSystemResource());
|
m_system_resource = std::addressof(is_app ? Kernel::GetApplicationSystemResource() : Kernel::GetSystemSystemResource());
|
||||||
|
|
||||||
|
m_is_default_application_system_resource = is_app;
|
||||||
|
|
||||||
/* Open reference to the system resource. */
|
/* Open reference to the system resource. */
|
||||||
m_system_resource->Open();
|
m_system_resource->Open();
|
||||||
}
|
}
|
||||||
|
@ -356,8 +378,6 @@ namespace ams::kern {
|
||||||
ON_RESULT_FAILURE { m_system_resource->Close(); };
|
ON_RESULT_FAILURE { m_system_resource->Close(); };
|
||||||
|
|
||||||
/* Setup page table. */
|
/* Setup page table. */
|
||||||
/* NOTE: Nintendo passes process ID despite not having set it yet. */
|
|
||||||
/* This goes completely unused, but even so... */
|
|
||||||
{
|
{
|
||||||
const auto as_type = static_cast<ams::svc::CreateProcessFlag>(params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask);
|
const auto as_type = static_cast<ams::svc::CreateProcessFlag>(params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask);
|
||||||
const bool enable_aslr = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) != 0;
|
const bool enable_aslr = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) != 0;
|
||||||
|
@ -848,7 +868,7 @@ namespace ams::kern {
|
||||||
size_t KProcess::GetUsedUserPhysicalMemorySize() const {
|
size_t KProcess::GetUsedUserPhysicalMemorySize() const {
|
||||||
const size_t norm_size = m_page_table.GetNormalMemorySize();
|
const size_t norm_size = m_page_table.GetNormalMemorySize();
|
||||||
const size_t other_size = m_code_size + m_main_thread_stack_size;
|
const size_t other_size = m_code_size + m_main_thread_stack_size;
|
||||||
const size_t sec_size = m_system_resource->IsSecureResource() ? static_cast<KSecureSystemResource *>(m_system_resource)->CalculateRequiredSecureMemorySize() : 0;
|
const size_t sec_size = this->GetRequiredSecureMemorySizeNonDefault();
|
||||||
|
|
||||||
return norm_size + other_size + sec_size;
|
return norm_size + other_size + sec_size;
|
||||||
}
|
}
|
||||||
|
@ -856,13 +876,20 @@ namespace ams::kern {
|
||||||
size_t KProcess::GetTotalUserPhysicalMemorySize() const {
|
size_t KProcess::GetTotalUserPhysicalMemorySize() const {
|
||||||
/* Get the amount of free and used size. */
|
/* Get the amount of free and used size. */
|
||||||
const size_t free_size = m_resource_limit->GetFreeValue(ams::svc::LimitableResource_PhysicalMemoryMax);
|
const size_t free_size = m_resource_limit->GetFreeValue(ams::svc::LimitableResource_PhysicalMemoryMax);
|
||||||
const size_t used_size = this->GetUsedUserPhysicalMemorySize();
|
|
||||||
const size_t max_size = m_max_process_memory;
|
const size_t max_size = m_max_process_memory;
|
||||||
|
|
||||||
|
/* Determine used size. */
|
||||||
|
/* NOTE: This does *not* check this->IsDefaultApplicationSystemResource(), unlike GetUsedUserPhysicalMemorySize(). */
|
||||||
|
const size_t norm_size = m_page_table.GetNormalMemorySize();
|
||||||
|
const size_t other_size = m_code_size + m_main_thread_stack_size;
|
||||||
|
const size_t sec_size = this->GetRequiredSecureMemorySize();
|
||||||
|
const size_t used_size = norm_size + other_size + sec_size;
|
||||||
|
|
||||||
|
/* NOTE: These function calls will recalculate, introducing a race...it is unclear why Nintendo does it this way. */
|
||||||
if (used_size + free_size > max_size) {
|
if (used_size + free_size > max_size) {
|
||||||
return max_size;
|
return max_size;
|
||||||
} else {
|
} else {
|
||||||
return free_size + used_size;
|
return free_size + this->GetUsedUserPhysicalMemorySize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -876,14 +903,20 @@ namespace ams::kern {
|
||||||
size_t KProcess::GetTotalNonSystemUserPhysicalMemorySize() const {
|
size_t KProcess::GetTotalNonSystemUserPhysicalMemorySize() const {
|
||||||
/* Get the amount of free and used size. */
|
/* Get the amount of free and used size. */
|
||||||
const size_t free_size = m_resource_limit->GetFreeValue(ams::svc::LimitableResource_PhysicalMemoryMax);
|
const size_t free_size = m_resource_limit->GetFreeValue(ams::svc::LimitableResource_PhysicalMemoryMax);
|
||||||
const size_t used_size = this->GetUsedUserPhysicalMemorySize();
|
|
||||||
const size_t sec_size = m_system_resource->IsSecureResource() ? static_cast<KSecureSystemResource *>(m_system_resource)->CalculateRequiredSecureMemorySize() : 0;
|
|
||||||
const size_t max_size = m_max_process_memory;
|
const size_t max_size = m_max_process_memory;
|
||||||
|
|
||||||
|
/* Determine used size. */
|
||||||
|
/* NOTE: This does *not* check this->IsDefaultApplicationSystemResource(), unlike GetUsedUserPhysicalMemorySize(). */
|
||||||
|
const size_t norm_size = m_page_table.GetNormalMemorySize();
|
||||||
|
const size_t other_size = m_code_size + m_main_thread_stack_size;
|
||||||
|
const size_t sec_size = this->GetRequiredSecureMemorySize();
|
||||||
|
const size_t used_size = norm_size + other_size + sec_size;
|
||||||
|
|
||||||
|
/* NOTE: These function calls will recalculate, introducing a race...it is unclear why Nintendo does it this way. */
|
||||||
if (used_size + free_size > max_size) {
|
if (used_size + free_size > max_size) {
|
||||||
return max_size - sec_size;
|
return max_size - this->GetRequiredSecureMemorySizeNonDefault();
|
||||||
} else {
|
} else {
|
||||||
return free_size + used_size - sec_size;
|
return free_size + this->GetUsedNonSystemUserPhysicalMemorySize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue