From 5905162e364abe8312cd95dd04555aaefcfc2293 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 26 Nov 2018 19:51:09 -0500 Subject: svc: Implement svcSetResourceLimitLimitValue() The opposite of the getter functions, this function sets the limit value for a particular ResourceLimit resource category, with the restriction that the new limit value must be equal to or greater than the current resource value. If this is violated, then ERR_INVALID_STATE is returned. e.g. Assume: current[Events] = 10; limit[Events] = 20; a call to this service function lowering the limit value to 10 would be fine, however, attempting to lower it to 9 in this case would cause an invalid state error. --- src/core/hle/kernel/svc.cpp | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'src/core/hle/kernel/svc.cpp') diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 9d1b000b5..1f19d5576 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1424,6 +1424,41 @@ static ResultCode GetResourceLimitCurrentValue(u64* out_value, Handle resource_l return RESULT_SUCCESS; } +static ResultCode SetResourceLimitLimitValue(Handle resource_limit, u32 resource_type, u64 value) { + LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}, Value={}", resource_limit, + resource_type, value); + + 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; + } + + auto& kernel = Core::System::GetInstance().Kernel(); + auto* const current_process = kernel.CurrentProcess(); + ASSERT(current_process != nullptr); + + 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 auto set_result = resource_limit_object->SetLimitValue(type, static_cast(value)); + if (set_result.IsError()) { + LOG_ERROR( + Kernel_SVC, + "Attempted to lower resource limit ({}) for category '{}' below its current value ({})", + resource_limit_object->GetMaxResourceValue(type), resource_type, + resource_limit_object->GetCurrentResourceValue(type)); + return set_result; + } + + return RESULT_SUCCESS; +} + namespace { struct FunctionDef { using Func = void(); @@ -1561,7 +1596,7 @@ static const FunctionDef SVC_Table[] = { {0x7B, nullptr, "TerminateProcess"}, {0x7C, SvcWrap, "GetProcessInfo"}, {0x7D, SvcWrap, "CreateResourceLimit"}, - {0x7E, nullptr, "SetResourceLimitLimitValue"}, + {0x7E, SvcWrap, "SetResourceLimitLimitValue"}, {0x7F, nullptr, "CallSecureMonitor"}, }; -- cgit v1.2.3