diff options
| author | 2018-01-15 15:31:10 -0500 | |
|---|---|---|
| committer | 2018-01-16 18:42:08 -0500 | |
| commit | 5bc14e791a8b4260dbf130d2e8724e394db4205c (patch) | |
| tree | b5a6e4a6fe2c3d15ce3a7facba12ec62dd16fc38 /src/core | |
| parent | Merge pull request #52 from ogniK5377/fsp (diff) | |
| download | yuzu-5bc14e791a8b4260dbf130d2e8724e394db4205c.tar.gz yuzu-5bc14e791a8b4260dbf130d2e8724e394db4205c.tar.xz yuzu-5bc14e791a8b4260dbf130d2e8724e394db4205c.zip | |
IPC: Push domain objects as move handles when not in a domain.
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/ipc_helpers.h | 22 | ||||
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.h | 8 |
2 files changed, 28 insertions, 2 deletions
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index 0f1077d9e..25530a3c8 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h | |||
| @@ -9,10 +9,13 @@ | |||
| 9 | #include <type_traits> | 9 | #include <type_traits> |
| 10 | #include <utility> | 10 | #include <utility> |
| 11 | #include "core/hle/ipc.h" | 11 | #include "core/hle/ipc.h" |
| 12 | #include "core/hle/kernel/client_port.h" | ||
| 13 | #include "core/hle/kernel/client_session.h" | ||
| 12 | #include "core/hle/kernel/domain.h" | 14 | #include "core/hle/kernel/domain.h" |
| 13 | #include "core/hle/kernel/handle_table.h" | 15 | #include "core/hle/kernel/handle_table.h" |
| 14 | #include "core/hle/kernel/hle_ipc.h" | 16 | #include "core/hle/kernel/hle_ipc.h" |
| 15 | #include "core/hle/kernel/kernel.h" | 17 | #include "core/hle/kernel/kernel.h" |
| 18 | #include "core/hle/kernel/server_port.h" | ||
| 16 | 19 | ||
| 17 | namespace IPC { | 20 | namespace IPC { |
| 18 | 21 | ||
| @@ -63,13 +66,20 @@ public: | |||
| 63 | : RequestHelperBase(context) { | 66 | : RequestHelperBase(context) { |
| 64 | memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH); | 67 | memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH); |
| 65 | 68 | ||
| 69 | context.ClearIncomingObjects(); | ||
| 70 | |||
| 66 | IPC::CommandHeader header{}; | 71 | IPC::CommandHeader header{}; |
| 67 | 72 | ||
| 68 | // The entire size of the raw data section in u32 units, including the 16 bytes of mandatory | 73 | // The entire size of the raw data section in u32 units, including the 16 bytes of mandatory |
| 69 | // padding. | 74 | // padding. |
| 70 | u32 raw_data_size = sizeof(IPC::DataPayloadHeader) / 4 + 4 + normal_params_size; | 75 | u32 raw_data_size = sizeof(IPC::DataPayloadHeader) / 4 + 4 + normal_params_size; |
| 71 | if (context.IsDomain()) | 76 | if (context.IsDomain()) { |
| 72 | raw_data_size += sizeof(DomainMessageHeader) / 4 + num_domain_objects; | 77 | raw_data_size += sizeof(DomainMessageHeader) / 4 + num_domain_objects; |
| 78 | } else { | ||
| 79 | // If we're not in a domain, turn the domain object parameters into move handles. | ||
| 80 | num_handles_to_move += num_domain_objects; | ||
| 81 | num_domain_objects = 0; | ||
| 82 | } | ||
| 73 | 83 | ||
| 74 | header.data_size.Assign(raw_data_size); | 84 | header.data_size.Assign(raw_data_size); |
| 75 | if (num_handles_to_copy || num_handles_to_move) { | 85 | if (num_handles_to_copy || num_handles_to_move) { |
| @@ -100,7 +110,15 @@ public: | |||
| 100 | 110 | ||
| 101 | template <class T, class... Args> | 111 | template <class T, class... Args> |
| 102 | void PushIpcInterface(Args&&... args) { | 112 | void PushIpcInterface(Args&&... args) { |
| 103 | context->AddDomainObject(std::make_shared<T>(std::forward<Args>(args)...)); | 113 | auto iface = std::make_shared<T>(std::forward<Args>(args)...); |
| 114 | if (context->IsDomain()) { | ||
| 115 | context->AddDomainObject(std::move(iface)); | ||
| 116 | } else { | ||
| 117 | auto port = iface->CreatePort(); | ||
| 118 | auto session = port->Connect(); | ||
| 119 | ASSERT(session.Succeeded()); | ||
| 120 | context->AddMoveObject(std::move(session).Unwrap()); | ||
| 121 | } | ||
| 104 | } | 122 | } |
| 105 | 123 | ||
| 106 | // Validate on destruction, as there shouldn't be any case where we don't want it | 124 | // Validate on destruction, as there shouldn't be any case where we don't want it |
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 164c6db69..6dceb766d 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h | |||
| @@ -175,6 +175,14 @@ public: | |||
| 175 | domain_objects.emplace_back(std::move(object)); | 175 | domain_objects.emplace_back(std::move(object)); |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | /// Clears the list of objects so that no lingering objects are written accidentally to the | ||
| 179 | /// response buffer. | ||
| 180 | void ClearIncomingObjects() { | ||
| 181 | move_objects.clear(); | ||
| 182 | copy_objects.clear(); | ||
| 183 | domain_objects.clear(); | ||
| 184 | } | ||
| 185 | |||
| 178 | private: | 186 | private: |
| 179 | std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; | 187 | std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; |
| 180 | SharedPtr<Kernel::Domain> domain; | 188 | SharedPtr<Kernel::Domain> domain; |