From 78da7422ae4b26f6eb08cab4b7b054a5633e0a50 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 9 Jul 2020 17:49:33 -0700 Subject: [PATCH] kern: implement SvcAcceptSession --- .../include/mesosphere/kern_k_server_port.hpp | 3 ++ .../source/kern_k_server_port.cpp | 32 ++++++++++++++++++ .../libmesosphere/source/kern_k_session.cpp | 2 +- .../source/svc/kern_svc_session.cpp | 33 +++++++++++++++++-- 4 files changed, 67 insertions(+), 3 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_server_port.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_server_port.hpp index 886171873..339f7381f 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_server_port.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_server_port.hpp @@ -41,6 +41,9 @@ namespace ams::kern { void EnqueueSession(KServerSession *session); void EnqueueSession(KLightServerSession *session); + KServerSession *AcceptSession(); + KLightServerSession *AcceptLightSession(); + constexpr const KPort *GetParent() const { return this->parent; } bool IsLight() const; diff --git a/libraries/libmesosphere/source/kern_k_server_port.cpp b/libraries/libmesosphere/source/kern_k_server_port.cpp index cbb8b93e1..9aff70a91 100644 --- a/libraries/libmesosphere/source/kern_k_server_port.cpp +++ b/libraries/libmesosphere/source/kern_k_server_port.cpp @@ -119,4 +119,36 @@ namespace ams::kern { } } + KServerSession *KServerPort::AcceptSession() { + MESOSPHERE_ASSERT_THIS(); + MESOSPHERE_ASSERT(!this->IsLight()); + + KScopedSchedulerLock sl; + + /* Return the first session in the list. */ + if (this->session_list.empty()) { + return nullptr; + } + + KServerSession *session = std::addressof(this->session_list.front()); + this->session_list.pop_front(); + return session; + } + + KLightServerSession *KServerPort::AcceptLightSession() { + MESOSPHERE_ASSERT_THIS(); + MESOSPHERE_ASSERT(this->IsLight()); + + KScopedSchedulerLock sl; + + /* Return the first session in the list. */ + if (this->light_session_list.empty()) { + return nullptr; + } + + KLightServerSession *session = std::addressof(this->light_session_list.front()); + this->light_session_list.pop_front(); + return session; + } + } diff --git a/libraries/libmesosphere/source/kern_k_session.cpp b/libraries/libmesosphere/source/kern_k_session.cpp index 7b56d268e..2194842d2 100644 --- a/libraries/libmesosphere/source/kern_k_session.cpp +++ b/libraries/libmesosphere/source/kern_k_session.cpp @@ -43,7 +43,7 @@ namespace ams::kern { this->process->Open(); /* Set our port. */ - this->port = port; + this->port = client_port; if (this->port != nullptr) { this->port->Open(); } diff --git a/libraries/libmesosphere/source/svc/kern_svc_session.cpp b/libraries/libmesosphere/source/svc/kern_svc_session.cpp index 36e540c0b..55ab32647 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_session.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_session.cpp @@ -21,7 +21,36 @@ namespace ams::kern::svc { namespace { + Result AcceptSession(ams::svc::Handle *out, ams::svc::Handle port_handle) { + /* Get the current handle table. */ + auto &handle_table = GetCurrentProcess().GetHandleTable(); + /* Get the server port. */ + KScopedAutoObject port = handle_table.GetObject(port_handle); + R_UNLESS(port.IsNotNull(), svc::ResultInvalidHandle()); + + /* Reserve an entry for the new session. */ + R_TRY(handle_table.Reserve(out)); + auto handle_guard = SCOPE_GUARD { handle_table.Unreserve(*out); }; + + /* Accept the session. */ + KAutoObject *session; + if (port->IsLight()) { + session = port->AcceptLightSession(); + } else { + session = port->AcceptSession(); + } + + /* Ensure we accepted successfully. */ + R_UNLESS(session != nullptr, svc::ResultNotFound()); + + /* Register the session. */ + handle_table.Register(*out, session); + handle_guard.Cancel(); + session->Close(); + + return ResultSuccess(); + } } @@ -32,7 +61,7 @@ namespace ams::kern::svc { } Result AcceptSession64(ams::svc::Handle *out_handle, ams::svc::Handle port) { - MESOSPHERE_PANIC("Stubbed SvcAcceptSession64 was called."); + return AcceptSession(out_handle, port); } /* ============================= 64From32 ABI ============================= */ @@ -42,7 +71,7 @@ namespace ams::kern::svc { } Result AcceptSession64From32(ams::svc::Handle *out_handle, ams::svc::Handle port) { - MESOSPHERE_PANIC("Stubbed SvcAcceptSession64From32 was called."); + return AcceptSession(out_handle, port); } }