diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_resource_limit.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_resource_limit.hpp index 286992183..8bfb6af05 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_resource_limit.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_resource_limit.hpp @@ -28,11 +28,12 @@ namespace ams::kern { s64 limit_values[ams::svc::LimitableResource_Count]; s64 current_values[ams::svc::LimitableResource_Count]; s64 current_hints[ams::svc::LimitableResource_Count]; + s64 peak_values[ams::svc::LimitableResource_Count]; mutable KLightLock lock; s32 waiter_count; KLightConditionVariable cond_var; public: - constexpr ALWAYS_INLINE KResourceLimit() : limit_values(), current_values(), current_hints(), lock(), waiter_count(), cond_var() { /* ... */ } + constexpr ALWAYS_INLINE KResourceLimit() : limit_values(), current_values(), current_hints(), peak_values(), lock(), waiter_count(), cond_var() { /* ... */ } virtual ~KResourceLimit() { /* ... */ } static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ } @@ -42,6 +43,7 @@ namespace ams::kern { s64 GetLimitValue(ams::svc::LimitableResource which) const; s64 GetCurrentValue(ams::svc::LimitableResource which) const; + s64 GetPeakValue(ams::svc::LimitableResource which) const; s64 GetFreeValue(ams::svc::LimitableResource which) const; Result SetLimitValue(ams::svc::LimitableResource which, s64 value); diff --git a/libraries/libmesosphere/source/kern_k_resource_limit.cpp b/libraries/libmesosphere/source/kern_k_resource_limit.cpp index 5ef2e04b5..dca3419dc 100644 --- a/libraries/libmesosphere/source/kern_k_resource_limit.cpp +++ b/libraries/libmesosphere/source/kern_k_resource_limit.cpp @@ -32,6 +32,7 @@ namespace ams::kern { this->limit_values[i] = 0; this->current_values[i] = 0; this->current_hints[i] = 0; + this->peak_values[i] = 0; } */ } @@ -70,6 +71,21 @@ namespace ams::kern { return value; } + s64 KResourceLimit::GetPeakValue(ams::svc::LimitableResource which) const { + MESOSPHERE_ASSERT_THIS(); + + s64 value; + { + KScopedLightLock lk(this->lock); + value = this->peak_values[which]; + MESOSPHERE_ASSERT(value >= 0); + MESOSPHERE_ASSERT(this->current_values[which] <= this->limit_values[which]); + MESOSPHERE_ASSERT(this->current_hints[which] <= this->current_values[which]); + } + + return value; + } + s64 KResourceLimit::GetFreeValue(ams::svc::LimitableResource which) const { MESOSPHERE_ASSERT_THIS(); @@ -124,6 +140,7 @@ namespace ams::kern { if (this->current_values[which] + value <= this->limit_values[which]) { this->current_values[which] += value; this->current_hints[which] += value; + this->peak_values[which] = std::max(this->peak_values[which], this->current_values[which]); return true; } diff --git a/libraries/libmesosphere/source/svc/kern_svc_resource_limit.cpp b/libraries/libmesosphere/source/svc/kern_svc_resource_limit.cpp index de3bdb0c6..3640c614e 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_resource_limit.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_resource_limit.cpp @@ -53,6 +53,20 @@ namespace ams::kern::svc { return ResultSuccess(); } + Result GetResourceLimitPeakValue(int64_t *out_peak_value, ams::svc::Handle resource_limit_handle, ams::svc::LimitableResource which) { + /* Validate the resource. */ + R_UNLESS(IsValidLimitableResource(which), svc::ResultInvalidEnumValue()); + + /* Get the resource limit. */ + KScopedAutoObject resource_limit = GetCurrentProcess().GetHandleTable().GetObject(resource_limit_handle); + R_UNLESS(resource_limit.IsNotNull(), svc::ResultInvalidHandle()); + + /* Get the peak value. */ + *out_peak_value = resource_limit->GetCurrentValue(which); + + return ResultSuccess(); + } + Result CreateResourceLimit(ams::svc::Handle *out_handle) { /* Create a new resource limit. */ KResourceLimit *resource_limit = KResourceLimit::Create(); @@ -99,6 +113,10 @@ namespace ams::kern::svc { return GetResourceLimitCurrentValue(out_current_value, resource_limit_handle, which); } + Result GetResourceLimitPeakValue64(int64_t *out_peak_value, ams::svc::Handle resource_limit_handle, ams::svc::LimitableResource which) { + return GetResourceLimitPeakValue(out_peak_value, resource_limit_handle, which); + } + Result CreateResourceLimit64(ams::svc::Handle *out_handle) { return CreateResourceLimit(out_handle); } @@ -117,6 +135,10 @@ namespace ams::kern::svc { return GetResourceLimitCurrentValue(out_current_value, resource_limit_handle, which); } + Result GetResourceLimitPeakValue64From32(int64_t *out_peak_value, ams::svc::Handle resource_limit_handle, ams::svc::LimitableResource which) { + return GetResourceLimitPeakValue(out_peak_value, resource_limit_handle, which); + } + Result CreateResourceLimit64From32(ams::svc::Handle *out_handle) { return CreateResourceLimit(out_handle); } diff --git a/libraries/libvapours/include/vapours/svc/svc_definitions.hpp b/libraries/libvapours/include/vapours/svc/svc_definitions.hpp index 51bb6faee..47bab8fc8 100644 --- a/libraries/libvapours/include/vapours/svc/svc_definitions.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_definitions.hpp @@ -83,6 +83,7 @@ HANDLER(0x34, Result, WaitForAddress, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::ArbitrationType, arb_type), INPUT(int32_t, value), INPUT(int64_t, timeout_ns)) \ HANDLER(0x35, Result, SignalToAddress, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::SignalType, signal_type), INPUT(int32_t, value), INPUT(int32_t, count)) \ HANDLER(0x36, void, SynchronizePreemptionState) \ + HANDLER(0x37, Result, GetResourceLimitPeakValue, OUTPUT(int64_t, out_peak_value), INPUT(::ams::svc::Handle, resource_limit_handle), INPUT(::ams::svc::LimitableResource, which)) \ \ HANDLER(0x3C, void, KernelDebug, INPUT(::ams::svc::KernelDebugType, kern_debug_type), INPUT(uint64_t, arg0), INPUT(uint64_t, arg1), INPUT(uint64_t, arg2)) \ HANDLER(0x3D, void, ChangeKernelTraceState, INPUT(::ams::svc::KernelTraceState, kern_trace_state)) \ diff --git a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp index 29f4fa1eb..26bf251ec 100644 --- a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp @@ -391,6 +391,9 @@ namespace ams::svc { /* 7.x+ Should memory allocation be optimized? This requires IsApplication. */ CreateProcessFlag_OptimizeMemoryAllocation = (1 << 11), + /* 11.x+ DisableDeviceAddressSpaceMerge. */ + CreateProcessFlag_DisableDeviceAddressSpaceMerge = (1 << 12), + /* Mask of all flags. */ CreateProcessFlag_All = CreateProcessFlag_Is64Bit | CreateProcessFlag_AddressSpaceMask | @@ -398,7 +401,8 @@ namespace ams::svc { CreateProcessFlag_EnableAslr | CreateProcessFlag_IsApplication | CreateProcessFlag_PoolPartitionMask | - CreateProcessFlag_OptimizeMemoryAllocation, + CreateProcessFlag_OptimizeMemoryAllocation | + CreateProcessFlag_DisableDeviceAddressSpaceMerge, }; /* Debug types. */