summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2018-11-26 22:59:51 -0500
committerGravatar GitHub2018-11-26 22:59:51 -0500
commit852a462df3b8629791ae982dfe6c54fb6a5fcc5e (patch)
tree5f8c155e870c25840ecfc42c6a3017f7dab12d42 /src/core/hle/kernel/svc.cpp
parentMerge pull request #1794 from Tinob/master (diff)
parentsvc: Implement svcSetResourceLimitLimitValue() (diff)
downloadyuzu-852a462df3b8629791ae982dfe6c54fb6a5fcc5e.tar.gz
yuzu-852a462df3b8629791ae982dfe6c54fb6a5fcc5e.tar.xz
yuzu-852a462df3b8629791ae982dfe6c54fb6a5fcc5e.zip
Merge pull request #1805 from lioncash/resource
svc: Implement svcCreateResourceLimit, svcGetResourceLimitCurrentValue(), svcGetResourceLimitLimitValue(), and svcSetResourceLimitLimitValue()
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp121
1 files changed, 117 insertions, 4 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index f287f7c97..1f19d5576 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -105,6 +105,38 @@ ResultCode MapUnmapMemorySanityChecks(const VMManager& vm_manager, VAddr dst_add
105 105
106 return RESULT_SUCCESS; 106 return RESULT_SUCCESS;
107} 107}
108
109enum class ResourceLimitValueType {
110 CurrentValue,
111 LimitValue,
112};
113
114ResultVal<s64> RetrieveResourceLimitValue(Handle resource_limit, u32 resource_type,
115 ResourceLimitValueType value_type) {
116 const auto type = static_cast<ResourceType>(resource_type);
117 if (!IsValidResourceType(type)) {
118 LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type);
119 return ERR_INVALID_ENUM_VALUE;
120 }
121
122 const auto& kernel = Core::System::GetInstance().Kernel();
123 const auto* const current_process = kernel.CurrentProcess();
124 ASSERT(current_process != nullptr);
125
126 const auto resource_limit_object =
127 current_process->GetHandleTable().Get<ResourceLimit>(resource_limit);
128 if (!resource_limit_object) {
129 LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}",
130 resource_limit);
131 return ERR_INVALID_HANDLE;
132 }
133
134 if (value_type == ResourceLimitValueType::CurrentValue) {
135 return MakeResult(resource_limit_object->GetCurrentResourceValue(type));
136 }
137
138 return MakeResult(resource_limit_object->GetMaxResourceValue(type));
139}
108} // Anonymous namespace 140} // Anonymous namespace
109 141
110/// Set the process heap to a given Size. It can both extend and shrink the heap. 142/// Set the process heap to a given Size. It can both extend and shrink the heap.
@@ -1346,6 +1378,87 @@ static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) {
1346 return RESULT_SUCCESS; 1378 return RESULT_SUCCESS;
1347} 1379}
1348 1380
1381static ResultCode CreateResourceLimit(Handle* out_handle) {
1382 LOG_DEBUG(Kernel_SVC, "called");
1383
1384 auto& kernel = Core::System::GetInstance().Kernel();
1385 auto resource_limit = ResourceLimit::Create(kernel);
1386
1387 auto* const current_process = kernel.CurrentProcess();
1388 ASSERT(current_process != nullptr);
1389
1390 const auto handle = current_process->GetHandleTable().Create(std::move(resource_limit));
1391 if (handle.Failed()) {
1392 return handle.Code();
1393 }
1394
1395 *out_handle = *handle;
1396 return RESULT_SUCCESS;
1397}
1398
1399static ResultCode GetResourceLimitLimitValue(u64* out_value, Handle resource_limit,
1400 u32 resource_type) {
1401 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type);
1402
1403 const auto limit_value = RetrieveResourceLimitValue(resource_limit, resource_type,
1404 ResourceLimitValueType::LimitValue);
1405 if (limit_value.Failed()) {
1406 return limit_value.Code();
1407 }
1408
1409 *out_value = static_cast<u64>(*limit_value);
1410 return RESULT_SUCCESS;
1411}
1412
1413static ResultCode GetResourceLimitCurrentValue(u64* out_value, Handle resource_limit,
1414 u32 resource_type) {
1415 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type);
1416
1417 const auto current_value = RetrieveResourceLimitValue(resource_limit, resource_type,
1418 ResourceLimitValueType::CurrentValue);
1419 if (current_value.Failed()) {
1420 return current_value.Code();
1421 }
1422
1423 *out_value = static_cast<u64>(*current_value);
1424 return RESULT_SUCCESS;
1425}
1426
1427static ResultCode SetResourceLimitLimitValue(Handle resource_limit, u32 resource_type, u64 value) {
1428 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}, Value={}", resource_limit,
1429 resource_type, value);
1430
1431 const auto type = static_cast<ResourceType>(resource_type);
1432 if (!IsValidResourceType(type)) {
1433 LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type);
1434 return ERR_INVALID_ENUM_VALUE;
1435 }
1436
1437 auto& kernel = Core::System::GetInstance().Kernel();
1438 auto* const current_process = kernel.CurrentProcess();
1439 ASSERT(current_process != nullptr);
1440
1441 auto resource_limit_object =
1442 current_process->GetHandleTable().Get<ResourceLimit>(resource_limit);
1443 if (!resource_limit_object) {
1444 LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}",
1445 resource_limit);
1446 return ERR_INVALID_HANDLE;
1447 }
1448
1449 const auto set_result = resource_limit_object->SetLimitValue(type, static_cast<s64>(value));
1450 if (set_result.IsError()) {
1451 LOG_ERROR(
1452 Kernel_SVC,
1453 "Attempted to lower resource limit ({}) for category '{}' below its current value ({})",
1454 resource_limit_object->GetMaxResourceValue(type), resource_type,
1455 resource_limit_object->GetCurrentResourceValue(type));
1456 return set_result;
1457 }
1458
1459 return RESULT_SUCCESS;
1460}
1461
1349namespace { 1462namespace {
1350struct FunctionDef { 1463struct FunctionDef {
1351 using Func = void(); 1464 using Func = void();
@@ -1405,8 +1518,8 @@ static const FunctionDef SVC_Table[] = {
1405 {0x2D, nullptr, "UnmapPhysicalMemory"}, 1518 {0x2D, nullptr, "UnmapPhysicalMemory"},
1406 {0x2E, nullptr, "GetFutureThreadInfo"}, 1519 {0x2E, nullptr, "GetFutureThreadInfo"},
1407 {0x2F, nullptr, "GetLastThreadInfo"}, 1520 {0x2F, nullptr, "GetLastThreadInfo"},
1408 {0x30, nullptr, "GetResourceLimitLimitValue"}, 1521 {0x30, SvcWrap<GetResourceLimitLimitValue>, "GetResourceLimitLimitValue"},
1409 {0x31, nullptr, "GetResourceLimitCurrentValue"}, 1522 {0x31, SvcWrap<GetResourceLimitCurrentValue>, "GetResourceLimitCurrentValue"},
1410 {0x32, SvcWrap<SetThreadActivity>, "SetThreadActivity"}, 1523 {0x32, SvcWrap<SetThreadActivity>, "SetThreadActivity"},
1411 {0x33, SvcWrap<GetThreadContext>, "GetThreadContext"}, 1524 {0x33, SvcWrap<GetThreadContext>, "GetThreadContext"},
1412 {0x34, SvcWrap<WaitForAddress>, "WaitForAddress"}, 1525 {0x34, SvcWrap<WaitForAddress>, "WaitForAddress"},
@@ -1482,8 +1595,8 @@ static const FunctionDef SVC_Table[] = {
1482 {0x7A, nullptr, "StartProcess"}, 1595 {0x7A, nullptr, "StartProcess"},
1483 {0x7B, nullptr, "TerminateProcess"}, 1596 {0x7B, nullptr, "TerminateProcess"},
1484 {0x7C, SvcWrap<GetProcessInfo>, "GetProcessInfo"}, 1597 {0x7C, SvcWrap<GetProcessInfo>, "GetProcessInfo"},
1485 {0x7D, nullptr, "CreateResourceLimit"}, 1598 {0x7D, SvcWrap<CreateResourceLimit>, "CreateResourceLimit"},
1486 {0x7E, nullptr, "SetResourceLimitLimitValue"}, 1599 {0x7E, SvcWrap<SetResourceLimitLimitValue>, "SetResourceLimitLimitValue"},
1487 {0x7F, nullptr, "CallSecureMonitor"}, 1600 {0x7F, nullptr, "CallSecureMonitor"},
1488}; 1601};
1489 1602