svc: Implement SetResourceLimitLimitValues
* Also correct existing name and add missing error codes
This commit is contained in:
@ -16,6 +16,7 @@
|
||||
#include "core/hle/kernel/address_arbiter.h"
|
||||
#include "core/hle/kernel/client_port.h"
|
||||
#include "core/hle/kernel/client_session.h"
|
||||
#include "core/hle/kernel/config_mem.h"
|
||||
#include "core/hle/kernel/errors.h"
|
||||
#include "core/hle/kernel/event.h"
|
||||
#include "core/hle/kernel/handle_table.h"
|
||||
@ -390,6 +391,8 @@ private:
|
||||
VAddr names, u32 name_count);
|
||||
ResultCode GetResourceLimitLimitValues(VAddr values, Handle resource_limit_handle, VAddr names,
|
||||
u32 name_count);
|
||||
ResultCode SetResourceLimitLimitValues(Handle res_limit, VAddr names, VAddr resource_list,
|
||||
u32 name_count);
|
||||
ResultCode CreateThread(Handle* out_handle, u32 entry_point, u32 arg, VAddr stack_top,
|
||||
u32 priority, s32 processor_id);
|
||||
void ExitThread();
|
||||
@ -1074,7 +1077,8 @@ ResultCode SVC::CreateAddressArbiter(Handle* out_handle) {
|
||||
const auto current_process = kernel.GetCurrentProcess();
|
||||
const auto& resource_limit = current_process->resource_limit;
|
||||
if (!resource_limit->Reserve(ResourceLimitType::AddressArbiter, 1)) {
|
||||
return ResultCode{0xC8601833};
|
||||
return ResultCode(ErrCodes::OutOfAddressArbiters, ErrorModule::OS,
|
||||
ErrorSummary::OutOfResource, ErrorLevel::Status);
|
||||
}
|
||||
|
||||
// Create address arbiter.
|
||||
@ -1197,14 +1201,48 @@ ResultCode SVC::GetResourceLimitLimitValues(VAddr values, Handle resource_limit_
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < name_count; ++i) {
|
||||
const u32 name = memory.Read32(names + i * sizeof(u32));
|
||||
const s64 value = resource_limit->GetLimitValue(static_cast<ResourceLimitType>(name));
|
||||
const auto name = static_cast<ResourceLimitType>(memory.Read32(names + i * sizeof(u32)));
|
||||
if (name >= ResourceLimitType::Max) {
|
||||
return ERR_INVALID_ENUM_VALUE;
|
||||
}
|
||||
const s64 value = resource_limit->GetLimitValue(name);
|
||||
memory.Write64(values + i * sizeof(u64), value);
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ResultCode SVC::SetResourceLimitLimitValues(Handle res_limit, VAddr names, VAddr resource_list,
|
||||
u32 name_count) {
|
||||
LOG_TRACE(Kernel_SVC, "called resource_limit={:08X}, names={:08X}, name_count={}", res_limit,
|
||||
names, name_count);
|
||||
|
||||
const auto resource_limit =
|
||||
kernel.GetCurrentProcess()->handle_table.Get<ResourceLimit>(res_limit);
|
||||
if (!resource_limit) {
|
||||
return ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < name_count; ++i) {
|
||||
const auto name = static_cast<ResourceLimitType>(memory.Read32(names + i * sizeof(u32)));
|
||||
if (name >= ResourceLimitType::Max) {
|
||||
return ERR_INVALID_ENUM_VALUE;
|
||||
}
|
||||
const s64 value = memory.Read64(resource_list + i * sizeof(u64));
|
||||
const s32 value_high = value >> 32;
|
||||
if (value_high < 0) {
|
||||
return ERR_OUT_OF_RANGE_KERNEL;
|
||||
}
|
||||
if (name == ResourceLimitType::Commit && value_high != 0) {
|
||||
auto& config_mem = kernel.GetConfigMemHandler().GetConfigMem();
|
||||
config_mem.app_mem_alloc = value_high;
|
||||
}
|
||||
resource_limit->SetLimitValue(name, static_cast<s32>(value));
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/// Creates a new thread
|
||||
ResultCode SVC::CreateThread(Handle* out_handle, u32 entry_point, u32 arg, VAddr stack_top,
|
||||
u32 priority, s32 processor_id) {
|
||||
@ -1250,9 +1288,9 @@ ResultCode SVC::CreateThread(Handle* out_handle, u32 entry_point, u32 arg, VAddr
|
||||
}
|
||||
|
||||
// Update thread count in resource limit.
|
||||
const auto& resource_limit = current_process->resource_limit;
|
||||
if (!resource_limit->Reserve(ResourceLimitType::Thread, 1)) {
|
||||
return ResultCode{0xC860180C};
|
||||
return ResultCode(ErrCodes::OutOfThreads, ErrorModule::OS, ErrorSummary::OutOfResource,
|
||||
ErrorLevel::Status);
|
||||
}
|
||||
|
||||
// Create thread.
|
||||
@ -1331,7 +1369,8 @@ ResultCode SVC::CreateMutex(Handle* out_handle, u32 initial_locked) {
|
||||
const auto current_process = kernel.GetCurrentProcess();
|
||||
const auto& resource_limit = current_process->resource_limit;
|
||||
if (!resource_limit->Reserve(ResourceLimitType::Mutex, 1)) {
|
||||
return ResultCode{0xC860180D};
|
||||
return ResultCode(ErrCodes::OutOfMutexes, ErrorModule::OS, ErrorSummary::OutOfResource,
|
||||
ErrorLevel::Status);
|
||||
}
|
||||
|
||||
// Create mutex.
|
||||
@ -1405,7 +1444,8 @@ ResultCode SVC::CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max_c
|
||||
const auto current_process = kernel.GetCurrentProcess();
|
||||
const auto& resource_limit = current_process->resource_limit;
|
||||
if (!resource_limit->Reserve(ResourceLimitType::Semaphore, 1)) {
|
||||
return ResultCode{0xC860180E};
|
||||
return ResultCode(ErrCodes::OutOfSemaphores, ErrorModule::OS, ErrorSummary::OutOfResource,
|
||||
ErrorLevel::Status);
|
||||
}
|
||||
|
||||
// Create semaphore
|
||||
@ -1501,7 +1541,8 @@ ResultCode SVC::CreateEvent(Handle* out_handle, u32 reset_type) {
|
||||
const auto current_process = kernel.GetCurrentProcess();
|
||||
const auto& resource_limit = current_process->resource_limit;
|
||||
if (!resource_limit->Reserve(ResourceLimitType::Event, 1)) {
|
||||
return ResultCode{0xC860180F};
|
||||
return ResultCode(ErrCodes::OutOfEvents, ErrorModule::OS, ErrorSummary::OutOfResource,
|
||||
ErrorLevel::Status);
|
||||
}
|
||||
|
||||
// Create event.
|
||||
@ -1553,7 +1594,8 @@ ResultCode SVC::CreateTimer(Handle* out_handle, u32 reset_type) {
|
||||
const auto current_process = kernel.GetCurrentProcess();
|
||||
const auto& resource_limit = current_process->resource_limit;
|
||||
if (!resource_limit->Reserve(ResourceLimitType::Timer, 1)) {
|
||||
return ResultCode{0xC8601810};
|
||||
return ResultCode(ErrCodes::OutOfTimers, ErrorModule::OS, ErrorSummary::OutOfResource,
|
||||
ErrorLevel::Status);
|
||||
}
|
||||
|
||||
// Create timer.
|
||||
@ -1711,7 +1753,8 @@ ResultCode SVC::CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my
|
||||
const auto current_process = kernel.GetCurrentProcess();
|
||||
const auto& resource_limit = current_process->resource_limit;
|
||||
if (!resource_limit->Reserve(ResourceLimitType::SharedMemory, 1)) {
|
||||
return ResultCode{0xC860180B};
|
||||
return ResultCode(ErrCodes::OutOfSharedMems, ErrorModule::OS, ErrorSummary::OutOfResource,
|
||||
ErrorLevel::Status);
|
||||
}
|
||||
|
||||
// When trying to create a memory block with address = 0,
|
||||
@ -2282,7 +2325,7 @@ const std::array<SVC::FunctionDef, 180> SVC::SVC_Table{{
|
||||
{0x76, &SVC::Wrap<&SVC::TerminateProcess>, "TerminateProcess"},
|
||||
{0x77, nullptr, "SetProcessResourceLimits"},
|
||||
{0x78, nullptr, "CreateResourceLimit"},
|
||||
{0x79, nullptr, "SetResourceLimitValues"},
|
||||
{0x79, &SVC::Wrap<&SVC::SetResourceLimitLimitValues>, "SetResourceLimitLimitValues"},
|
||||
{0x7A, nullptr, "AddCodeSegment"},
|
||||
{0x7B, nullptr, "Backdoor"},
|
||||
{0x7C, &SVC::Wrap<&SVC::KernelSetState>, "KernelSetState"},
|
||||
|
Reference in New Issue
Block a user