Merge pull request #1857 from lioncash/res-info

kernel/svc: Implement the resource limit svcGetInfo option
merge-requests/60/head
bunnei 2018-12-04 12:23:19 +07:00 committed by GitHub
commit da5659fb87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 37 additions and 11 deletions

@ -42,9 +42,10 @@ ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) {
u16 generation = next_generation++; u16 generation = next_generation++;
// Overflow count so it fits in the 15 bits dedicated to the generation in the handle. // Overflow count so it fits in the 15 bits dedicated to the generation in the handle.
// CTR-OS doesn't use generation 0, so skip straight to 1. // Horizon OS uses zero to represent an invalid handle, so skip to 1.
if (next_generation >= (1 << 15)) if (next_generation >= (1 << 15)) {
next_generation = 1; next_generation = 1;
}
generations[slot] = generation; generations[slot] = generation;
objects[slot] = std::move(obj); objects[slot] = std::move(obj);

@ -13,6 +13,7 @@
namespace Kernel { namespace Kernel {
enum KernelHandle : Handle { enum KernelHandle : Handle {
InvalidHandle = 0,
CurrentThread = 0xFFFF8000, CurrentThread = 0xFFFF8000,
CurrentProcess = 0xFFFF8001, CurrentProcess = 0xFFFF8001,
}; };

@ -44,6 +44,10 @@ SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) {
return process; return process;
} }
SharedPtr<ResourceLimit> Process::GetResourceLimit() const {
return resource_limit;
}
void Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { void Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) {
program_id = metadata.GetTitleID(); program_id = metadata.GetTitleID();
is_64bit_process = metadata.Is64BitProgram(); is_64bit_process = metadata.Is64BitProgram();

@ -171,14 +171,7 @@ public:
} }
/// Gets the resource limit descriptor for this process /// Gets the resource limit descriptor for this process
ResourceLimit& GetResourceLimit() { SharedPtr<ResourceLimit> GetResourceLimit() const;
return *resource_limit;
}
/// Gets the resource limit descriptor for this process
const ResourceLimit& GetResourceLimit() const {
return *resource_limit;
}
/// Gets the default CPU ID for this process /// Gets the default CPU ID for this process
u8 GetDefaultProcessorID() const { u8 GetDefaultProcessorID() const {

@ -663,7 +663,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
TotalMemoryUsage = 6, TotalMemoryUsage = 6,
TotalHeapUsage = 7, TotalHeapUsage = 7,
IsCurrentProcessBeingDebugged = 8, IsCurrentProcessBeingDebugged = 8,
ResourceHandleLimit = 9, RegisterResourceLimit = 9,
IdleTickCount = 10, IdleTickCount = 10,
RandomEntropy = 11, RandomEntropy = 11,
PerformanceCounter = 0xF0000002, PerformanceCounter = 0xF0000002,
@ -787,6 +787,33 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
*result = 0; *result = 0;
return RESULT_SUCCESS; return RESULT_SUCCESS;
case GetInfoType::RegisterResourceLimit: {
if (handle != 0) {
return ERR_INVALID_HANDLE;
}
if (info_sub_id != 0) {
return ERR_INVALID_COMBINATION;
}
Process* const current_process = Core::CurrentProcess();
HandleTable& handle_table = current_process->GetHandleTable();
const auto resource_limit = current_process->GetResourceLimit();
if (!resource_limit) {
*result = KernelHandle::InvalidHandle;
// Yes, the kernel considers this a successful operation.
return RESULT_SUCCESS;
}
const auto table_result = handle_table.Create(resource_limit);
if (table_result.Failed()) {
return table_result.Code();
}
*result = *table_result;
return RESULT_SUCCESS;
}
case GetInfoType::RandomEntropy: case GetInfoType::RandomEntropy:
if (handle != 0) { if (handle != 0) {
LOG_ERROR(Kernel_SVC, "Process Handle is non zero, expected 0 result but got {:016X}", LOG_ERROR(Kernel_SVC, "Process Handle is non zero, expected 0 result but got {:016X}",