diff options
| author | 2018-11-26 22:59:51 -0500 | |
|---|---|---|
| committer | 2018-11-26 22:59:51 -0500 | |
| commit | 852a462df3b8629791ae982dfe6c54fb6a5fcc5e (patch) | |
| tree | 5f8c155e870c25840ecfc42c6a3017f7dab12d42 /src/core/hle/kernel/svc.cpp | |
| parent | Merge pull request #1794 from Tinob/master (diff) | |
| parent | svc: Implement svcSetResourceLimitLimitValue() (diff) | |
| download | yuzu-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.cpp | 121 |
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 | |||
| 109 | enum class ResourceLimitValueType { | ||
| 110 | CurrentValue, | ||
| 111 | LimitValue, | ||
| 112 | }; | ||
| 113 | |||
| 114 | ResultVal<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 | ||
| 1381 | static 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 | |||
| 1399 | static 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 | |||
| 1413 | static 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 | |||
| 1427 | static 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 | |||
| 1349 | namespace { | 1462 | namespace { |
| 1350 | struct FunctionDef { | 1463 | struct 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 | ||