From 1d6399c222e6c0478193160648cddf43b8d8eff9 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 26 Nov 2018 18:48:07 -0500 Subject: svc: Implement svcGetResourceLimitLimitValue() This kernel service function retrieves the maximum allowable value for a provided resource category for a given resource limit instance. Given we already have the functionality added to the resource limit instance itself, it's sufficient to just hook it up. The error scenarios for this are: 1. If an invalid resource category type is provided, then ERR_INVALID_ENUM is returned. 2. If an invalid handle is provided, then ERR_INVALID_HANDLE is returned (bad thing goes in, bad thing goes out, as one would expect). If neither of the above error cases occur, then the out parameter is provided with the maximum limit value for the given category and success is returned. --- src/core/hle/kernel/resource_limit.h | 6 +++++- src/core/hle/kernel/svc.cpp | 29 ++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h index bec065543..59dc11c22 100644 --- a/src/core/hle/kernel/resource_limit.h +++ b/src/core/hle/kernel/resource_limit.h @@ -14,7 +14,7 @@ namespace Kernel { class KernelCore; -enum class ResourceType { +enum class ResourceType : u32 { PhysicalMemory, Threads, Events, @@ -25,6 +25,10 @@ enum class ResourceType { ResourceTypeCount }; +constexpr bool IsValidResourceType(ResourceType type) { + return type < ResourceType::ResourceTypeCount; +} + class ResourceLimit final : public Object { public: /** diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 4b7991c32..5e604411b 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1364,6 +1364,33 @@ static ResultCode CreateResourceLimit(Handle* out_handle) { return RESULT_SUCCESS; } +static ResultCode GetResourceLimitLimitValue(u64* out_value, Handle resource_limit, + u32 resource_type) { + LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type); + + const auto type = static_cast(resource_type); + if (!IsValidResourceType(type)) { + LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'.", resource_type); + return ERR_INVALID_ENUM_VALUE; + } + + const auto& kernel = Core::System::GetInstance().Kernel(); + const auto* const current_process = kernel.CurrentProcess(); + ASSERT(current_process != nullptr); + + const auto resource_limit_object = + current_process->GetHandleTable().Get(resource_limit); + if (!resource_limit_object) { + LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", + resource_limit); + return ERR_INVALID_HANDLE; + } + + const s64 limit_value = resource_limit_object->GetMaxResourceValue(type); + *out_value = static_cast(limit_value); + return RESULT_SUCCESS; +} + namespace { struct FunctionDef { using Func = void(); @@ -1423,7 +1450,7 @@ static const FunctionDef SVC_Table[] = { {0x2D, nullptr, "UnmapPhysicalMemory"}, {0x2E, nullptr, "GetFutureThreadInfo"}, {0x2F, nullptr, "GetLastThreadInfo"}, - {0x30, nullptr, "GetResourceLimitLimitValue"}, + {0x30, SvcWrap, "GetResourceLimitLimitValue"}, {0x31, nullptr, "GetResourceLimitCurrentValue"}, {0x32, SvcWrap, "SetThreadActivity"}, {0x33, SvcWrap, "GetThreadContext"}, -- cgit v1.2.3