Fixes for control IPC (#57)

* Correctly handle -WithContext IPC Requests

They should be treated the same as the non WithContext variants.

* Only send domain data on non-control IPC responses

Control IPC doesn't make use of domains so we shouldn't send extra data
in the response.

* Add the IStorage implementation to CMakeLists
This commit is contained in:
Billy Laws 2020-06-23 19:49:06 +01:00 committed by GitHub
parent 8d470d3218
commit c423a66020
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 14 additions and 15 deletions

View File

@ -83,6 +83,7 @@ add_library(skyline SHARED
${source_DIR}/skyline/services/timesrv/ITimeZoneService.cpp
${source_DIR}/skyline/services/fssrv/IFileSystemProxy.cpp
${source_DIR}/skyline/services/fssrv/IFileSystem.cpp
${source_DIR}/skyline/services/fssrv/IStorage.cpp
${source_DIR}/skyline/services/nvdrv/INvDrvServices.cpp
${source_DIR}/skyline/services/nvdrv/devices/nvmap.cpp
${source_DIR}/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.cpp

View File

@ -76,7 +76,7 @@ namespace skyline::kernel::ipc {
auto padding = util::AlignUp(offset, constant::IpcPaddingSum) - offset; // Calculate the amount of padding at the front
pointer += padding;
if (isDomain && (header->type == CommandType::Request)) {
if (isDomain && (header->type == CommandType::Request || header->type == CommandType::RequestWithContext)) {
domain = reinterpret_cast<DomainHeaderRequest *>(pointer);
pointer += sizeof(DomainHeaderRequest);
@ -102,7 +102,7 @@ namespace skyline::kernel::ipc {
payloadOffset = cmdArg;
if (payload->magic != util::MakeMagic<u32>("SFCI") && header->type != CommandType::Control) // SFCI is the magic in received IPC messages
if (payload->magic != util::MakeMagic<u32>("SFCI") && (header->type != CommandType::Control && header->type != CommandType::ControlWithContext)) // SFCI is the magic in received IPC messages
state.logger->Debug("Unexpected Magic in PayloadHeader: 0x{:X}", u32(payload->magic));
pointer += constant::IpcPaddingSum - padding;
@ -124,7 +124,7 @@ namespace skyline::kernel::ipc {
}
}
if (header->type == CommandType::Request) {
if (header->type == CommandType::Request || header->type == CommandType::RequestWithContext) {
state.logger->Debug("Header: Input No: {}, Output No: {}, Raw Size: {}", inputBuf.size(), outputBuf.size(), u64(cmdArgSz));
if (header->handleDesc)
state.logger->Debug("Handle Descriptor: Send PID: {}, Copy Count: {}, Move Count: {}", bool(handleDesc->sendPid), u32(handleDesc->copyCount), u32(handleDesc->moveCount));
@ -134,9 +134,9 @@ namespace skyline::kernel::ipc {
}
}
IpcResponse::IpcResponse(bool isDomain, const DeviceState &state) : isDomain(isDomain), state(state) {}
IpcResponse::IpcResponse(const DeviceState &state) : state(state) {}
void IpcResponse::WriteResponse() {
void IpcResponse::WriteResponse(bool isDomain) {
auto tls = state.process->GetPointer<u8>(state.thread->tls);
u8 *pointer = tls;

View File

@ -310,8 +310,6 @@ namespace skyline {
std::vector<u8> payload; //!< This holds all of the contents to be pushed to the payload
public:
bool nWrite{}; //!< This is to signal the IPC handler to not write this, as it will be manually written
bool isDomain{}; //!< If this is a domain request
u32 errorCode{}; //!< The error code to respond with, it is 0 (Success) by default
std::vector<KHandle> copyHandles; //!< A vector of handles to copy
std::vector<KHandle> moveHandles; //!< A vector of handles to move
@ -321,7 +319,7 @@ namespace skyline {
* @param isDomain If the following request is a domain request
* @param state The state of the device
*/
IpcResponse(bool isDomain, const DeviceState &state);
IpcResponse(const DeviceState &state);
/**
* @brief Writes an object to the payload
@ -350,8 +348,9 @@ namespace skyline {
/**
* @brief Writes this IpcResponse object's contents into TLS
* @param isDomain Indicates if this is a domain response
*/
void WriteResponse();
void WriteResponse(bool isDomain);
};
}
}

View File

@ -82,7 +82,7 @@ namespace skyline::service {
std::lock_guard serviceGuard(mutex);
auto serviceObject = CreateService(ServiceString.at(serviceName));
KHandle handle{};
if (response.isDomain) {
if (session.isDomain) {
session.domainTable[++session.handleIndex] = serviceObject;
response.domainObjects.push_back(session.handleIndex);
handle = session.handleIndex;
@ -97,7 +97,7 @@ namespace skyline::service {
void ServiceManager::RegisterService(std::shared_ptr<BaseService> serviceObject, type::KSession &session, ipc::IpcResponse &response, bool submodule) { // NOLINT(performance-unnecessary-value-param)
std::lock_guard serviceGuard(mutex);
KHandle handle{};
if (response.isDomain) {
if (session.isDomain) {
session.domainTable[session.handleIndex] = serviceObject;
response.domainObjects.push_back(session.handleIndex);
handle = session.handleIndex++;
@ -131,7 +131,7 @@ namespace skyline::service {
if (session->serviceStatus == type::KSession::ServiceStatus::Open) {
ipc::IpcRequest request(session->isDomain, state);
ipc::IpcResponse response(session->isDomain, state);
ipc::IpcResponse response(state);
switch (request.header->type) {
case ipc::CommandType::Request:
@ -154,8 +154,7 @@ namespace skyline::service {
} else {
session->serviceObject->HandleRequest(*session, request, response);
}
if (!response.nWrite)
response.WriteResponse();
response.WriteResponse(session->isDomain);
break;
case ipc::CommandType::Control:
case ipc::CommandType::ControlWithContext:
@ -174,7 +173,7 @@ namespace skyline::service {
default:
throw exception("Unknown Control Command: {}", request.payload->value);
}
response.WriteResponse();
response.WriteResponse(false);
break;
case ipc::CommandType::Close:
state.logger->Debug("Closing Session");